• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

ESP + Leonardo: почти заработало. Почти.

andreuccio

New member
Я совсем новичок в Arduino и программируемых микроконтроллерах, буквально неделю назад подарил сыну Матрешку Z, а позав чера получил и набор для собственного проекта.
Хотелось бы сделать индикатор погоды с подключением по WiFi,
Для этого я запасся ES8266 и Iskra Neo (аналог Arduino Leonardi). Подключил в точности вот так как здесь:http://microcontrollerelectronics.com/esp8266-wi-fi-module-revisited/ : питание 3.3в с микроконтроллера, TX и RX выводы WiFi модуля соединил с TX-RX выводами ардуино.
И, о, чудо - все заработало со следующим кодом, которые занимается в основном тем что перебрасывает данные с виртуального последовательного порта от компьютера на последовательный порт к ESP.
Код:
#define SSID "xxx"
#define PASS "xxx"

void setup() {

  Serial.begin(9600); //виртуальный порт по usb
  Serial1.begin(115200); // tx-rx порты к ES8266
  Serial1.println("AT+RST"); // Сброс ES8266
  delay(5000); while (Serial1.available()) Serial.write(Serial1.read()); // Выводим все что в буфере

  Serial1.println("AT+CWMODE=1"); // Устанавливаем режим станции
  delay(5000);while (Serial1.available()) Serial.write(Serial1.read());  // Выводим все что в буфере

  String cmd = "AT+CWJAP=\"";  cmd += SSID;   cmd += "\",\"";  cmd += PASS;   cmd += "\"";
  Serial1.println(cmd); // Подключаемся к WiFi

  delay(5000);  while (Serial1.available()) Serial.write(Serial1.read()); // Выводим все что в буфере

  Serial1.println("AT+CIPMUX=0"); // Singe connection

  delay(5000); while (Serial1.available()) Serial.write(Serial1.read()); // Выводим все что в буфере

  cmd = "AT+CIPSTART=\"TCP\",\"";
  cmd += "api.openweathermap.org";
  cmd += "\",80";
  Serial1.println(cmd); // Устанавливаем TCP соединение

  delay(5000);while (Serial1.available()) Serial.write(Serial1.read()); // Выводим все что в буфере

  cmd = "GET /data/2.5/weather?id=520555&mode=json&units=metric&appid=5193f5758dae77df9266ea9817ba3efc";
  cmd += " HTTP/1.1\r\nHost: api.openweathermap.org\r\n\r\n";

  Serial1.print("AT+CIPSEND=");
  Serial1.println(cmd.length()); // Готовим GET запрос

delay(5000);
if (Serial1.find(">"))
  {
    Serial.print(">");
    Serial.print(cmd);
    Serial1.print(cmd); //Посылаем GET-запрос
  }
  else
  {
    Serial.println("Сonnection timeout");
  }

  delay(1000);

  Serial.println("Amount of data in Serial1 buffer");
  Serial.print(Serial1.available());

  delay(5000);    while (Serial1.available()) Serial.write(Serial1.read());  // Выводим все что в буфере
  Serial1.println("AT+CIPCLOSE");
  delay(5000); while (Serial1.available()) Serial.write(Serial1.read());
  Serial1.println("AT+CWQAP"); // If you like disconnect AP, uncomment this line
  delay(5000); while (Serial1.available()) Serial.write(Serial1.read());
    }
void loop()
{
}

Модуль исправно подключался к WiFi, выводил список аксесс пойнтов, устанавливал TCP соединение. Но вот собственно с целью работы - получения погодных данных с сервера у меня не заладилось.
Данные куда-то пропадают из буфера.
Вот принт монитора порта:
Код:
AT+RST

OK

ets Jan  8 2013,rst cause:2, boot mode:(3,7)
AT+CWMODE=1

OK
AT+CWJAP="xxxx","xxxx"

WIFI DISCONNECT
WIFI CONNECTED
AT+CIPMUX=0

busy p...

OK
AT+CIPSTART="TCP","api.openweathermap.org",80

CONNECT

OK
>GET /data/2.5/weather?id=520555&mode=json&units=metric&appid=5193f5758dae77df9266ea9817ba3efc HTTP/1.1
Host: api.openweathermap.org

Amount of data in Serial1 buffer
63
Recv 136 bytes

SEND OK

+IPD,803:HTTP/1.1 200 OK
ServeAT+CIPCLOSE

CLOSED

OK
AT+CWQAP

OK
WIFI DISCONNECT

Видно что соединение устанавливается исправно, и даже HTTP запрос выдает код 200 - OK
но вот данные переданные в ответе куда-то пропали.

Что я делаю не так? Допускаю что ошибка совсем глупая, но хотелось бы понять в чем дело.?

Прошивка не самая новая, но и не сильно устаревшая.
AT+GMR AT version:0.25.0.0(Jun 5 2015 16:27:16)
SDK version:1.1.1
Ai-Thinker Technology Co. Ltd.
Jun 23 2015 23:23:50
 
Последнее редактирование:

Victor

Administrator
Команда форума
Что я делаю не так? Допускаю что ошибка совсем глупая, но хотелось бы понять в чем дело.?
хардварный буфер Serial1 всего 64 байта - он переполняется, пока вы ждете 5 секунд.
Вот кусок данных длиной как раз 63 байта (с учетом CR+LF), который вы и получаете
Код:
Recv 136 bytes
SEND OK
+IPD,803:HTTP/1.1 200 OK
Serve
 

andreuccio

New member
хардварный буфер Serial1 всего 64 байта - он переполняется, пока вы ждете 5 секунд.
Что-то в этом есть, конечно. Но пока что ни подбором или убиранием задержек, ни считыванием в предварительно инициализированный буфер вместо передачи порт-порт мне ничего исправить не удалось.
Самое необъяснимое то что если в коде после установления tcp поставить просто трансляцию с одного порта на другой в цикле, и вручную набрать AT+CIPSEND и данные (можно копипастой) - то response выдается не обрезанным.
 

fandy

Member
Вместо delay(1000);

поставьте что-то типа:
unsigned long time=millis();
time += 5000;
do{
if(Serial1.available())
Serial.write(Serial1.read());
}
while(millis()<time);
 

andreuccio

New member
Вместо delay(1000);
поставьте что-то типа:unsigned long time=millis();
Спасибо, красивое решение. Проблема снята, и она была не одна. Как оказалось и сервер иногда забывал отвечать и это лечилось установкой упрощенного режима передачи AT+CIPMODE=1.
Ну и не обошлось без приключений:
- утром пришла гениальная идея выровнять скорости обоих портов
- командой AT+IPR чип благополучно закирпичился и перестал работать.
- побежал в магазин за usb2serial ftl конвертером
- с ним чип отказался перепрошиваться
- в процессе возни обнаружилось что при сбросе ES8266 в порт идет мессага про нелицензионный нераспознаваемый девайс
- оказалось что драйвера USB2SERIAL которые винда ставит по умолчанию не любят дешевые китайские микросхемы и блокируют их
- поменял драйвера
- перепрошил, ура
- поигрался напрямую по интерфейсу, выяснилось что и тут не все гладко
- выяснил про волшшебную команду AT+CIPMODE
- подключил через ардуину, переписал программу.
- заработало.

окончательный код
Код:
#define SSID "xx"
#define PASS "xxx"

#define TIMEOUT 5000
#define BAUDRATE 9600
#define SERVERREQ "GET http://api.openweathermap.org/data/2.5/weather?id=520555&mode=json&units=metric&appid=5193f5758dae77df9266ea9817ba3efc"
#define SERVER "api.openweathermap.org"
#define OK "OK"


void setup() {

  boolean status;
  String cmd;

  Serial.begin(BAUDRATE);
  Serial1.begin(BAUDRATE);
  Serial1.setTimeout(TIMEOUT);

delay(10000);
  Serial.println("\nReset\n");

  Serial1.println("AT+RST");
  Serial1.find(OK);

  Serial.println("\nConnecting WiFi\n");
  cmd = "AT+CWJAP=\"";  cmd += SSID;   cmd += "\",\"";  cmd += PASS;   cmd += "\"";

  Serial1.println(cmd);
  status = Serial1.find(OK);

if (status) {
    Serial.println("\n WiFi Connecttion success!\n");
  }

  Serial1.println("AT+CIPMODE=1"); // Unvarnished mode, magic line!
  Serial1.find(OK);

  Serial.println("\nTCP start\n");
  cmd = "AT+CIPSTART=\"TCP\",\""; cmd += SERVER; cmd += "\",80";
  Serial1.println(cmd);
  status = Serial1.find(OK);

Serial.println(status);
  if (status) {
    Serial.println("\n TCP linking success!\n");
  }

  Serial.println("\nGET request\n");
  Serial1.println("AT+CIPSEND");
  status = Serial1.find(">");

Serial1.println(SERVERREQ);
Serial1.println("\r\n\r\n");

unsigned long tim = millis();
tim += 5000;
do{
if(Serial1.available())
Serial.write(Serial1.read());
}
while(millis()<tim);


//  Serial1.println("AT+CIPCLOSE");
// Serial1.println("AT+CWQAP");
}


void loop()
{

}
 
Сверху Снизу