Latching momentary button code not working

I’ve tried several different ways described by others to achieve latching of a momentary push button to change state but I have been unsuccessful. The current attempt was derived from Trex’s post here: http://forum.arduino.cc/index.php?topic=248802.0

#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 16, 2); // set the LCD address to 0x27 for a 16 chars and 2 line display

#include <RHReliableDatagram.h>
#include <RH_NRF24.h>
#include <SPI.h>

//=======For the radio======

#define CLIENT_ADDRESS 1
#define SERVER_ADDRESS 2

// Singleton instance of the radio driver
RH_NRF24 driver;
// RH_NRF24 driver(8, 7);   // For RFM73 on Anarduino Mini

// Class to manage message delivery and receipt, using the driver declared above
RHReliableDatagram manager(driver, CLIENT_ADDRESS);
uint8_t radioArray[5];//Array with 6 positions.
// Dont put this on the stack:
uint8_t buf[RH_NRF24_MAX_MESSAGE_LEN];

//====For the buttons====
const byte button0pin = 4;
const byte button1pin = 5;
const byte button2pin = 6;
const byte button3pin = 7;
const byte switch4pin = 3;
byte button0state;
byte button1state;
byte button2state;
byte button3state;
byte switch4state;
byte lastSwitch4state = 1;
byte state4 = 0;//toggle state
unsigned long buttonDebounce = 0;

int SetpointVariable = 30;
int rpm;


String Str1 = "On";
String Str2 = "Off";
String Str3;

void setup() {

  radioArray[0] = 0;// sets motor to off at start up.

  pinMode(button0pin, INPUT_PULLUP);
  pinMode(button1pin, INPUT_PULLUP);
  pinMode(button2pin, INPUT_PULLUP);
  pinMode(button3pin, INPUT_PULLUP);
  pinMode(switch4pin, INPUT_PULLUP);

  lcd.init();                      // initialize the lcd
  lcd.init();
  lcd.backlight();
  lcd.setCursor(3, 0);
  lcd.print("Lava Valley");
  lcd.setCursor(5, 1);
  lcd.print("Produce");
  delay(2000);
  lcd.clear();
  lcd.print("Seedr Controller");
  lcd.setCursor(1, 1);
  lcd.print("by Chris Dalby");
  delay(2000);
  lcd.clear();
  lcd.print("Set RPM  ");
  lcd.print(SetpointVariable);
  Serial.begin(9600);
  Serial.println("powered up");
  delay(1000);
  if (!manager.init())
    Serial.println("init failed");
  // Defaults after init are 2.402 GHz (channel 2), 2Mbps, 0dBm



}

void ToggleState() {
  state4 = state4 ^ 1; //XOR 1 toggles LSB, effectively jumping between 0 and 1
}

void loop()
{

  readButtons();
  adjRequiredRpm();
  calibration();
  setStartStop();
  exchangeData();
  displayRpm();

  //  sendDatatoServer();//Send RequiredRpm & Start/Stop to Server.

}

void readButtons() {
  button0state = digitalRead(button0pin);
  button1state = digitalRead(button1pin);
  button2state = digitalRead(button2pin);
  button3state = digitalRead(button3pin);
  switch4state = digitalRead(switch4pin);

  //for debugging.
  /*
    Serial.print(button0state);
    Serial.print(button1state);
    Serial.print(button2state);
    Serial.print(button3state);
    Serial.println(switch4state);
  */
}

void setStartStop() /*{
  if (switch4state == LOW) {
  radioArray[0]=1;
  if (radioArray[0]==1) {
    Str3=Str1;
  }

  }
  if (switch4state == HIGH) {
  radioArray[0]=0;
  if (radioArray[0]==0) {
    Str3=Str2;
  }
  }
  }*/
{
  if (switch4state == LOW && buttonDebounce == 0) {
    buttonDebounce = millis();
  }

  if (switch4state == HIGH) {
    if ((buttonDebounce != 0) && (millis() - buttonDebounce > 20)) {
      ToggleState();
    }
  }

  if (state4 == 0) {
    radioArray[0] = 1;
    if (radioArray[0] == 1) {
      Str3 = Str1;
    }
    buttonDebounce = 0;
  }
  if (state4 = 1) {
    radioArray[0] = 0;
    if (radioArray[0] == 0) {
      Str3 = Str2;
    }
  }
}

void adjRequiredRpm() {
  if (button0state == LOW) {
    SetpointVariable = SetpointVariable + 1;
    if (SetpointVariable > 60) {
      SetpointVariable = 60;
    }
  }
  if (button1state == LOW) {
    SetpointVariable = SetpointVariable - 1;
    if (SetpointVariable < 10) {
      SetpointVariable = 10;
    }
  }


}

void calibration() {
  if (button2state == LOW && switch4state == HIGH) {
    radioArray[5] = 1;
    lcd.clear();
    lcd.print("Calibration Mode");
    lcd.setCursor(0, 1);
    lcd.print("Switch to run");

    if (switch4state == LOW) {
      lcd.clear();
      lcd.print("Calibration Mode");
      lcd.setCursor(0, 1);
      lcd.print("   Calibrating   ");
    }

  }
}


void listenForServer() {
  /*    if (manager.sendtoWait(data, sizeof(data), SERVER_ADDRESS))
    {
      uint8_t len = sizeof(buf);
      uint8_t from;
      if (manager.recvfromAckTimeout(buf, &len, 2000, &from))
      {
        Serial.println((char*)buf);
      }
        }  */
}

void displayRpm() {
  lcd.clear();
  lcd.print("Set RPM  ");
  lcd.print(SetpointVariable);
  lcd.setCursor(0, 1);
  lcd.print("Motor ");
  lcd.print(Str3);
  lcd.print(" RPM ");
  lcd.print(rpm);
}



void exchangeData()  {
  // serial.println(radioArray);
  delay(200);
  /* if (manager.sendtoWait(radioArray, sizeof(radioArray), SERVER_ADDRESS))
    {
     Serial.println("Message sent, waiting for reply");
     // Now wait for a reply from the server
     uint8_t len = sizeof(buf);
     uint8_t from;
     if (manager.recvfromAckTimeout(buf, &len, 200, &from))
     {
       Serial.print("got reply from : 0x");
       Serial.print(from, HEX);
       Serial.print(": ");
       Serial.println((char*)buf);
     }
     else
     {
       Serial.println("No reply, is nrf24_reliable_datagram_server running?");
     }
     /*char msg[4];
       itoa(data, msg, 10);

       driver.send((uint8_t *)msg, strlen(msg));
       driver.waitPacketSent();
    }*/
}

In “void setStartStop”, I am trying to set a start or a stop command with one momentary button which I would like to latch each time the button is pressede and released. The Str3 is then displayed on a i2c lcd. The radioArray will be used to transmit the start/stop state to a remote for switching the motor on and off.
In the commented out code, I had it all working fine with a toggle switch.

Can anyone see why the latching doesn’t work?

The code, as it stands does not switch at all.

You can NOT debounce FIVE buttons using ONE time variable.

Use arrays for the current states, the previous states, etc. and that oversight will become glaringly obvious and dirt simple to fix.

PaulS:
You can NOT debounce FIVE buttons using ONE time variable.

Use arrays for the current states, the previous states, etc. and that oversight will become glaringly obvious and dirt simple to fix.

Might be obvious to you but…

Heres the latest code.

#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 16, 2); // set the LCD address to 0x27 for a 16 chars and 2 line display

#include <RHReliableDatagram.h>
#include <RH_NRF24.h>
#include <SPI.h>

//=======For the radio======

#define CLIENT_ADDRESS 1
#define SERVER_ADDRESS 2

// Singleton instance of the radio driver
RH_NRF24 driver;
// RH_NRF24 driver(8, 7);   // For RFM73 on Anarduino Mini

// Class to manage message delivery and receipt, using the driver declared above
RHReliableDatagram manager(driver, CLIENT_ADDRESS);
uint8_t radioArray[5];//Array with 6 positions.
// Dont put this on the stack:
uint8_t buf[RH_NRF24_MAX_MESSAGE_LEN];

//====For the buttons====
const byte button0pin = 4;
const byte button1pin = 5;
const byte button2pin = 6;
const byte button3pin = 7;
const byte button4pin = 3;

int buttonState[5];//replaces byte below.
/*byte button0state;
byte button1state;
byte button2state;
byte button3state;
byte switch4state;
*/
int lastButtonState[5] = {1,1,1,1,1};//replaces byte below.
//byte lastSwitch4state = 1;

byte state4 = 0;//toggle state
unsigned long buttonDebounce = 0;

int SetpointVariable = 30;
int rpm;


String Str1 = "On";
String Str2 = "Off";
String Str3;

void setup() {

  radioArray[0] = 0;// sets motor to off at start up.

  pinMode(button0pin, INPUT_PULLUP);
  pinMode(button1pin, INPUT_PULLUP);
  pinMode(button2pin, INPUT_PULLUP);
  pinMode(button3pin, INPUT_PULLUP);
  pinMode(button4pin, INPUT_PULLUP);

  lcd.init();                      // initialize the lcd
  lcd.init();
  lcd.backlight();
  lcd.setCursor(3, 0);
  lcd.print("Lava Valley");
  lcd.setCursor(5, 1);
  lcd.print("Produce");
  delay(2000);
  lcd.clear();
  lcd.print("Seedr Controller");
  lcd.setCursor(1, 1);
  lcd.print("by Chris Dalby");
  delay(2000);
  lcd.clear();
  lcd.print("Set RPM  ");
  lcd.print(SetpointVariable);
  Serial.begin(9600);
  Serial.println("powered up");
  delay(1000);
  if (!manager.init())
    Serial.println("init failed");
  // Defaults after init are 2.402 GHz (channel 2), 2Mbps, 0dBm



}

void ToggleState() {
  state4 = state4 ^ 1; //XOR 1 toggles LSB, effectively jumping between 0 and 1
}

void loop()
{

  readButtons();
  adjRequiredRpm();
  calibration();
  setStartStop();
  exchangeData();
  displayRpm();

  //  sendDatatoServer();//Send RequiredRpm & Start/Stop to Server.

}

void readButtons() {
  buttonState[0] = digitalRead(button0pin);
  buttonState[1] = digitalRead(button1pin);
  buttonState[2] = digitalRead(button2pin);
  buttonState[3] = digitalRead(button3pin);
  buttonState[4] = digitalRead(button4pin);
  
  /*
  button0state = digitalRead(button0pin);
  button1state = digitalRead(button1pin);
  button2state = digitalRead(button2pin);
  button3state = digitalRead(button3pin);
  switch4state = digitalRead(switch4pin);
*/
  //for debugging.
  /*
    Serial.print(button0state);
    Serial.print(button1state);
    Serial.print(button2state);
    Serial.print(button3state);
    Serial.println(switch4state);
  */
}

void setStartStop() /*{
  if (switch4state == LOW) {
  radioArray[0]=1;
  if (radioArray[0]==1) {
    Str3=Str1;
  }

  }
  if (switch4state == HIGH) {
  radioArray[0]=0;
  if (radioArray[0]==0) {
    Str3=Str2;
  }
  }
  }*/
{
  if (buttonState[4] == 0 && buttonDebounce == 0) {
    buttonDebounce = millis();
  }

  if (buttonState[4] == 1) {
    if ((buttonDebounce != 0) && (millis() - buttonDebounce > 20)) {
      ToggleState();
    }
  }

  if (state4 == 0) {
    radioArray[0] = 1;
    if (radioArray[0] == 1) {
      Str3 = Str1;
    }
    buttonDebounce = 0;
  }
  if (state4 = 1) {
    radioArray[0] = 0;
    if (radioArray[0] == 0) {
      Str3 = Str2;
    }
  }
}

void adjRequiredRpm() {
  if (buttonState[0] == 0) {
    SetpointVariable = SetpointVariable + 1;
    if (SetpointVariable > 60) {
      SetpointVariable = 60;
    }
  }
  if (buttonState[1] == 0) {
    SetpointVariable = SetpointVariable - 1;
    if (SetpointVariable < 10) {
      SetpointVariable = 10;
    }
  }


}

void calibration() {
  if (buttonState[2] == 0 && buttonState[4] == 1) {
    radioArray[5] = 1;
    lcd.clear();
    lcd.print("Calibration Mode");
    lcd.setCursor(0, 1);
    lcd.print("Switch to run");

    if (buttonState[4] == 0) {
      lcd.clear();
      lcd.print("Calibration Mode");
      lcd.setCursor(0, 1);
      lcd.print("   Calibrating   ");
    }

  }
}


void listenForServer() {
  /*    if (manager.sendtoWait(data, sizeof(data), SERVER_ADDRESS))
    {
      uint8_t len = sizeof(buf);
      uint8_t from;
      if (manager.recvfromAckTimeout(buf, &len, 2000, &from))
      {
        Serial.println((char*)buf);
      }
        }  */
}

void displayRpm() {
  lcd.clear();
  lcd.print("Set RPM  ");
  lcd.print(SetpointVariable);
  lcd.setCursor(0, 1);
  lcd.print("Motor ");
  lcd.print(Str3);
  lcd.print(" RPM ");
  lcd.print(rpm);
}



void exchangeData()  {
  // serial.println(radioArray);
  delay(200);
  /* if (manager.sendtoWait(radioArray, sizeof(radioArray), SERVER_ADDRESS))
    {
     Serial.println("Message sent, waiting for reply");
     // Now wait for a reply from the server
     uint8_t len = sizeof(buf);
     uint8_t from;
     if (manager.recvfromAckTimeout(buf, &len, 200, &from))
     {
       Serial.print("got reply from : 0x");
       Serial.print(from, HEX);
       Serial.print(": ");
       Serial.println((char*)buf);
     }
     else
     {
       Serial.println("No reply, is nrf24_reliable_datagram_server running?");
     }
     /*char msg[4];
       itoa(data, msg, 10);

       driver.send((uint8_t *)msg, strlen(msg));
       driver.waitPacketSent();
    }*/
}

I think the “const byte buttonxpin = x” needs to be changed but not sure to what.

I think the "const byte buttonxpin = x" needs to be changed but not sure to what.

const byte buttonPin[] = { 4, 5, 6, 7, 3 };
unsigned long buttonDebounce[5];

Then, you can use for loops...
Then, you can use for loops...
Then, you can use for loops...
Then, you can use for loops...
Then, you can use for loops...

And if you just want to be lazy effective, just grab a library like you do with the NRF24. I like to use Bounce2.

Bounce buttons[5];

is all you need then for 5 buttons :slight_smile:

Thanks Septillion, If I get the urge, or if I can’t get this working, I’ll change it all again! :frowning:

OK, PaulS,
Here is where I am at.

#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 16, 2); // set the LCD address to 0x27 for a 16 chars and 2 line display

#include <RHReliableDatagram.h>
#include <RH_NRF24.h>
#include <SPI.h>

//=======For the radio======

#define CLIENT_ADDRESS 1
#define SERVER_ADDRESS 2

// Singleton instance of the radio driver
RH_NRF24 driver;
// RH_NRF24 driver(8, 7);   // For RFM73 on Anarduino Mini

// Class to manage message delivery and receipt, using the driver declared above
RHReliableDatagram manager(driver, CLIENT_ADDRESS);
uint8_t radioArray[5];//Array with 6 positions.
// Dont put this on the stack:
uint8_t buf[RH_NRF24_MAX_MESSAGE_LEN];

//====For the buttons====
const byte buttonPin[]={4,5,6,7,3};//replaces const byte below.
/*
const byte button0pin = 4;
const byte button1pin = 5;
const byte button2pin = 6;
const byte button3pin = 7;
const byte button4pin = 3;
*/
int buttonState[5];//replaces byte below.
/*byte button0state;
byte button1state;
byte button2state;
byte button3state;
byte switch4state;
*/
int lastButtonState[5] = {1,1,1,1,1};//replaces byte below.
//byte lastSwitch4state = 1;

byte state4 = 0;//toggle state
unsigned long buttonDebounce[5];

int SetpointVariable = 30;
int rpm;


String Str1 = "On";
String Str2 = "Off";
String Str3;

void setup() {

  radioArray[0] = 0;// sets motor to off at start up.

//pinMode(buttonPin[0,1,2,3,4], INPUT_PULLUP);

  pinMode(buttonPin[0], INPUT_PULLUP);
  pinMode(buttonPin[1], INPUT_PULLUP);
  pinMode(buttonPin[2], INPUT_PULLUP);
  pinMode(buttonPin[3], INPUT_PULLUP);
  pinMode(buttonPin[4], INPUT_PULLUP);

  lcd.init();                      // initialize the lcd
  lcd.init();
  lcd.backlight();
  lcd.setCursor(3, 0);
  lcd.print("Lava Valley");
  lcd.setCursor(5, 1);
  lcd.print("Produce");
  delay(2000);
  lcd.clear();
  lcd.print("Seedr Controller");
  lcd.setCursor(1, 1);
  lcd.print("by Chris Dalby");
  delay(2000);
  lcd.clear();
  lcd.print("Set RPM  ");
  lcd.print(SetpointVariable);
  Serial.begin(9600);
  Serial.println("powered up");
  delay(1000);
  if (!manager.init())
    Serial.println("init failed");
  // Defaults after init are 2.402 GHz (channel 2), 2Mbps, 0dBm



}

void ToggleState() {
  state4 = state4 ^ 1; //XOR 1 toggles LSB, effectively jumping between 0 and 1
}

void loop()
{

  readButtons();
  adjRequiredRpm();
  calibration();
  setStartStop();
  exchangeData();
  displayRpm();

  //  sendDatatoServer();//Send RequiredRpm & Start/Stop to Server.

}

void readButtons() {
  buttonState[0] = digitalRead(buttonPin[0]);
  buttonState[1] = digitalRead(buttonPin[1]);
  buttonState[2] = digitalRead(buttonPin[2]);
  buttonState[3] = digitalRead(buttonPin[3]);
  buttonState[4] = digitalRead(buttonPin[4]);
  
  /*
  button0state = digitalRead(button0pin);
  button1state = digitalRead(button1pin);
  button2state = digitalRead(button2pin);
  button3state = digitalRead(button3pin);
  switch4state = digitalRead(switch4pin);
*/
  //for debugging.
  /*
    Serial.print(button0state);
    Serial.print(button1state);
    Serial.print(button2state);
    Serial.print(button3state);
    Serial.println(switch4state);
  */
}

void setStartStop() /*{
  if (switch4state == LOW) {
  radioArray[0]=1;
  if (radioArray[0]==1) {
    Str3=Str1;
  }

  }
  if (switch4state == HIGH) {
  radioArray[0]=0;
  if (radioArray[0]==0) {
    Str3=Str2;
  }
  }
  }*/
{
  if (buttonState[4] == 0 && buttonDebounce[4] == 0) {
    buttonDebounce[4] = millis();
  }

  if (buttonState[4] == 1) {
    if ((buttonDebounce[4] != 0) && (millis() - buttonDebounce[4] > 20)) {
      ToggleState();
    }
  }

  if (state4 == 0) {
    radioArray[0] = 1;
    if (radioArray[0] == 1) {
      Str3 = Str1;
    }
    buttonDebounce[4] = 0;
  }
  if (state4 = 1) {
    radioArray[0] = 0;
    if (radioArray[0] == 0) {
      Str3 = Str2;
    }
  }
}

void adjRequiredRpm() {
  if (buttonState[0] == 0) {
    SetpointVariable = SetpointVariable + 1;
    if (SetpointVariable > 60) {
      SetpointVariable = 60;
    }
  }
  if (buttonState[1] == 0) {
    SetpointVariable = SetpointVariable - 1;
    if (SetpointVariable < 10) {
      SetpointVariable = 10;
    }
  }


}

void calibration() {
  if (buttonState[2] == 0 && buttonState[4] == 1) {
    radioArray[5] = 1;
    lcd.clear();
    lcd.print("Calibration Mode");
    lcd.setCursor(0, 1);
    lcd.print("Switch to run");

    if (buttonState[4] == 0) {
      lcd.clear();
      lcd.print("Calibration Mode");
      lcd.setCursor(0, 1);
      lcd.print("   Calibrating   ");
    }

  }
}


void listenForServer() {
  /*    if (manager.sendtoWait(data, sizeof(data), SERVER_ADDRESS))
    {
      uint8_t len = sizeof(buf);
      uint8_t from;
      if (manager.recvfromAckTimeout(buf, &len, 2000, &from))
      {
        Serial.println((char*)buf);
      }
        }  */
}

void displayRpm() {
  lcd.clear();
  lcd.print("Set RPM  ");
  lcd.print(SetpointVariable);
  lcd.setCursor(0, 1);
  lcd.print("Motor ");
  lcd.print(Str3);
  lcd.print(" RPM ");
  lcd.print(rpm);
}



void exchangeData()  {
  // serial.println(radioArray);
  delay(200);
  /* if (manager.sendtoWait(radioArray, sizeof(radioArray), SERVER_ADDRESS))
    {
     Serial.println("Message sent, waiting for reply");
     // Now wait for a reply from the server
     uint8_t len = sizeof(buf);
     uint8_t from;
     if (manager.recvfromAckTimeout(buf, &len, 200, &from))
     {
       Serial.print("got reply from : 0x");
       Serial.print(from, HEX);
       Serial.print(": ");
       Serial.println((char*)buf);
     }
     else
     {
       Serial.println("No reply, is nrf24_reliable_datagram_server running?");
     }
     /*char msg[4];
       itoa(data, msg, 10);

       driver.send((uint8_t *)msg, strlen(msg));
       driver.waitPacketSent();
    }*/
}

Now I am back where I started, still button 4 in “void setStartStop” does not work or latch. Now I know your shaking your head at how stupid I am, but for what ever reason, I still don’t get what the “glaringly obvious and dirt simple to fix” is. Hours have gone by, (actually, many days have gone by on this sketch), and I have not progressed.

I am assuming there is a problem in this part of the code but I cannot see it.

void setStartStop() /*{
  if (switch4state == LOW) {
  radioArray[0]=1;
  if (radioArray[0]==1) {
    Str3=Str1;
  }

  }
  if (switch4state == HIGH) {
  radioArray[0]=0;
  if (radioArray[0]==0) {
    Str3=Str2;
  }
  }
  }*/
{
  if (buttonState[4] == 0 && buttonDebounce[4] == 0) {
    buttonDebounce[4] = millis();
  }

  if (buttonState[4] == 1) {
    if ((buttonDebounce[4] != 0) && (millis() - buttonDebounce[4] > 20)) {
      ToggleState();
    }
  }

  if (state4 == 0) {
    radioArray[0] = 1;
    if (radioArray[0] == 1) {
      Str3 = Str1;
    }
    buttonDebounce[4] = 0;
  }
  if (state4 = 1) {
    radioArray[0] = 0;
    if (radioArray[0] == 0) {
      Str3 = Str2;
    }
  }
}
  pinMode(buttonPin[0], INPUT_PULLUP);
  pinMode(buttonPin[1], INPUT_PULLUP);
  pinMode(buttonPin[2], INPUT_PULLUP);
  pinMode(buttonPin[3], INPUT_PULLUP);
  pinMode(buttonPin[4], INPUT_PULLUP);

or

   for(byte b=0; b<5; b++)
   {
      pinMode(buttonPin[b], INPUT_PULLUP);
   }

4 lines of code vs 5 is not much of a savings, but, what if you had 100 switches?

  if (state4 == 0) {

Why isn’t state an array, too?

  if (state4 = 1) {

Oops.

PaulS:

  pinMode(buttonPin[0], INPUT_PULLUP);

pinMode(buttonPin[1], INPUT_PULLUP);
  pinMode(buttonPin[2], INPUT_PULLUP);
  pinMode(buttonPin[3], INPUT_PULLUP);
  pinMode(buttonPin[4], INPUT_PULLUP);



or


for(byte b=0; b<5; b++)
  {
      pinMode(buttonPin[b], INPUT_PULLUP);
  }



4 lines of code vs 5 is not much of a savings, but, what if you had 100 switches?

I did have "pinMode(buttonPin[0,1,2,3,4], INPUT_PULLUP; but decided I was wrong.
Thanks for the right way.

  if (state4 == 0) {

Why isn’t state an array, too?
[/quote
Because I don’t know yet how to make
'state" an array and then limit all within to 0 or 1.

  if (state4 = 1) {

Oops.

Well spotted, thanks.

Still no button working though.
Starts with lcd displaying Str2 as it should, then on button4 press and release it toggles to Str1, again, as it should. But the on further button presses, no change.

latest code.

#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 16, 2); // set the LCD address to 0x27 for a 16 chars and 2 line display

#include <RHReliableDatagram.h>
#include <RH_NRF24.h>
#include <SPI.h>

//=======For the radio======

#define CLIENT_ADDRESS 1
#define SERVER_ADDRESS 2

// Singleton instance of the radio driver
RH_NRF24 driver;
// RH_NRF24 driver(8, 7);  // For RFM73 on Anarduino Mini

// Class to manage message delivery and receipt, using the driver declared above
RHReliableDatagram manager(driver, CLIENT_ADDRESS);
uint8_t radioArray[5];//Array with 6 positions.
// Dont put this on the stack:
uint8_t buf[RH_NRF24_MAX_MESSAGE_LEN];

//====For the buttons====
const byte buttonPin = {4, 5, 6, 7, 3}; //replaces const byte below.
/*
  const byte button0pin = 4;
  const byte button1pin = 5;
  const byte button2pin = 6;
  const byte button3pin = 7;
  const byte button4pin = 3;
*/
int buttonState[5];//replaces byte below.
/*byte button0state;
  byte button1state;
  byte button2state;
  byte button3state;
  byte switch4state;
*/
int lastButtonState[5] = {1, 1, 1, 1, 1}; //replaces byte below.
//byte lastSwitch4state = 1;

byte state4 = 0;//toggle state
unsigned long buttonDebounce[5];

int SetpointVariable = 30;
int rpm;

String Str1 = “On”;
String Str2 = “Off”;
String Str3;

void setup() {

radioArray[0] = 0;// sets motor to off at start up.

//pinMode(buttonPin[0,1,2,3,4], INPUT_PULLUP);
  for (byte b = 0; b < 5; b++)
  {
    pinMode(buttonPin[b], INPUT_PULLUP);
  }
  /*
    pinMode(buttonPin[0], INPUT_PULLUP);
    pinMode(buttonPin[1], INPUT_PULLUP);
    pinMode(buttonPin[2], INPUT_PULLUP);
    pinMode(buttonPin[3], INPUT_PULLUP);
    pinMode(buttonPin[4], INPUT_PULLUP);
  */
  lcd.init();                      // initialize the lcd
  lcd.init();
  lcd.backlight();
  lcd.setCursor(3, 0);
  lcd.print(“Lava Valley”);
  lcd.setCursor(5, 1);
  lcd.print(“Produce”);
  delay(2000);
  lcd.clear();
  lcd.print(“Seedr Controller”);
  lcd.setCursor(1, 1);
  lcd.print(“by Chris Dalby”);
  delay(2000);
  lcd.clear();
  lcd.print("Set RPM  ");
  lcd.print(SetpointVariable);
  Serial.begin(9600);
  Serial.println(“powered up”);
  delay(1000);
  if (!manager.init())
    Serial.println(“init failed”);
  // Defaults after init are 2.402 GHz (channel 2), 2Mbps, 0dBm

}

void ToggleState() {
  state4 = state4 ^ 1; //XOR 1 toggles LSB, effectively jumping between 0 and 1
}

void loop()
{

readButtons();
  adjRequiredRpm();
  calibration();
  setStartStop();
  exchangeData();
  displayRpm();

//  sendDatatoServer();//Send RequiredRpm & Start/Stop to Server.

}

void readButtons() {
  buttonState[0] = digitalRead(buttonPin[0]);
  buttonState[1] = digitalRead(buttonPin[1]);
  buttonState[2] = digitalRead(buttonPin[2]);
  buttonState[3] = digitalRead(buttonPin[3]);
  buttonState[4] = digitalRead(buttonPin[4]);

/*
    button0state = digitalRead(button0pin);
    button1state = digitalRead(button1pin);
    button2state = digitalRead(button2pin);
    button3state = digitalRead(button3pin);
    switch4state = digitalRead(switch4pin);
  /
  //for debugging.
  /

    Serial.print(button0state);
    Serial.print(button1state);
    Serial.print(button2state);
    Serial.print(button3state);
    Serial.println(switch4state);
  */
}

void setStartStop() /*{
  if (switch4state == LOW) {
  radioArray[0]=1;
  if (radioArray[0]==1) {
    Str3=Str1;
  }

}
  if (switch4state == HIGH) {
  radioArray[0]=0;
  if (radioArray[0]==0) {
    Str3=Str2;
  }
  }
  }*/
{
  if (buttonState[4] == 0 && buttonDebounce[4] == 0) {
    buttonDebounce[4] = millis();
  }

if (buttonState[4] == 1) {
    if ((buttonDebounce[4] != 0) && (millis() - buttonDebounce[4] > 20)) {
      ToggleState();
    }
  }

if (state4 == 1) {
    radioArray[0] = 1;
    if (radioArray[0] == 1) {
      Str3 = Str1;
    }
    buttonDebounce[4] = 0;
  }
  if (state4 == 0) {
    radioArray[0] = 0;
    if (radioArray[0] == 0) {
      Str3 = Str2;
    }
  }
}

void adjRequiredRpm() {
  if (buttonState[0] == 0) {
    SetpointVariable = SetpointVariable + 1;
    if (SetpointVariable > 60) {
      SetpointVariable = 60;
    }
  }
  if (buttonState[1] == 0) {
    SetpointVariable = SetpointVariable - 1;
    if (SetpointVariable < 10) {
      SetpointVariable = 10;
    }
  }

}

void calibration() {
  if (buttonState[2] == 0 && buttonState[4] == 1) {
    radioArray[5] = 1;
    lcd.clear();
    lcd.print(“Calibration Mode”);
    lcd.setCursor(0, 1);
    lcd.print(“Switch to run”);

if (buttonState[4] == 0) {
      lcd.clear();
      lcd.print(“Calibration Mode”);
      lcd.setCursor(0, 1);
      lcd.print("  Calibrating  ");
    }

}
}

void listenForServer() {
  /*    if (manager.sendtoWait(data, sizeof(data), SERVER_ADDRESS))
    {
      uint8_t len = sizeof(buf);
      uint8_t from;
      if (manager.recvfromAckTimeout(buf, &len, 2000, &from))
      {
        Serial.println((char*)buf);
      }
        }  */
}

void displayRpm() {
  lcd.clear();
  lcd.print("Set RPM  ");
  lcd.print(SetpointVariable);
  lcd.setCursor(0, 1);
  lcd.print("Motor “);
  lcd.print(Str3);
  lcd.print(” RPM ");
  lcd.print(rpm);
}

void exchangeData()  {
  // serial.println(radioArray);
  delay(200);
  /* if (manager.sendtoWait(radioArray, sizeof(radioArray), SERVER_ADDRESS))
    {
    Serial.println(“Message sent, waiting for reply”);
    // Now wait for a reply from the server
    uint8_t len = sizeof(buf);
    uint8_t from;
    if (manager.recvfromAckTimeout(buf, &len, 200, &from))
    {
      Serial.print(“got reply from : 0x”);
      Serial.print(from, HEX);
      Serial.print(": ");
      Serial.println((char*)buf);
    }
    else
    {
      Serial.println(“No reply, is nrf24_reliable_datagram_server running?”);
    }
    /*char msg[4];
      itoa(data, msg, 10);

driver.send((uint8_t )msg, strlen(msg));
      driver.waitPacketSent();
    }
/
}

I find it very difficult to follow your code, with so much stuff commented out (and a code block embedded in a quote block doesn't really help).

Can you delete all the comments, and post the code again?

I really don't understand this bit of code.

  if (state4 == 1) {
    radioArray[0] = 1;
    if (radioArray[0] == 1) {
      Str3 = Str1;
    }
    buttonDebounce[4] = 0;
  }
  if (state4 == 0) {
    radioArray[0] = 0;
    if (radioArray[0] == 0) {
      Str3 = Str2;
    }
  }

After assigning a value to radioArray[0], why is it necessary to test that the value is the value assigned?

I also don't understand what you think buttonDebounce is doing. In general, debouncing buttons is useful when you are looking at a switch changing state (becoming pressed or becoming released). Since you are not concerned about changes in state, I can't see what debouncing is for.

Here you go.

#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 16, 2); // set the LCD address to 0x27 for a 16 chars and 2 line display

#include <RHReliableDatagram.h>
#include <RH_NRF24.h>
#include <SPI.h>

//=======For the radio======

#define CLIENT_ADDRESS 1
#define SERVER_ADDRESS 2

// Singleton instance of the radio driver
RH_NRF24 driver;


// Class to manage message delivery and receipt, using the driver declared above
RHReliableDatagram manager(driver, CLIENT_ADDRESS);
uint8_t radioArray[5];//Array with 6 positions.
// Dont put this on the stack:
uint8_t buf[RH_NRF24_MAX_MESSAGE_LEN];

//====For the buttons====
const byte buttonPin[] = {4, 5, 6, 7, 3}; 

int buttonState[5];

int lastButtonState[5] = {1, 1, 1, 1, 1}; 


byte state[5] = {0,0,0,0,0};//toggle state
unsigned long buttonDebounce[5];

int SetpointVariable = 30;
int rpm;


String Str1 = "On";
String Str2 = "Off";
String Str3;

void setup() {

  radioArray[0] = 0;// sets motor to off at start up.

  //sets pinmode and pullup resistors
  for (byte b = 0; b < 5; b++)
  {
    pinMode(buttonPin[b], INPUT_PULLUP);
  }
 
  lcd.init();                      // initialize the lcd
  lcd.init();
  lcd.backlight();
  lcd.setCursor(3, 0);
  lcd.print("Lava Valley");
  lcd.setCursor(5, 1);
  lcd.print("Produce");
  delay(2000);
  lcd.clear();
  lcd.print("Seedr Controller");
  lcd.setCursor(1, 1);
  lcd.print("by Chris Dalby");
  delay(2000);
  lcd.clear();
  lcd.print("Set RPM  ");
  lcd.print(SetpointVariable);
  Serial.begin(9600);
  Serial.println("powered up");
  delay(1000);
  if (!manager.init())
    Serial.println("init failed");
  // Defaults after init are 2.402 GHz (channel 2), 2Mbps, 0dBm



}

void ToggleState() {
  
  for (state b=0; b>5; b++) {
    state[b] = (state[b], ^1)
  }
 // state4 = state4 ^ 1; //XOR 1 toggles LSB, effectively jumping between 0 and 1
}

void loop()
{

  readButtons();
  adjRequiredRpm();
  calibration();
  setStartStop();
  exchangeData();
  displayRpm();

  //  sendDatatoServer();//Send RequiredRpm & Start/Stop to Server.

}

void readButtons() {
  buttonState[0] = digitalRead(buttonPin[0]);
  buttonState[1] = digitalRead(buttonPin[1]);
  buttonState[2] = digitalRead(buttonPin[2]);
  buttonState[3] = digitalRead(buttonPin[3]);
  buttonState[4] = digitalRead(buttonPin[4]);

  //for debugging.
  /*
    Serial.print(button0state);
    Serial.print(button1state);
    Serial.print(button2state);
    Serial.print(button3state);
    Serial.println(switch4state);
  */
}

void setStartStop() 
{
  if (buttonState[4] == 0 && buttonDebounce[4] == 0) {
    buttonDebounce[4] = millis();
  }

  if (buttonState[4] == 1) {
    if ((buttonDebounce[4] != 0) && (millis() - buttonDebounce[4] > 20)) {
      ToggleState();
    }
  }

  if (state4 == 1) {
    radioArray[0] = 1;
    if (radioArray[0] == 1) {
      Str3 = Str1;
    }
    buttonDebounce[4] = 0;
  }
  if (state4 == 0) {
    radioArray[0] = 0;
    if (radioArray[0] == 0) {
      Str3 = Str2;
    }
  }
}

void adjRequiredRpm() {
  if (buttonState[0] == 0) {
    SetpointVariable = SetpointVariable + 1;
    if (SetpointVariable > 60) {
      SetpointVariable = 60;
    }
  }
  if (buttonState[1] == 0) {
    SetpointVariable = SetpointVariable - 1;
    if (SetpointVariable < 10) {
      SetpointVariable = 10;
    }
  }


}

void calibration() {
  if (buttonState[2] == 0 && buttonState[4] == 1) {
    radioArray[5] = 1;
    lcd.clear();
    lcd.print("Calibration Mode");
    lcd.setCursor(0, 1);
    lcd.print("Switch to run");

    if (buttonState[4] == 0) {
      lcd.clear();
      lcd.print("Calibration Mode");
      lcd.setCursor(0, 1);
      lcd.print("   Calibrating   ");
    }

  }
}


void listenForServer() {
  /*    if (manager.sendtoWait(data, sizeof(data), SERVER_ADDRESS))
    {
      uint8_t len = sizeof(buf);
      uint8_t from;
      if (manager.recvfromAckTimeout(buf, &len, 2000, &from))
      {
        Serial.println((char*)buf);
      }
        }  */
}

void displayRpm() {
  lcd.clear();
  lcd.print("Set RPM  ");
  lcd.print(SetpointVariable);
  lcd.setCursor(0, 1);
  lcd.print("Motor ");
  lcd.print(Str3);
  lcd.print(" RPM ");
  lcd.print(rpm);
}



void exchangeData()  {
  // serial.println(radioArray);
  delay(200);
  /* if (manager.sendtoWait(radioArray, sizeof(radioArray), SERVER_ADDRESS))
    {
     Serial.println("Message sent, waiting for reply");
     // Now wait for a reply from the server
     uint8_t len = sizeof(buf);
     uint8_t from;
     if (manager.recvfromAckTimeout(buf, &len, 200, &from))
     {
       Serial.print("got reply from : 0x");
       Serial.print(from, HEX);
       Serial.print(": ");
       Serial.println((char*)buf);
     }
     else
     {
       Serial.println("No reply, is nrf24_reliable_datagram_server running?");
     }
     /*char msg[4];
       itoa(data, msg, 10);

       driver.send((uint8_t *)msg, strlen(msg));
       driver.waitPacketSent();
    }*/
}

You will notice I am currently making a poor attempt at making a string out of “state”.
I know this is wrong, but at least I am trying. (That’s what my wife tells me, at least):wink:

void ToggleState() {
  
  for (state b=0; b>5; b++) {
    state[b] = (state[b], ^1)
  }
 // state4 = state4 ^ 1; //XOR 1 toggles LSB, effectively jumping between 0 and 1
}

The usual process for toggling a value like state involves using the proper data type, such as boolean.

Then, use the ! operator to toggle the state.

   state[b] = !state[b];

If the function is going to toggle all the states, the function should have a plural name.

PaulS:
I really don't understand this bit of code.

  if (state4 == 1) {

radioArray[0] = 1;
   if (radioArray[0] == 1) {
     Str3 = Str1;
   }
   buttonDebounce[4] = 0;
 }
 if (state4 == 0) {
   radioArray[0] = 0;
   if (radioArray[0] == 0) {
     Str3 = Str2;
   }
 }



After assigning a value to radioArray[0], why is it necessary to test that the value is the value assigned?

I remember having trouble at one stage with errors and this fixed it. Just deleted the "if(radioArray == 0)" and it all works again. Thanks.

I also don't understand what you think buttonDebounce is doing. In general, debouncing buttons is useful when you are looking at a switch changing state (becoming pressed or becoming released). Since you are not concerned about changes in state, I can't see what debouncing is for.

Well, I'd rather not have it too. BUT, just about every example of latching I have read on this forum says "you must have debounce".

Well, I'd rather not have it too. BUT, just about every example of latching I have read on this forum says "you must have debounce".

Yes, but latching involves knowing when the state changes, not just is the switch currently pressed.

PaulS:
The usual process for toggling a value like state involves using the proper data type, such as boolean.

Then, use the ! operator to toggle the state.

   state[b] = !state[b];

If the function is going to toggle all the states, the function should have a plural name.

I need to get the state array sorted so I can reference button2 to a state as well. Unfortunately your response above went straight over my head.
Can you help get the following sorted?

void ToggleState() {
  
 // for (state b=0; b>5; b++) {
 //   state[b] = (state[b], ^1)
 // }
  state[4] = state[4] ^ 1; //XOR 1 toggles LSB, effectively jumping between 0 and 1
}

Full code here if needed.

#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 16, 2); // set the LCD address to 0x27 for a 16 chars and 2 line display

#include <RHReliableDatagram.h>
#include <RH_NRF24.h>
#include <SPI.h>

//=======For the radio======

#define CLIENT_ADDRESS 1
#define SERVER_ADDRESS 2

// Singleton instance of the radio driver
RH_NRF24 driver;


// Class to manage message delivery and receipt, using the driver declared above
RHReliableDatagram manager(driver, CLIENT_ADDRESS);
uint8_t radioArray[5];//Array with 6 positions.
// Dont put this on the stack:
uint8_t buf[RH_NRF24_MAX_MESSAGE_LEN];

//====For the buttons====
const byte buttonPin[] = {4, 5, 6, 7, 3}; 

int buttonState[5];

int lastButtonState[5] = {1, 1, 1, 1, 1}; 


byte state[5] = {0,0,0,0,0};//toggle state
unsigned long buttonDebounce[5];

int SetpointVariable = 30;
int rpm;


String Str1 = "On";
String Str2 = "Off";
String Str3;

void setup() {

  radioArray[0] = 0;// sets motor to off at start up.

  //sets pinmode and pullup resistors
  for (byte b = 0; b < 5; b++)
  {
    pinMode(buttonPin[b], INPUT_PULLUP);
  }
 
  lcd.init();                      // initialize the lcd
  lcd.init();
  lcd.backlight();
  lcd.setCursor(3, 0);
  lcd.print("Lava Valley");
  lcd.setCursor(5, 1);
  lcd.print("Produce");
  delay(2000);
  lcd.clear();
  lcd.print("Seedr Controller");
  lcd.setCursor(1, 1);
  lcd.print("by Chris Dalby");
  delay(2000);
  lcd.clear();
  lcd.print("Set RPM  ");
  lcd.print(SetpointVariable);
  Serial.begin(9600);
  Serial.println("powered up");
  delay(1000);
  if (!manager.init())
    Serial.println("init failed");
  // Defaults after init are 2.402 GHz (channel 2), 2Mbps, 0dBm



}

void ToggleState() {
  
 // for (state b=0; b>5; b++) {
 //   state[b] = (state[b], ^1)
 // }
  state[4] = state[4] ^ 1; //XOR 1 toggles LSB, effectively jumping between 0 and 1
}

void loop()
{

  readButtons();
  adjRequiredRpm();
  calibration();
  setStartStop();
  exchangeData();
  displayRpm();

  //  sendDatatoServer();//Send RequiredRpm & Start/Stop to Server.

}

void readButtons() {
  buttonState[0] = digitalRead(buttonPin[0]);
  buttonState[1] = digitalRead(buttonPin[1]);
  buttonState[2] = digitalRead(buttonPin[2]);
  buttonState[3] = digitalRead(buttonPin[3]);
  buttonState[4] = digitalRead(buttonPin[4]);

  //for debugging.
  /*
    Serial.print(button0state);
    Serial.print(button1state);
    Serial.print(button2state);
    Serial.print(button3state);
    Serial.println(switch4state);
  */
}

void setStartStop() 
{
  if (buttonState[4] == 0 && buttonDebounce[4] == 0) {
    buttonDebounce[4] = millis();
   ToggleState();
  }
/*
  if (buttonState[4] == 0) {
    if ((buttonDebounce[4] != 0) && (millis() - buttonDebounce[4] > 20)) {
      ToggleState();
    }
  }
*/
  if (state[4] == 1) {
    radioArray[0] = 1;
    Str3 = Str1;
    //if (radioArray[0] == 1) {
     // Str3 = Str1;
    //}
    
  }
  if (state[4] == 0) {
    radioArray[0] = 0;
     Str3 = Str2;
   // if (radioArray[0] == 0) {
     
  //  }
  }
  buttonDebounce[4] = 0;
}

void adjRequiredRpm() {
  if (buttonState[0] == 0) {
    SetpointVariable = SetpointVariable + 1;
    if (SetpointVariable > 60) {
      SetpointVariable = 60;
    }
  }
  if (buttonState[1] == 0) {
    SetpointVariable = SetpointVariable - 1;
    if (SetpointVariable < 10) {
      SetpointVariable = 10;
    }
  }


}

void calibration() {
  if (buttonState[2] == 0 && buttonState[4] == 1) {
    ToggleState();
    radioArray[5] = 1;
    lcd.clear();
    lcd.print("Calibration Mode");
    lcd.setCursor(0, 1);
    lcd.print("Switch to run");

    if (buttonState[4] == 0) {
      lcd.clear();
      lcd.print("Calibration Mode");
      lcd.setCursor(0, 1);
      lcd.print("   Calibrating   ");
    }

  }
}


void listenForServer() {
  /*    if (manager.sendtoWait(data, sizeof(data), SERVER_ADDRESS))
    {
      uint8_t len = sizeof(buf);
      uint8_t from;
      if (manager.recvfromAckTimeout(buf, &len, 2000, &from))
      {
        Serial.println((char*)buf);
      }
        }  */
}

void displayRpm() {
  lcd.clear();
  lcd.print("Set RPM  ");
  lcd.print(SetpointVariable);
  lcd.setCursor(0, 1);
  lcd.print("Motor ");
  lcd.print(Str3);
  lcd.print(" RPM ");
  lcd.print(rpm);
}



void exchangeData()  {
  // serial.println(radioArray);
  delay(200);
  /* if (manager.sendtoWait(radioArray, sizeof(radioArray), SERVER_ADDRESS))
    {
     Serial.println("Message sent, waiting for reply");
     // Now wait for a reply from the server
     uint8_t len = sizeof(buf);
     uint8_t from;
     if (manager.recvfromAckTimeout(buf, &len, 200, &from))
     {
       Serial.print("got reply from : 0x");
       Serial.print(from, HEX);
       Serial.print(": ");
       Serial.println((char*)buf);
     }
     else
     {
       Serial.println("No reply, is nrf24_reliable_datagram_server running?");
     }
     /*char msg[4];
       itoa(data, msg, 10);

       driver.send((uint8_t *)msg, strlen(msg));
       driver.waitPacketSent();
    }*/
}

Can you help get the following sorted?

Code: [Select]

void ToggleState() {

// for (state b=0; b>5; b++) {
// state = (state**, ^1)**
// }
** state[4] = state[4] ^ 1; //XOR 1 toggles LSB, effectively jumping between 0 and 1**
}[/quote]
Doesn’t it seem reasonable that if you wanted to toggle the state of one specific element of the array, and that was done using:
**__ <strong>**  state[4] = state[4] ^ 1;**</strong> __**
that doing the same thing to the bth element in the loop that that would be done using
**__ <strong>**  state[b] = state[b] ^ 1;**</strong> __**
Why did you try to invent new syntax?

PaulS:
Doesn’t it seem reasonable that if you wanted to toggle the state of one specific element of the array, and that was done using:

  state[4] = state[4] ^ 1;

that doing the same thing to the bth element in the loop that that would be done using

  state[b] = state[b] ^ 1;

Why did you try to invent new syntax?

Like this?

#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 16, 2); // set the LCD address to 0x27 for a 16 chars and 2 line display

#include <RHReliableDatagram.h>
#include <RH_NRF24.h>
#include <SPI.h>

//=======For the radio======

#define CLIENT_ADDRESS 1
#define SERVER_ADDRESS 2

// Singleton instance of the radio driver
RH_NRF24 driver;


// Class to manage message delivery and receipt, using the driver declared above
RHReliableDatagram manager(driver, CLIENT_ADDRESS);
uint8_t radioArray[5];//Array with 6 positions.
// Dont put this on the stack:
uint8_t buf[RH_NRF24_MAX_MESSAGE_LEN];

//====For the buttons====
const byte buttonPin[] = {4, 5, 6, 7, 3}; 

int buttonState[5];

int lastButtonState[5] = {1, 1, 1, 1, 1}; 


byte state[5] = {0,0,0,0,0};//toggle state
unsigned long buttonDebounce[5];

int SetpointVariable = 30;
int rpm;


String Str1 = "On";
String Str2 = "Off";
String Str3;

void setup() {

  radioArray[0] = 0;// sets motor to off at start up.

  //sets pinmode and pullup resistors
  for (byte b = 0; b < 5; b++)
  {
    pinMode(buttonPin[b], INPUT_PULLUP);
  }
 
  lcd.init();                      // initialize the lcd
  lcd.init();
  lcd.backlight();
  lcd.setCursor(3, 0);
  lcd.print("Lava Valley");
  lcd.setCursor(5, 1);
  lcd.print("Produce");
  delay(2000);
  lcd.clear();
  lcd.print("Seedr Controller");
  lcd.setCursor(1, 1);
  lcd.print("by Chris Dalby");
  delay(2000);
  lcd.clear();
  lcd.print("Set RPM  ");
  lcd.print(SetpointVariable);
  Serial.begin(9600);
  Serial.println("powered up");
  delay(1000);
  if (!manager.init())
    Serial.println("init failed");
  // Defaults after init are 2.402 GHz (channel 2), 2Mbps, 0dBm



}

void ToggleState() {
  
  for (state b=0; b>5; b++) {
    state[b] = (state[b], ^1);
  }
 // state[b] = state[b] ^ 1; //XOR 1 toggles LSB, effectively jumping between 0 and 1
}

void loop()
{

  readButtons();
  adjRequiredRpm();
  calibration();
  setStartStop();
  exchangeData();
  displayRpm();

  //  sendDatatoServer();//Send RequiredRpm & Start/Stop to Server.

}

void readButtons() {
  buttonState[0] = digitalRead(buttonPin[0]);
  buttonState[1] = digitalRead(buttonPin[1]);
  buttonState[2] = digitalRead(buttonPin[2]);
  buttonState[3] = digitalRead(buttonPin[3]);
  buttonState[4] = digitalRead(buttonPin[4]);

  //for debugging.
  /*
    Serial.print(button0state);
    Serial.print(button1state);
    Serial.print(button2state);
    Serial.print(button3state);
    Serial.println(switch4state);
  */
}

void setStartStop() 
{
  if (buttonState[4] == 0 && buttonDebounce[4] == 0) {
    buttonDebounce[4] = millis();
   ToggleState();
  }
/*
  if (buttonState[4] == 0) {
    if ((buttonDebounce[4] != 0) && (millis() - buttonDebounce[4] > 20)) {
      ToggleState();
    }
  }
*/
  if (state[4] == 1) {
    radioArray[0] = 1;
    Str3 = Str1;
    //if (radioArray[0] == 1) {
     // Str3 = Str1;
    //}
    
  }
  if (state[4] == 0) {
    radioArray[0] = 0;
     Str3 = Str2;
   // if (radioArray[0] == 0) {
     
  //  }
  }
  buttonDebounce[4] = 0;
}

void adjRequiredRpm() {
  if (buttonState[0] == 0) {
    SetpointVariable = SetpointVariable + 1;
    if (SetpointVariable > 60) {
      SetpointVariable = 60;
    }
  }
  if (buttonState[1] == 0) {
    SetpointVariable = SetpointVariable - 1;
    if (SetpointVariable < 10) {
      SetpointVariable = 10;
    }
  }


}

void calibration() {
  if (buttonState[2] == 0 && buttonState[4] == 1) {
    ToggleState();
    if(state[2] == 0){
    radioArray[5] = 1;
    lcd.clear();
    lcd.print("Calibration Mode");
    lcd.setCursor(0, 1);
    lcd.print("Switch to run");
    }

    if (buttonState[4] == 0) {
      state[4] = 0;
      lcd.clear();
      lcd.print("Calibration Mode");
      lcd.setCursor(0, 1);
      lcd.print("   Calibrating   ");
    }

  }
}


void listenForServer() {
  /*    if (manager.sendtoWait(data, sizeof(data), SERVER_ADDRESS))
    {
      uint8_t len = sizeof(buf);
      uint8_t from;
      if (manager.recvfromAckTimeout(buf, &len, 2000, &from))
      {
        Serial.println((char*)buf);
      }
        }  */
}

void displayRpm() {
  lcd.clear();
  lcd.print("Set RPM  ");
  lcd.print(SetpointVariable);
  lcd.setCursor(0, 1);
  lcd.print("Motor ");
  lcd.print(Str3);
  lcd.print(" RPM ");
  lcd.print(rpm);
}



void exchangeData()  {
  // serial.println(radioArray);
  delay(200);
  /* if (manager.sendtoWait(radioArray, sizeof(radioArray), SERVER_ADDRESS))
    {
     Serial.println("Message sent, waiting for reply");
     // Now wait for a reply from the server
     uint8_t len = sizeof(buf);
     uint8_t from;
     if (manager.recvfromAckTimeout(buf, &len, 200, &from))
     {
       Serial.print("got reply from : 0x");
       Serial.print(from, HEX);
       Serial.print(": ");
       Serial.println((char*)buf);
     }
     else
     {
       Serial.println("No reply, is nrf24_reliable_datagram_server running?");
     }
     /*char msg[4];
       itoa(data, msg, 10);

       driver.send((uint8_t *)msg, strlen(msg));
       driver.waitPacketSent();
    }*/
}
Arduino: 1.6.7 (Linux), Board: "Arduino/Genuino Uno"

/home/anne/Arduino/wireless_seeder_controller_client/wireless_seeder_controller_client.ino: In function 'void ToggleState()':
wireless_seeder_controller_client:82: error: expected ';' before 'b'
   for (state b=0; b>5; b++) {
              ^
wireless_seeder_controller_client:82: error: 'b' was not declared in this scope
   for (state b=0; b>5; b++) {
                   ^
wireless_seeder_controller_client:83: error: expected primary-expression before '^' token
     state[b] = (state[b], ^1);
                           ^
exit status 1
expected ';' before 'b'

  This report would have more information with
  "Show verbose output during compilation"
  enabled in File > Preferences.

Like this?

No. Like this:

    for(byte b=0; b<5; b++)
    {
       state[b] = state[b] ^ 1;
    }

So now when I ToggleState, how do I define which state in the array to toggle.

void setStartStop() 
{
  if (buttonState[4] == 0 && buttonDebounce[4] == 0) {
    buttonDebounce[4] = millis();
   ToggleState();
  }

Shouldn't you be iterating? As in:

  if (buttonState[i] == 0 && buttonDebounce[i] == 0) {

The main point of using an array is to enable it.