0

I am working on a project contains :

  1. ESP8266 as a WebServer that has a dashboard on web browser to control 8 relays connected to arduino.
  2. arduino uno board to control relays based on commands come from ESP8266 via TX/RX.

I am looking for an Arduino code to make communication between Arduino Uno and ESP8266 via UART to send commands from ESP to arduino.

(EX : sending 'A' means realy1 on, sending 'B' mean relay1 off, and so on..).

6
  • 2
    and where is the problem? – Juraj Jun 6 at 9:02
  • 2
    You send a letter on ESP when something needs to be done, and make the Arduino wait letters and perform actions based on received letters. – Justme Jun 6 at 9:04
  • @Juraj I type (Serial.write('A');) in loop <ESP code>, in Arduino code must to print(relay1 on) on serial monitor, but the problem is when I press on relay1 on button on the server's webpage , multiple strings printed on arduino's serial monitor(ex: relay 8 on relay 7 off relay 7 off), do I have to clear serial buffer every time I receive string? – Basel Jun 6 at 9:54
  • 4
    Maybe if you were to show us your code and your wiring we might have a clue what you are talking about. Until then, we can't help you. – Majenko Jun 6 at 11:40
  • One or both sides isn't maintaining state. If you continuously write "A" in a loop the Arduino will continuously read "A"--that's what loop does; it loops. – Dave Newton Jun 6 at 13:01
1

Are you sure you need two microcontrollers for your project? I guess only one of them would be enough. I would keep the ESP8266 because of the web server.

If you want to keep the two microcontrollers, you need to wire ESP Tx to UNO Rx pin. Do not connect the ESP Rx to the UNO Tx, because ESP works under 3.3.V and UNO under 5V. So it is OK for the ESP to send 3.3 V to the UNO, but the opposite would fuse your ESP. If you need this connection, use a logic-level shifter.

Now let’s see how to do a simple program that takes input from the serial bus. The idea is to use an event so that you don’t need to poll the serial bus all the time. The Arduino framework allows you to monitor the incoming bytes with the serialEvent function. Boards that have multiple hardware serial also have multiple serialEvent (serialEvent1, serialEvent2 or serialEvent3). Not all boards support serialEvent, so if it is your case you will need to use the polling technique, i.e. you check the presence of incoming bytes as fast as the microcontroller can do it in the main loop. For that you need to uncomment the first line of the loop. But on a regular UNO board, it should work.

When the serial event is triggered, the serialEvent() function checks if bytes are really available, then check that the letters received are A B or C and if so, it stores the letter received in the COMMAND global variable.

Then, in the main loop, the test if (COMMAND > 0) will be true, and the command can be executed. The COMMAND variable is then set to 0 so that the command is not executed twice.

See also https://www.arduino.cc/reference/en/language/functions/communication/serial/serialevent/

char COMMAND = 0;

/**
 *
 */
void fastBlink()
{
    for (int cnt = 0; cnt < 10; cnt++)
    {
        digitalWrite(LED_BUILTIN, LOW);
        delay(45);
        digitalWrite(LED_BUILTIN, HIGH);
        delay(5);
    }
}

/**
 *
 */
void serialEvent()
{
    while (Serial.available())
    {
        char inChar = (char)Serial.read();

        if (inChar == '\n' ||
            inChar == '\r')
        {
            Serial.flush();
            break;
        }
        else if (inChar == 'A' ||
                 inChar == 'B' ||
                 inChar == 'C')
        {
            COMMAND = inChar;
        }
    }
}

/**
 *
 */
void commandA()
{
    Serial.println("Executing command A");
    fastBlink();
}

/**
 *
 */
void commandB()
{
    Serial.println("Executing command B");
    fastBlink();
}

/**
 *
 */
void setup()
{
    Serial.begin(9600);
    Serial.println("\nSTART");

    pinMode(LED_BUILTIN, OUTPUT);
    fastBlink();
}

/**
 *
 */
void loop()
{
    // serialEvent(); // Uncomment this line if the program doesn’t work.
    // yield(); // Uncomment this if the program runs on the ESP8266. Without this command, the ESP will freeze if the loop is too fast.
    if (COMMAND > 0)
    {
        Serial.print("COMMAND = ");
        Serial.println(COMMAND);
        if (COMMAND == 'A')
            commandA();
        else if (COMMAND == 'B')
            commandB();
        COMMAND = 0;
    }
}
1
  • thank you, problem solved – Basel Jun 7 at 9:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.