Here is a demo that reads the buttons and incoming Bluetooth messages independently to control what is printed. There are flags set to indicate a new button or Bluetooth message. It uses the state change detection method to read the button switches so only one message for each button press. See also the state change for active low switches. The code was tested on an Uno so the Bluetooth module was connected to a SoftwareSerial port to keep the hardware serial port free for upload and program debug and output. BT TX to Uno pin 6 and BT RX to Uno pin 7. I use the Receive with End Markers code from the serial input basics tutorial for serial input into a string, avoiding the potential problems that can occur with use of the String class. The data sent to the Bluetooth module must be terminated with a line feed ('\n'). Carriage return optional.
#include <SoftwareSerial.h>
struct Buttons
{
byte pin;
bool currentState;
bool lastState;
};
const byte NUM_BUTTONS = 4;
Buttons button[NUM_BUTTONS]; // array of button switches
bool messageStates[NUM_BUTTONS]; // array of message numbers
const byte numChars = 11;
char receivedChars[numChars]; // an array to store the received data
// flags for states
bool newButton = false;
bool newData = false;
bool newBluetooth = false;
SoftwareSerial ss(6, 7);
void setup()
{
Serial.begin(115200);
Serial.println("Arduino up");
ss.begin(9600);
ss.println("Bluetooth up");
button[0] = {2, 1, 1};
button[1] = {3, 1, 1};
button[2] = {4, 1, 1};
button[3] = {5, 1, 1};
for (int n = 0; n < NUM_BUTTONS; n++)
{
pinMode(button[n].pin, INPUT_PULLUP);
messageStates[n] = HIGH;
}
}
void loop()
{
// reset message states for this iteration
for (int n = 0; n < NUM_BUTTONS; n++)
{
messageStates[n] = HIGH;
}
// recveive from Bluetooth
recvWithEndMarker();
if (newData)
{
parseData();
}
// check for button presses
checkButtons();
//if either a button was pressed or a new Bluetooth message.
if (newButton || newBluetooth)
{
if (messageStates[0] == 0)
{
Serial.println("A+");
}
if (messageStates[1] == 0)
{
Serial.println("A-");
}
if (messageStates[2] == 0)
{
Serial.println("B+");
}
if (messageStates[3] == 0)
{
Serial.println("B-");
}
newButton = false;
newBluetooth = false;
}
}
void checkButtons()
{
static unsigned long timer = 0;
unsigned long interval = 50;
if (millis() - timer >= interval)
{
timer = millis();
for (int n = 0; n < NUM_BUTTONS; n++)
{
button[n].currentState = digitalRead(button[n].pin);
//Serial.println(button[n].currentState);
if ( button[n].currentState != button[n].lastState)
{
if (button[n].currentState == LOW)
{
messageStates[n] = 0;
newButton = true;
}
button[n].lastState = button[n].currentState;
}
}
}
}
void recvWithEndMarker()
{
static byte ndx = 0;
char endMarker = '\n';
char rc;
while (ss.available() > 0 && newData == false)
{
rc = ss.read();
if (rc == '\r') // ignore carriage return
{
return;
}
//Serial.println(rc);
if (rc != endMarker)
{
receivedChars[ndx] = rc;
ndx++;
if (ndx >= numChars)
{
ndx = numChars - 1;
}
}
else
{
receivedChars[ndx] = '\0'; // terminate the string
ndx = 0;
newData = true;
}
}
}
void parseData()
{
//Serial.println("parsing");
if (strcmp(receivedChars, "A+") == 0)
{
messageStates[0] = 0;
}
if (strcmp(receivedChars, "A-") == 0)
{
messageStates[1] = 0;
}
if (strcmp(receivedChars, "B+") == 0)
{
messageStates[2] = 0;
}
if (strcmp(receivedChars, "B-") == 0)
{
messageStates[3] = 0;
}
newData = false;
newBluetooth = true;
}