Arduino Uno — ESP 8266: отправка AT-команд через код
Я купил ESP 8266 & Я могу отправлять AT-команды и получать ответ через последовательный монитор, когда загружаю пустой скетч. Я изменил скорость передачи данных с 115200 до 9600 с помощью AT+CIOBAUD=9600
и теперь могу выполнять AT-команды со скоростью 9600 бод.
Пустой скетч:
void setup()
{
}
void loop()
{
}
Вот как выглядит моя схема:
Проблема
Проблема в том, что когда я создаю собственный скетч для запуска AT-команд, он не работает. Вот как выглядит мой скетч:
#include <SoftwareSerial.h>
SoftwareSerial esp8266(0,1); //RX, TX
void setup()
{
Serial.begin(9600);
esp8266.begin(9600);
Serial.println("Run AT Command");
esp8266.print("AT\r\n");
}
void loop(){
String response = "";
while(esp8266.available()) {
char c = esp8266.read();
response+=c;
Serial.print(c);
}
if(response != ""){
Serial.println(response);
}
}
ESP8266 получает 3,3 В, но я прочитал, что TX и RX отправляют 5 В, и они также должны быть 3,3 В. Не знаю, из-за этого ли это, но я могу запускать AT-команды на пустом скетче, так что это немного странно.
ОБНОВЛЕНИЕ:
Мой скетч:
#include <SoftwareSerial.h>
SoftwareSerial esp8266(2, 3); //RX, TX
void setup()
{
Serial.begin(9600);
esp8266.begin(9600);
esp8266.print("AT\r\n");
}
void loop() {
String response = "";
while (esp8266.available()) {
char c = esp8266.read();
response += c;
}
if (response != "") {
Serial.println("Response: " + response);
}
}
Последовательный монитор показывает следующее:
Response: A
Response: T
OK
Response:
ВЫВОД при запуске команды AT+CIFSR:
Response: A
Response: T+CIFSR
Response:
+CIFSR:APIP
Response: ,"192.168.4.1
Response: "
+CIFSR:APMA
Response: C,"5e:cf:7f:80
Response: :f7:74"
OK
Теперь возникает вопрос: как сохранить строку, возвращаемую из файла esp8266. Я думал, что моя строка ответа должна хранить «ОК», но этого не произошло.
@Java Gamer, 👍1
Обсуждение3 ответа
Конечно, вы не можете использовать одни и те же контакты для аппаратного и программного серийного номера, но эта часть, похоже, решена в комментариях.
Теперь возникает вопрос: как сохранить строку, возвращаемую из файла esp8266. Я думал, что моя строка ответа должна хранить «ОК», но этого не произошло.
while (esp8266.available()) {
char c = esp8266.read();
response += c;
}
Это будет считываться только до тех пор, пока доступны символы, но ATmega может запускать этот цикл намного быстрее, чем принимаются символы, поэтому, если все сообщение не было ранее передано, оно, скорее всего, получит только один или два символа до того, как будут получены символы. приемный буфер оказывается (временно) пустым и прекращает работу.
Вместо этого следует читать до тех пор, пока не будет найдено завершающее условие, например символ новой строки. В целях безопасности вы также можете установить тайм-аут "сдаться и попробовать еще раз", но сделать его долгим.
Некоторые пытаются решить эту проблему, вставляя короткие задержки перед попыткой чтения, но это неразумно — зависимость от задержек создает ненадежность, поскольку необходимая задержка может легко измениться из-за условий, которые на первый взгляд могут показаться маловажными, например, esp866 может реагировать медленнее, если он видит много широковещательного трафика в сети или если меняется версия прошивки.
Есть еще одна техника, которую вы можете использовать вместо того, чтобы ждать новых символов от ESP8266. Ваш код начинается:
void loop() {
String response = "";
while (esp8266.available()) {
char c = esp8266.read();
response += c;
} // while
Это приводит к созданию новой String
каждый раз, когда вводится loop()
, и в ней накапливаются данные от ESP8266, но они теряются, если вы выйти из loop()
. Так что, возможно, лучше сделать это по-другому:
const char EOL = '\n'; // Конец линии
String response = ""; // Создаем строку один раз, вне цикла()
void loop() {
char c = '\0'; // Инициализация в NUL
while (esp8266.available() && c!=EOL) { // Ожидание конца строки
c = esp8266.read();
response += c;
} // пока
if (c==EOL) {
Serial.print("Response: "); // Не используйте '+', если можете!!!
Serial.println(response);
// Делаем другую обработку
response = ""; // Очистить ответ для следующей строки
} // если
Это имеет три эффекта:
- Он сохраняет неполный
ответ
между вызовамиloop()
. - Он обрабатывает
ответ
только после считывания конца строки. - Он обеспечивает правильную работу
loop()
(что важно для других Arduino), а не зависание.
Просто проверьте, помогает ли этот ответ. Вот в чем дело: для AT-команд с последовательного монитора RX или Arduino должны быть подключены к RX ESP, а TX Arduino к TX ESP. Вот почему вы можете вводить AT-команды с вашей схемой, когда загружается пустая программа.
Теперь, чтобы Arduino могла обмениваться данными с ESP с помощью программы, вам необходимо подключить RX Arduino к TX ESP и TX Arduino к RX ESP. В вашем случае при использовании программного последовательного порта 2 & 3, затем контакт 2 к TX Esp и контакт 3 к RX ESP.
Чтобы прочитать "ОК" из ESP, попробуйте следующий код:
if(esp8266.find("OK"))
Также вы можете попробовать прочитать этот код:
esp8266.find("pin="); // это действует как указатель.
int value = esp8266.read(); //возвращает код ASCII. это будет читать значение, которое идет после pin=
Ссылка: https://www.arduino.cc/en/Serial/read
- AT-команда не отвечает на последовательный монитор
- Отправка данных Arduino в MySQL с помощью phpMyAdmin и XAMPP на Windows10
- Arduino выводит значения мусора на serial monitor с ESP8266
- ошибка: espcomm_upload_mem failed при загрузке скетча
- фатальная ошибка ESP8266WiFi.h: Такого файла или каталога нет
- Как подключить Wi-Fi Shield ESP-12E-ESP8266-UART-WIFI-Wireless-Shield к Arduino
- Получить данные с сайта с помощью ESP8266 с помощью AT-команд
- Захват изображений с OV7670 (без FIFO) с использованием Arduino Uno?
Почему вы используете программный последовательный порт?, @PhillyNJ
Потому что большинство примеров, которые я видел, использовали их, @Java Gamer
Хорошо, имеет смысл. Я обычно использую Mega с Serial и Serial 2. Согласно вашей диаграмме frizting, похоже, что у вас поменялись местами RX и TX., @PhillyNJ
Я пытался изменить TX на RX и RX на TX в Arduino, но когда я это делаю, я не получаю ответа от AT-команд на последовательном мониторе., @Java Gamer
Если вы используете Uno, как на изображении, используйте другие контакты для software serial, например 2,3. Подключите контакт 2 к ESP TX и контакт 3 к ESP RX. В вашем коде попробуйте SoftwareSerial(2,3);, @SoreDakeNoKoto
На самом деле это сработало, спасибо. Я получил нормальный ответ. Но кажется, что моя «строка ответа» на самом деле не является строкой, возвращаемой ESP8266. Я обновил свой основной вопрос. Пожалуйста, проверьте это, @Java Gamer
Вы перегружаете приемный контакт ESP, подключаясь к 5-вольтовому передатчику. Хотя это вряд ли будет источником вашей проблемы, это повредит ESP. (Передающая сторона ESP в порядке, потому что приемник Arduino по-прежнему будет видеть ВЫСОКОЕ напряжение 3,3 В.) Вы должны поместить делитель напряжения на приемный контакт: Ardu Tx ----- 1 кОм ---- ESP Rx ---- - 2кОм ----- Земля, @JRobert
Я понял вашу мысль, не могли бы вы показать на диаграмме, мне будет намного проще., @Java Gamer