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

Баги/глюки/проблемы в каком-то конкретном примере из пакета Sming

anakod

Moderator
Команда форума
Стирание в spiffs на 16Mбайт Flash делать в цикле нельзя.
Можно ;)

UPD: "Обошел" глюк костылём корявой работы с регистрами.
Обнаружил второй интересный глюк: если модуль рестартует после прошивки с зажатым "ресетом", то I2C библиотека не может нормально "дергать" GPIO.
Как удалось обойти?

Я в последней версии (закомитил буквально день-два назад) убрал лишнюю оптимизацию для OneWire (она тут не нужна, т.к. в отличии от ардуины ESP и так очень быстрый), и теперь, надеюсь все должно работать без побочных эффектов.
 

pvvx

Активный участник сообщества
Если оно вызвано по таймеру или таску из ets_ru(), то нельзя. Меняй, не меняй стек.
У вас вписан собственный переключатель задач на прерываниях первого таймера? Тогда штатный ШИМ работать не будет.
Экспериментирую с ets_set_idle_cb() для выхода из ets_run() и запуска тасков и таймеров без переключения стека - пока полет нормальный :) https://github.com/pvvx/EspLua/blob/master/app/main/delay.c
Дикое подобие RTOS :)
task_delay_us(us) - это подобие delay() c запуском процессов SDK и снижением потребления в цикле ets_run() - там всё стоит на "waiti 0" = потребление в пару мА
Выход CPU из "waiti 0" только по прерыванию (или есть варинты со спец регистрами CPU свзянных со счетчиком тактов...). По тому надо заряжать таймер. Выхода из ets_run() нет - сделано через delay_end()
Процедура, назначенная в ets_set_idle_cb() вызывается в цикле ets_run() перед "waiti 0" после каждой обработки системных таблиц 'тасков' или программных таймеров. Если что-то "запущено" из таблиц таймеров, то обязано завершиться - иначе другие таймеры и т.д. больше не будут отрабатывать в ets_run()... Т.е. вызов из процедуры обработки таймера ets_run() приводит к остановке других системных процессов, запускаемых из ets_run()... приходиться перенаправлять выход из процедур таймера (это временное решение - затычка :) )... Вроде так.
Проще полностью переписать ets_run() и пропатчить SDK ( в ld удалить и написать свой код обработки таблиц post и таймеров - он короткий)
Весь бардак из-за (с) у RTOS, да на нем выходит много кода и короткий стек (!) для процессов...
И это решение не катит для многих задач.
WDT в новых SDK считает и обращения к 'таскам' (развели там целую таблицу флагов), кроме таймера и других процедур подтверждения WDT. По тому просто сбросить регистр WDT не катит. От этого в SDK 1.2.0 ввели
void system_soft_wdt_stop(void);
void system_soft_wdt_restart(void);

Перевел ets_run() из ROM-BIOS на СИ. Проверил с проектом - работает.
 
Последнее редактирование:

SamGold

New member
Подключил внешние I2C RTC часы DS1307 с батарейкой.
Также использовал вот эту библиотеку https://github.com/davidhbrown/RealTimeClockDS1307
На той же шине подключен I2C дисплей.

Обнаружился интересный глюк, время из часов читается через раз, вот так:
Код:
22:06:57
1F:7F:7F
22:07:01
1F:7F:7F
Если в промежутках между чтением времени что-то выводить на дисплей, то проблема исчезает.
Подскажите, в какую сторону копать?
 

anakod

Moderator
Команда форума
Уже обсуждалось, в первую очередь нужно проверить подтяжку, на 3V3 она отличается и может быть существенно меньше. Альтернативный вариант - программная часть, здесь стоит внимательно поверить код и инициализацию устройств.
 

SamGold

New member
Подтяжка на sda и scl- 4.7k к +5V. Питание DS1307: 5V.
Проблема обнаружилась в том, что DS1307 строго через 1 раз отвечает NACK.
Сделал вот такую заглушку для корректной работы:

Было:
Код:
  // Reset the register pointer
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.write((uint8_t) 0x00);
  Wire.endTransmission();
Стало:
Код:
  // Reset the register pointer
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.write((uint8_t) 0x00);
  if (Wire.endTransmission()==2){
        Wire.beginTransmission(DS1307_I2C_ADDRESS);
        Wire.write((uint8_t) 0x00);
        Wire.endTransmission();
    }
Причину NACK так и не установил, пробовал опрашивать DS1307 в 2 раза реже(1 раз в 6 сек.), не помогло.
 

anakod

Moderator
Команда форума
Может быть Вы что-то недочитываете первый раз? А может в endTransmission true/false передать.
 

SamGold

New member
Отловился баг после изучения даташита на часы. Согласно даташиту, нужно слать STOP после приема данных, в Wire.h это не работает.
Вот фикс Wire.h:

Было:
Код:
uint8_t TwoWire::requestFrom(int address, int quantity, bool sendStop /* = true*/)
{
    rxPos = 0;
    rxLen = 0;

    if (!master->start(((uint8_t)(address << 1)) | I2C_READ)) return 0; // received NACK on transmit of address

    for (int i = 0; i < quantity; i++)
        rxBuf[rxLen++] = master->read(sendStop && (quantity == i + 1));

        return quantity;
}
Стало:
Код:
uint8_t TwoWire::requestFrom(int address, int quantity, bool sendStop /* = true*/)
{
    rxPos = 0;
    rxLen = 0;

    if (!master->start(((uint8_t)(address << 1)) | I2C_READ)) return 0; // received NACK on transmit of address

    for (int i = 0; i < quantity; i++)
        rxBuf[rxLen++] = master->read(sendStop && (quantity == i + 1));

        if (sendStop) master->stop();
   
        return quantity;
}
Было бы неплохо добавить данный фикс в Sming, возможно даже стоит if (sendStop) вообще убрать.
Также в библиотеке DS1307 было заменено Wire.requestFrom(DS1307_I2C_ADDRESS, 8); на явное Wire.requestFrom(DS1307_I2C_ADDRESS, 8,true);
Теперь часы работают как часы :D
 

Данило

New member
Здравствуйте.
Вопрос по MQTT.
Подскажите в чем проблема: почему то не публикует сообщение без таймера, если просто вызвать метод.

Код:
void publishMessage(String text)
{
    if (mqtt.getConnectionState() != eTCS_Connected)
        startMqttClient(); // Auto reconnect

    Serial.println("Let's publish message now!");
    mqtt.publish("main/server",text);
}
и когда вызываю publishMessage("hello world"); , он не публикует и не принимае сообщение/
 

alexhi

Member
Здравствуйтe!
Не пойму как сменить адрес брокера MQTT значением из файла.

В самом начале примера MQTT_CLIENT HELLO есть объявление
MqttClient mqtt("test.mosquitto.org", 1883, onMessageReceived);
которое инициализируется при старте программы.
И если я в init() пытаюсь подставить другого брокера напр.,
BROKER = "iot.eclipce.org"; (которое беру из файла)
MqttClient mqtt(BROKER, 1883, onMessageReceived);
то программа уходит в ребут.
Как сделать смену брокера?
 
Последнее редактирование:

Dr. Morg

New member
В примере HttpServer_ConfigNetwork на OS X вылетает следущая ошибка при компиляции:
23:15:49 **** Build of configuration Sming for project HttpServer_ConfigNetwork ****

make all

C+ app/application.cpp

C+ /opt/sming/Sming/appinit/user_main.cpp

AR out/build/app_app.a

LD out/build/app.out

/opt/sming/Sming/compiler/lib//libsming.a(HttpServer.o):(.text._ZN10HttpServer13initWebSocketER20HttpServerConnectionR11HttpRequestR12HttpResponse+0x8): undefined reference to `vtable for WebSocket'

/opt/sming/Sming/compiler/lib//libsming.a(HttpServer.o):(.text._ZN10HttpServer13initWebSocketER20HttpServerConnectionR11HttpRequestR12HttpResponse+0xc): undefined reference to `WebSocket::WebSocket(HttpServerConnection*)'

/opt/sming/Sming/compiler/lib//libsming.a(HttpServer.o):(.text._ZN10HttpServer13initWebSocketER20HttpServerConnectionR11HttpRequestR12HttpResponse+0x10): undefined reference to `WebSocket::initialize(HttpRequest&, HttpResponse&)'

/opt/sming/Sming/compiler/lib//libsming.a(HttpServer.o):(.text._ZN10HttpServer13initWebSocketER20HttpServerConnectionR11HttpRequestR12HttpResponse+0x31): undefined reference to `WebSocket::WebSocket(HttpServerConnection*)'

/opt/sming/Sming/compiler/lib//libsming.a(HttpServer.o): In function `HttpServer::initWebSocket(HttpServerConnection&, HttpRequest&, HttpResponse&)':

C:\DEV\ESP8266\Sming\Sming/Wiring/WVector.h:47: undefined reference to `WebSocket::initialize(HttpRequest&, HttpResponse&)'

collect2: error: ld returned 1 exit status

make: *** [out/build/app.out] Error 1



23:15:50 Build Finished (took 1s.171ms)

Где он нашёл путь:
Код:
C:\DEV\ESP8266\Sming\Sming/Wiring/WVector.h:47: undefined reference to `WebSocket::initialize(HttpRequest&, HttpResponse&)'
Я так и не понял...
 

aliaksei

New member
Пытаюсь собрать HttpServer_ConfigNetwork. Пример собирается, но в браузер ругается что не найден файл.

Вставляем в OnIndex код и смотрим
Код:
    Vector<String> files = fileList();
    Serial.printf("filecount %d\r\n", files.count());
    for (unsigned int i = 0; i < files.count(); i++) {
        Serial.printf("%02x\r\n", files[i][0]);
        Serial.printf("%02x\r\n", files[i][1]);
        Serial.printf("%02x\r\n", files[i][2]);
        Serial.printf("%02x\r\n", files[i][3]);
        Serial.printf("%02x\r\n", files[i][4]);
        Serial.println(files[i]);
    }
Во-первых, неправильно считает число файлов. Во-вторых, где-то в собирателе spiffy.exe что-то не так.

Так собирает spiffy товарища https://github.com/xlfe/spiffy
2015-10-10-22-19-07.png
А так C:\Espressif\examples\nodemcu-spiffy\build\spiffy.exe
2015-10-10-22-26-45.png

В первом случае читается такое
2015-10-10-22-15-58.png
Во втором - просто 0x01

Вобщем или лыжи не едут или я.
 

aliaksei

New member
Проверил sizeof заголовков, оказалось они разные (spiffs_page_object_ix_header 0x2c на ESP и 0x2e на десктопе). Ситуация немного улучшается если из определения структур убрать __attribute(( packed ))
fileList при этом видит имя первого файла, но по-прежнему считает что файл один, new TemplateFileStream() файлы не видит.
 
Проверил sizeof заголовков, оказалось они разные (spiffs_page_object_ix_header 0x2c на ESP и 0x2e на десктопе). Ситуация немного улучшается если из определения структур убрать __attribute(( packed ))
fileList при этом видит имя первого файла, но по-прежнему считает что файл один, new TemplateFileStre
В sming/develop мноого фиксов касательно spiffs. Обновите сминг cd Sming/ && git fetch && git checkout develop && git pull && make && make spiffy и тогда пробуйте примеры требующие ФС. И еще - обратите внимание, что теперь spiffs НЕ МОНТИРУЕТСЯ автоматом, в init надо spiffs_mount(); добавить.
 

aliaksei

New member
Так определенно лучше. Сборка spiffy.exe из тех же исходников что использует Sming пошла на пользу. Теперь заголовки совпадают. ))
Ну и остальное тоже работает. Спасибо.
 

M-a-x-x

New member
В Debian не собиралась прошивка MeteoControl, ругался на spiffy. В "Makefile-user.mk" закомментировал последнюю строку "SPIFF_FILES = web" и все получилось.
Еще во всех примерах в файле "Makefile-user.mk" указано:
# MacOS / Linux
# SMING_HOME = /opt/sming/Sming
а нужно
# SMING_HOME = /opt/Sming/Sming

UPD. Надо было просто собрать командой "make" в каталоге opt/Sming/Sming/spiffy/ этот spiffy, комментировать ничего не нужно.
 
Последнее редактирование:

ghostaz

New member
Здравствуйте.
Помогите разобраться. Не компилируется пример Basic_Blink. Текст ошибки:
00:30:11 **** Build of configuration Sming for project Basic_Blink ****
make all
C+ app/application.cpp
AR out/build/app_app.a
LD out/build/app.out
c:/espressif/xtensa-lx106-elf/bin/../lib/gcc/xtensa-lx106-elf/5.1.0/../../../../xtensa-lx106-elf/bin/ld.exe: cannot find -lsming
collect2.exe: error: ld returned 1 exit status
make: *** [out/build/app.out] Error 1

00:30:16 Build Finished (took 4s.791ms)

Что я не так делаю?
 

Symrak

New member
ghostaz, открой как проект и скомпилируй Sming (для Windows он лежит в папке <диск установки>\tools\sming\Sming).
 

Symrak

New member
Уважаемые форумчане, помогите пожалуйста разобраться со следующим вопросом.

Есть проект с использованием кода и библиотек датчиков DHT22 и BMP180, LCD дисплея Nokia5110, а так же обращения к NTP серверу и получение данных с HTTP-сервера посредством GET-запроса и последующего разбора ответа с использованием HttpClient.

Работа с датчиками, дисплеем и NTP сервером успешно выполняется: модуль подключается к Wi-Fi, устанавливает соединение с сервером, получает данные с него, получает данные с датчиков и отображает их на дисплее.

При попытке добавить в существующую программу работу с HTTP (за образец брался голый код примера работы с ThingSpeak), модуль постоянно перезагружается со следующими сообщениями rst cause:1, boot mode:(3,6) или rst cause:1, boot mode:(3,7) (полный вариант – см. спойлеры):

1:06:54.293> ets Jan 8 2013,rst cause:1, boot mode:(3,6)
1:06:54.293> load 0x40100000, len 22264, room 16
1:06:54.293> tail 8
1:06:54.293> chksum 0x45
1:06:54.293> load 0x3ffe8000, len 856, room 0
1:06:54.293> tail 8
1:06:54.293> chksum 0x88
1:06:54.443> load 0x3ffe8358, len 4888, room 0
1:06:54.443> tail 8
1:06:54.443> chksum 0xf6
1:06:54.443> csum 0xf6
1:06:54.542> rlFatal exception (0):
1:06:54.542> epc1=0x4023c448, epc2=0x00000000, epc3=0x00000000, excvaddr=0x00000000, depc=0x00000000
1:05:04.343> ets Jan 8 2013,rst cause:1, boot mode:(3,7)
1:05:04.343> load 0x40100000, len 22264, room 16
1:05:04.343> tail 8
1:05:04.343> chksum 0x45
1:05:04.343> load 0x3ffe8000, len 856, room 0
1:05:04.343> tail 8
1:05:04.343> chksum 0x88
1:05:04.498> load 0x3ffe8358, len 4888, room 0
1:05:04.498> tail 8
1:05:04.498> chksum 0xf6
1:05:04.498> csum 0xf6
1:05:04.593> rlFatal exception (0):
1:05:04.593> epc1=0x4023c448, epc2=0x00000000, epc3=0x00000000, excvaddr=0x00000000, depc=0x00000000

При этом, отдельно взятый пример работы с ThingSpeak работает отлично.

Схема расположена на Breadboard.
Между Gnd и Vcc модуля стоят конденсаторы 0.1 uF и 470 uF.
Модуль запитывался как от USB-UART переходника с хорошим конвертером на 3.3 V, так и от модуля на AMS1117 – результат тот же. Подключение Li-Ion батареи эффекта на возимело.

Вставлял в код WDT.alive(), результат остался прежним.

P.S. Где можно найти мануал с описанием всех причин reset'ов с кодами? :)
 
Сверху Снизу