Editorial Solution

  • In this task, two Arduino UNO boards communicate via UART (Serial Communication) to control the brightness of LED2 and toggle the LED1 ON and OFF.
  • Both Arduino’s will log the data as follows: 
    • Arduino Board2 prints the received ADC values [0 to 1023].
    • Arduino Board1 prints the LED1 status [ON or OFF].
  • For proper UART communication between two controllers, both must use the same baud rate (e.g., 9600, 4800, 115200).

Hardware Connection

  • Board 1 Connections
    • LED1 
      • Connected to digital pin 7 using 330Ω resistor in series with LED to limit current through it.
    • Potentiometer 
      • Terminal 1 → VCC.
      • Terminal 2 → Pin A0.
      • Terminal 3 → GND .
  • Board 2 Connections
    • Push Button Switch
      • One terminal is connected to digital pin 2 and the other is connected to GND.
      • Use an internal pull-up resistor on digital pin 2 to avoid the floating state of the pin.
    • LED2 
      • Connected to digital pin 7 using 330Ω resistor in series with LED to limit current through it.
  • UART Connection (SoftwareSerial):
    • The Board1 D3 pin (RX) is connected to the Board2 D4 pin  (TX).
    • The Board1 D4 pin (TX) is connected to the  Board2 D3 pin (RX)
  • Connect Arduino UNO to PC via USB cable.

Firmware

  • Arduino UNO has only one hardware serial module using Tx (Pin 1) and Rx (Pin 0).
  • These pins are also used for USB communication with the Serial Monitor.
  • Using the same pins for both tasks, data logging on the serial monitor, and data transmission between two Arduino UNO boards can cause data conflicts.
  • To prevent this, we assign different pins for board-to-board communication.
  • The SoftwareSerial library helps create additional Tx and Rx pins.

 

Board 1 code 

#include <SoftwareSerial.h>

#define POTENTIOMETER A0
#define LED_PIN 7

SoftwareSerial mySerial(3, 4);  // 3-RX, 4-TX (For communication with Board 2)

uint16_t previousValue = 0;

void setup() {
  pinMode(LED_PIN, OUTPUT);
  mySerial.begin(9600);  // Initialize software Serial communication
  Serial.begin(115200);  // Initialize Hardware Serial communication
}

void loop() {

  uint16_t potValue = analogRead(A0);  // Read potentiometer value (0-1023)
  if (previousValue != potValue) {

    uint8_t upperByte = potValue >> 8;  // Upper byte
    uint8_t lowerByte = potValue;       // Lower byte

    // Send the two bytes
    mySerial.write(lowerByte);
    mySerial.write(upperByte);

    previousValue = potValue;
  }

  if (mySerial.available()) {
    String receivedCmd = mySerial.readStringUntil('\n');
    if (receivedCmd == "T") {
      digitalWrite(LED_PIN, !digitalRead(LED_PIN));  // Toggle LED state
      Serial.print("LED is ");
      Serial.println(digitalRead(LED_PIN) ? "ON" : "OFF");  // Print state
    }
  }

  delay(100);  // Small delay for stability
}

 

Board 2 code 

#include <SoftwareSerial.h>

#define LED_PIN 9
#define SWITCH_PIN 2
#define DEBOUNCE_DELAY 50  // debounce delay

uint8_t previousValue = 0;

bool last_button_state = 1;            // Previous button state (1: not pressed, 0: pressed)
bool current_button_state = 1;         // Current button state
unsigned long last_debounce_time = 0;  // Timestamp of the last button state change

uint16_t adcValue = 0;
SoftwareSerial mySerial(3, 4);  // 3-RX, 4-TX (For communication with Board 1)

void setup() {
  pinMode(LED_PIN, OUTPUT);
  pinMode(SWITCH_PIN, INPUT_PULLUP);
  mySerial.begin(9600);  // Initialize Software Serial communication
  Serial.begin(115200);  // Initialize Hardware Serial communication
}

void loop() {

  if (is_debounced_press(SWITCH_PIN)) {
    mySerial.write("T\n");  // Send command to toggle LED
  }

  // Receive brightness value from Master
  if (mySerial.available() >= 2) {

    uint8_t lowerByte = mySerial.read();  // Read the lower byte
    uint8_t upperByte = mySerial.read();  // Read the upper byte

    // Combine the two bytes into a 16-bit value
    uint16_t adcValue = (upperByte << 8) | lowerByte;

    // print received brightness value on serial monitor
    Serial.print("Received ADC Value: ");
    Serial.println(adcValue);

    //Map ADC value(0-1023)  to 0 to 255
    uint8_t brightness = adcValue / 4;
    if (previousValue != brightness) {
      analogWrite(LED_PIN, brightness);  // Adjust LED brightness
      previousValue = brightness;
    }
  }
}


// Checks if the button is pressed and debounced.

bool is_debounced_press(int button_pin) {
  int reading = digitalRead(button_pin);

  // If the button state has changed, reset the debounce timer
  if (reading != last_button_state) {
    last_debounce_time = millis();
  }
  last_button_state = reading;
  // If the button state is stable for more than 50 msec the debounce delay, update the state.
  if ((millis() - last_debounce_time) > DEBOUNCE_DELAY) {
    if (reading != current_button_state) {
      current_button_state = reading;


      if (current_button_state == 0) {
        return true;  // valid press detected
      }
    }
  }
  return false;  // No valid press detected
}

Code Explanation

Includes & Setup:

  • #include <SoftwareSerial.h>: Enables software serial communication.
  • SoftwareSerial mySerial(3, 4);: Sets up software serial communication on pins 3 (RX) & 4 (TX) for Boards.
  • mySerial.begin(9600);: Initializes software serial communication at 9600 baud rate.
  • Serial.begin(115200);: Initializes hardware serial for debugging at 115200 baud rate.


Board1 loop()

  • Read potentiometer ADC value.
  • If ( previousValue != potValue ) then only  mySerial.write(data_Byte); send upper and lower byte of potentiometer ADC value to the board1.
  • mySerial.available(): Checks where data is available from Board2 or not.
  • mySerial.readStringUntil('\n'); read the string “T” received from board1.
  • LED gets toggled after receiving the correct string and prints "LED is ON" OR “LED is OFF” on the serial monitor.

Board2 loop()

  • Receive Brightness
    • if (mySerial.available()>= 2): Checks for data from Board1.
    • mySerial.read();  Read upper and lower bytes received from board1.
    • uint8_t brightness = adcValue / 4; : It map the ADC value to 0 to 255.
    • analogWrite(LED_PIN, brightness);: Sets LED brightness.
  • Push Button Switch press detection:
    • is_debounced_press(int button_pin);  : Function checks whether the valid button is pressed or not. If a valid button press is detected it will return true.
  • Send Toggle Command
    • After detecting a valid button press mySerial.write("T\n");   will send toggle command to board1.

Output

Hardware Setup

Screen-Shot Of Output


 Video


 

Submit Your Solution