This application consists of 2 arduino iot 33, 1 sender and one receiver. The issue involves sending BPM and Button data to the receiver from the sender. On the sender are 6 buttons with 1 acting as the tap tempo button and the other 5 acting as selection buttons.
I started working with 1 UART channel to send BPM data from my application (worked perfectly). I then realized I needed to send button presses from 5 different buttons over UART as well. Now I know I can fit the 3 chars of a bpm and the 5 button chars for a total of 8 chars but I need the buttons and the BPM to send at different timings: BPM data at a set time and the button data whenever they are pushed. When I added the second UART channel, things stopped working entirely on the sender arduino. I'm at a loss for what to do. Any help is very much appreciated.
Another thing: I've made sure that my new serial wiring is correct with sercom being set up on pins 5 and 6 on each of the 2 arduinos, making sure pin5(RX) on the sender connects to pin6(TX) on the receiver and pin6(TX) on the sender connected to pin5(RX) on the receiver.
Sender Code
#include <ArduinoTapTempo.h>
#include <Bounce2.h>
const int BUTTON_PIN = 9;
const int LED_PIN = A5; // Pin for the LED
const int SERIAL_BAUD_RATE = 9600;
ArduinoTapTempo tapTempo;
const int ledPins[] = { 13, A1, A2, A3, A4 }; // Define an array of button pins
const int numLEDs = 5; // Number of LEDs
const int buttonPins[] = { 4, 2, 3, 7, 8 }; // Define an array of button pins
const int numButtons = 5;
int buttonChar[numButtons];
int bpmAdjust = 0;
int currentBPM = 120; // Store the current BPM
int adjustedBPM = 120;
int persistantBPM = 120;
bool resetDownbeat = false;
unsigned long resetTime = 0;
unsigned long lastUpdateMillis = 0;
const unsigned long updateInterval = 10;
unsigned long previousMillis = 0;
unsigned long interval;
Bounce resetButton = Bounce();
Bounce buttons[5]; // Create an array of debounced buttons
bool ledState[5] = { false }; // Store the state of each LED
bool resetButtonPressed = false; // Flag to track reset button press
unsigned long previousTimer = 0; // Initialize a variable to store the last time the code ran
const unsigned long timerInter = 500; // Interval in milliseconds (1 second)
Uart mySerial (&sercom0, 5, 6, SERCOM_RX_PAD_1, UART_TX_PAD_0); // <----- this is what was added that broke the tap tempo functionality.
void setup() {
pinMode(BUTTON_PIN, INPUT_PULLUP);
pinMode(LED_PIN, OUTPUT);
Serial.begin(9600);
Serial1.begin(9600); // BPM sent over Serial1
mySerial.begin(9600); // Button data send over mySerial
tapTempo.setTotalTapValues(4);
tapTempo.setBeatsUntilChainReset(8);
tapTempo.setMaxBPM(200);
tapTempo.setMinBPM(40);
for (int i = 0; i < 5; i++) {
pinMode(buttonPins[i], INPUT_PULLUP); // Set button pins as INPUT_PULLUP
pinMode(ledPins[i], OUTPUT); // Set LED pins as OUTPUT
buttons[i].attach(buttonPins[i]);
buttons[i].interval(50); // Debounce interval in milliseconds
}
delay(1000);
}
void loop() {
unsigned long currentTimer = millis(); // Get the current time
for (int i = 0; i < 5; i++) {
buttons[i].update(); // Update the button states
if (buttons[i].fell()) { // Button pressed
ledState[i] = !ledState[i]; // Toggle LED state
digitalWrite(ledPins[i], ledState[i]); // Update the LED state
}
}
for (int i = 0; i < 5; i++) {
bool buttonState = digitalRead(buttonPins[i]);
mySerial.print("Button ");
mySerial.print(i + 1);
mySerial.print(": ");
mySerial.println(buttonState);
}
bool buttonDown = digitalRead(BUTTON_PIN) == LOW;
tapTempo.update(buttonDown);
currentBPM = tapTempo.getBPM();
adjustedBPM = currentBPM + bpmAdjust;
unsigned long currentMillis = millis();
interval = 60000 / adjustedBPM;
// Serial.println(adjustedBPM);
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
digitalWrite(LED_PIN, !digitalRead(LED_PIN)); // Toggle the LED state
Serial.println(adjustedBPM);
}
if (currentTimer - previousTimer >= timerInter) {
previousTimer = currentTimer; // Update the previous time
// Serial.println(currentBPM);
if (currentBPM >= 50 && currentBPM <= 250) {
// send bytes
transmitterBPM(currentBPM);
}
}
}
void transmitterBPM(int bpm) {
// Serial.println(bpm);
if (bpm >= 100 && bpm <= 999) {
byte highByte = bpm / 100;
byte middleByte = (bpm / 10) % 10;
byte lowByte = bpm % 10;
Serial1.write(highByte);
Serial1.write(middleByte);
Serial1.write(lowByte);
}
}
Receiver Code
#include <Bounce2.h>
int bpmAdjust = 0;
int currentBPM; // Store the current BPM
int adjustedBPM;
int persistantBPM;
int previousBPM;
// UART
int bitOne = 1;
int bitTwo = 1;
int bitThree = 0;
unsigned long previousTimer = 0; // Initialize a variable to store the last time the code ran
const unsigned long timerInter = 500; // Interval in milliseconds (1 second)
Uart mySerial(&sercom0, 5, 6, SERCOM_RX_PAD_1, UART_TX_PAD_0);
enum ReceiverState {
IDLE,
WAIT_FOR_BUTTON,
PROCESS_BUTTON_DATA
};
ReceiverState receiverState = IDLE;
String receivedDataBuffer = "";
void setup() {
Serial.begin(9600);
Serial1.begin(9600);
mySerial.begin(9600);
}
void loop() {
unsigned long currentTimer = millis(); // Get the current time
if (currentTimer - previousTimer >= timerInter) {
previousTimer = currentTimer; // Update the previous time
if (Serial1.available() >= 3) {
bitOne = Serial1.read();
bitTwo = Serial1.read();
bitThree = Serial1.read();
}
String concatenatedString = String(bitOne) + String(bitTwo) + String(bitThree);
currentBPM = concatenatedString.toInt();
}
receiver();
if (currentBPM != previousBPM) {
previousBPM = currentBPM;
}
}
void receiver() {
if (mySerial.available() > 0) {
char receivedChar = mySerial.read();
processReceivedChar(receivedChar);
}
}
void processReceivedChar(char receivedChar) {
switch (receiverState) {
case IDLE:
if (receivedChar == 'B') {
receiverState = WAIT_FOR_BUTTON;
receivedDataBuffer = "";
}
break;
case WAIT_FOR_BUTTON:
if (receivedChar == ':') {
receiverState = PROCESS_BUTTON_DATA;
} else {
receivedDataBuffer += receivedChar;
}
break;
case PROCESS_BUTTON_DATA:
// Process the button data
int buttonNumber = receivedDataBuffer.toInt();
processReceivedData(buttonNumber);
// Return to the IDLE state
receiverState = IDLE;
break;
}
}
void processReceivedData(int buttonNumber) {
Serial.print("Button Pressed: ");
Serial.println(buttonNumber);
}