Can anyone help with my project. Weather station integration.

 

 

 Hi,

Ive been tinkering away trying to make a sketch to integrate my weather station with OpenEnergyMonitor. The weather station in question is a PeetBros Ultimeter 100 that outputs serial data.

I have found the necessary code to grab the serial data from the station, but am just having trouble with the RF12 components of the code. Im unable to pickup my transmissions on a simple serial base unit, and im not sure how to troubleshoot at which end (Tx or Rx) is causing the problem.

The sketch is very much a draft and im still working on a few things such as my BMP pressure is not correct (negitive values) and I want to have more precision with the temperature.

Im planning on doing a writeup on my build once done.

Any help with these problems, or if anyone can suggest any improvements i could make to my code it would be very much appreciated.

 

Kind regards,

Mike Christiansen

 

 

/*

Code by Mike Christiansen [email protected]

 

for open use, modifacation and sharing. No liability assumed.

 

Any feedback most appreciated, im only an arduino beginner :)

 

Code for Openenergymonotor tx device running on a jeenode.

this tx transmits data from a peet bros weather station 

(wind speed, direction, averaged speed, outdoor temp, and 

wind direction name (from michael p code) along with data

from a BMP085.

 

Attachments to the jeenode uses the folowing jee ports

 

Weatherstation serial port, uses arduino pin 6 (rx) 

jeenode port 3 dio 5v and gnd through a ttl-rs232 converter

 

BMP085

Pressure bord, P4

 

 

Thanks to these people for there code contrubition.

Michael P from ADS-WS1 yahoo group

 

 

 

*/

//==============================BMP085==============================

//                         Jeenode - Jeelabs

#include <Ports.h>

#include "PortsBMP085.h"

#include <RF12.h>

#include <avr/sleep.h>

#include <avr/eeprom.h>

PortI2C four (4);

BMP085 psensor (four, 3); // ultra high resolution

MilliTimer timer;

 

//==================================Openenergymonotor===========================

//                             http://openenergymonitor.org

 

 

//---------------------------------------------------------------------------------------------------

// RF12 settings 

//---------------------------------------------------------------------------------------------------

// fixed RF12 settings

 

#define MYNODE      18          

#define network     212      //default network group (can be in the range 1-250). All nodes required to communigate together must be on the same network group

#define freq RF12_915MHZ     //Frequency of RF12B module can be RF12_433MHZ, RF12_868MHZ or RF12_915MHZ. You should use the one matching the module you have.

 

// set the sync mode to 2 if the fuses are still the Arduino default

// mode 3 (full powerdown) can only be used with 258 CK startup fuses

#define RADIO_SYNC_MODE 2

 

#define COLLECT 0x20 // collect mode, i.e. pass incoming without sending acks

//--------------------------------------------------------------------------------------------------

 

//--------------------------------------------------------------------------------------------------

// CT energy monitor setup definitions 

//--------------------------------------------------------------------------------------------------

/*

int inPinI=                3;    //I/O analogue 3 = emonTx CT2 channel. Change to analogue 0 for emonTx CT1 chnnel  

int numberOfSamples=       1480; //The period (one wavelength) of mains 50Hz is 20ms. Each samples was measured to take 0.188ms. This meas that 106.4 samples/wavelength are possible. 1480 samples takes 280.14ms which is 14 wavelengths. 

int Vrms=                  230;  //UK assumed supply voltage. Tolerance: +10%-6%

int CT_BURDEN_RESISTOR=    56;   //value in ohms of burden resistor R3 and R6

int CT_TURNS=              1500; //number of turns in CT sensor. 1500 is the vaue of the efergy CT http://www.efergy.com/Products/efergy-Shop-Accessories/EFERGY/Jackplug-E...

double CAL=1.2477;          //*calibration coefficient* IMPORTANT - each monitor must be calibrated. See step 4 http://openenergymonitor.org/emon/node/58

*/

//########################################################################################################################

//Data Structure to be received 

//######################################################################################################################## 

typedef struct {

   int ct1; // current transformer 1

 int ct2; // current transformer 2

 int temp1; // Outdoor temperature 1

 int temp2; // BMP085  temperature 2

 int temp3; // Server  temperature 3

          int BMP_pres;         // BMP085  Pressure

 int emon_wind_speed;  // PeetBros wind speed out

          int emon_wind_dir;    // PeetBros wind direction out

          int emon_avg_wind;    // PeetBros 5min ave wind speed

          int emon_wind_name;   // Wind as named below

} Payload;

Payload emontx;

//########################################################################################################################

  

 

//=================BELOW FOR SERIAL READ FROM PEET BROS STATION===================

//                 THANKS TO MICHAEL P FROM ADS-WS1 YAHOO GROUP

#include <NewSoftSerial.h>

//                          rx tx

NewSoftSerial  weather_port1(6,7);

int wind_speed =0;  //  wind speed in kmh

int wind_dir = 0;   //  wind dir in degrees

int temp = 0;       //  Outdoor temp fahrenheit

int tempc = 0;      //  Outdoor temp celsius

float rain = 0;     //  not attached in my example

float bar = 0; 

int id_temp =0;     //  not attached in my example

int hum = 0;        //  not attached in my example

int id_hum = 0;     //  not attached in my example

int day = 0;        //  time not used

int minutes = 0;    //  time not used 

float day_rain = 0; //  not attached in my example

int avg_wind = 0;   //  averaged wind speed over 1 minute

 

byte chrconv(byte);

unsigned int getword(char *);

void get_weather();

char * wind_name(int);

char * getLine();

 

unsigned int getword(char * ptr)

{

  return( chrconv(*(ptr+0)) << 12 | chrconv(*(ptr+1)) << 8 | chrconv(*(ptr+2)) << 4 | chrconv(*(ptr+3)));

}

byte chrconv(byte chr)

{

 if  (chr  < 48 || chr > 70)

   return -1;

   

 return  (0x40 & chr) ? (9 + (0x0f & chr) ) : (chr - 48);

}

 

//================="WITHOUT DELAY" CODE FOR WRITING TO RF12b=======================

//                  using arduino example blink without delay

long previousMillis = 0;

long interval = 10000; 

//================================SETUP============================================

void setup(){

//================================BMP085============================

psensor.getCalibData();

//===============================PeetBros============================

Serial.begin(9600); 

weather_port1.begin(2400);  

 

//============================Openenergymonotor=========================

  //-----------------------------------------

  // RFM12B Initialize

  //------------------------------------------

  rf12_initialize(MYNODE,freq,network);   //Initialize RFM12 with settings defined above 

  rf12_sleep(0);                             //Put the RFM12 to sleep - Note: This RF12 sleep interupt method might not be 100% repiable. Put RF to sleep: RFM12B module can be kept off while not used – saving roughly 15 mA

  //------------------------------------------

  

  Serial.print("Node: "); 

  Serial.print(MYNODE); 

  Serial.print(" Freq: "); 

  Serial.print(freq); 

  Serial.print(" Network: "); 

  Serial.println(network);

  delay(1000);

  

//===========================PeetBros=========================================

}

char wLine[100];

char * getLine()

{

  char cc=0;

  int ii=0;

  while(cc != '!')

  {

    delay(1); 

    cc = weather_port1.read();

    

  }

  wLine[0]='!';

  ii=1;

  while(1)

  {

    if(weather_port1.available() > 0)

    {

       cc = weather_port1.read();

       if (ii < 99 and cc != '\n' and cc != '\r' and cc  > 31)

       {

         wLine[ii] = cc;

         ii++;

       }

       else

       {

          wLine[ii] = '\0';

          return &(wLine[0]);

      }

    } 

  } 

}

void get_weather()

{

 

   // char * ptr = "!!030100D8017402632755030600F0----0006052000360201\0";

    char * ptr = getLine();

    int num_chars = strlen(ptr);

    //Serial.println(ptr);

    //Serial.println( num_chars);

    if (!ptr or *ptr != '!' or *(ptr+1) !=  '!')

    {

     Serial.println("no header");

      return;

    }

    //0000 wind speed [0.1 kph]

    wind_speed = (getword(ptr+2) /10.0); 

    //00D8 wind direction [0-255]

    int tWindDir = (getword(ptr+6) * 360)/255;

    if ( tWindDir >=0 and tWindDir <=360)

    wind_dir = tWindDir;

    //0174 current outdoor temp [0.1 deg F]

    temp = (getword(ptr+10) /10.0);

    // Maths - Temp conversion to degrees C

    tempc = ((temp-32)/1.8);

    //0263 rain long term total [0.01 inches]

    rain = (getword(ptr+14) / 100.0);

    //2755 current barometer [0.1 mbar]

    bar = (getword(ptr+18) / 10.0) *0.0295301;

    //0306 current indoor temp [0.1 deg F]

    id_temp = (getword(ptr+22) /10.0);

    //---- current outdoor humidity [0.1%]

    hum = (getword(ptr+26) / 10.0);

    //---- current indoor humidity [0.1%]

    id_hum = (getword(ptr+30) / 10.0) ;

    //0006 date [day of year, -1]

    day = (getword(ptr+34) + 1);

    //0520 time [minute of day, 0-1440]

    minutes = (getword(ptr+38));

    //0036 today's rain total [0.01 inches]

    day_rain = (getword(ptr+42) / 100.0);

    //0000 1 min wind speed average [0.1 kph]

    avg_wind = (getword(ptr+46) / 10.0);

    

  

}

char * wind_name(int windir)

{

 

  char * wname[17] = {"", "N", "NNE", "NE", "ENE", "E", "ESE", "SE", "SSE", "S", "SSW", "SW", "WSW", "W", "WNW",  "NW", "NNW"};

  float rawDir =  float(windir) / 22.5;

  int  offset = int(rawDir + 1.5);

  offset = offset > 16 ? offset- 16 : offset;

  return wname[offset]; 

  

}

void send_rf12() {

//==================================BMP085===================================

    psensor.startMeas(BMP085::TEMP);

    delay(16);

    int32_t traw = psensor.getResult(BMP085::TEMP);

 

    psensor.startMeas(BMP085::PRES);

    delay(32);

    int32_t praw = psensor.getResult(BMP085::PRES);

    

    struct { int16_t temp; int32_t pres; } payload;

    psensor.calculate(payload.temp, payload.pres);

    

    // this code is not needed for use as remote node, keep it for debugging

    //Serial.print("BMP ");

    //Serial.print("temp = ");

    //Serial.print(payload.temp/10.0);

    //Serial.print(' ');

    //Serial.print("Pressure = ");

    //Serial.println(payload.pres);

    

//--------------------------------------------------------------------------------------------------

// Create emon payload

//--------------------------------------------------------------------------------------------------

int temp1 = tempc;              // Outdoor temperature 1

int temp2 = payload.temp/10.0;       // BMP085  temperature 2

int BMP_pres =  payload.pres/1;             // BMP085  Pressure

int emon_wind_speed = wind_speed;     // PeetBros wind speed out

int emon_wind_dir = wind_dir;         // PeetBros wind direction out

int emon_avg_wind = avg_wind;         // PeetBros 5min ave wind speed

//char emon_wind_name = wind_name(wind_dir);       // Wind name

 

//---------------------------------------------------------------------------------------------------

//Serial print for debug

//---------------------------------------------------------------------------------------------------

delay (10);

Serial.print("temp1: ");

Serial.println(temp1/1.0);

delay(5);

Serial.print("temp2: ");

Serial.println(temp2/1.0);

delay(5);

Serial.print("pres: ");

Serial.println(BMP_pres);

delay(5);

Serial.print("emon_wind_speed: ");

Serial.println(emon_wind_speed);

delay(5);

Serial.print("emon_wind_dir: ");

Serial.println(emon_wind_dir);

delay(5);

Serial.print("emon_avg_wind: ");

Serial.println(emon_avg_wind);

delay(5);

//--------------------------------------------------------------------------------------------------

// Send payload data via RF

//--------------------------------------------------------------------------------------------------

    rf12_sleep(-1);     //wake up RF module

    while (!rf12_canSend())

    rf12_recvDone();

    rf12_sendStart(rf12_hdr, &emontx, sizeof emontx, RADIO_SYNC_MODE); 

    rf12_sleep(0);    //put RF module to sleep

}

    

 

 

void loop() {

 

   unsigned long currentMillis = millis();

   

   if(currentMillis - previousMillis > interval) {

   // save the last time you blinked the LED 

   previousMillis = currentMillis;

   //do whatever is in these brackets

    

   send_rf12();

   }

 

   get_weather();

   

   String prBuff = String("W Dir:") + wind_name(wind_dir) + String("  W Spd:") + wind_speed;

   //Serial.println(prBuff);

   prBuff = String("Avg Spd:") + avg_wind + String(" W deg:") + wind_dir;

   //Serial.print(prBuff);

   //Serial.print ("temp:");

   //Serial.println (tempc);

   //Serial.print("wind dir:");

   //Serial.println(wind_dir);

   //Serial.print("wind speed:");

   //Serial.print(wind_speed);

   //Serial.println("kms");

   //Serial.print("avg_wind: ");

   //Serial.print(winddir);

   //Serial.print(avg_wind);

   //Serial.println("kms");

 

}

 

glyn.hudson's picture

Re: Can anyone help with my project. Weather station integration.

 If your not using a CT sensor it would be a good idea to remove the energy monitoring code. See here for a barebones RFM12 Tx and Rx code: https://github.com/openenergymonitor/RFM12B_Simple

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.