Hi everyone,
I usually only need to use google to debug all my problems, but this time is different, I've been pulling my hair over this bug for 2 days and really can't figure out what I did wrong.
I'm programming a finite state machine, using a switch case statement to execute the code corresponding to the current state. Everything is working fine until the system reaches "state = 6". At this point, nothing in the switch case is getting executed. I've put print statements in all cases, including a default one, and nothing is getting printed.
The void loop is still getting run, I put a print statement outside the switch case and sure enough, it's printed every time.
Without further ado, here is my code :
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#define CRqst 0
#define AAdrs 1
#define StpEN 2
#define SrtEN 3
#define Rst 4
RF24 radio(9, 10); // CE, CSN
byte self[6] = "0Node";
byte child[6] = "0Node";
byte gate[6] = "0Node";
byte voidAddress[6] = "00000";
int address = 0;
int state = 0;
int prevState = 0;
unsigned long timer = 0;
unsigned long ackTimeout = 10000;
unsigned long sendNewCRqstDelay = 100;
uint8_t sender = 0;
struct Payload {
unsigned int address;
unsigned int instruction;
unsigned long data;
};
Payload res;
void setup() {
Serial.begin(9600);
radio.begin();
while(!Serial.available()){};
}
void loop(){
prevState = state;
switch (state) {
case 0:
Serial.println("State 0");
Serial.println("State 0 - Initializing");
radio.openWritingPipe(gate);
radio.stopListening();
state = 1;
break;
case 1:
Serial.println("State 1");
if(millis()-timer > sendNewCRqstDelay){
timer = millis();
Payload P = {0,0,0};
Serial.println("Sending CRqst");
if(radio.write(&P,sizeof(P))){
Serial.println("Ack received");
radio.openReadingPipe(1,gate);
radio.startListening();
timer = millis();
state = 2;
Serial.println("Waiting for AAdrs");
}
else{
Serial.println("Ack not received");
}
}
break;
case 2:
Serial.println("State 2");
if (radio.available()){
Serial.println("Received payload");
if (readIncoming()){
Serial.println("Payload is addressed to this node");
if(res.address == 0 && res.instruction == AAdrs){
Serial.println("Payload is a AAdrs");
state = 3;
}
}
}
else if (millis()-timer > ackTimeout){
Serial.println("CRqst timed out");
state = 0;
}
break;
case 3:
Serial.println("State 3");
Serial.println("Updating addresses and setting up");
updateAddresses();
radio.openReadingPipe(1,self);
radio.openReadingPipe(2,gate);
radio.startListening();
state = 4;
break;
case 4:
Serial.println("State 4");
if (radio.available(&sender)){
Serial.println("Received Payload");
if (readIncoming()){
Serial.println("Payload is addressed to this node");
if (sender == 1 && res.instruction == StpEN){
Serial.println("Instructed to stop expanding the network by self pipe");
radio.openReadingPipe(2,voidAddress);
state = 6;
break;
}
if (sender == 2 && res.instruction == CRqst){
Serial.println("Payload is a CRqst from gate pipe");
radio.openWritingPipe(gate);
radio.stopListening();
state = 5;
break;
}
if (sender == 1 && res.instruction == Rst){
Serial.println("Instructed to reset by self pipe");
delay(res.data);
state = 0;
break;
}
}
}
break;
case 5:
Serial.println("State 5");
Payload p = {0,AAdrs,address+1};
if (radio.write(&p,sizeof(p))){
Serial.println("Address assignment successful");
radio.openWritingPipe(child);
radio.startListening();
state = 6;
break;
}
else{
Serial.println("Address assignment failed");
state = 3;
break;
}
break;
case 6:
Serial.println("State 6");
if (radio.available()){
Serial.println("Received Payload");
if (readIncoming()){
Serial.println("Payload is addressed to this node");
if (res.instruction == SrtEN){
Serial.println("Instructed to start expanding network by self pipe");
state = 3;
break;
}
if (res.instruction == Rst){
Serial.print("Instructed to reset by self pipe with delay : ");
Serial.println(res.data);
delay(res.data);
state = 0;
break;
}
}
}
break;
default:
Serial.println("Default state");
break;
}
if (prevState != state){
Serial.println("------");
Serial.println(state);
Serial.println("------");
}
delay(5);
}
void updateAddresses(){
address = int(res.data);
self[0] = address;
child[0] = address+1;
}
bool readIncoming(){
Serial.println("Reading Incoming");
radio.read(&res, sizeof(res)); //Reading the data
if(res.address == address or res.address == 0){
Serial.println(res.instruction);
Serial.println(res.data);
Serial.println("**************************");
return true;
}
else if(state == 6){
radio.stopListening();
if(radio.write(&res,sizeof(res))){
Serial.println("Message forwarded");
}
else{
Serial.println("Transmission to child failed");
}
radio.startListening();
return false;
}
}
Initially, I wanted to delete some of the code for readability's sake, but the bug is so obscure that I don't want to miss including any information.
If someone can help me that would be awesome, my project is currently stalled because of this.
Thanks for reading !
PS: below is an example of output from the arduino, with all current print statement. I've made sure to send the correct data to the arduino via NRF24L01 module to make it reach state 6. Not sure if that will help, but I'll include it anyway
------
0
------
State 0
State 0 - Initializing
------
1
------
State 1
Sending CRqst
Ack received
Waiting for AAdrs
------
2
------
State 2
Received payload
Reading Incoming
1
2
**************************
Payload is addressed to this node
Payload is a AAdrs
------
3
------
State 3
Updating addresses and setting up
------
4
------
State 4
<bunch of them repeating, I cut them out>
State 4
Received Payload
Reading Incoming
2
0
**************************
Payload is addressed to this node
Instructed to stop expanding the network by self pipe
------
6
------