7 years, 8 months ago.

when combining 2 of this code why only the 2nd part of the while loop works?

these will be the 2 code i want to combine.

Serial pc(SERIAL_TX, SERIAL_RX);
Serial xbee1(PA_9, PA_10);
DigitalOut Relay(PB_0); 
 
const char RelayCommand[3] = { 0xAB, 0x01, 0x99 };
 
int main() {
 
  int byteCount = 0; 
  char byteIn;
  while (true) {
    byteIn = xbee1.getc(); 
    if (byteCount < 3) { // still looking for the header
      if (byteIn == RelayCommand[byteCount]) // data in matches the next byte in the header 
        byteCount++;                                           // expect the next header byte
      else if (byteIn == RelayCommand[0])        // Got the first byte of a header when we didn't expect it
        byteCount = 1;                                         // expect the second byte next
      else 
        byteCount = 0;                                         // No idea what's going on. Go back to the start
    } else {   // got the full header.
        if (byteIn == 0x01) {
          Relay = 1;
          pc.printf("on");
        }
        else if  (byteIn == 0x00) {
          Relay = 0;
          pc.printf("off");
        }
        byteCount = 0; 
    }
  }  
}

and

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 };
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;
}
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;
        }
    }
}

so when i combine it only line 127-144 works. why is that and how to make the whole while loop work?

#include "mbed.h" 
Ticker PIR_ticker;
Ticker analogue_ticker;
 
AnalogIn sensor(A0);
DigitalIn alarm(A1, PullUp);
 
DigitalOut led1(LED1);
DigitalOut Relay(PB_0); 
 
Serial pc(SERIAL_TX, SERIAL_RX);
Serial xbee1(PA_9, PA_10);
 
int byteCount = 0; 
char byteIn;
 
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 };
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;
}

// read STATE from xbee
const char RelayCommand[3] = { 0xAB, 0x01, 0x99 };
void getSTATE()
{
    byteIn = xbee1.getc();
}    
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;
        }
        byteIn = xbee1.getc();
         if (byteCount < 3) { // still looking for the header
        if (byteIn == RelayCommand[byteCount]) // data in matches the next byte in the header 
          byteCount++;                                           // expect the next header byte
        else if (byteIn == RelayCommand[0])        // Got the first byte of a header when we didn't expect it
          byteCount = 1;                                         // expect the second byte next
        else 
          byteCount = 0;                                         // No idea what's going on. Go back to the start
         } else {   // got the full header.
          if (byteIn == 0x01) {
            Relay = 1;
            pc.printf("on");
          }
          else if  (byteIn == 0x00) {
            Relay = 0;
            pc.printf("off");
          }
          byteCount = 0; 
      } 
    }
}
posted by vic nes 20 Jul 2016

1 Answer

7 years, 8 months ago.

getc() will block until it gets data so the loop will sit there waiting for data to arrive from the radio.

If the only thing the while loop is doing is reading data then that's not a problem. If it needs to also do something else then it is a problem.

Fortunately there is a simple solution, make all of the data reception code conditional on there being data to read.

if (xbee.readable()) {
  byteIn = xbee1.getc());
  ...
  all the other code to do with reading the received data
  ...
}

Also when you combined the two pieces of code byteIn and byteCount seems to have become globals for no good reason and this function which is never called seems to have magically appeared.

void getSTATE()
{
    byteIn = xbee1.getc();
}   

Accepted Answer