Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5

Peet Bros Anemometer > WeatherDuino converter
#2

I need some help Huh 


I now have a working converter for direction (pulses to analog 0-5V)  BUT the output of the speed is in MPH!

For the WD we need pulses as input but Peet Bros has THREE calibration calculations (see previous post)
which must then be done in th WD software?!

what's the best way to move forward here...?

Thanks!


Idea I bought a MCP4725 DAC to convert the direction from degrees into analog output but this is not yet incorporated in the sketch below...
Code:
// Peet Bros wind sensor convertor


#define windSpeedPin 2
#define windDirPin 3
#define windSpeedINT 0 // INT0
#define windDirINT 1   // INT1

#define windSpeedOutPin 8
#define windDirOutPin   9

// Pin 13 has an LED connected on most Arduino boards.
int LED = 13;

const unsigned long DEBOUNCE = 10000ul;      // Minimum switch time in microseconds
const unsigned long DIRECTION_OFFSET = 0ul;  // Manual direction offset in degrees, if required
const unsigned long TIMEOUT = 1500000ul;       // Maximum time allowed between speed pulses in microseconds
const unsigned long UPDATE_RATE = 500ul;     // How often to send out NMEA data in milliseconds

volatile unsigned long speedPulse = 0ul;    // Time capture of speed pulse
volatile unsigned long dirPulse = 0ul;      // Time capture of direction pulse
volatile unsigned long speedTime = 0ul;     // Time between speed pulses (microseconds)
volatile unsigned long directionTime = 0ul; // Time between direction pulses (microseconds)
volatile boolean newData = false;           // New speed pulse received
volatile unsigned long lastUpdate = 0ul;    // Time of last serial output
int windDirection = 0;
volatile boolean ignoreNextReading = false;

boolean debug = true;

void setup()
{
 pinMode(LED, OUTPUT);
 pinMode(windSpeedOutPin, OUTPUT);
 pinMode(windDirOutPin, OUTPUT);

 Serial.begin(115200, SERIAL_8N1);

 pinMode(windSpeedPin, INPUT_PULLUP);
 attachInterrupt(windSpeedINT, readWindSpeed, FALLING);

 pinMode(windDirPin, INPUT_PULLUP);
 attachInterrupt(windDirINT, readWindDir, FALLING);

 interrupts();
}


void readWindSpeed()
{
 // Despite the interrupt being set to FALLING edge, double check the pin is now LOW
 if (((micros() - speedPulse) > DEBOUNCE) && (digitalRead(windSpeedPin) == LOW))
 {
   // Work out time difference between last pulse and now
   speedTime = micros() - speedPulse;

   // Direction pulse should have occured after the last speed pulse
   if (dirPulse - speedPulse >= 0) directionTime = dirPulse - speedPulse;

   newData = true;
   speedPulse = micros();    // Capture time of the new speed pulse
 }
}

void readWindDir()
{
 if (((micros() - dirPulse) > DEBOUNCE) && (digitalRead(windDirPin) == LOW))
 {
   dirPulse = micros();        // Capture time of direction pulse
 }
}

void calcWindSpeedAndDir()
{
 unsigned long dirPulse_, speedPulse_;
 unsigned long speedTime_;
 unsigned long directionTime_;
 unsigned long windDirection = 0l, rps = 0l, mph = 0l;
// Peet Bros wind sensor convertor


#define windSpeedPin 2
#define windDirPin 3
#define windSpeedINT 0 // INT0
#define windDirINT 1   // INT1

#define windSpeedOutPin 8
#define windDirOutPin   9

// Pin 13 has an LED connected on most Arduino boards.
int LED = 13;

const unsigned long DEBOUNCE = 10000ul;      // Minimum switch time in microseconds
const unsigned long DIRECTION_OFFSET = 0ul;  // Manual direction offset in degrees, if required
const unsigned long TIMEOUT = 1500000ul;       // Maximum time allowed between speed pulses in microseconds
const unsigned long UPDATE_RATE = 500ul;     // How often to send out NMEA data in milliseconds

volatile unsigned long speedPulse = 0ul;    // Time capture of speed pulse
volatile unsigned long dirPulse = 0ul;      // Time capture of direction pulse
volatile unsigned long speedTime = 0ul;     // Time between speed pulses (microseconds)
volatile unsigned long directionTime = 0ul; // Time between direction pulses (microseconds)
volatile boolean newData = false;           // New speed pulse received
volatile unsigned long lastUpdate = 0ul;    // Time of last serial output
int windDirection = 0;
volatile boolean ignoreNextReading = false;

boolean debug = true;

void setup()
{
  pinMode(LED, OUTPUT);
  pinMode(windSpeedOutPin, OUTPUT);
  pinMode(windDirOutPin, OUTPUT);

  Serial.begin(115200, SERIAL_8N1);

  pinMode(windSpeedPin, INPUT_PULLUP);
  attachInterrupt(windSpeedINT, readWindSpeed, FALLING);

  pinMode(windDirPin, INPUT_PULLUP);
  attachInterrupt(windDirINT, readWindDir, FALLING);

  interrupts();
}


void readWindSpeed()
{
  // Despite the interrupt being set to FALLING edge, double check the pin is now LOW
  if (((micros() - speedPulse) > DEBOUNCE) && (digitalRead(windSpeedPin) == LOW))
  {
    // Work out time difference between last pulse and now
    speedTime = micros() - speedPulse;

    // Direction pulse should have occured after the last speed pulse
    if (dirPulse - speedPulse >= 0) directionTime = dirPulse - speedPulse;

    newData = true;
    speedPulse = micros();    // Capture time of the new speed pulse
  }
}

void readWindDir()
{
  if (((micros() - dirPulse) > DEBOUNCE) && (digitalRead(windDirPin) == LOW))
  {
    dirPulse = micros();        // Capture time of direction pulse
  }
}

void calcWindSpeedAndDir()
{
  unsigned long dirPulse_, speedPulse_;
  unsigned long speedTime_;
  unsigned long directionTime_;
  unsigned long windDirection = 0l, rps = 0l, mph = 0l;

  // Get snapshot of data into local variables. Note: an interrupt could trigger here
  noInterrupts();
  dirPulse_ = dirPulse;
  speedPulse_ = speedPulse;
  speedTime_ = speedTime;
  directionTime_ = directionTime;
  interrupts();

  // Make speed zero, if the pulse delay is too long
  if (micros() - speedPulse_ > TIMEOUT) speedTime_ = 0ul;

  // The following converts revolutions per 100 seconds (rps) to mph x 100
  // This calculation follows the Peet Bros. piecemeal calibration data
  if (speedTime_ > 0)
  {

    // to prevent calculation errors with float numbers, make them larger
    rps = 100000000 / speedTime_;

    if (1 < rps && rps < 323)
    {
      //      float mph = (-0.1095 * (rps * rps)) + (2.9318 * rps) - 0.1412;
      mph = (-1095 * rps * rps + 29318 * rps * 100 - 14120000) / 1000000;
    }
    else if (323 <= rps && rps < 5436)
    {
      //            mph = 0.0052 * (rps * rps) + 2.1980 * rps + 1.1091;
      mph = (52 * rps * rps + 21980 * rps * 100 + 110910000) / 1000000;
    }
    else if (5436 <= rps && rps < 6633)
    {
      //            mph = 0.1104 * (rps * rps) - 9.5685 * rps + 329.87;
      mph = (1104 * rps * rps - 95685 * rps * 100 + 32987000000) / 1000000;
    }

    
    // Remove the possibility of negative speed
    if (mph < 0l) mph = 0l;
    
    // only calculate direction if we have wind
    if (mph >= 0)
    {
      // Calculate direction from captured pulse times
      windDirection = ( ( (directionTime_ * 360) / speedTime_) + DIRECTION_OFFSET) % 360;
    }
    else
    {
      mph = 0;
    }

    //============================================
    // output to Weatherduino

    //int degrees2analog = map(dirOut, 0, 360, 0, 255);
    analogWrite(windDirOutPin, map(windDirection, 0, 360, 0, 255));

    //============================================


    if (debug)
    {
      Serial.print("speedTime_: "); Serial.println(speedTime_);
      Serial.print("rps: "); Serial.println(rps);
      Serial.print("dir: "); Serial.println(windDirection);
      Serial.print("mph: "); Serial.println(mph);
      Serial.println("");
    }
  }
}


void loop()
{
  int i;
  const unsigned int LOOP_DELAY = 50;
  const unsigned int LOOP_TIME = TIMEOUT / LOOP_DELAY;

  digitalWrite(LED, !digitalRead(LED));    // Toggle LED

  i = 0;
  // If there is new data, process // Peet Bros wind sensor convertor


#define windSpeedPin 2
#define windDirPin 3
#define windSpeedINT 0 // INT0
#define windDirINT 1   // INT1

#define windSpeedOutPin 8
#define windDirOutPin   9

// Pin 13 has an LED connected on most Arduino boards.
int LED = 13;

const unsigned long DEBOUNCE = 10000ul;      // Minimum switch time in microseconds
const unsigned long DIRECTION_OFFSET = 0ul;  // Manual direction offset in degrees, if required
const unsigned long TIMEOUT = 1500000ul;       // Maximum time allowed between speed pulses in microseconds
const unsigned long UPDATE_RATE = 500ul;     // How often to send out NMEA data in milliseconds

volatile unsigned long speedPulse = 0ul;    // Time capture of speed pulse
volatile unsigned long dirPulse = 0ul;      // Time capture of direction pulse
volatile unsigned long speedTime = 0ul;     // Time between speed pulses (microseconds)
volatile unsigned long directionTime = 0ul; // Time between direction pulses (microseconds)
volatile boolean newData = false;           // New speed pulse received
volatile unsigned long lastUpdate = 0ul;    // Time of last serial output
int windDirection = 0;
volatile boolean ignoreNextReading = false;

boolean debug = true;

void setup()
{
  pinMode(LED, OUTPUT);
  pinMode(windSpeedOutPin, OUTPUT);
  pinMode(windDirOutPin, OUTPUT);

  Serial.begin(115200, SERIAL_8N1);

  pinMode(windSpeedPin, INPUT_PULLUP);
  attachInterrupt(windSpeedINT, readWindSpeed, FALLING);

  pinMode(windDirPin, INPUT_PULLUP);
  attachInterrupt(windDirINT, readWindDir, FALLING);

  interrupts();
}


void readWindSpeed()
{
  // Despite the interrupt being set to FALLING edge, double check the pin is now LOW
  if (((micros() - speedPulse) > DEBOUNCE) && (digitalRead(windSpeedPin) == LOW))
  {
    // Work out time difference between last pulse and now
    speedTime = micros() - speedPulse;

    // Direction pulse should have occured after the last speed pulse
    if (dirPulse - speedPulse >= 0) directionTime = dirPulse - speedPulse;

    newData = true;
    speedPulse = micros();    // Capture time of the new speed pulse
  }
}

void readWindDir()
{
  if (((micros() - dirPulse) > DEBOUNCE) && (digitalRead(windDirPin) == LOW))
  {
    dirPulse = micros();        // Capture time of direction pulse
  }
}

void calcWindSpeedAndDir()
{
  unsigned long dirPulse_, speedPulse_;
  unsigned long speedTime_;
  unsigned long directionTime_;
  unsigned long windDirection = 0l, rps = 0l, mph = 0l;

  // Get snapshot of data into local variables. Note: an interrupt could trigger here
  noInterrupts();
  dirPulse_ = dirPulse;
  speedPulse_ = speedPulse;
  speedTime_ = speedTime;
  directionTime_ = directionTime;
  interrupts();

  // Make speed zero, if the pulse delay is too long
  if (micros() - speedPulse_ > TIMEOUT) speedTime_ = 0ul;

  // The following converts revolutions per 100 seconds (rps) to mph x 100
  // This calculation follows the Peet Bros. piecemeal calibration data
  if (speedTime_ > 0)
  {

    // to prevent calculation errors with float numbers, make them larger
    rps = 100000000 / speedTime_;

    if (1 < rps && rps < 323)
    {
      //      float mph = (-0.1095 * (rps * rps)) + (2.9318 * rps) - 0.1412;
      mph = (-1095 * rps * rps + 29318 * rps * 100 - 14120000) / 1000000;
    }
    else if (323 <= rps && rps < 5436)
    {
      //            mph = 0.0052 * (rps * rps) + 2.1980 * rps + 1.1091;
      mph = (52 * rps * rps + 21980 * rps * 100 + 110910000) / 1000000;
    }
    else if (5436 <= rps && rps < 6633)
    {
      //            mph = 0.1104 * (rps * rps) - 9.5685 * rps + 329.87;
      mph = (1104 * rps * rps - 95685 * rps * 100 + 32987000000) / 1000000;
    }

    
    // Remove the possibility of negative speed
    if (mph < 0l) mph = 0l;
    
    // only calculate direction if we have wind
    if (mph >= 0)
    {
      // Calculate direction from captured pulse times
      windDirection = ( ( (directionTime_ * 360) / speedTime_) + DIRECTION_OFFSET) % 360;
    }
    else
    {
      mph = 0;
    }

    //============================================
    // output to Weatherduino

    //int degrees2analog = map(dirOut, 0, 360, 0, 255);
    analogWrite(windDirOutPin, map(windDirection, 0, 360, 0, 255));

    //============================================


    if (debug)
    {
      Serial.print("speedTime_: "); Serial.println(speedTime_);
      Serial.print("rps: "); Serial.println(rps);
      Serial.print("dir: "); Serial.println(windDirection);
      Serial.print("mph: "); Serial.println(mph);
      Serial.println("");
    }
  }
}


void loop()
{
  int i;
  const unsigned int LOOP_DELAY = 50;
  const unsigned int LOOP_TIME = TIMEOUT / LOOP_DELAY;

  digitalWrite(LED, !digitalRead(LED));    // Toggle LED

  i = 0;
  // If there is new data, process it, otherwise wait for LOOP_TIME to pass
  while ((newData != true) && (i < LOOP_TIME))
  {
    i++;
    delayMicroseconds(LOOP_DELAY);
  }

  calcWindSpeedAndDir();    // Process new data
  newData = false;
}it, otherwise wait for LOOP_TIME to pass
  while ((newData != true) && (i < LOOP_TIME))
  {
    i++;
    delayMicroseconds(LOOP_DELAY);
  }

  calcWindSpeedAndDir();    // Process new data
  newData = false;
}
 // Get snapshot of data into local variables. Note: an interrupt could trigger here
 noInterrupts();
 dirPulse_ = dirPulse;
 speedPulse_ = speedPulse;
 speedTime_ = speedTime;
 directionTime_ = directionTime;
 interrupts();

 // Make speed zero, if the pulse delay is too long
 if (micros() - speedPulse_ > TIMEOUT) speedTime_ = 0ul;

 // The following converts revolutions per 100 seconds (rps) to mph x 100
 // This calculation follows the Peet Bros. piecemeal calibration data
 if (speedTime_ > 0)
 {

   // to prevent calculation errors with float numbers, make them larger
   rps = 100000000 / speedTime_;

   if (1 < rps && rps < 323)
   {
     //      float mph = (-0.1095 * (rps * rps)) + (2.9318 * rps) - 0.1412;
     mph = (-1095 * rps * rps + 29318 * rps * 100 - 14120000) / 1000000;
   }
   else if (323 <= rps && rps < 5436)
   {
     //            mph = 0.0052 * (rps * rps) + 2.1980 * rps + 1.1091;
     mph = (52 * rps * rps + 21980 * rps * 100 + 110910000) / 1000000;
   }
   else if (5436 <= rps && rps < 6633)
   {
     //            mph = 0.1104 * (rps * rps) - 9.5685 * rps + 329.87;
     mph = (1104 * rps * rps - 95685 * rps * 100 + 32987000000) / 1000000;
   }

   
   // Remove the possibility of negative speed
   if (mph < 0l) mph = 0l;
   
   // only calculate direction if we have wind
   if (mph >= 0)
   {
     // Calculate direction from captured pulse times
     windDirection = ( ( (directionTime_ * 360) / speedTime_) + DIRECTION_OFFSET) % 360;
   }
   else
   {
     mph = 0;
   }

   //============================================
   // output to Weatherduino

   //int degrees2analog = map(dirOut, 0, 360, 0, 255);
   analogWrite(windDirOutPin, map(windDirection, 0, 360, 0, 255));

   //============================================


   if (debug)
   {
     Serial.print("speedTime_: "); Serial.println(speedTime_);
     Serial.print("rps: "); Serial.println(rps);
     Serial.print("dir: "); Serial.println(windDirection);
     Serial.print("mph: "); Serial.println(mph);
     Serial.println("");
   }
 }
}


void loop()
{
 int i;
 const unsigned int LOOP_DELAY = 50;
 const unsigned int LOOP_TIME = TIMEOUT / LOOP_DELAY;

 digitalWrite(LED, !digitalRead(LED));    // Toggle LED

 i = 0;
 // If there is new data, process it, otherwise wait for LOOP_TIME to pass
 while ((newData != true) && (i < LOOP_TIME))
 {
   i++;
   delayMicroseconds(LOOP_DELAY);
 }

 calcWindSpeedAndDir();    // Process new data
 newData = false;
}
Reply


Messages In This Thread
Peet Bros Anemometer > WeatherDuino converter - by edr1924 - 11-05-2019, 20:48
RE: Advice needed... Peet Bros Anemometer > WeatherDuino converter - by edr1924 - 14-05-2019, 17:45
RE: Peet Bros Anemometer > WeatherDuino converter - by engolling - 14-05-2019, 22:04
RE: Peet Bros Anemometer > WeatherDuino converter - by edr1924 - 15-05-2019, 11:43
RE: Peet Bros Anemometer > WeatherDuino converter - by engolling - 15-05-2019, 12:29
RE: Peet Bros Anemometer > WeatherDuino converter - by edr1924 - 15-05-2019, 13:03



Users browsing this thread: 1 Guest(s)