• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе 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()
{

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