8 years, 6 months ago.

how to use the timer object to send my ultrasonic sensor reading wireless to the xbee coordinator?

i want to do it at a regular interval of 2 sec. my code right now is

include the mbed library with this snippet

#include "mbed.h"

Ticker analogue_ticker;

DigitalOut led1(LED1);
float dist;
float ain;
AnalogIn sensor(A0);
Serial pc(SERIAL_TX, SERIAL_RX);
Serial xbee1(PA_9, PA_10);

void getAnalogue() {
    led1 = !led1;
    ain = sensor.read(); /* Read analog value (output will be any value between 0 and 1 */
        dist = ain*1024*5/1000;
}

int main() {
    // Init the ticker with the address of the function  to be attached and the interval (200 ms)
    analogue_ticker.attach(&getAnalogue, 2.0);
    
    while (true) {
        pc.printf("ain = %.4f, dist = %.4f\t", ain, dist);
        wait(2);
    }
}

1 Answer

8 years, 5 months ago.

You're almost there. The ticker is reading the value every 2 seconds. All you need to change is make it so that instead of waiting for a fixed time the main loop waits until there has been a range measurement.

#include "mbed.h"
 
Ticker analogue_ticker;
 
DigitalOut led1(LED1);
AnalogIn sensor(A0);
Serial pc(SERIAL_TX, SERIAL_RX);
Serial xbee1(PA_9, PA_10);

// use the keyword volatile for anything that is changed in an interrupt or timer and then read in the main loop.
// without it the compiler could over-optimize.
volatile float dist;
volatile float ain;
volatile bool newReading = false;
 
void getAnalogue() {
    led1 = !led1;
    ain = sensor.read(); /* Read analog value (output will be any value between 0 and 1 */
    dist = ain*1024*5/1000;
    newReading = true;
}
 
int main() {
    // Init the ticker with the address of the function  to be attached and the interval (2s)
    analogue_ticker.attach(&getAnalogue, 2.0);
    
    while (true) {
        if (newReading) { // if the ticker has run...
          pc.printf("ain = %.4f, dist = %.4f\r\n", ain, dist);
          newReading = false;
        } 
    }

}

Accepted Answer

i want to now put my pir program in the main loop also. when thr is a change in the state of the pir sensor i want to send both readings from the PIR and ultrasonic sensors at the same time, to the coordinator. After sending, i wan to restart the 2 seconds timer. If there is no change to the state of the PIR, allow the timer to run, so that the transmission is still carried out at 2 seconds interval.

my pir code is

DigitalOut led1(LED1);
DigitalIn alarm(A1, PullUp);
Serial pc(SERIAL_TX, SERIAL_RX);
Serial xbee1(PA_9,PA_10);
 
int main() {
 pc.printf("running\n");
 
 bool sent = false;
 
 while(1) {
 
   unsigned char alarmOn[4] = { 0xAB, 0x01, 0x88, 0x01 };
   unsigned char alarmOff[4] = { 0xAB, 0x01, 0x88, 0x00 };
  
   if (alarm){ 
        led1=1;
        if(sent == false){    
          pc.printf("detected");
          for (int i = 0; i<4; i++)
            xbee1.putc(alarmOn[i]);
          
          sent = true;
          wait(0.1);
        }
      } else {
         led1=0;
         if (sent == true) { // alarm was on.
            pc.printf("not detected");
            for (int i = 0; i<4; i++)
               xbee1.putc(alarmOff[i]);
            
            sent = false;
            wait(0.1);
         }
      } 
  } 
}
posted by vic nes 29 Jun 2016

Then all you need to do is start/stop the ticker when you detect a change in the PIR.

The code below will manually measure the range when the PIR is triggered and then every 2 seconds after than until the alarm stops.

...
Ticker analogue_ticker;
AnalogIn sensor(A0);

volatile float dist;
volatile float ain;
volatile bool newReading = false;
 
void getAnalogue() {
    ain = sensor.read();
    dist = ain*1024*5/1000;
    newReading = true;
}

 
int main() {
 pc.printf("running\n");
 
 bool sent = false;

   unsigned char alarmOn[4] = { 0xAB, 0x01, 0x88, 0x01 };
   unsigned char alarmOff[4] = { 0xAB, 0x01, 0x88, 0x00 };
 
 while(1) {
 
   if (alarm){ 
        led1=1;
        if(sent == false){    
          pc.printf("detected");
          for (int i = 0; i<4; i++)
            xbee1.putc(alarmOn[i]);
          
          getAnalogue();
          analogue_ticker.attach(&getAnalogue, 2.0);
          sent = true;
        }
        if (newReading) { // if the ticker has run...
          pc.printf("ain = %.4f, dist = %.4f\r\n", ain, dist);
          newReading = false;
        } 
      } else {
         led1=0;
         if (sent == true) { // alarm was on.
            pc.printf("not detected");
            analogue_ticker.detach();
            for (int i = 0; i<4; i++)
               xbee1.putc(alarmOff[i]);
           
            sent = false;
         }
      } 
  } 
}

If you want to send the range all the time then the code is the same lines in a different order.

...
...
 analogue_ticker.attach(&getAnalogue, 2.0);
 while(1) {
 
   if (alarm){ 
        led1=1;
        if(sent == false){    
          pc.printf("detected");
          for (int i = 0; i<4; i++)
            xbee1.putc(alarmOn[i]);
          
          analogue_ticker.detach();
          getAnalogue();
          analogue_ticker.attach(&getAnalogue, 2.0);
          sent = true;
        }
      } else {
         led1=0;
         if (sent == true) { // alarm was on.
            pc.printf("not detected");
            for (int i = 0; i<4; i++)
               xbee1.putc(alarmOff[i]);
           
            sent = false;
         }
      } 

        if (newReading) { // if the ticker has run...
          pc.printf("ain = %.4f, dist = %.4f\r\n", ain, dist);
          newReading = false;
        } 

  } 

One thing to be careful of, never call the code to take a reading manually while the ticker is still active, if those detach commands weren't there then there is a risk of the program crashing. This is because analog input reads take time, you could be in the middle of reading the analog input when the ticker interrupts and causes the program to try a second analog read at the same time. Trying to read an analog input while in the middle of reading an analog input will cause things to crash.

posted by Andy A 29 Jun 2016

hmm what does line 7 "bool newReading = false;", line 12 "newReading = true;" and line 39 "newReading = false;" means? also if i might ask why do i nid "bool sent = false;" at line 19. line 35 why is it sent=true but line 49 sent=false?

posted by vic nes 29 Jun 2016

NewReading is set true when there is an analog reading that has not been reported. Line 7 is setting the initial value to false, line 12 is setting it true when the sensor has been read. Line 37 is a short version of if(newReading==true) Line 39 sets it back to false once the new value has been reported.

19, 35 and 49 are the same thing but tracking whether the alarm on message has been sent or not.

posted by Andy A 29 Jun 2016

if i want to make it like this > if either the pir or ultrasonic senses it will be considered occupied. but both must not detect for it to be vacant. do i need to change anything? i drew one flow chart . i inserted the file. how would the flow chart look for he whole program if i seperate it into the main loop flowchart and ticker flowchart.

/media/uploads/vicnes105/doc1.docx

posted by vic nes 01 Jul 2016

That flow chart isn't quite right (also if you are going to post an image please post it as an image not a propitiatory document format). What you have right now is:

When PIR becomes active 
  Send alarm on
  Send ultrasound
  while (PIR is active)
    send ultrasound every 2 seconds

When PIR becomes inactive
  send alarm off message

Return to start

Flowcharts don't work too well when you have tickers running independent of the main code, you end up with several flow charts with links between them.

If you want two different things to trigger the alarm then the logical thing to do is to treat the two of them in the same way or as close as possible. Have two tickers, once for each sensor

The main code checks if there is new data from either sensor, if there is it checks the last measured state of both sensors and whether the alarm is currently active and then takes the appropriate actions.

The pesudocode for that would be

Main start

Start PIR ticker
Start Ultrasound ticker
Alarm On = false

while (true)
  
  if (newPIR or newUltrasound)
    if (alarm on == false)
      if (PIR alarm or ultrasound alarm)
        send alarm on message
        alarm on = true

    if (alarm on == true)
      if (newUltrasound)
        send ultrasound range
      if ( not PIR alarm and not ultrasound alarm)
        send alarm off message
        alarm on = false
     
    newPIR = false
    newUltrasound = false
  
end of while
end of main

PIR ticker
  if (active) PIR alarm = true else PIR alarm = false
  newPIR = true

Ultrasound ticker
  range = read sensor
  if (range<threshold)  ultrasound alarm = true else ultrasound alarm = false
  newUltrasound = true
posted by Andy A 01 Jul 2016

whr do i put this part > PIR ticker if (active) PIR alarm = true else PIR alarm = false newPIR = true

Ultrasound ticker range = read sensor if (range<threshold) ultrasound alarm = true else ultrasound alarm = false newUltrasound = true

is it like this?

include the mbed library with this snippet

#include "mbed.h"
Ticker PIR_ticker;
Ticker analogue_ticker;
AnalogIn sensor(A0);
DigitalOut led1(LED1);
DigitalIn alarm(A1, PullUp);
Serial pc(SERIAL_TX, SERIAL_RX);
Serial xbee1(PA_9, PA_10); 
volatile float dist;
volatile float ain;
volatile bool newReading = false;
volatile bool newPIR = false;
 
void getAnalogue() {
    ain = sensor.read();
    dist = ain*1024*5/1000;
    newReading = true;
}

void getPIR() {
    newPIR = true;
}    
 
 
int main() {
 pc.printf("running\n");
 
 bool sent = false;
 
   unsigned char alarmOn[4] = { 0xAB, 0x01, 0x88, 0x01 };
   unsigned char alarmOff[4] = { 0xAB, 0x01, 0x88, 0x00 };
   
   getAnalogue();
          analogue_ticker.attach(&getAnalogue, 2.0);
          
   getPIR();
          PIR_ticker.attach(&getPIR, 2.0);
                      
 
 while(1) {
 
   if(newPIR||newReading)
    if (sent == false){ 
    
        led1=1;
        pc.printf("detected");
        sent = false;
          for (int i = 0; i<4; i++)
            xbee1.putc(alarmOn[i]);
            sent = true;
   if(sent == true)
   getAnalogue();
          analogue_ticker.attach(&getAnalogue, 2.0);
    if(newReading)
     pc.printf("ain = %.4f, dist = %.4f\r\n", ain, dist);
          newReading = false;
     if(!newPIR&&!newReading)
      sent = true;
      for (int i = 0; i<4; i++)
               xbee1.putc(alarmOff[i]);
         sent = false;      
  }
 }      
}            
posted by vic nes 01 Jul 2016

No, they go as the functions called by Tickers. Your code above will crash a after a random amount of time, you are reading an analog input in these main loop while a Ticker is running that reads it.

You attach the Tickers at the start and just leave them running, no need to change them again.

The main code then only checks the values set by the Tickers I'm not going to try editing code on a phone so you'll have to wait until Monday if you can't work it out.

posted by Andy A 02 Jul 2016

a sry edit wrong

posted by vic nes 04 Jul 2016

Ticker PIR_ticker;
Ticker analogue_ticker;
AnalogIn sensor(A0);
DigitalOut led1(LED1);
DigitalIn alarm(A1, PullUp);
Serial pc(SERIAL_TX, SERIAL_RX);
Serial xbee1(PA_9, PA_10);
volatile float dist;
volatile float ain;
volatile bool PIRAlarm = false;
volatile bool newReading = false;
volatile bool newPIR = false;

void getAnalogue()
{
    ain = sensor.read();
    dist = ain*1024*5/1000;
    newReading = true;
}

void getPIR()
{
    PIRAlarm = alarm; 
    newPIR = true;
}


main()
{
    pc.printf("running\n");

    bool alarmOn = false;

    unsigned char alarmOnMsg[4] = { 0xAB, 0x01, 0x88, 0x01 };
    unsigned char alarmOffMsg[4] = { 0xAB, 0x01, 0x88, 0x00 };

    // check both every two seconds. No reason why these times have to be the same. Could be different if wanted.
    analogue_ticker.attach(&getAnalogue, 2.0);
    PIR_ticker.attach(&getPIR, 2.0);


    while(1) {

        if(newPIR||newReading) {
            if (alarmOn == false) {
                if (PIRAlarm || (dist < 0.4f)) {
                    led1=1;
                    for (int i = 0; i<4; i++)
                        xbee1.putc(alarmOnMsg[i]);
                    alarmOn = true;
                }
            }

            if (alarmOn && !PIRAlarm && (dist > 0.5f)) {
                for (int i = 0; i<4; i++)
                    xbee1.putc(alarmOffMsg[i]);
                alarmOn = false;
            }

            if (alarmOn && newReading) // only send range message if it's a ultrasound reading.
                pc.printf("ain = %.4f, dist = %.4f\r\n", ain, dist);

            newPIR = false;
            newReading = false;
        }
    }
}
posted by Andy A 04 Jul 2016

the ticker is called the interrupt service routine right .if i want to draw it would the interrupt service routine flow chart look like this? /media/uploads/vicnes105/asd.png

/media/uploads/vicnes105/ultrasonic_sensor_behaviourr.png .also i wan to make another xbee packet to send the ultrasonic sensor reading. the ultrasonic one will be unsigned char ultrasonic[4] = { 0xAB,0x01,0x87,0-5metre(but how do i put in hexadecimal?) }; how to know what to put for the last byte? the ultrasonic sensor measures 0-5 metre.

posted by vic nes 05 Jul 2016

That's not quite right on the flow chart. There are two completely independent ISRs, one for the PIR, one for the ultrasound. In the code above they are both running at the same rate and starting at the same time so they will effectively be at the same time however there is no reason why this needs to be the case. You could run the PIR at 1 second or 1/10th of a second and so get faster detection of movement.

What resolution do you need on the ultrasound? You have a single byte so you can have 256 possible values. The easiest solution is to send the range in meters but that gives terrible resolution. Sending range in meters * 10 will give you a 10 cm resolution but if the maximum range is 5 meters you're still only using values up to about 50. 1cm resolution would require being able to count to 500 which you can't do. For maximum resolution with a 5 meter maximum range you have about 50 values per meter, that gives you 2cm resolution.

int rangeIn2cmUnits = (dist/0.02) + 0.5; // convert to units of 2cm and round to nearest integer.
if (rangeIn2cmUnits < 0) // sanity check, should never be negative but just in case...
  rangeIn2cmUnits = 0;
if (rangeIn2cmUnits > 250) // over 5 meters
  rangeIn2cmUnits = 251; // use a value of 251 to indicate anything over 5m.

ultrasonic[3] = rangeIn2cmUnits; // set the last value of the message to the range.

At the other end of the link multiply the value by 0.02 to get back to meters.

posted by Andy A 05 Jul 2016

ah .i should leave the last byte space blank right for this below?

unsigned char ultrasonic[4] = { 0xAB, 0x01, 0x88 };

for the pir it can send off or on as in

for (int i = 0; i<4; i++)
                        xbee1.putc(alarmOnMsg[i]);
and

for (int i = 0; i<4; i++)
                        xbee1.putc(alarmOffMsg[i]);

then for the ultrasonic sensor i would just put like this?

for (int i = 0; i<4; i++)
                        xbee1.putc(ultrasonic[i]);
posted by vic nes 05 Jul 2016

No, don't leave it blank.

Creating an array with 4 elements but only setting 3 values when you create it is a bad idea, to anyone reading the code it will look like you either only use 3 bytes or you forgot to include one value. Set the last byte to something and then add a comment saying that it will be changed depending on the range.

It doesn't matter what you set the last byte to, you'll need to change it to be the correct value for the range each time you send it, but set it to something. In the code above the highest valid value is 251 (for anything over 5m) so you could set it to 255, that way if you ever see that value you know something has gone wrong.

posted by Andy A 06 Jul 2016

ah i see. how about the the my second question. i would put it like that?

posted by vic nes 06 Jul 2016

Yes. Don't forget to set the value of the last byte before sending it.

posted by Andy A 06 Jul 2016

i wan to ask this part

if (alarm on == true)
      if (newUltrasound)
        send ultrasound range
      if ( not PIR alarm and not ultrasound alarm)
        send alarm off message
        alarm on = false

the code for that part is

 if (alarmOn && !PIRAlarm && (dist > 0.5f)) {
                for (int i = 0; i<4; i++)
                    xbee1.putc(alarmOffMsg[i]);
                alarmOn = false;

it should not be like this> if (alarmOn && !PIRAlarm && ! (dist > 0.5f))

the not is it you forgot to add or is it dont nid to add?

for this part>

if (alarmOn && newReading) 
                pc.printf("ain = %.4f, dist = %.4f\r\n", ain, dist);

i also nid to send the bytes to the xbee rite? means will be like this>>

if (alarmOn && newReading) 
                pc.printf("ain = %.4f, dist = %.4f\r\n", ain, dist);

for (int i = 0; i<4; i++)
                        xbee1.putc(alarmOnMsg[i]);

for (int i = 0; i<4; i++)
                        xbee1.putc(ultrasonic[i]);

i wan to know which parts of this code below to put this>""for (int i = 0; i<4; i++) xbee1.putc(ultrasonic[i]);" is it below line 58 and below line 70?

do i nid to add the "bool ultrasonic = false" like for the alarmOn?

Ticker PIR_ticker;
Ticker analogue_ticker;
AnalogIn sensor(A0);
DigitalOut led1(LED1);
DigitalIn alarm(A1, PullUp);
Serial pc(SERIAL_TX, SERIAL_RX);
Serial xbee1(PA_9, PA_10);
volatile float dist;
volatile float ain;
volatile bool PIRAlarm = false;
volatile bool newReading = false;
volatile bool newPIR = false;
 
void getAnalogue()
{
    ain = sensor.read();
    dist = ain*1024*5/1000;
    newReading = true;
}
 
void getPIR()
{
    PIRAlarm = alarm; 
    newPIR = true;
}
 
 
main()
{
    pc.printf("running\n");
 
    bool alarmOn = false;
 
    unsigned char alarmOnMsg[4] = { 0xAB, 0x01, 0x88, 0x01 };
    unsigned char alarmOffMsg[4] = { 0xAB, 0x01, 0x88, 0x00 };
    unsigned char ultrasonic[4] = { 0xAB, 0x01, 0x88, 0xFF };
    
    int rangeIn2cmUnits = (dist/0.02) + 0.5; // convert to units of 2cm and round to nearest integer.
if (rangeIn2cmUnits < 0) // should never be negative but just in case
  rangeIn2cmUnits = 0;
if (rangeIn2cmUnits > 250) // over 5 meters
  rangeIn2cmUnits = 251; // use a value of 251 to indicate anything over 5m.
  
 ultrasonic[3] = rangeIn2cmUnits; // set the last value of the message to the range.
 
    // check both every two seconds
    analogue_ticker.attach(&getAnalogue, 2.0);
    PIR_ticker.attach(&getPIR, 1.0);
 
 
    while(1) {
 
        if(newPIR||newReading) {
            if (alarmOn == false) {
                if (PIRAlarm || (dist < 0.4f)) {
                    led1=1;
                    for (int i = 0; i<4; i++)
                        xbee1.putc(alarmOnMsg[i]);
                    alarmOn = true;
                }
            }
 
            if (alarmOn && !PIRAlarm && (dist > 0.5f)) {
                for (int i = 0; i<4; i++)
                    xbee1.putc(alarmOffMsg[i]);
                alarmOn = false;
            }
 
            if (alarmOn && newReading) 
                pc.printf("ain = %.4f, dist = %.4f\r\n", ain, dist);
 
            newPIR = false;
            newReading = false;
        }
    }
}

also did i put this on the correct place?>>

int rangeIn2cmUnits = (dist/0.02) + 0.5; // convert to units of 2cm and round to nearest integer.
if (rangeIn2cmUnits < 0) // should never be negative but just in case
  rangeIn2cmUnits = 0;
if (rangeIn2cmUnits > 250) // over 5 meters
  rangeIn2cmUnits = 251; // use a value of 251 to indicate anything over 5m.
  
 ultrasonic[3] = rangeIn2cmUnits; // set the last value of the message to the range.

lastly whr do i put the printf messages to test like if it is working as intended like "not occupied" and "occupied" when i test the pir and ultrasonic?

posted by vic nes 07 Jul 2016

1) The pesudo code and the final code have very slightly different logic which is why the lines aren't identical

2) Sort of. The line if (alarmOn && newReading) is where you want to send the new ultrasound ranges. It may or may not be where you want to send the alarm on message.

3) No you don't need "bool ultrasonic = false" The alarmOn signal is for either source of alarm, it is set by both the PIR and the ultrasound..

4) No you didn't put the range conversion in the correct place. As I said before, that needs to be done every time you send a range. Where you put it it is only called once before the sensor had ever been read.

Also you have the same message for alarm on and ultrasound range of 2cm. The alarm off message and a range of 0cm are also the same. You need to send a different first 3 bytes for the two different messages.

posted by Andy A 07 Jul 2016

Code split into two parts due to post size limits...

#include "mbed.h"
Ticker PIR_ticker;
Ticker analogue_ticker;

AnalogIn sensor(A0);
DigitalIn alarm(A1, PullUp);

DigitalOut led1(LED1);

Serial pc(SERIAL_TX, SERIAL_RX);
Serial xbee1(PA_9, PA_10);

volatile float dist;
volatile float ain;
volatile bool newReading = false;

volatile bool PIRAlarm  = false;
volatile bool newPIR = false;


bool alarmOn = false;

// read the ultrasound range
void getAnalogue()
{
    ain = sensor.read();
    dist = ain*1024*5/1000;
    newReading = true;
}

// read PIR sensor
void getPIR()
{
    PIRAlarm  = alarm;
    newPIR = true;
}

// send an ultrasound range message
const unsigned char ultrasonicMsg[4] = { 0xAB, 0x01, 0x89 }; // Changed from AB 01 88
void sendRange(float distance)
{
// calculate the range byte
    int rangeIn2cmUnits = (distance/0.02) + 0.5; // convert to units of 2cm and round to nearest integer.
    if (rangeIn2cmUnits < 0) // should never be negative but just in case
        rangeIn2cmUnits = 0;
    if (rangeIn2cmUnits > 250) // over 5 meters
        rangeIn2cmUnits = 251; // use a value of 251 to indicate anything over 5m.

// send the message header
    for (int i = 0; i<3; i++)
        xbee1.putc(ultrasonicMsg[i]);
// send the range
    xbee1.putc((unsigned char)rangeIn2cmUnits);

}

// send the alarm on/off message
const unsigned char alarmMsg[3] = { 0xAB, 0x01, 0x88 };
void sendAlarm(bool on)
{
    // send the message header
    for (int i = 0; i<3; i++)
        xbee1.putc(alarmMsg[i]);
    //send the alarm status
    if (on)
        xbee1.putc(0x01);
    else
        xbee1.putc(0x00);

    // set/clear the flag indicating that the alarm is in.
    alarmOn = on;

    // set the LED to match the alarm status
    if (on)
        led1=1;
    else
        led1 = 0;
}
posted by Andy A 07 Jul 2016

Second half of code.

int main()
{
    pc.printf("running\n");

// attach the tickers to read the values.
    analogue_ticker.attach(&getAnalogue, 2.0);
    PIR_ticker.attach(&getPIR, 1.0);

// loop forever
    while(1) {

        if(newPIR||newReading) {  // if there is something to do

            if (alarmOn == false) {   // if the alarm is currently off

                if (PIRAlarm || (dist < 0.4f)) {  // if the alarm should be on
                    sendAlarm(true); // send the alarm on message
                }

            } else {  // the alarm is currently on

                if (!PIRAlarm  && (dist > 0.5f)) {  // no PIR and range is > 0.5m
                    sendAlarm(false); // send the alarm off message
                }

            }

            // if the alarm is on and we have a new range measurment
            if (alarmOn && newReading) {
                sendRange(dist);   // send the range message
                pc.printf("ain = %.4f, dist = %.4f\r\n", ain, dist); // output debug text
            }

            // clear the new reading flags.
            newPIR = false;
            newReading = false;
        }
    }
}
posted by Andy A 07 Jul 2016

The code includes all this conditions below already?:

if the pir senses and the distance of the ultrasonic sensor is less than 0.4 it means occupied.

if the pir senses and distance of the ultrasonic sensor above 0.4 still considered occupied.

if the pir does not sense and distance of the ultrasonic sensor is below 0.4 is considered occupied.

if pir does not sense and distance of the ultrasonic sensor is above 0.4 is considered vacant.

i also want to printf the "occupied" and "vacant".

i remember u wrote this "At the other end of the link multiply the value by 0.02 to get back to meters." whr is the other end of the link mean?

posted by vic nes 07 Jul 2016

You should be able to answer all your questions yourself. The logic in the code is about as simple as it gets and there are comments at the start of each block. If you can't answer the questions then you need to work through some programming tutorials. You can't keep asking people to do every single line of code for you, you'll never learn if you do that.

The other end of the link is whatever the xbee radio is talking to.

posted by Andy A 07 Jul 2016

ah yes i will read some tutorial.

posted by vic nes 07 Jul 2016

yes all the conditions is thr.

posted by vic nes 08 Jul 2016