Как связаться между Arduino Uno и ESP8266 через последовательные порты TX/RX?

Я работаю над проектом, который содержит :

  1. ESP8266 как веб-сервер, который имеет панель мониторинга в веб-браузере для управления 8 реле, подключенными к arduino.
  2. плата arduino uno для управления реле на основе команд поступает от ESP8266 через TX/RX.

Я ищу код Arduino для связи между Arduino Uno и ESP8266 через UART для отправки команд из ESP в arduino.

(НАПРИМЕР : отправка "A" означает включение realy1, отправка "B" означает выключение relay1 и так далее...).

, 👍0

Обсуждение

и в чем же проблема?, @Juraj

Может быть, если бы вы показали нам свой код и проводку, мы бы поняли, о чем вы говорите. До тех пор мы не можем вам помочь., @Majenko

Одна или обе стороны не поддерживают состояние. Если вы постоянно пишете"A" в цикле, Arduino будет постоянно читать"A"-это то, что делает "loop"; он зацикливается., @Dave Newton

Вместо этого рассмотрите возможность использования синхронного i2c или SPI. Есть причина, по которой большинство внутриплатных коммуникаций не используют асинхронные последовательные протоколы., @st2000


1 ответ


0

Вы уверены, что вам нужны два микроконтроллера для вашего проекта? Думаю, только одного из них будет достаточно. Я бы сохранил ESP8266 из-за веб-сервера.

Если вы хотите сохранить два микроконтроллера, вам нужно подключить ESP Tx к контакту UNO Rx. Не подключайте ESP Rx к UNO Tx, так как ESP работает под напряжением 3.3 В, а UNO-под напряжением 5 В. Таким образом, ESP может посылать 3,3 В в UNO, но обратное приведет к взрыву вашего ESP. Если вам нужно это соединение, используйте шифтер логического уровня.

Теперь давайте посмотрим, как сделать простую программу, которая принимает входные данные с последовательной шины. Идея состоит в том, чтобы использовать событие, чтобы вам не нужно было постоянно опрашивать последовательную шину. Фреймворк Arduino позволяет отслеживать входящие байты с помощью функции serialEvent. Платы с несколькими аппаратными последовательностями также имеют несколько serialEvent (serialEvent1, serialEvent2 или serialEvent3). Не все платы поддерживают serialEvent, поэтому в вашем случае вам нужно будет использовать метод опроса, то есть вы проверяете наличие входящих байтов так быстро, как это может сделать микроконтроллер в основном цикле. Для этого вам нужно раскомментировать первую строку цикла. Но на обычной плате Uno это должно сработать.

При срабатывании последовательного события функция serialEvent() проверяет, действительно ли доступны байты, затем проверяет, что полученные буквы являются A B или C, и если да, то сохраняет полученную букву в глобальной переменной КОМАНДЫ.

Затем, в основном цикле, тест if (COMMAND > 0) будет истинным, и команда может быть выполнена. Затем переменная COMMAND устанавливается в 0, чтобы команда не выполнялась дважды.

См. также 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;
    }
}
,

спасибо, проблема решена, @Basel