Arduino with three xbee,s

As addition to my remote readout SHT humidity/temp. sensor i would like to ad another xbee to the network.
arduino duemi with XBEE router/end device and SHT sensor
arduino mega with XBEE router/end device and wind direction finder sensor
arduino duemi with XBEE coordinater and display for read out both sensors

But how to adres (program) the first serial string from the SHT and the second serial string from the wind direction sensor and how to read this in the arduino script

such as if Serial is available(SHT) <1; {
lcd.print…
and if Serial is available(wind)<1; {
lcd.print…

Is this the way to do it?
Has anyone a ideer about this?
I am very interested.

Theo

If the XBees are attached to Arduinos, as they appear to be, the Arduino collects the sensor data, and formats a string to be sent. The XBee, the, is just a radio.

The wind Arduino could send <W:windSpeedData>, while the temp Arduino sends <T:tempAndHumidityData>.

The collector Arduino reads all serial data, and parses it to determine what kind of data was sent (T or W).

The problem you will have is making sure that the two senders do not send data at the same time.

This can be handled by making the senders slave that never speak unless spoken two. The master sends a request like . The T device sees it, and does nothing because it is not the device being spoken to. The W device sees the message, too, and replies with the wind data.

If the master sends , the W device ignores it, and the T device responds.

The replies should still have the identifier of the source, just to make sure the correct device is responding.

Paul, Tanks for your reply. Indeed I must discriminete the difference between senders like the wind and the humidity/temp sensor. I will play with the C++ software ( with the help of making thinks talk from Tom Igoe) for the arduino,s and will hopefully find my way. If not I wil come back with some quistions. What I understand so far is that each arduini must send a named serial string via its radio which is detected by the recieving radio and the arduino to send the corect dat to the correct place on the display. Theo

What I understand so far is that each arduini must send a named serial string via its radio

Each Arduino must send serial data that contains an ID that is unique to the sender.

which is detected by the recieving radio and the arduino to send the corect dat to the correct place on the display.

The unique ID is not detected by the receiving radio, since the radio does not interpret the stream of data. You don’t, as near as I can tell, need an Arduino on the receiving end, if all it is doing is passing data to the PC. Something like this http://www.sparkfun.com/products/8687 is cheaper than an Arduino with XBee shield. The application on the PC needs to interpret the data to see which device sent it, to determine what the data is and where to display it.

Hi,

first excuse me for my english. I try to improve it. I am interested by this post, cause I begin to build a weather station with two parts, like your project ilioSS. Here is how I planned to compose the weather station. In a Stevenson Shield located in the field behind my house, I plan to connect sensors (temperature (DS18B20), humidity (SHT21), pressure and rain (hobby-boards)) to an Arduino with a RF transceiver (sureelectronics.net/goods.php?id=1053). The power supply will comes from a battery and a little solar panel. Anemometer and wind vane (1-wire based) will be located on the roof and connected to a little PC like this one pcengines.ch/alix2.htm. I already experienced a fpFsense firewall on alix 2D3, and it works well. One RF transceiver (home side) will be connected via RS232 to the the Alix board powered by FreeBsd, and the 1-wire from anemometer and wind vane will be via an 1-wire/USB interface to the USB port. I found that I can use linux scripts, OWFS and RRDTools as a good way to manage the data's. Maybe, it's not the better, or simply not the right one.

For the moment I experience the different sensors on the arduino board and lcd display. I placed two orders for some components to Sure-electronics and Sparkfun. As at this moment, I don't received them, I am triying to clarify in my mind, what will be the final structure.

By reading this post, I was interested by the way to transfer data's from field to home via RF transceiver or Xbee's.

I will come back to you when I will be a little more advanced in my project.

Philippe

Paul, The layout of the system i am experience with is alfollow; 1 arduino duemi with the sht75 sensor and a XBEE sending serial string containing temp, humi, dewpoint. 1 arduino equipth with a 16x4 display 4bit. which display all well. in adition to this I lined up a thirth arduino. 1 arduino mega as a wind direction due to the use of three interrupts with a XBEE as router/enddevice sending serial string with 0-to 16 for the wind direction. All of this means that the display arduino must know from wich arduino wich string comes in order to place the serial on the ride place on the display. Therefore i uses also for the display a arduino. Finaly there will be no pc the system is stand alone so to speak. Howe to send the string from the wind and howe to send the string from the temp/humi. and howe to check in the receiving arduino which string is read? That is my problem to solve. Paul if it take some time you hear again from me this is due to my work i will be away for a week beginning next year. So by now all the best in 2011 Theo

Howe to send the string from the wind and howe to send the string from the temp/humi. and howe to check in the receiving arduino which string is read? That is my problem to solve.

If you post your code that is currently running on the wind Arduino, I can show you how to modify it to send the data that you want, including a unique ID.

If you post your code that is currently running on the temp/humi Arduino, I can show you how to modify it to send the data that you want, including a unique ID.

If you post your code that is currently running on the receiving Arduino, I can show you how to modify it to determine where the data came from, and to parse the rest of the data that is sent.

It's really not that big a job.

Hi Paul, As soon as i am on my home computer again I will send you the scripts. Regards, Theo

Hello Paul again,

I get the ideer you get my problem. It is not that you didn,t understand the problem but more the way i explained the case. I found it hard to exppain the problem in such a way that somewone else also can understand the problem.

First of al i wil reply to you in a desent maner that means scripts in the scripts format. here we go

//Teller programma voor windrichting
//DD 29-12-2010
//xbee_send_teller_serial
//zonder display 
//met serial voor xbee te zenden naar coordinater
//probleem interrupt 5 op pin 18 checken nu middels input opgelost
//display dusdanig aansluiten dat interrupt niet in de weg zitten
//vervalt dus ook IR sensor noord set op input 4
//bij opstarten eerst een volle slag maken met e wind vaan.
//#include <ctype.h>
#include <LiquidCrystal.h>
#define encoder0PinA 2  // interrupt
#define encoder0PinB 3  // interrupt
//const int set0Pin = 4;  //  noord set (16) IR sensor
#define encoder0PinC 18 // interrupt 5 op pin 18
volatile unsigned int encoder0Pos = 16;
unsigned int tmp_Pos = 0;
LiquidCrystal lcd(6, 7, 8, 9, 10, 11, 12);
// arduino   6  min  8   9  10 11  12
// display   4   5   6  11  12 13  14
const int numRows =  4;
const int numCols = 20;
int led = 13;   // for checking nul ""o"" doorgang
boolean A_set;
boolean B_set;

void setup() {
 
  pinMode(encoder0PinA, INPUT); 
  pinMode(encoder0PinB, INPUT); 
//  pinMode(set0Pin, INPUT);
  pinMode(led, OUTPUT);
// encoder pin on interrupt 0 (pin 2)
  attachInterrupt(0, doEncoderA, CHANGE);

// encoder pin on interrupt 1 (pin 3)
  attachInterrupt(1, doEncoderB, CHANGE);
  
// encoder pin on interrupt 5 (pin 18)
  attachInterrupt(5, doEncoderC, CHANGE);
  lcd.begin(numCols, numRows);
  Serial.begin (9600);
  
//  char windValue = encoder0Pos;
}


void loop(){ 

//Check of wind vaan door de noord gaat?
// intterrupt oplijnen op interrupt 5 en input 18 zie teller_019 o.i.d.
// e.e.a. om van 16 tot 31 te kunnen en blijven tellen tellen omdat bij set
// at encoderPinC we niet terug aftellen minder dan 16 .
//  if (encoder0Pos == 15) {
//  encoder0Pos = encoder0Pos +16;
  Serial.begin(9600);
//  char windValue;
//  Serial.print(windValue, DEC);
//Check for change in position
  if (tmp_Pos != encoder0Pos) {
   Serial.print("Teller:"); Serial.println(encoder0Pos, DEC); 
         
    if (encoder0Pos == 16)  {
     lcd.clear(); 
     lcd.setCursor(0,0);
     lcd.print("16NOORD");
//     delay(1000);
    } 
    if (encoder0Pos == 17)  {
     lcd.clear(); 
     lcd.setCursor(0,0);
     lcd.print("17NoordNoordOost");
//     delay(1000);
    }
    if (encoder0Pos == 18)  {
      lcd.clear();
     lcd.setCursor(0,0);
     lcd.print("18NoordOostNoord");
  //   delay(1000);
    }
    if (encoder0Pos == 19)  {
      lcd.clear();
     lcd.setCursor(0,0);
     lcd.print("19NoordOostOost");
//     delay(1000);
    }
    if (encoder0Pos == 20)  {
      lcd.clear();
     lcd.setCursor(0,0);
     lcd.print("20OOST");
//     delay(1000);
    }
    if (encoder0Pos == 21)  {
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("21OostOostZuid");
//      delay(1000);
      
    }
    if (encoder0Pos == 22)  {
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("22ZuidOostZuid");
//      delay(1000);   
      
     }
    if (encoder0Pos == 23)  {
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("23ZuidZuidOost");
//      delay(1000);
    
     }
    if (encoder0Pos == 24)  {
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("24ZUID");
//      delay(1000);
    
     }
    if (encoder0Pos == 25)  {
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("25WestZuidZuid");
//      delay(1000);
    
     }
    if (encoder0Pos == 26)  {
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("26OostOostZuid");
//      delay(1000);
    
     }
    if (encoder0Pos == 27)  {
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("27OostOostZuid");
//      delay(1000); 
     
      }
    if (encoder0Pos == 28)  {
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("28OostOostZuid");
//      delay(1000);
     
     
      }
    if (encoder0Pos == 29)  {
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("29OostOostZuid");
//      delay(1000);
     
      }
    if (encoder0Pos == 30)  {
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("30OostOostZuid");
//      delay(1000);
     
      }
    if (encoder0Pos == 31)  {
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("31OostOostZuid");
//      delay(1000);
     
      }
    if (encoder0Pos == 32)  {
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("32OostOostZuid");
//      delay(1000);
     
      }
    if (encoder0Pos == 33)  {
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("33OostOostZuid");
//      delay(1000);
     
      }
    if (encoder0Pos == 34)  {
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("34NoordWestNoord");
//      delay(1000);
     
      }
    if (encoder0Pos == 35)  {
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("35NoordNoordWest");
//      delay(1000); 
    }
  }

  tmp_Pos = encoder0Pos;

}
// Interrupt on A changing state
void doEncoderA(){

// Low to High transition?
  if (digitalRead(encoder0PinA) == HIGH) { 
    A_set = true;
    if (!B_set) {
      encoder0Pos = encoder0Pos + 1;
    
   }        
}

// High-to-low transition?
  if (digitalRead(encoder0PinA) == LOW) {
    A_set = false;
  }

}

// Interrupt on B changing state
void doEncoderB(){

// Low-to-high transition?
  if (digitalRead(encoder0PinB) == HIGH) {   
    B_set = true;
    if (!A_set) {
      encoder0Pos = encoder0Pos - 1;
       {
  if (encoder0Pos < 16){
//  tmp_Pos= tmp_Pos +16;
  encoder0Pos= encoder0Pos+20;
  }
    }
  }
  }

// High-to-low transition?
  if (digitalRead(encoder0PinB) == LOW) {
    B_set = false;
  }
}
void doEncoderC() {
  if (digitalRead(encoder0PinC) == LOW)  {
   digitalWrite( led ,HIGH);
    encoder0Pos = 16;
  } else{ digitalWrite( led, LOW);}
 
}

this was the wind script following the display script


/*
xbee_recieve_serial_data_test_02
Language: Arduino

Tested op board Duemi met display XBEE als coordinater 1047 recieve.
Duemi als sender met SHT en XBEE als router end device 1247 send
DD 29 dec. 2010
E.e.a. t.b.v. meteo project. default in XBEE geladen en panid en ni opnieuw geprog.
*/

#include <LiquidCrystal.h>
LiquidCrystal lcd(6,7,8,9,10,11,12);
// display 4 5 6 11 12 13 14
// arduino 6 min 8 9 10 11 12
volatile unsigned int encoder0Pos;
char tCValue1;
char tCValue2;
char rhTrueValue1;
char rhTrueValue2;
char DauwpuntValue1;
char DauwpuntValue2;
int incomingByte[15]; // Serial data array met plaats voor 15 bytes
char inByte = 0;

void setup()
{

lcd.begin(4,16); // LCD rows and colomns
lcd.clear(); // LCD leeg maken
lcd.setCursor(0,0);
// 1234567890123456
lcd.print(“Temp. :”);
lcd.setCursor(0,1);
// 1234567890123456
lcd.print(“Vochtigh:”);
lcd.setCursor(-4,2);
// 1234567890123456
lcd.print(“Dauwpunt:”);
lcd.setCursor(-4,3);
// 1234567890123456
lcd.print(“Wind :”);

}

void loop()
{

Serial.begin(9600);

if (Serial.available() > 0) { // get any incoming data:

for (int i=0; i<11; i++) { // elf stuks bytes laden in array
inByte = Serial.read();
incomingByte = inByte;

  • Serial.print(inByte); // voor de serial port*

  • }*

  • }*

  • tCValue1=(incomingByte[1]); // eerste char byte van de temp*

  • tCValue2=(incomingByte[2]); // tweede char byte van de temp*

  • rhTrueValue1=(incomingByte[4]);*

  • rhTrueValue2=(incomingByte[5]);*

  • DauwpuntValue1=(incomingByte[7]);*

  • DauwpuntValue2=(incomingByte[8]);*
    for ( int i=0; i<11; i++) // uitlezen van de array

  • {*

  • lcd.setCursor(9,0); *

  • lcd.print (tCValue1); // print to LCD*

  • lcd.setCursor(10,0);*

  • lcd.print (tCValue2); *

  • lcd.setCursor(9,1);*

  • lcd.print(rhTrueValue1);*

  • lcd.setCursor(10,1);*

  • lcd.print(rhTrueValue2);*

  • lcd.setCursor(5,2);*

  • lcd.print(DauwpuntValue1);*

  • lcd.setCursor(6,2);*

  • lcd.print(DauwpuntValue2);*

  • lcd.setCursor(5,3);*

  • lcd.print(encoder0Pos);*

  • }*
    }
    As the max of the message is there i will make a new post for the sensor SHT script.

void loop(){
  Serial.begin(9600);

Serial.begin() belongs in setup(), not loop(). There is no reason to call begin() more than once.

   Serial.print("Teller:"); Serial.println(encoder0Pos, DEC);

With the XBee properly connected, it will broadcast the string “Teller:” followed by the encoder value, as a string. Adding start and end of packet markers, and shortening the ID would be good.

   Serial.print("<W:");
  Serial.print(encoder0Pos, DEC);
  Serial.print(">");
        if (Serial.available() > 0) {                // get any incoming data:
               for (int i=0; i<11; i++) {            // elf stuks bytes laden in array
                          inByte = Serial.read();

This code checks that there is at least one byte available to read, and, if so, reads all 11 of them.

This code will read all the serial data waiting to be read. If what is read constitutes a whole packet, it will parse the packet.

char inData[24];
byte index;
boolean started = false;
boolean ended = false;

void loop()
{
  while(Serial.available() > 0)
  {
      char aChar = Serial.read();
      if(aChar == '<')
      {
          started = true;
          index = 0;
          inData[index] = '\0';
      }
      else if(aChar == '>')
      {
          ended = true;
      }
      else if(started)
      {
          inData[index] = aChar;
          index++;
          inData[index] = ',';
      }
  }

  if(started && ended)
  {
      // Use the value
      if(inData[0] == 'W')
      {
         // The rest of the string is wind data
         inData[0] = ' ';
         int windVal = atoi(inData);
         // Do something with windVal
      }
      else if(inData[0] == 'T')
     {
         // The rest of the string is temperature and humidity data
         inData[0] = ' ';

         // Parse the data, maybe using scanf

         // Do something with the data
     }

      // Get ready for the next time
      started = false;
      ended = false;

      index = 0;
      inData[index] = '\0';
  }
}

Paul,
Here is the bottom part of the script wich is most important while the whole script is even without comments is over the max 9000 characters.

``void loop()

{
char cmd; /* command input by user /
int humidVal; /
humidity value read from SHT75 /
int tempVal ; /
temperature value from SHT75 /
unsigned char statusVal; /
contents of status register /
float fHumidity; /
working value for humidity calculation /
float fTemperature; /
working value for temperature calculation /
float dewPoint; /
calculated Dew Point value /
unsigned char error; /
return value for routine calls */
unsigned int port; // keuze welke input wordt uitgelezen
float Temperature; // temp. berekend voor LCD/Serial
float Humidity; // humid. berekend voor LCD/Serial
float logEx; // dauwpunt berekening voor LCD/Serial
float Dauwpunt; // berekende dauwpunt waarde voor LCD/Serial
float t; // temp. berekend voor
float rhLin; // rhLin berekening voor temp. compensatie
float rhTrue; // rhTrue is rhLin met temp. compensatie
float tC; // temp. waarde voor LCD/LCD
float rh; // rh waarde voor LCD/LCD

if (digitalRead (XBEE==LOW)) {

digitalWrite(xbeeLed,HIGH); // on XBEE serial communication
digitalWrite(lcdLed,LOW);
digitalWrite(serLed,LOW);
lcd.setCursor(5,3);
lcd.print(“on xbee”);

Serial.begin(9600);

port=5; // leest de data uit ARDUINO data port

sMeasure ((unsigned char *)&tempVal, MEASURE_TEMP, 0, port); // leest de temp waarde grof uit de SHT
sMeasure ((unsigned char *)&humidVal, MEASURE_HUMI, 0, port);

#define C1 -2.0468
#define C2 +0.0367
#define C3 -0.0000015955

/* Constants for temperature-compensated relative humidity /
#define T1 +0.01
#define T2 +0.00008
/
Constants for conversion of temperature reading to Centigrade */
//#define D1 -40.10 //5.0V operation
#define D1 -39.651 //3.3V operation geinterpoleerd uit data sheet
#define D2 +0.01

t = float(tempVal); // ruwe SHT temp waarde omzetten naar float
tC = ( t / 100 ) - 39.651; /* Linear conversion of temperature geeft te lage waardes met deze wijze van berekening*/

rh = float(humidVal); // ruwe SHT humid waarde omzetten naar float
rhLin = C1 + ( C2 * rh ) + ( C3 * rh * rh ); /* “ticks” to relative H geeft denk ik de juiste waardes met deze wijze van berekening */
rhTrue = ( tC - 25 ) * ( T1 + ( T2 * rh )) + rhLin; // is compensatie voor als als temp veel afwijkt van 25 graden
// rhLin = -2.0468 +( +0.0367 * rh ) + ( -0.0000015955 * rh * rh ); // waarde volgens datasheet ruwe waarde omrekenen naar werkelijke waarde

// Tn = 243.12 constante voor berekening 0 - 50 Dgr above water
// m = 17.62 constante voor berekening 0 - 50 dgr boven water
Dauwpunt = 243.12 * ( log ( rhLin / 100 ) + (( 17.62 * tC) / ( 243.12 + tC ))) /
( 17.62 - ((log( rhLin / 100 )) - ( 17.62 * tC ) / ( 243.12 + tC ))); // nieuwe berekening volgend de data sheet met rhLin.

lcd.setCursor(9,0); // print to LCD
lcd.print(tC);
lcd.setCursor(9,1);
lcd.print(rhTrue); // omdat temp rond 25 graden ligt. geen compensatie
lcd.setCursor(6,2);
lcd.print(Dauwpunt);
lcd.setCursor(5,3);
char tCValue = tC;
char rhTrueValue = rhTrue;
char DauwpuntValue = Dauwpunt;

Serial.print(".");
Serial.print(tCValue, DEC);
Serial.print(",");
Serial.print(rhTrueValue, DEC);
Serial.print(",");
Serial.println(DauwpuntValue, DEC);

port=-0; // zet de port weer uit i.v.m. opwarmen sensor < 10% in tijd spanning erop

delay(10000); // vertraging om port 10 sec uit te schakelen i.v.m. opwarmen. Dus elke 10 sec. een meting.
if (tC > 18.89) { // toegevoegd om te schakelen
digitalWrite ( ledPin,HIGH);
}else{
digitalWrite( ledPin,LOW); // toegevoegd om te schakelen

}
}
}
I think the clou is in this part.
Note if I switch of the humidity arduino then I will read on the display le er 16 which is some text from the wind arduino so the communication is working.
However do I have to change someting in the XBEE as well?

Hear from you.
Regards Theo

if (digitalRead (XBEE==LOW))

This is comparing the value of XBEE with LOW, and then reading from the TRUE pin or the FALSE pin. Not likely to be doing what you want to do.

#define         C1      -2.0468
#define         C2      +0.0367
#define         C3      -0.0000015955

These, and the Serial.begin() do not belong in loop().

              [glow]Serial.print("<T:");[/glow]
              Serial.print(tCValue, DEC);
              Serial.print(",");
              Serial.print(rhTrueValue, DEC);
              Serial.print(",");
              Serial.[glow]print[/glow](DauwpuntValue, DEC); // was println
              [glow]Serial.print(">");[/glow]

This code will produce output that the receiver is looking for, when it determines where the data came from.

PaulS,

Tanks for the code I will implement in the scripts and find my way. In deed it was the way I tought it must be some where some howe. But exactely to do is someting else. I keep on trying to get what I want with this arduino stuff. Regards, Theo