Slow serial communication

hey guys, i have problem with my project. i'm using 2 arduino uno that communication with UART. but the respon is very slow. can someone help me to fixed this problem?

here the code

//MASTER
#include <DHT.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>  //library untuk LCD dengan I2C


//deklarasi pin
#define water A2
#define pompa_air 7
#define fan 5
#define IR 11
#define Touch 10
#define buzzer 12

LiquidCrystal_I2C lcd(0x27, 16, 2);
DHT dht(4, DHT11);  // deklarasi (pin, jenis DHT) pada DHT

void setup() {
  Serial.begin(57600);
  dht.begin();
  lcd.init();
  lcd.backlight();
  pinMode(water, INPUT);
  pinMode(IR, INPUT);
  pinMode(buzzer, OUTPUT);
  pinMode(pompa_air, OUTPUT);
  pinMode(fan, OUTPUT);
  pinMode(Touch, INPUT);
}

void loop() {
  
  int sensor_touch = digitalRead(Touch);             //membaca nilai sensor touch
  int sensor_IR = digitalRead(IR);                   //membaca nilai sensor infrared
  int sensor_water = analogRead(water);              // Membaca nilai analog water sensor
  float Level = map(sensor_water, 0, 1023, 0, 100);  // Konversi nilai water levelsensor ke persentase
  float t = dht.readTemperature();                   // Membaca nilai suhu DHT

  //lTampilan Pada LCD
  lcd.setCursor(0, 0);
  lcd.print("air:");
  lcd.print(Level);

  Serial.print("tinggi_Air :");
  Serial.println(Level);
  Serial.print("IR :");
  Serial.println(sensor_IR);
  Serial.print("Touch :");
  Serial.println(sensor_touch);
  Serial.print("suhu :");
  Serial.println(t);
  
  //KONDISI SENSOR WATER LEVEL
  if (Level < 30) {
    digitalWrite(pompa_air, HIGH);
  
  } else {
    digitalWrite(pompa_air, LOW);
  }

  //KONDISI SENSOR DHT
  if (t > 32.00) {
    digitalWrite(fan, LOW);
  } else {
    digitalWrite(fan, HIGH);
  }

  //KONDISI SENSOR TOUCH
  if (sensor_touch == HIGH) {
    Serial.write('A');
  }
  else
    Serial.write('a');

  //KONDISI SENSOR IR
  if (sensor_IR == HIGH) {
    Serial.write('B');
  } 
  else{
    Serial.write('b');
  }
  delay(500);
}
//SLAVE
#include <Servo.h>  //LIBRARY UNTUK MOTOR SERVO
Servo myServo1;     //DEKLARASI NAMA VARIABEL MOTOR SERVO1
Servo myServo2;     //DEKLARASI NAMA VARIABEL MOTOR SERVO2
char message;
int pos;

#include <HX711_ADC.h>
#include <LiquidCrystal_I2C.h>
#if defined(ESP8266) || defined(ESP32) || defined(AVR)
#include <EEPROM.h>
#endif
//pins:
const int HX711_dout = 8;  //mcu > HX711 dout pin
const int HX711_sck = 9;   //mcu > HX711 sck pin

//HX711 constructor:
HX711_ADC LoadCell(HX711_dout, HX711_sck);
const int calVal_eepromAdress = 0;
unsigned long t = 100;

#define buzzer 12
LiquidCrystal_I2C lcd(0x27, 16, 2);

void setup() {
  Serial.begin(57600);
  delay(10);
  lcd.init();
  lcd.backlight();
  Serial.println();
  Serial.println("Starting...");
  pinMode(buzzer, OUTPUT);
  myServo1.attach(3);  //DEKLARASI PIN MOTOR SERVO 1
  myServo2.attach(4);  //DEKLARASI PIN MOTOR SERVO 2
  LoadCell.begin();
  //LoadCell.setReverseOutput();  //uncomment to turn a negative output value to positive
  float calibrationValue;    // calibration value (see example file "Calibration.ino")
  calibrationValue = 696.0;  // uncomment this if you want to set the calibration value in the sketch
#if defined(ESP8266) || defined(ESP32)
  EEPROM.begin(512);  // uncomment this if you use ESP8266/ESP32 and want to fetch the calibration value from eeprom
#endif
  EEPROM.get(calVal_eepromAdress, calibrationValue);  // uncomment this if you want to fetch the calibration value from eeprom

  unsigned long stabilizingtime = 2000;  // preciscion right after power-up can be improved by adding a few seconds of stabilizing time
  boolean _tare = true;                  //set this to false if you don't want tare to be performed in the next step
  LoadCell.start(stabilizingtime, _tare);
  if (LoadCell.getTareTimeoutFlag()) {
    Serial.println("Timeout, check MCU>HX711 wiring and pin designations");
    while (1)
      ;
  } else {
    LoadCell.setCalFactor(calibrationValue);  // set calibration value (float)
    Serial.println("Startup is complete");
  }
}


void loop() {
  static boolean newDataReady = 0;
  const int serialPrintInterval = 1000;  //increase value to slow down serial print activity
  float i;




  // check for new data/start next conversion:
  if (LoadCell.update()) newDataReady = true;

  // get smoothed value from the dataset:
  if (newDataReady) {
    if (millis() > t + serialPrintInterval) {
      i = LoadCell.getData();
      Serial.print("Load_cell output val: ");
      Serial.println(i);
      newDataReady = 0;
      delay(20);
      t = millis();
    }
  }

  if (i < 30) {
      myServo1.write(180);
    } else {
      myServo1.write(0);
    }


  if (Serial.available() >= 0) {
    message = Serial.read();
    Serial.println(message);

    //MENJALANKAN INSTRUKSI ARDUINO MASTER UNTUK INPUT SENSOR TOUCH
    if (message == 'A') {
      myServo2.write(180);
    } else if (message == 'a') {
      myServo2.write(0);
    }

    //MENJALANKAN INSTRUKSI ARDUINO MASTER UNTUK INPUT SENSOR IR
    if (message == 'B') {
      digitalWrite(buzzer, LOW);

    } else if (message == 'b') {
      digitalWrite(buzzer, HIGH);
    }


  }
    delay(500);
}

Your topic has been moved; Please do not post in "Uncategorized"; see the sticky topics in Uncategorized - Arduino Forum.


Define very slow. Delays will not speed up your code :wink:

Having that call at the end of the loop function in both the master and slave sketches might contribute to slow responses.

so how much delay i give to my code?

A better question would be "what are you trying to accomplish with a delay() call, and could it be better accomplished using millis()"?

None.

Note:
Your use of millis() is slightly wrong. You should never use addition, you should use subtraction. The human brain does not have a problem with it but a microcontroller works differently.
Not solving your problem but change

if (millis() > t + serialPrintInterval) {

to

if (millis() -t > serialPrintInterval) {

PS
You might benefit from reading Robin's updated Serial Input Basics tutorial.

pelipur,

The code for both the Master and the Slave each have 500ms delays in them. That is likely to be the cause of the slow response.

I did some tests to determine how much effect each of the delays had on the overall performance.

Because I don't have all your hardware, I stripped out parts of your code, so that only the parts involving the serial communication remained.
When the slave received an 'A' or 'a', I modified the code to turn a pin high or low as that is easier to see on an oscilloscope trace than a servo signal changing.
I also turned on pullups on the two inputs used, so that they didn't float.

I ended up with the following code:
Master:

//MASTER
#define IR 7
#define Touch 12

void setup() {
  Serial.begin(57600);
  pinMode(IR, INPUT_PULLUP);
  pinMode(Touch, INPUT_PULLUP);
}

void loop() {

  int sensor_touch = digitalRead(Touch);
  int sensor_IR = digitalRead(IR);

  if (sensor_touch == HIGH) {
    Serial.write('A');
  }
  else {
    Serial.write('a');
  }

  if (sensor_IR == HIGH) {
    Serial.write('B');
  }
  else {
    Serial.write('b');
  }
  delay(500);  
}

Slave:


// SLAVE
char message;

#define buzzer 12
#define ledPin 13

void setup() {
  Serial.begin(57600);
}

void loop() {

  if (Serial.available() >= 0) {
    message = Serial.read();
    Serial.println(message);

    if (message == 'A') {
      digitalWrite(ledPin, HIGH);
    } else if (message == 'a') {
      digitalWrite(ledPin, LOW);
    }

    if (message == 'B') {
      digitalWrite(buzzer, HIGH);
    } else if (message == 'b') {
      digitalWrite(buzzer, LOW);
    }
  }
  delay(500);
}

I fed a 200mHz square wave signal from a function generator into the 'Touch' input, and used an oscilloscope to monitor the following signals:

  • Channel 1 - Yellow trace - 200mHz 'Touch' signal.
  • Channel 2 - Red trace - Serial.write() output.
  • Channel 3 - Blue trace - Slave output pin.

With both delays set to 500ms, to act as a reference, I obtained the following results:


It takes 1.48 seconds after the input changes state for the slave output to change state. The output has change after the third Serial.write() after the input changes (narrow low going pulses on the red trace may be difficult to see).

I then reduced the delays, one at a time.
Master delay reduced to 50ms, Slave delay 500ms:


Response time similar / slightly increased 1.61 seconds.

Master delay 500ms, Slave delay 50ms:


Response time 0.42 seconds. It can be seen that the output responds to the first serial output after the input changes state.

The fastest response I got by removing the delay from the Slave completely, and setting the delay in the master to 1ms.


Response time now less than 2ms.
Here I have turned the zoom on to show that the output changes after the first serial output that has changed from 'aB' to 'AB'.

Without that 1ms delay to separate the Serial.write()s, the serial output does not send correctly, and the Slave cannot decode it.

So it is the delay in the code for the Slave that has the greatest effect. I suggest you reduce it to zero.

None, I see no reason to have any in your code. What seems really fast to us mere humans is very slow to Arduino. When you see delay(someNumber); in Serial comms examples, it's usually to slow down the rate of Serial.print(something); in the Serial monitor for our convenience in terms of reading it with our slow eyes and brains.

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