UART woes. Looking for guidance on what could be going wrong

I'm trying to create a test for communication between two Adruino IOT 33's over UART. The idea is the user can push a button and have the corresponding LED turn on. The IOT's are correctly hooked up over UART via MX and TX and one IOT 33 controls the buttons while the other controls the LEDS. All of the buttons work correctly. All of the LEDs are working correctly. When I go to push buttons 2-8 they work as expected (kind of) but when I push button 1 it doesn't turn on... but it does turn on when I push any of the other buttons.

I've rewired this project more time than I'd like to admit and have confirmation that the communication over UART is functioning as well we multimeter tests to make sure there aren't any crossovers.

Receiver Code

const int ledPins[] = {2, 3, 4, 5, 6, 7, A6, A7}; // Updated for A6 and A7
const int numLEDs = 8; // Number of LEDs

void setup() {
  Serial1.begin(115200); // Initialize UART with a baud rate of 115200
  for (int i = 0; i < numLEDs; i++) {
    pinMode(ledPins[i], OUTPUT); // Set LED pins as outputs
    digitalWrite(ledPins[i], LOW); // Initialize LEDs as off
  }

  pinMode(LED_BUILTIN, OUTPUT); // Set built-in LED pin as output
  digitalWrite(LED_BUILTIN, LOW); // Switch off the built-in LED
}

void loop() {

  if (Serial1.available() > 0) {
    char buttonChar = Serial1.read();
    Serial.println("Received character: " + String(buttonChar)); // Debugging output
    if (buttonChar >= '0' && buttonChar <= '7') {
        int ledIndex = buttonChar - '0';
        Serial.println("Toggling LED at index: " + String(ledIndex)); // Debugging output
        digitalWrite(ledPins[ledIndex], !digitalRead(ledPins[ledIndex]));
    }
}

  if (Serial1.available() > 0) {
    char buttonChar = Serial1.read(); // Read the button character from the serial buffer
    
    // Check if the received data corresponds to an LED (e.g., '0' to '7')
    if (buttonChar >= '0' && buttonChar <= '7') {
      int ledIndex = buttonChar - '0'; // Convert the character to an integer index
      
      // Toggle the state of the specified LED
      digitalWrite(ledPins[ledIndex], !digitalRead(ledPins[ledIndex])); // Toggle the state of the corresponding LED
    }
  }
}

Transmitter Code

const int buttonPins[] = { 2, 3, 4, 5, 6, 7, 8, 9 };  // Define an array of button pins
const int numButtons = 8;                             // Number of buttons

int buttonStates[numButtons];                 // Current button states
int lastButtonStates[numButtons];             // Previous button states
unsigned long lastDebounceTimes[numButtons];  // Last time each button state changed
unsigned long debounceDelay = 50;             // Debounce delay in milliseconds

// Define digital pin numbers for LEDs
const int ledPins[] = { 2, 3, 4, 5, 6, 7, A6, A7 };  // Updated for A6 and A7

void setup() {
  Serial.begin(115200);   // Initialize serial communication at 115200 bits per second
  Serial1.begin(115200);  // Initialize UART with a baud rate of 115200
  for (int i = 0; i < numButtons; i++) {
    pinMode(buttonPins[i], INPUT_PULLUP);  // Set button pins as inputs with internal pull-up resistors
    buttonStates[i] = HIGH;                // Initialize button states
    lastButtonStates[i] = HIGH;            // Initialize last button states
    lastDebounceTimes[i] = 20;             // Initialize debounce times
  }

  for (int i = 0; i < numButtons; i++) {
    pinMode(ledPins[i], OUTPUT);    // Set LED pins as outputs
    digitalWrite(ledPins[i], LOW);  // Initialize LEDs as off
  }

  pinMode(LED_BUILTIN, OUTPUT);  // Set LED pin as output
}

void loop() {
  for (int i = 0; i < numButtons; i++) {
    int reading = digitalRead(buttonPins[i]);

    if (reading != lastButtonStates[i]) {
      // Record the last time the button state changed
      lastDebounceTimes[i] = millis();
    }

    if ((millis() - lastDebounceTimes[i]) > debounceDelay) {
      // If the button state has been stable for a while, we consider it valid
      if (reading != buttonStates[i]) {
        Serial.println("Button " + String(i) + " state: " + String(reading));
        buttonStates[i] = reading;  // Update the button state

        if (buttonStates[i] == LOW) {
          Serial1.println(i);  // Button is clicked (pressed)
          // You can add specific actions for each button here
          // For example, you can use a switch statement to identify which button was pressed
          // and take different actions based on the button.
        } else {
          Serial1.println('0');
        }
      }
    }

    // Save the current button state as the last state
    lastButtonStates[i] = reading;
  }
}

const int ledPins[] = { 2, 3, 4, 5, 6, 7, A6, A7 };  // Updated for A6 and A7

const int buttonPins[] = { 2, 3, 4, 5, 6, 7, 8, 9 };  // Define an array of button pins

Why are you using the same pins for both LEDs and buttons ?

1 Like

I thought I needed to let my Transmitter know what was on the other side! Dang let me remove this and see what shakes out. Thank you

Unfortunately removing the LED data form the transmitter didnt make a difference.

Is the button good?

Yes. The button shows up in the debugg function Serial.println("Button " + String(i) + " state: " + String(reading));

Hi @tim_tam_tam ,

Welcome to the forum..
Nice job on the posting..
Problem mostly in your transmitting..
Your debounce confuses me, seems backwards..

Tossed it into a simulator using a mega so I could test receiving code at the same time using additional UARTS of that board..

I changed the debounce routine..
Always send button index that is changing, not only when its low..
Removed use of String objects..
Reduced types to bytes where applicable..

const byte buttonPins[] = { 2, 3, 4, 5, 6, 7, 8, 9 };  // Define an array of button pins
const byte numButtons = 8;                             // Number of buttons

byte buttonStates[numButtons];                 // Current button states
byte lastButtonStates[numButtons];             // Previous button states
unsigned long lastDebounceTimes[numButtons];  // Last time each button state changed
byte debounceDelay = 50;             // Debounce delay in milliseconds

// Define digital pin numbers for LEDs
const byte ledPins[] = { 23, 25, 27, 29, 31, 33, 34, 35 };  // Updated for Mega
//temp string for printing..
char buff[80];

void setup() {
  Serial.begin(115200);   // Initialize serial communication at 115200 bits per second
  Serial1.begin(115200);  // Initialize UART with a baud rate of 115200
  Serial2.begin(115200); //init receiver, remove this on seperation..
  for (int i = 0; i < numButtons; i++) {
    pinMode(buttonPins[i], INPUT_PULLUP);  // Set button pins as inputs with internal pull-up resistors
    buttonStates[i] = HIGH;                // Initialize button states
    lastButtonStates[i] = HIGH;            // Initialize last button states
    lastDebounceTimes[i] = 0;             // Initialize debounce times
  }

  for (int i = 0; i < numButtons; i++) {
    pinMode(ledPins[i], OUTPUT);    // Set LED pins as outputs
    digitalWrite(ledPins[i], LOW);  // Initialize LEDs as off
  }
  pinMode(LED_BUILTIN, OUTPUT);  // Set LED pin as output
}

void loop() {

  unsigned long now = millis();

  for (int i = 0; i < numButtons; i++) {
    //read buttons with debounce..
    if ((now - lastDebounceTimes[i]) > debounceDelay) {
      buttonStates[i] = digitalRead(buttonPins[i]);
    }
    // Button state has changed..
    if (lastButtonStates[i] != buttonStates[i]) {
      //button has changed, start debouncing..
      lastDebounceTimes[i] = now;
      //print nice formatted string into buff..
      sprintf(buff, "Button %d state %d", i, buttonStates[i]);
      Serial.println(buff);
      lastButtonStates[i] = buttonStates[i];  // Update the last button state
      //send button number to be toggled..
      Serial1.print(i);
    }
  }

  //receiver code..
  //this would be in the other sketch using Serial1 object..
  if (Serial2.available()) {
    char buttonChar = Serial2.read();
    Serial.print("Received character: "); // Debugging output
    Serial.println(buttonChar);
    if (buttonChar >= '0' && buttonChar <= '7') {
      int ledIndex = buttonChar - '0';
      Serial.print("Toggling LED at index: "); // Debugging output
      Serial.println(ledIndex);
      digitalWrite(ledPins[ledIndex], !digitalRead(ledPins[ledIndex]));
    }
  }
}

Seems to work..

Mega Serial Leds..

good luck.. ~q

It would be best if you posted an annotated schematic showing exactly how you have wired it, be sure all connections are on it. Also links to technical information on the buttons will help.

Thank you for the help!

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.