Go Down

Topic: Arduino with three xbee,s (Read 9263 times) previous topic - next topic

ilioSS

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

PaulS

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 <W>. 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 <T>, 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.

ilioSS

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

PaulS

Quote
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.

Quote
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.

breizh13

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

ilioSS

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


PaulS

Quote
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.


ilioSS

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

ilioSS

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

Code: [Select]

//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
Code: [Select]

/*
 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.

PaulS

Code: [Select]
void loop(){
 Serial.begin(9600);

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

Code: [Select]
  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.
Code: [Select]
  Serial.print("<W:");
 Serial.print(encoder0Pos, DEC);
 Serial.print(">");


Code: [Select]
       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.

Code: [Select]
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';
 }
}

ilioSS

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.

Code: [Select]
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

PaulS

Code: [Select]
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.

Code: [Select]
#define         C1      -2.0468
#define         C2      +0.0367
#define         C3      -0.0000015955

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

Code: [Select]
             [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.

ilioSS

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

Go Up