Suggestion on Stopping wireless collisions

Does anyone have a good suggestion for preventing collisions on a 915MHz wireless network?

I’ve need to relay a message from one master device to a slave device and back again over considerable distance. The relaying and the distance don’t seem to be much of an issue any longer but the more sensors there are in close proximity to one another (30ft) to more packets either don’t make it to the destination or don’t get acknowledged. I tried using a mesh network I made as well as radioHeads mesh network, but ultimately they had serious failure issues when used.

I realized that I only need the sensor to talk to the master device one at a time, so I don’t actually need the complexity of a true mesh. I just need the sensors that are in range to convey the signal to the ones that are out of range. I have tried a number of approaches to prevent collisions and to prevent 2 radios from transmitting at the same time, but alas as soon as I start adding stations the only one that is reliable is the closest on to me.

here is the current code I am trying to use to prevent the collisions but alas it does not work.

bool TX(uint8_t retries,uint8_t _Length,uint16_t TimeToWait){
  bool SendSuccess=false;                      //  WAS IT EVEN ABLE TO SEND
  if(CheckForOpenChannel(TimeToWait)){
    for(uint8_t i=0;i<retries;i++){
      uint8_t j=0;
      uint8_t jattempt=100;
      while(j<jattempt){                      //  THE RADIO DOESN'T ALWAYS SEND WHEN ASK KEEP ASKING UNTIL IT DOES
        if(rf69.send(_RFBuffer,_Length)){
          SendSuccess=true;
          break;                              //  EXIT WHILE LOOP
          j=jattempt+100;                     //  JUST IN CASE WHILE LOOP DOESN'T BREAK
        }
        j++;
      }
    }
  }
  if(SendSuccess==true){
    Serial.println("Sent");
    return true;
  }
  return false;
}
bool CheckForOpenChannel(uint16_t TimeToWait){
  uint16_t SendTimer=0;
  bool OpenChannel=false;
  while((SendTimer<TimeToWait)&&(!OpenChannel)){
    //Serial.print("rssi: ");Serial.println(rf69.rssiRead());
    if(rf69.rssiRead()<(-85)){
      OpenChannel=true;
    }
    SendTimer+=1;delay(1);
  }
  return OpenChannel;
}

Short, infrequent messages, possibly with randomized delays in between, have a better chance of getting through than long, frequent messages.

And remember the random function isn't random. It's a formula that looks random but it is predictable. The following code will always print the same number:

void setup() {
  Serial.begin(9600);
  while(!Serial); //wait for Serial to connect on "native USB" Arduinos and Teensy
  Serial.print("Random number: ");
  Serial.println(random(100));
}
void loop() {}

So each different slave needs to have a source of randomness which is different from all the others. Use randomSeed() of the slave's ID number or anything that is different on every slave.

Have the master query sensors one by one, so sensors don't start transmitting randomly.

How about this: when a sensor powers up, it searches for a master (sends a broadcast message). A master in range will respond, register the node, and assign it an address. Later the master can contact the node on that address.

The more remote ones are trickier. They don't see a master, so maybe they have to send a second broadcast looking for a relay. Then all nodes that receive this, and which have a connection to your master, can offer themselves as relay. The accepted relay then asks the master for a new node address and passes it on to the remote node.

That is right, only have a slave transmit when it is specifically requested to by the master. That is the essence of a master / slave configuration.

To any Millennium Snowflake reading, the master / slave configuration is not an offensive term, what ever you may think.

So in short, you need the code for a full mesh network. :roll_eyes: