Logo

dev-resources.site

for different kinds of informations.

Master-Slave Communication Between Two Arduino Boards

Published at
7/31/2024
Categories
arduino
electronics
diyproject
tutorial
Author
akshay_jain
Author
11 person written this
akshay_jain
open
Master-Slave Communication Between Two Arduino Boards

In this project, we'll explore how to set up master-slave communication between two Arduino boards using UART communication.

Understanding Master-Slave Communication

In a master-slave communication setup between two Arduino boards, one board acts as the master, while the other functions as the slave.
The master board sends commands to the slave board to perform specific tasks, and the slave board carries out these operations and sends a response back to the master.

These tasks can include actions like turning on an LED, reading sensor values, or controlling the speed of a motor. While the master sends the commands, the slave processes them and executes the required tasks.
The communication between the master and slave is established using Serial UART Communication, which utilises three pins: Rx (Receive), Tx (Transmit), and GND (Ground).

In this project, the Master Arduino sends commands to the Slave Arduino through the Serial Tx Pin and receives responses from the Slave Arduino via the Serial Rx Pin.

The master will send the following commands:

  • Request the temperature reading from the Slave board.
  • Request the humidity reading from the Slave board.
  • Request the analog value read from the A0 input on the Slave board.
  • Turn the LED ON/OFF based on the analog input value.

Once the master receives all the responses, it will display the data on an LCD.

On the other side, the slave board listens for commands from the master and provides the appropriate response based on the command received.

Components Required

  • 2 Arduino UNO R3
  • 16 x 2 LCD
  • 2, 10 kΩ Potentiometer
  • 220 Ω Resistance
  • 2 Breadboards
  • Red LED
  • 100 Ω Resistance
  • Temperature Sensor
  • L293D
  • 104 pf Ceramic Capacitor
  • multiple Connecting Wires
  • 5V DC Motor
  • DC Fan
  • USB A/B cable

Circuit Diagram

Image description

Master Code

#include "master.h"
#define MOTOR_PIN 3
void setup() {
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  // set the cursor to (column = 0,row = 0)
  lcd.setCursor(0, 0);
  lcd.print("Master Slave");
  lcd.setCursor(0, 1);
  // set the cursor to (column = 0,row = 1)
  lcd.print("Demo");
  // provide delay of 2 second
  delay(300);
  //Initialize serial and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ;  // wait for serial port to connect. Needed for native USB
  }
  pinMode(MOTOR_PIN, OUTPUT);  // declare Motor pin to be an output
}
void loop() {
  getTempearture();
  getHumidity();
  getSpeed();
  setMotorSpeed();
  lcdUpdate();
}
void setMotorSpeed() {
  if (paramerters.Status[SPD_STA_INDX] == STATUS_OK) {
    analogWrite(MOTOR_PIN, map(paramerters.Speed,0,100,0,255));  // set the Speed of Motor
  }
}
// For temperture
// CMD : START_CHAR TEMP_CMD END_CHAR
// RESP: START_CHAR TEMP_RSP STATUS BYTE1 BYTE2 BYTE3 BYTE4 END_CHAR
void getTempearture() {
  float temp;
  float *ptemp = &temp;
  unsigned char cmdBuffer[3] = { START_CHAR, TEMP_CMD, END_CHAR };
  unsigned char rspBuffer[10] = { 0 };
  unsigned char rspIndex = 0;
  Serial.write(cmdBuffer, 3);
  while (Serial.available() == 0)
    ;
  do {
    rspBuffer[rspIndex++] = Serial.read();
    // this delay is provided because it takes approx 10 ms to receiev a new character at 9600 baurdrate
    delay(10);
  } while (Serial.available() != 0);
  if ((rspBuffer[0] == START_CHAR) && (rspBuffer[1] == TEMP_RSP) && (rspBuffer[7] == END_CHAR)) {
    if (rspBuffer[2] == STATUS_OK) {
      ptemp = (float *)(rspBuffer + 3);
      paramerters.Temperature = *ptemp;
    }
    paramerters.Status[TEM_STA_INDX] = rspBuffer[2];
  }
}
// For humidity
// CMD : START_CHAR HUMIDITY_CMD END_CHAR
// RESP: START_CHAR HUMIDITY_RSP STATUS BYTE1 BYTE2 BYTE3 BYTE4 END_CHAR
void getHumidity() {
  float hum;
  float *phum = &hum;
  unsigned char cmdBuffer[3] = { START_CHAR, HUMIDITY_CMD, END_CHAR };
  unsigned char rspBuffer[10] = { 0 };
  unsigned char rspIndex = 0;
  Serial.write(cmdBuffer, 3);
  while (Serial.available() == 0)
    ;
  do {
    rspBuffer[rspIndex++] = Serial.read();
    // this delay is provided because it takes approx 10 ms to receiev a new character at 9600 baurdrate
    delay(10);
  } while (Serial.available() != 0);
  if ((rspBuffer[0] == START_CHAR) && (rspBuffer[1] == HUMIDITY_RSP) && (rspBuffer[7] == END_CHAR)) {
    if (rspBuffer[2] == STATUS_OK) {
      phum = (float *)(rspBuffer + 3);
      paramerters.Humidity = *phum;
    }
    paramerters.Status[HUM_STA_INDX] = rspBuffer[2];
  }
}
// For speed
// CMD : START_CHAR SPEED_CMD END_CHAR
// RESP: START_CHAR SPEED_RSP STATUS BYTE1 END_CHAR
void getSpeed() {
  int spd;
  int *pspd = &spd;
  unsigned char cmdBuffer[3] = { START_CHAR, SPEED_CMD, END_CHAR };
  unsigned char rspBuffer[10] = { 0 };
  unsigned char rspIndex = 0;
  Serial.write(cmdBuffer, 3);
  while (Serial.available() == 0)
    ;
  do {
    rspBuffer[rspIndex++] = Serial.read();
    // this delay is provided because it takes approx 10 ms to receiev a new character at 9600 baurdrate
    delay(10);
  } while (Serial.available() != 0);
  if ((rspBuffer[0] == START_CHAR) && (rspBuffer[1] == SPEED_RSP) && (rspBuffer[5] == END_CHAR)) {
    if (rspBuffer[2] == STATUS_OK) {
      pspd = (int *)(rspBuffer + 3);
      paramerters.Speed = *pspd;
    }
    paramerters.Status[SPD_STA_INDX] = rspBuffer[2];
  }
  if (paramerters.Status[SPD_STA_INDX] == STATUS_OK) {
    if (paramerters.Speed >= 50) {
      //it indicates high speed
      setLEDON();
    } else {
      //it indicates low speed
      setLEDOff();
    }
  }
}
// For led ON
// CMD : START_CHAR LED_ON_CMD END_CHAR
// RESP: START_CHAR LED_ON_RSP STATUS END_CHAR
void setLEDON() {
  unsigned char cmdBuffer[3] = { START_CHAR, LED_ON_CMD, END_CHAR };
  unsigned char rspBuffer[10] = { 0 };
  unsigned char rspIndex = 0;
  Serial.write(cmdBuffer, 3);
  while (Serial.available() == 0);
  do {
    rspBuffer[rspIndex++] = Serial.read();
    // this delay is provided because it takes approx 10 ms to receiev a new character at 9600 baurdrate
    delay(10);
  } while (Serial.available() != 0);
  if ((rspBuffer[0] == START_CHAR) && (rspBuffer[1] == LED_ON_RSP) && (rspBuffer[3] == END_CHAR)) {
    if (rspBuffer[2] == STATUS_OK) {
      paramerters.Led_state = 1;
    }
    paramerters.Status[LED_STA_INDX] = rspBuffer[2];
  }
}
// For led OFF
// CMD : START_CHAR LED_OFF_CMD END_CHAR
// RESP: START_CHAR LED_OFF_RSP STATUS END_CHAR
void setLEDOff() {
  unsigned char cmdBuffer[3] = { START_CHAR, LED_OFF_CMD, END_CHAR };
  unsigned char rspBuffer[10] = { 0 };
  unsigned char rspIndex = 0;
  Serial.write(cmdBuffer, 3);
  while (Serial.available() == 0)
    ;
  do {
    rspBuffer[rspIndex++] = Serial.read();
    // this delay is provided because it takes approx 10 ms to receiev a new character at 9600 baurdrate
    delay(10);
  } while (Serial.available() != 0);
  if ((rspBuffer[0] == START_CHAR) && (rspBuffer[1] == LED_OFF_RSP) && (rspBuffer[3] == END_CHAR)) {
    if (rspBuffer[2] == STATUS_OK) {
      paramerters.Led_state = 0;
    }
    paramerters.Status[LED_STA_INDX] = rspBuffer[2];
  }
}
void lcdUpdate() {
  lcd.clear();
  // DisplaY Temperature
  // set the cursor to (column = 0,row = 0)
  lcd.setCursor(0, 0);
  lcd.print("Tem=");
  if (paramerters.Status[TEM_STA_INDX] == STATUS_OK) {
    lcd.print(paramerters.Temperature);
  } else {
    lcd.print("NOK");
  }
  // DisplaY LED Status
  lcd.print(" LED=");
  if (paramerters.Status[LED_STA_INDX] == STATUS_OK) {
    lcd.write(paramerters.Led_state | 0x30);
  } else {
    lcd.print("NOK");
  }
  // Display Humidity
  // set the cursor to (column = 0,row = 1)
  lcd.setCursor(0, 1);
  lcd.print("Hum=");
  if (paramerters.Status[HUM_STA_INDX] == STATUS_OK) {
    lcd.print(paramerters.Humidity);
  } else {
    lcd.print("NOK");
  }
  // Display Speed
  lcd.print(" SP=");
  if (paramerters.Status[HUM_STA_INDX] == STATUS_OK) {
    lcd.print(paramerters.Speed);
    lcd.print('%');
  } else {
    lcd.print("NOK");
  }
}
Enter fullscreen mode Exit fullscreen mode

Slave Code

#include "slave.h"
#define ALARM_LED 8
#define LED_ON 0
#define LED_OFF 1
char serialInput;
int dataIndex = 0;
char databuffer[10] = { 0 };
bool dataRcvd = false;  // whether the string receiving is completed.
unsigned char rspBuffer[10];
void setup() {
  Serial.begin(9600);          // initialize serial port
  dht.begin();                 // Initialize the DHT sensor
  pinMode(ALARM_LED, OUTPUT);  // Initialize alarm LED
  digitalWrite(ALARM_LED, LED_OFF);
}
void loop() {
  getTemphumidity();
  getSpeed();
  if (dataRcvd == true) {
    // Check for start and end character
    if ((databuffer[0] = START_CHAR) && (databuffer[2] = END_CHAR)) {
      // Check if its the temperature command
      // For temperture
      // CMD : START_CHAR TEMP_CMD END_CHAR
      // RESP: START_CHAR TEMP_RSP STATUS BYTE1 BYTE2 BYTE3 BYTE4 END_CHAR
      if (databuffer[1] == TEMP_CMD) {
        rspBuffer[0] = START_CHAR;
        rspBuffer[1] = TEMP_RSP;
        if (paramerters.Status[TEM_STA_INDX] == STATUS_OK) {
          rspBuffer[2] = STATUS_OK;
          memcpy((rspBuffer + 3), &(paramerters.Temperature), 4);
        } else {
          rspBuffer[2] = STATUS_NOT_OK;
          memset((rspBuffer + 3), 0x00, 4);
        }
        rspBuffer[7] = END_CHAR;
        Serial.write(rspBuffer, 8);
      }
      // Check if it is Humidity command
      // For humidity
      // CMD : START_CHAR HUMIDITY_CMD END_CHAR
      // RESP: START_CHAR HUMIDITY_RSP STATUS BYTE1 BYTE2 BYTE3 BYTE4 END_CHAR
      else if (databuffer[1] == HUMIDITY_CMD) {
        rspBuffer[0] = START_CHAR;
        rspBuffer[1] = HUMIDITY_RSP;
        if (paramerters.Status[HUM_STA_INDX] == STATUS_OK) {
          rspBuffer[2] = STATUS_OK;
          memcpy((rspBuffer + 3), &(paramerters.Humidity), 4);
        } else {
          rspBuffer[2] = STATUS_NOT_OK;
          memset((rspBuffer + 3), 0x00, 4);
        }
        rspBuffer[7] = END_CHAR;
        Serial.write(rspBuffer, 8);
      }
      // Check if it is Speed command
      // For speed
      // CMD : START_CHAR SPEED_CMD END_CHAR
      // RESP: START_CHAR SPEED_RSP STATUS BYTE1 END_CHAR
      else if (databuffer[1] == SPEED_CMD) {
        rspBuffer[0] = START_CHAR;
        rspBuffer[1] = SPEED_RSP;
        if (paramerters.Status[SPD_STA_INDX] == STATUS_OK) {
          rspBuffer[2] = STATUS_OK;
          memcpy((rspBuffer + 3), &(paramerters.Speed), 2);
        } else {
          rspBuffer[2] = STATUS_NOT_OK;
          memset((rspBuffer + 3), 0x00, 2);
        }
        rspBuffer[5] = END_CHAR;
        Serial.write(rspBuffer, 6);
      }
      // For led ON
      // CMD : START_CHAR LED_ON_CMD END_CHAR
      // RESP: START_CHAR LED_ON_RSP STATUS END_CHAR
      else if (databuffer[1] == LED_ON_CMD) {
        rspBuffer[0] = START_CHAR;
        rspBuffer[1] = LED_ON_RSP;
        digitalWrite(ALARM_LED, LED_ON);
        rspBuffer[2] = STATUS_OK;
        rspBuffer[3] = END_CHAR;
        Serial.write(rspBuffer, 4);
      }
      // For led OFF
      // CMD : START_CHAR LED_OFF_CMD END_CHAR
      // RESP: START_CHAR LED_OFF_RSP STATUS END_CHAR
      else if (databuffer[1] == LED_OFF_CMD) {
        rspBuffer[0] = START_CHAR;
        rspBuffer[1] = LED_OFF_RSP;
        digitalWrite(ALARM_LED, LED_OFF);
        rspBuffer[2] = STATUS_OK;
        rspBuffer[3] = END_CHAR;
        Serial.write(rspBuffer, 4);
      }
    }
    dataRcvd = false;
    memset(databuffer, 0x00, sizeof(databuffer));
  }
}
void getTemphumidity() {
  static unsigned long int previousTick = 0;
  static unsigned long int currentTick;
  float temperature;
  float humidity;
  currentTick = millis();
  if ((currentTick - previousTick) >= 100) {
    previousTick = currentTick;
    // Read temperature and humidity from the DHT sensor
    temperature = dht.readTemperature(false);
    humidity = dht.readHumidity();
    // Check if the sensor reading is valid (non-NaN)
    if (!isnan(temperature)) {
      paramerters.Temperature = temperature;
      paramerters.Status[TEM_STA_INDX] = STATUS_OK;
      // Serial.print("Temperature: ");
      // Serial.print(temperature);
    } else {
      paramerters.Status[TEM_STA_INDX] = STATUS_NOT_OK;
    }
    if (!isnan(humidity)) {
      paramerters.Humidity = humidity;
      paramerters.Status[HUM_STA_INDX] = STATUS_OK;
      // Serial.print(" °F, Humidity: ");
      // Serial.print(humidity);
      // Serial.println("%");
    } else {
      paramerters.Status[HUM_STA_INDX] = STATUS_NOT_OK;
    }
  }
}
void getSpeed() {
  int analogPin = A0;  // potentiometer wiper (middle terminal) is connected to analog pin 0
  int analogVal = 0;   // variable to store the value read
  analogVal = analogRead(analogPin);  // read the Analog input pin
  paramerters.Speed = map(analogVal, 0, 1023, 0, 100);
  paramerters.Status[SPD_STA_INDX] = STATUS_OK;
}
/*
  SerialEvent occurs whenever a new data comes in the hardware serial RX. This
  routine is run between each time loop() runs, so using delay inside loop can
  delay response. Multiple bytes of data may be available.
*/
void serialEvent() {
  while (Serial.available()) {
    // get the new byte:
    serialInput = Serial.read();
    databuffer[dataIndex++] = serialInput;
    // if the incoming character is a line feed character '\n', set a flag so the main loop can do something about it
    if (serialInput == END_CHAR) {
      dataRcvd = true;
      dataIndex = 0;
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

This project demonstrates how to implement master-slave communication between two Arduino boards using Serial UART Communication. By utilizing simple commands, the master board can control the slave board to perform various tasks and display the results on an LCD. For a detailed step-by-step guide, visit our blog post on Master-Slave Communication Between Two Arduino Boards.

Video

electronics Article's
30 articles in total
Favicon
AUIRS21814STR: Features, Specs & More
Favicon
Microgrid as a Service Market to Develop New Trend and Growth Story
Favicon
Troubleshooting Arduino Not Detected on COM Port in Windows
Favicon
Tech Helpr: Your Ultimate Destination for Gaming and Tech Products
Favicon
Biofeedback Instrument Market Share, Growth and Forecast by 2031
Favicon
Camera Accessories Market Regional Share, Trends, and Forecast by 2031
Favicon
Display Controller Market Size, Share and Forecast by 2031
Favicon
Emerging Trends in Automated Security Systems in Bangladesh
Favicon
The Rise of Automated Security Systems in Bangladesh: A New Era of Safety
Favicon
Shopping Way Pk
Favicon
Optimizing Workplace Safety with Addsoft’s Safety Training Kiosk and Secure PPE Lockers!
Favicon
Building the Micro Journal
Favicon
How Air Conditioner relay works
Favicon
Difference between firing and conduction angle of scr
Favicon
Embedded Systems 101: The Silent Powerhouses of Our Digital World
Favicon
Controlling a 28BYJ-48 Stepper Motor with Arduino: A Step-by-Step Guide
Favicon
Harnessing the Potential of Safety Training Kiosks: A Detailed Guide!
Favicon
Master-Slave Communication Between Two Arduino Boards
Favicon
Indirect Band Gap Semiconductor
Favicon
Understanding MicroPython: Python for Small Devices
Favicon
Afinal, o que são os 0's e 1's?
Favicon
Elevate Your Industrial Processes with Subhot Industrial Heater
Favicon
So Long Venerable Z80 and Thanks For All the Fish!
Favicon
Top Arduino Uno Projects for Beginners and Engineering Students
Favicon
Best Countries for Contract Electronics Manufacturing, Part 2: Malaysia, Thailand, Vietnam, and India
Favicon
Best Countries for Contract Electronics Manufacturing, Part 1: China, Taiwan, the USA, and Mexico
Favicon
Deep Drawn Components manufacturers
Favicon
Simple current load
Favicon
Exploring the Synergy of Robotics and Electronics: A Glimpse into the Future
Favicon
Navigating the Data-Driven Revolution: Big Data Analytics in Semiconductor and Electronics Market Trends

Featured ones: