A story of three xbees; two emitters and one hub

So I have two transmitting xbees sending data to a central arduino/xbee and that part is dandy. (btw, im working in transparent mode).

Now since these are all talking on the same serial port, I am getting both values mushed together when I want to be able to distinguish between each value from each emitting xbee.

tips? suggestions? whats possible?

Have the transmitting XBees include a unique identifier with the data. Could just be a single character.

Or are you saying you are seeing the data from the two transmitting nodes interleaved at the receiver?

Have the transmitting XBees include a unique identifier with the data. Could just be a single character.

I've tried your suggestion before, but might not be executing it right. for one of the transmitters, I am serially writing the incoming sensor value and and 'A' to establish an identifier like so:

  Serial.write('A');
Serial.write(average);
delay(100);

am I completely off? what were you suggesting?

oh, and let me clarify, im sending sensor data from each transmitting xbee to a single receiving xbee. I am getting the sensor readings, except everything is all being mushed together when I am reading from the receiving end.

Yes, that is exactly what I was suggesting, but define "mushed". If one transmitter sends "A123" and the other sends "B999", is the receiver seeing something like "AB129399"?

is the receiver seeing something like "AB129399"?

It fluctuates between the values. So in other words, when printing in the receiver, i.e. im just listening to any old thing coming into the serial port, i get a flash of one value from one emitter then another value from the other. Make sense? I guess yes they are overlapping each other

But is any single message from either transmitter intact? "One value from one emitter then another value from the other" is what I might expect, best case.

Or are characters from one transmitter intermixed with those from the other transmitter?

I want to dumb this down to be 100% sure I answer that correctly.

So I two dividing print lines in the receiver that show two different Serial.read() variables I created. When printed, I first place one xbee transmitter 20 feet away, then I have another within arms reach the incoming lines both sync to the same number until I shift around one of the transmitters, then that new incoming value shows up, and affects everything else.

How about posting the code for the receiver.
Also post a copy of the output, and explain how it is not what you expected.

My gut feel on this is that the data from the two transmitters stands to get mixed up, unless measures are taken to prevent it. The best approach might be to change to API mode. It can probably be made to work in transparent mode, but some scheme to prevent the two transmitters from transmitting simultaneously will be needed. Such an implementation stands to be relatively clunky as compared to API mode.

Receiver Code :

#include <LiquidCrystal.h>

const int ledPin = 13;
//const int signalStrengthPin = 9;

//byte incomingByte, val_read;
int val_read;

int emitter2;

 
//int RSSIpin = 9;
//unsigned long rssiDur;

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup()
{
  Serial.begin(38400);
 lcd.begin(16,2);
lcd.noAutoscroll();
     
  pinMode(ledPin, OUTPUT);
 // pinMode(signalStrengthPin, INPUT);
}

void loop()
{


 //rssiDur = pulseIn(RSSIpin, LOW, 200);
  // print signal strength
  //Serial.println(rssiDur);
 
  if (Serial.available()>0)
  {
   // if ((int(val_read) == 'B'))
    
val_read = Serial.read();

Serial.println(int(val_read));
delay(100);


//delay(100);
//Serial.print(int(inches));
lcd.setCursor(0,0);
lcd.print("Bike1 = ");
lcd.print(int(val_read), DEC);
  
  emitterTwo();
}
}
void emitterTwo(){

   if ((int(val_read) == 1))
    {
      emitter2 = Serial.read();
      Serial.println(int(emitter2));
      delay(100);
      lcd.setCursor(0,1);
lcd.print("Bike2 = ");
lcd.print(int(emitter2), DEC);
  }
}

...and Emitter Code for only of the modules (basically same exact code) :

//Transmitter modules. These are the bike units intended to show signal strength indication in correlation to a central networked hub.
//x bees have been configured with personal ID's to avoid interference with other networks (encryption).
//optimal xbee use is outdoors, no wall interference/metal(close contact). range is 300ft at optimal conditions. 
//





const int rssi_pin = 9; //RSSI Pin of the XBee Module
 int rssiDur; //variable to read pin
byte inches_val;

//LED pins//////////////////////////
const int led3 = 3;
const int led4 = 4;
const int led5 = 5;
const int led6 = 6;
const int led7= 7;
const int led8= 8;
const int led10= 10;
const int led11= 11;
const int led12= 12;
const int led13= 13;
/////////////////////////////////////

///Averager Variables///////////////////////////////

//this is intended to place first 10 read incoming RSSI values in an array and average. smoother readings

const int numReadings = 10;

int readings[numReadings];      // the readings from the RSSI
int index = 0;                  // the index of the current reading
int total = 0;                  // the running total
int average = 0;                // the average


///////////////////////////////////////////////////



void setup(){
  
   for (int thisReading = 0; thisReading < numReadings; thisReading++)
    readings[thisReading] = 0; 

pinMode (led3, OUTPUT);
pinMode (led4, OUTPUT);
pinMode (led5, OUTPUT);
pinMode (led6, OUTPUT);
pinMode (led7, OUTPUT);
pinMode (led8, OUTPUT);
pinMode (led10, OUTPUT);
pinMode (led11, OUTPUT);
pinMode (led12, OUTPUT);
pinMode (led13, OUTPUT);
  
   //Serial1.begin(38400);
  Serial.begin(38400); //Xbee communicating at this baud
}




void loop(){


 rssiDur = pulseIn(rssi_pin, LOW, 200); //this is set to 200ms with ATRP @ 2
inches_val = rssiDur; // XBee times out 10-12 inches apart, so added 11
inches_val = rssiDur + 24; // XBee times out 10-12 inches apart, so added 11
min(inches_val, 1);
//min(inches_val, 18);
total= total - readings[index];         
  // read from the sensor:  
  readings[index] = inches_val; 
  // add the reading to the total:
  total= total + readings[index];       
  // advance to the next position in the array:  
  index = index + 1;                    

  // if we're at the end of the array...
  if (index >= numReadings)              
    // ...wrap around to the beginning: 
    index = 0;                           

  // calculate the average:
  average = total / numReadings;         
  
 //Serial.print("Signal Strength distance inches = ");
//Serial.println(average );
  Serial.write(1);
    //Serial.write("emitter two");
  Serial.write(average);   
  delay(100);        // delay in between rea

// value 10 = 1 meter
if (average > 24 && average < 124){ //1-5 meters
 // Serial.write(1);
   digitalWrite(led3, HIGH);
       digitalWrite(led4, HIGH);
        digitalWrite(led5, HIGH);
        digitalWrite(led6, HIGH);
        digitalWrite(led7, HIGH);
        digitalWrite(led8, HIGH);
        digitalWrite(led10, HIGH);
        digitalWrite(led11, HIGH);
        digitalWrite(led12, HIGH);
        digitalWrite(led13, HIGH);
        
}
  if (average > 124 && average < 224){ //5-10 meters
  //Serial.write(2);
   digitalWrite(led3, HIGH);
       digitalWrite(led4, HIGH);
        digitalWrite(led5, HIGH);
        digitalWrite(led6, HIGH);
        digitalWrite(led7, HIGH);
         digitalWrite(led8, HIGH);
        digitalWrite(led10, HIGH);
        digitalWrite(led11, HIGH);
        digitalWrite(led12, LOW);
        digitalWrite(led13, LOW);
        
  }
  if (average > 224 && average < 324){ //10- 15 meters 
  //Serial.write(3); //this is 10 meters. write to reciever 
   digitalWrite(led3, HIGH);
       digitalWrite(led4, HIGH);
        digitalWrite(led5, HIGH);
        digitalWrite(led6, HIGH);
        digitalWrite(led7, HIGH);
         digitalWrite(led8, HIGH);
         digitalWrite(led10, LOW);
        digitalWrite(led11, LOW);
        digitalWrite(led12, LOW);
        digitalWrite(led13, LOW);
        
  }
  if (average > 324 && average < 424){ //15-20 meters
  //Serial.write(4);
    digitalWrite(led3, HIGH);
       digitalWrite(led4, HIGH);
        digitalWrite(led5, HIGH);
        digitalWrite(led6, HIGH);
        digitalWrite(led7, LOW);
           digitalWrite(led8, LOW);
        digitalWrite(led10, LOW);
        digitalWrite(led11, LOW);
        digitalWrite(led12, LOW);
        digitalWrite(led13, LOW);
        
  }
  if (average > 424 ){ //20-30 meters
 // Serial.write(5);
   digitalWrite(led3, HIGH);
       digitalWrite(led4, HIGH);
        digitalWrite(led5, LOW);
        digitalWrite(led6, LOW);
        digitalWrite(led7, LOW);
         digitalWrite(led8, LOW);
        digitalWrite(led10, LOW);
        digitalWrite(led11, LOW);
        digitalWrite(led12, LOW);
        digitalWrite(led13, LOW);
      
    }
    
    //isolated instances below
   
  if (average == 24 ){ //if their is no signal
  Serial.write(9);
   digitalWrite(led3, LOW);
       digitalWrite(led4, LOW);
        digitalWrite(led5, LOW);
        digitalWrite(led6, LOW);
        digitalWrite(led7, LOW);
         digitalWrite(led8, LOW);
        digitalWrite(led10, LOW);
        digitalWrite(led11, LOW);
        digitalWrite(led12, LOW);
        digitalWrite(led13, LOW);
}

both emitter values show up, but overlapping each other. and not mixed together, I mean with this code It shows one value, clears, then shows another value from other emitter, but all in same line.

And Im sure API mode would be useful, but I am not too comfortable right now to take on a new beast. If it is a must, and their isn't a good suggestion for what I am doing now, I need a push in the right direction for API mode aside from configuring AT command and installing an arduino library.

OK I'll have a look. What kind of XBees are these? Series 1? Series 2?

Here are a few things off the top.

  1. delay(100) in receiver code. Since there are two transmitters each sending every 100ms, probably the code never gets to the emitterTwo() function. I would use no delay in the receiver. It should constantly be watching for incoming data, not "sleeping" -- it can do nothing while delay() executes.

  2. int(val_read) does nothing, since val_read is an int.

  3. Serial.read() reads a byte. Serial.write() writes a byte. So Serial.write(average), where average is an int, may not have the desired effect.

  4. In emitterTwo(), the receiver code appears to check the first byte to identify the sender. But this is not done in loop(). The code should be consistent, should treat every incoming message identically, and there should be a fixed message structure. The code should not make assumptions about which transmitter's message might be received first, or that the two will always alternate perfectly. Some sort of message start delimiter may be a good thing. Just as a starting idea, each transmitter could always send a message like "ndd" where the * is the start delimiter, n is a single byte identifying the transmitter, and dd is two bytes representing the data sent by the transmitter. Then the receiver code could watch for "" as the start of a message, then decode the next three bytes accordingly. If another * shows up in the next three bytes, then that is an error, but would allow the receiver to re-sync.

  5. It appears you are trying to determine distance (in inches!) based on the RSSI value. This will be a gross approximation at best. Further, if these are S2 (mesh) XBees, RSSI only represents the last hop, so it's entirely possible that the furthest transmitter would route through the closer one, and the hub would see no difference in the RSSI values for the two transmitters.

Hope this helps.

Let me read over that. They are series 1

And can you give me a example in code ? Having hard time understanding that with syntax

danieljay:
And can you give me a example in code ? Having hard time understanding that with syntax

An example of what exactly?

Transmitter code might look like

    const byte nodeID = 1;
    int myData;

    Serial.write('*');            //message start delimiter
    Serial.write(nodeID);
    Serial.write(myData >> 8);    //most significant byte
    Serial.write(myData & 0xFF);  //least significant byte

Receiver code might look like

    byte c;
    byte nodeID;
    int myData;

    c = Serial.read();
    if (c == '*') {                     //wait for start delimiter
        nodeID = Serial.read();
        myData = Serial.read() << 8;    //msb
        myData += Serial.read();        //lsb
        
        //message received and decoded, continue processing it...
    }

Checking for a premature start delimiter is left as an exercise for the reader :smiley:

Great! When I get home I'm going to test this out and let you know. And start delimiter ? You mean some kinda delay for emitters? Unclear what you mean by that

A start delimiter is just a special character of your choosing that serves to mark the start of a message. I chose an asterisk (*) but any character can be used, as long as it's not also used in the data being sent. Having said that, since we are sending binary data, we have a problem with that because there's no guarantee that a byte of "myData" in the example code above won't look like an asterisk. As as simplifying assumption, we could dispense with checking for a "premature" start delimiter, and see how things work just relying on knowing that the messages are a constant length. I'd expect that it would actually work fairly well. This is the kind of robustness that can be had with API mode. There is at least one very good library out there to help operate in API mode (here), but in sticking to transparent mode, we get to do it ourselves, or take the easy way out and live with a weaker design.

eh, not having much luck. the LCD prints out a -257 and nothing changes.

here the code:

Emitter:

//Transmitter modules. These are the bike units intended to show signal strength indication in correlation to a central networked hub.
//x bees have been configured with personal ID's to avoid interference with other networks (encryption).
//optimal xbee use is outdoors, no wall interference/metal(close contact). range is 300ft at optimal conditions. 
//





const int rssi_pin = 9; //RSSI Pin of the XBee Module
 int rssiDur; //variable to read pin
byte inches_val;

//LED pins//////////////////////////
const int led3 = 3;
const int led4 = 4;
const int led5 = 5;
const int led6 = 6;
const int led7= 7;
const int led8= 8;
const int led10= 10;
const int led11= 11;
const int led12= 12;
const int led13= 13;
/////////////////////////////////////

///Averager Variables///////////////////////////////

//this is intended to place first 10 read incoming RSSI values in an array and average. smoother readings

const int numReadings = 10;

int readings[numReadings];      // the readings from the RSSI
int index = 0;                  // the index of the current reading
int total = 0;                  // the running total
byte average = 0;                // the average


///////////////////////////////////////////////////
const byte nodeID = 1;
    int myData;


void setup(){
  
   for (int thisReading = 0; thisReading < numReadings; thisReading++)
    readings[thisReading] = 0; 

pinMode (led3, OUTPUT);
pinMode (led4, OUTPUT);
pinMode (led5, OUTPUT);
pinMode (led6, OUTPUT);
pinMode (led7, OUTPUT);
pinMode (led8, OUTPUT);
pinMode (led10, OUTPUT);
pinMode (led11, OUTPUT);
pinMode (led12, OUTPUT);
pinMode (led13, OUTPUT);
  
   //Serial1.begin(38400);
  Serial.begin(38400); //Xbee communicating at this baud
}




void loop(){


 rssiDur = pulseIn(rssi_pin, LOW, 200); //this is set to 200ms with ATRP @ 2
inches_val = rssiDur; // XBee times out 10-12 inches apart, so added 11
inches_val = rssiDur + 24; // XBee times out 10-12 inches apart, so added 11
min(inches_val, 1);
//min(inches_val, 18);
total= total - readings[index];         
  // read from the sensor:  
  readings[index] = inches_val; 
  // add the reading to the total:
  total= total + readings[index];       
  // advance to the next position in the array:  
  index = index + 1;                    

  // if we're at the end of the array...
  if (index >= numReadings)              
    // ...wrap around to the beginning: 
    index = 0;                           

  // calculate the average:
  average = total / numReadings;         
  


    Serial.write('*');            //message start delimiter
    Serial.write(nodeID);
    Serial.write(average >> 8);    //most significant byte
    Serial.write(average & 0xFF);  //least significant byte
delay(100);
// value 10 = 1 meter
if (average > 24 && average < 124){ //1-5 meters
 // Serial.write(1);
   digitalWrite(led3, HIGH);
       digitalWrite(led4, HIGH);
        digitalWrite(led5, HIGH);
        digitalWrite(led6, HIGH);
        digitalWrite(led7, HIGH);
        digitalWrite(led8, HIGH);
        digitalWrite(led10, HIGH);
        digitalWrite(led11, HIGH);
        digitalWrite(led12, HIGH);
        digitalWrite(led13, HIGH);
        
}
  if (average > 124 && average < 224){ //5-10 meters
  //Serial.write(2);
   digitalWrite(led3, HIGH);
       digitalWrite(led4, HIGH);
        digitalWrite(led5, HIGH);
        digitalWrite(led6, HIGH);
        digitalWrite(led7, HIGH);
         digitalWrite(led8, HIGH);
        digitalWrite(led10, HIGH);
        digitalWrite(led11, HIGH);
        digitalWrite(led12, LOW);
        digitalWrite(led13, LOW);
        
  }
  if (average > 224 && average < 324){ //10- 15 meters 
  //Serial.write(3); //this is 10 meters. write to reciever 
   digitalWrite(led3, HIGH);
       digitalWrite(led4, HIGH);
        digitalWrite(led5, HIGH);
        digitalWrite(led6, HIGH);
        digitalWrite(led7, HIGH);
         digitalWrite(led8, HIGH);
         digitalWrite(led10, LOW);
        digitalWrite(led11, LOW);
        digitalWrite(led12, LOW);
        digitalWrite(led13, LOW);
        
  }
  if (average > 324 && average < 424){ //15-20 meters
  //Serial.write(4);
    digitalWrite(led3, HIGH);
       digitalWrite(led4, HIGH);
        digitalWrite(led5, HIGH);
        digitalWrite(led6, HIGH);
        digitalWrite(led7, LOW);
           digitalWrite(led8, LOW);
        digitalWrite(led10, LOW);
        digitalWrite(led11, LOW);
        digitalWrite(led12, LOW);
        digitalWrite(led13, LOW);
        
  }
  if (average > 424 ){ //20-30 meters
 // Serial.write(5);
   digitalWrite(led3, HIGH);
       digitalWrite(led4, HIGH);
        digitalWrite(led5, LOW);
        digitalWrite(led6, LOW);
        digitalWrite(led7, LOW);
         digitalWrite(led8, LOW);
        digitalWrite(led10, LOW);
        digitalWrite(led11, LOW);
        digitalWrite(led12, LOW);
        digitalWrite(led13, LOW);
      
    }
    
    //isolated instances below
   
  if (average == 24 ){ //if their is no signal
  Serial.write(9);
   digitalWrite(led3, LOW);
       digitalWrite(led4, LOW);
        digitalWrite(led5, LOW);
        digitalWrite(led6, LOW);
        digitalWrite(led7, LOW);
         digitalWrite(led8, LOW);
        digitalWrite(led10, LOW);
        digitalWrite(led11, LOW);
        digitalWrite(led12, LOW);
        digitalWrite(led13, LOW);
}

}

reciever :

#include <LiquidCrystal.h>

const int ledPin = 13;
//const int signalStrengthPin = 9;

//byte incomingByte, val_read;
byte val_read;

int emitter2;


    byte nodeID;
 
    int average;
//int RSSIpin = 9;
//unsigned long rssiDur;

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup()
{
  Serial.begin(38400);
 lcd.begin(16,2);
lcd.noAutoscroll();
     
  pinMode(ledPin, OUTPUT);
 // pinMode(signalStrengthPin, INPUT);
}

void loop()
{


 //rssiDur = pulseIn(RSSIpin, LOW, 200);
  // print signal strength
  //Serial.println(rssiDur);
 
  if (Serial.available()>0)
  {
   // if ((int(val_read) == 'B'))
    
val_read = Serial.read();
 if (val_read == '*') {                     //wait for start delimiter
        nodeID = Serial.read();
        average = Serial.read() << 8;    //msb
        average += Serial.read();        //lsb
        
   while (val_read == '*' && nodeID == 1)    //message received and decoded, continue processing it...
    lcd.noAutoscroll();
    lcd.setCursor(0,0);
lcd.print("Bike1 = ");
lcd.print(average);

 }
 
  while (val_read == 'A' && nodeID ==2) {                     //wait for start delimiter
         
lcd.noAutoscroll();
      lcd.setCursor(0,1);
lcd.print("Bike2 = ");
lcd.print(average);
  }
}

  }

Try the following receiver code. I might also slow the transmitters down to once every two seconds, just for testing purposes.

#include <LiquidCrystal.h>

int val_read;
byte nodeID;
int average;
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup()
{
    Serial.begin(38400);
    lcd.begin(16,2);
}

void loop()
{
    val_read = Serial.read();
    if (val_read == '*') {               //wait for start delimiter
        nodeID = Serial.read();
        average = Serial.read() << 8;    //msb
        average += Serial.read();        //lsb

        //message received and decoded, continue processing it...
        if (nodeID == 1) {
            lcd.setCursor(0, 0);
            lcd.print("Bike1 = ");
            lcd.print(average, DEC);
            lcd.print("   ");
        }
        else if (nodeID == 2) {
            lcd.setCursor(0, 1);
            lcd.print("Bike2 = ");
            lcd.print(average, DEC);
            lcd.print("   ");
        }
    }
}

No go. I tried and also rearranged the emitter code as shown below :

const int rssi_pin = 9; //RSSI Pin of the XBee Module
 int rssiDur; //variable to read pin
byte inches_val;

//LED pins//////////////////////////
const int led3 = 3;
const int led4 = 4;
const int led5 = 5;
const int led6 = 6;
const int led7= 7;
const int led8= 8;
const int led10= 10;
const int led11= 11;
const int led12= 12;
const int led13= 13;
/////////////////////////////////////

///Averager Variables///////////////////////////////

//this is intended to place first 10 read incoming RSSI values in an array and average. smoother readings

const int numReadings = 10;

int readings[numReadings];      // the readings from the RSSI
int index = 0;                  // the index of the current reading
int total = 0;                  // the running total
byte average = 0;                // the average


///////////////////////////////////////////////////
const byte nodeID = 2;
    int myData2;


void setup(){
  
   for (int thisReading = 0; thisReading < numReadings; thisReading++)
    readings[thisReading] = 0; 

pinMode (led3, OUTPUT);
pinMode (led4, OUTPUT);
pinMode (led5, OUTPUT);
pinMode (led6, OUTPUT);
pinMode (led7, OUTPUT);
pinMode (led8, OUTPUT);
pinMode (led10, OUTPUT);
pinMode (led11, OUTPUT);
pinMode (led12, OUTPUT);
pinMode (led13, OUTPUT);
  
  
  Serial.begin(38400); //Xbee communicating at this baud
}

void loop(){


 rssiDur = pulseIn(rssi_pin, LOW, 200); //this is set to 200ms with ATRP @ 2
//inches_val = rssiDur + 24; // this is 24inches / 2 feet
//min(inches_val, 18);
total= total - readings[index];         
  // read from the sensor:  
  readings[index] = rssiDur; 
  // add the reading to the total:
  total= total + readings[index];       
  // advance to the next position in the array:  
  index = index + 1;                    

  // if we're at the end of the array...
  if (index >= numReadings)              
    // ...wrap around to the beginning: 
    index = 0;                           

  // calculate the average:
  average = total / numReadings;         
  


if (average > 24 && average < 124){ //1-5 meters
 // Serial.write(1);
   digitalWrite(led3, HIGH);
       digitalWrite(led4, HIGH);
        digitalWrite(led5, HIGH);
        digitalWrite(led6, HIGH);
        digitalWrite(led7, HIGH);
        digitalWrite(led8, HIGH);
        digitalWrite(led10, HIGH);
        digitalWrite(led11, HIGH);
        digitalWrite(led12, HIGH);
        digitalWrite(led13, HIGH);
        
}
  if (average > 124 && average < 224){ //5-10 meters
  //Serial.write(2);
   digitalWrite(led3, HIGH);
       digitalWrite(led4, HIGH);
        digitalWrite(led5, HIGH);
        digitalWrite(led6, HIGH);
        digitalWrite(led7, HIGH);
         digitalWrite(led8, HIGH);
        digitalWrite(led10, HIGH);
        digitalWrite(led11, HIGH);
        digitalWrite(led12, LOW);
        digitalWrite(led13, LOW);
        
  }
  if (average > 224 && average < 324){ //10- 15 meters 
  //Serial.write(3); //this is 10 meters. write to reciever 
   digitalWrite(led3, HIGH);
       digitalWrite(led4, HIGH);
        digitalWrite(led5, HIGH);
        digitalWrite(led6, HIGH);
        digitalWrite(led7, HIGH);
         digitalWrite(led8, HIGH);
         digitalWrite(led10, LOW);
        digitalWrite(led11, LOW);
        digitalWrite(led12, LOW);
        digitalWrite(led13, LOW);
        
  }
  if (average > 324 && average < 424){ //15-20 meters
  //Serial.write(4);
    digitalWrite(led3, HIGH);
       digitalWrite(led4, HIGH);
        digitalWrite(led5, HIGH);
        digitalWrite(led6, HIGH);
        digitalWrite(led7, LOW);
           digitalWrite(led8, LOW);
        digitalWrite(led10, LOW);
        digitalWrite(led11, LOW);
        digitalWrite(led12, LOW);
        digitalWrite(led13, LOW);
        
  }
  if (average > 424 ){ //20-30 meters
 // Serial.write(5);
   digitalWrite(led3, HIGH);
       digitalWrite(led4, HIGH);
        digitalWrite(led5, LOW);
        digitalWrite(led6, LOW);
        digitalWrite(led7, LOW);
         digitalWrite(led8, LOW);
        digitalWrite(led10, LOW);
        digitalWrite(led11, LOW);
        digitalWrite(led12, LOW);
        digitalWrite(led13, LOW);
      
    }
    
    //isolated instances below
   
  if (average == 24 ){ //if their is no signal
 // Serial.write(5);
   digitalWrite(led3, LOW);
       digitalWrite(led4, LOW);
        digitalWrite(led5, LOW);
        digitalWrite(led6, LOW);
        digitalWrite(led7, LOW);
         digitalWrite(led8, LOW);
        digitalWrite(led10, LOW);
        digitalWrite(led11, LOW);
        digitalWrite(led12, LOW);
        digitalWrite(led13, LOW);
}

 Serial.write('*');            //message start delimiter
    Serial.write(nodeID);
    Serial.write(average >> 8);    //most significant byte
    Serial.write(average & 0xFF);  //least significant byte
delay(200);
}
 Serial.write('*');            //message start delimiter
    Serial.write(nodeID);
    Serial.write(average >> 8);    //most significant byte
    Serial.write(average & 0xFF);  //least significant byte

Send 4 bytes as fast as possible. Which isn't very fast.

    val_read = Serial.read();
    if (val_read == '*') {               //wait for start delimiter
        nodeID = Serial.read();
        average = Serial.read() << 8;    //msb
        average += Serial.read();        //lsb

Expect all the data to arrive nearly instantaneously. Nope. Not going to happen (sorry, Jack).

You need to, of you are going to read 5 bytes, wait for there to be 4 bytes to read. Serial.available() is a good idea.