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

Делюсь опытом Зачем пользоваться костылем SoftSerial, когда у ESP8266 два аппаратных UART?

enjoynering

Well-known member
Бесит копипаста SoftSerial перекочевавшая с Arduino AVR на Arduino ESP8266. К AVR вопросов нет, там почти всегда один аппаратный UART и он занят bootloder-ом, поэтому без SoftSerial никак. Но зачем тащить кривой ногодрыг в проекты на ESP8266 с двумя аппаратными UART? Рассказываю как надо...

1. После старта ESP8266 Serial висит на UART0 подключенный к COM-USB мосту, пины GPIO01(TX)/GPIO03(RX)
2. Переключаем на сенсор (например MH-Z19) командой Serial.swap() висящий на втором UART2, пины GPIO15(TX)/GPIO13(RX)
3. На всякий случай чистим Serial буфер от мусора оставшегося от UART0 обмена, командой Serial.flush()
4. Передаем сообщения сенсору
5. Принимаем сообщение от сенсора ВО ВРЕМЕННУЮ ПЕРЕМЕННУЮ
6. Переключаем Serial назад на UART0 и чистим буфер от мусора оставшегося после обмена по UART2
7. Посылаем данные из временной переменной в COM-USB мост и на пины GPIO01(TX)/GPIO03(RX)
8. Переключаемся назад на сенсор и повторяем с п.3

На Arduino языке выглядит так:

Код:
Serial.begin(9600, SERIAL_8N1); //GPIO1 (TX) and GPIO3 (RX), 9600kbps, 8-bit data, no parity, 1-bit stop

//your brilliant code here

Serial.swap(); //GPIO15 (TX) and GPIO13 (RX)
Serial.flush(); //clear serial buffer

//your brilliant code here

Serial.swap(); //swap back to GPIO1 (TX) and GPIO3 (RX)
Serial.flush(); //clear serial buffer

//your brilliant code here
У платы WeMos D1 Mini UART2 висит на D8/TX и D7/RX
 

enjoynering

Well-known member
Народ немножко не вкурил. Поэтому дополню. У ESP8266 два полных аппаратных UART. Первый UART0 занят USB-COM мостом (для закачки прошивки и обмена с компьютером). Второй UART2 - абсолютно свободен. К AVR вопросов нет, там почти всегда один аппаратный UART и он занят USB-COM мостом и bootloder-ом, поэтому без SoftSerial никак. В ESP8266 Serial.swap() нужен для переключения между UART0 и UART2. Команда Serial.flush() нужна для очистки буфера - он один на оба UART и после переключения там может оставаться непрочитанная информация от предыдущего обмена. Если необходимости в обмене между ESP8266 и компьютером по COM порту нет, то «все эти переключения туда-обратно» не нужны. Достаточно одного вызова Serial.swap() после загрузки ESP8266 и весь Serial.print(), в том числе и встроенный debug от Arduino ESP8266 core, будет валится в UART2. А оно вам надо?
 

pvvx

Активный участник сообщества
Народ немножко не вкурил.
Народ уже "вкурил" давно, что:
UART мертв как средство связи в бытовом сегменте.
Что ESP8266 и прочие чипы, не содержащие встроенного USB контроллера для программирования, отладки и связи с компом мертвы.
UART не торчит ни у одного компа или прочего бытового хлама. Костыли, дозакупка всяких переходников и прочего для стыковки по UART ныне обходятся дороже.
Сам ESP8266 перешел в разряд антиквариата и для спорта у некромансеров - достать трупик из могилки и оживить... И ныне ещё запускают Linux на первых STM32 для прикола...
https://esp8266.ru/forum/threads/otpravka-pochty.4064/#post-69266
 

pvvx

Активный участник сообщества
А оно вам надо?
Поглумились 5 лет с ESP8089(ESP8266) и хватит. Для технического прогресса и активных народных тематик это очень большой срок. Обычно, по истечению со старта развития 3-х...5-ти лет любая активность "сообщества" в народных тематиках заканчивается. Остаются только некромансеры и приколисты, остальные уходят в более новые и популярные темы.
Всё, что вы написали про UART в ESP8266, известно ещё с 2015 года...
 

enjoynering

Well-known member
Понимаете в чем дело, я ни разу не программист. Зарабатываю на жизнь совсем другим ремеслом. Пописывание кода и пайка для меня хобби и с пособ уйти от стресса. Поэтому для меня Arduino самый быстрый и удобный вариант для отдыха. Я не хочу неделю курить мануалы на супер-пупер микропроцессор, чтоб помигать светодиодом и и предать Hello World по железному USB. Мне и UART-USB моста хватит. Но как перфекционист я люблю все делать правильно, без костылей. Работа другое дело, там знания пропорциональны заработной плате, потому там постоянно читаю, изучаю. Но эти знания никак не связаны с микроконтороллерами и программированием. Вас понимаю, но и вы нас поймите. У нас хоббистов и у вас профи(зарабатывающих на этом деньги) совсем разные задачи.
 

pvvx

Активный участник сообщества
У нас хоббистов и у вас профи(зарабатывающих на этом деньги) совсем разные задачи.
Я на народных тематиках не зарабатываю, а только трачу.
Тут всё гораздо проще - вы залезли в древнее устройство, не зная что описанная вами тема давно решена и описали её повторно. И так делают многие. Цели этого непонятны.
 

pvvx

Активный участник сообщества
Делюсь опытом (2020 год): На ESP8266 можно запустить Arduino!
 

exeland

Member
Я не хочу неделю курить мануалы на супер-пупер микропроцессор, чтоб помигать светодиодом и и предать Hello World по железному USB.
Ну вот поэтому и используют софтовый UART, чтоб не читая мануалы можно было повесить на любую ножку.
 

enjoynering

Well-known member
Для Serial.swap() не надо курить инструкцию неделю. Достаточно открыть официальный help на arduino esp8266 framework. У меня заняло 5 минут. Конечно копипастить куски чужого кода еще быстрее. Я тяп-ляп и в продакшн не могу. Всегда стараюсь задействовать переферию и оптимизировать код по максимуму. Поэтому чужими библиотеками почти не пользуюсь, пишу свои.

Когда я говорю "курить неделю" - это выглядит как-то так. И для Александра разворачивание environment обычно простая рутинная задача. Он программист и делает такие вещи регулярно. Но как видите даже он буксанул и курил день! У меня бы ушло неделю и не факт что я бы победил.
 

exeland

Member
Ну кому как удобно... Кому-то и ногодрыга хватает, кому-то свапать не понравиться постоянно. Если после вашего свапа возникнет прерывание с printf в теле что будет?
 

vidok

Member
Простите я новичок ,возможно чего то не понимаю, но мне интересно -- Serial.flush() Ожидает завершения передачи исходящих последовательных данных.
Serial.flush(); //clear serial buffer --- работу этой функции изменили?
 

CodeNameHawk

Moderator
Команда форума
так вроде в ESP8266 и сейчас функция flush() чистит буфер:
Так речь идёт о Serial.flush();
Код:
void HardwareSerial::flush()
{
    uint8_t bit_length = 0;
    if(!_uart || !uart_tx_enabled(_uart)) {
        return;
    }

    bit_length = uart_get_bit_length(_uart_nr); // data width, parity and stop
    uart_wait_tx_empty(_uart);
    //Workaround for a bug in serial not actually being finished yet
    //Wait for 8 data bits, 1 parity and 2 stop bits, just in case
    delayMicroseconds(bit_length * 1000000 / uart_get_baudrate(_uart) + 1);
}
Искать в https://github.com/esp8266/Arduino/blob/master/cores/esp8266/HardwareSerial.cpp
 

pvvx

Активный участник сообщества
Классная функция - uart_wait_tx_empty(_uart);
При 9600 не допускает работу WiFi на 0.3 секунды. 3 beacon-а... Гудбай все стандарты...
 

enjoynering

Well-known member
При 9600 не допускает работу WiFi на 0.3 секунды. 3 beacon-а... Гудбай все стандарты...
есть такая беда. но это беда всех молодых языков програмирования. дайте Arduino еще лет 10-15 и почистят.
 

CodeNameHawk

Moderator
Команда форума
есть такая беда
Это не беда, а просто особенность, которую надо учитывать.
На скорости 115200 время сокращается раз в десять, да и кто будет заполнять весь буфер данными и сразу ожидать опустошения буфера.
По идее обработка WiFi должна работать на прерываниях и не зависеть от основного цикла.
Может в есп32 так сделают, если в есп8266 нет.
 

pvvx

Активный участник сообщества
Это не беда, а просто особенность, которую надо учитывать.
Как и любую фичу, которых в ESP в каждой функции.
На скорости 115200 время сокращается раз в десять, да и кто будет заполнять весь буфер данными и сразу ожидать опустошения буфера.
Printf. Ранее же описано.
По идее обработка WiFi должна работать на прерываниях и не зависеть от основного цикла.
По идее нефиг брать глюкодром ESP, да с Arduino для чего-то рабочего...
В них только поиграть можно.
Может в есп32 так сделают, если в есп8266 нет.
Кто мешает это сделать самому, если так нужны эти глючные ESP?
Глючные по тому, что надо переписывать всё, включая сам чип :)
 
Сверху Снизу