Скрыть объявление
На нашем форуме недоступен просмотр изображений для неавторизованных пользователей. Если Вы уже зарегистрированы на нашем форуме, то можете войти. Если у Вас еще нет аккаунта, мы будем рады, если Вы к нам присоединитесь. Зарегистрироваться Вы можете здесь.

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

Тема в разделе "Sming Open Source Framework", создана пользователем JustACat, 23 мар 2015.

  1. Nikita

    Nikita Читатель

    Сообщения:
    21
    Симпатии:
    5
    Добрый день!

    Проблема с WDT. Пример Temperature_DS1820. С самим примером все более менее корректно, он выполняется один раз, выбирает первый датчик, выводит температуру с него. В случае если датчиков несколько модифицировал пример так, чтобы выводилась информация не с одного а с нескольких датчиков по таймеру и за один раз. В моем случае имею 3 подключенных датчика. Столкнулся с проблемой, приложение вылетает по wdt reset, уже после чтения данных со второго датчика. Каждая итерация и правда выполняется долго, там задержка на 1 сек перед чтением каждого датчика. В случае, если за одну итерации выполняется чтение только одного датчика, в моем случае 1 - 1, 2 - 2, 3 - 3, 4 -1, и т.д. то проблем нет, все работает. Пожалуйста, подскажите, есть ли варианты решения проблемы с WDT кроме отключения его или разнесения выполнения чтения датчиков DS18B20 в разные итерации?

    PS Не уверен, что выбрал правильную тему, прошу модераторов перенести вопрос в правильную, если не прав.
    Система: Mac OS, устанавливал по инструкции пару недель назад, после этого обновлял только примеры.

    *** Updated ***
    Отвечу на свой вопрос сам, помогли расставленные в коде WDT.alive().
     
    Последнее редактирование: 28 май 2015
  2. Nikita

    Nikita Читатель

    Сообщения:
    21
    Симпатии:
    5
    Пример Pressure_BMP180. Работает, но не понятно, как выбрать другие контакты для I2C? Это актуально для модулей с большим количеством контактов чем у esp-01, в частности, у меня esp-12. По умолчанию, SDA - GPIO2, SCL - GPIO0, но это не прописано в примере.
     
  3. Okadzaki

    Okadzaki Новичок

    Сообщения:
    24
    Симпатии:
    2
    Wire.pins(SCL,SDA) задаёте, перед Wire.begin()
     
    Nikita нравится это.
  4. anakod

    anakod Moderator Команда форума

    Сообщения:
    314
    Симпатии:
    100
    Да, верно. Еще можно глобально значение по умолчанию переопределить.
     
    Nikita нравится это.
  5. verzi

    verzi Новичок

    Сообщения:
    23
    Симпатии:
    1
    В примере Temperature_DS1820 если оставить все как есть, то не работает. Или я не успеваю консоль открыть что бы увидеть вывод :(.
    Если сделать так
    Код (раскрыть)

    Код (C):
    1. #include <user_config.h>
    2. #include <SmingCore/SmingCore.h>
    3. #include <Libraries/OneWire/OneWire.h>
    4.  
    5. #define WORK_PIN 13 // GPIO0
    6.  
    7. OneWire ds(WORK_PIN);
    8. Timer procTimer;
    9. float heatsinktemp;
    10.  
    11. void getTemp()
    12. {
    13.         byte i;
    14.         byte present = 0;
    15.         byte type_s;
    16.         byte data[12];
    17.         byte addr[8];
    18.  
    19.         ds.begin(); // It's required for one-wire initialization!
    20.  
    21.         if (!ds.search(addr))
    22.         {
    23.             Serial.println("No addresses found.");
    24.             Serial.println();
    25.             ds.reset_search();
    26.             delay(250);
    27.             return;
    28.         }
    29.  
    30.         Serial.print("Thermometer ROM =");
    31.         for( i = 0; i < 8; i++)
    32.         {
    33.             Serial.write(' ');
    34.             Serial.print(addr[i], HEX);
    35.         }
    36.  
    37.         if (OneWire::crc8(addr, 7) != addr[7])
    38.         {
    39.           debugf("OneWire CRC is not valid!");
    40.           return;
    41.         }
    42.         Serial.println();
    43.  
    44.         // the first ROM byte indicates which chip
    45.         switch (addr[0]) {
    46.         case 0x10:
    47.           Serial.println("  Chip = DS18S20");  // or old DS1820
    48.           type_s = 1;
    49.           break;
    50.         case 0x28:
    51.           Serial.println("  Chip = DS18B20");
    52.           type_s = 0;
    53.           break;
    54.         case 0x22:
    55.           Serial.println("  Chip = DS1822");
    56.           type_s = 0;
    57.           break;
    58.         default:
    59.           Serial.println("Device is not a DS18x20 family device.");
    60.           return;
    61.         }
    62.  
    63.         ds.reset();
    64.         ds.select(addr);
    65.         ds.write(0x44, 1);        // start conversion, with parasite power on at the end
    66.  
    67.         delay(1000);     // maybe 750ms is enough, maybe not
    68.         // we might do a ds.depower() here, but the reset will take care of it.
    69.  
    70.         present = ds.reset();
    71.         ds.select(addr);
    72.         ds.write(0xBE);         // Read Scratchpad
    73.  
    74.         Serial.print("  Data = ");
    75.         Serial.print(present, HEX);
    76.         Serial.print(" ");
    77.         for ( i = 0; i < 9; i++)
    78.         {
    79.             // we need 9 bytes
    80.             data[i] = ds.read();
    81.             Serial.print(data[i], HEX);
    82.             Serial.print(" ");
    83.         }
    84.         Serial.print(" CRC=");
    85.         Serial.print(OneWire::crc8(data, 8), HEX);
    86.         Serial.println();
    87.  
    88.         // Convert the data to actual temperature
    89.         // because the result is a 16 bit signed integer, it should
    90.         // be stored to an "int16_t" type, which is always 16 bits
    91.         // even when compiled on a 32 bit processor.
    92.         int16_t raw = (data[1] << 8) | data[0];
    93.         if (type_s)
    94.         {
    95.             raw = raw << 3; // 9 bit resolution default
    96.             if (data[7] == 0x10)
    97.             {
    98.               // "count remain" gives full 12 bit resolution
    99.               raw = (raw & 0xFFF0) + 12 - data[6];
    100.             }
    101.         } else {
    102.             byte cfg = (data[4] & 0x60);
    103.             // at lower res, the low bits are undefined, so let's zero them
    104.             if (cfg == 0x00) raw = raw & ~7;  // 9 bit resolution, 93.75 ms
    105.             else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
    106.             else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
    107.             //// default is 12 bit resolution, 750 ms conversion time
    108.         }
    109.  
    110.         heatsinktemp = (float)raw / 16.0;
    111.         Serial.print("  Temperature = ");
    112.         Serial.print(heatsinktemp);
    113.         Serial.println(" Celsius, ");
    114.         return;
    115.  
    116. }
    117.  
    118. void init()
    119. {
    120.     Serial.begin(SERIAL_BAUD_RATE); // 115200 by default
    121.     Serial.systemDebugOutput(true); // Allow debug output to serial
    122.     procTimer.initializeMs(2000, getTemp).start();
    123.  
    124. }
    125.  

    То все ОК. Но терзают меня смутные сомнения по поводу ds.begin(); вроде не место ему тут. А если его оставить в void init(), то вот эта часть срабатывает всегда, т.е. не отследить подключен ли датчик или нет.
    Код (Text):
    1. if (!ds.search(addr))
    2.     {
    3.         Serial.println("No addresses found.");
    4.         Serial.println();
    5.         ds.reset_search();
    6.         delay(250);
    7.         return;
    8.     }
    Первый скриншот сделан с кодом приведенным выше. Сначала датчик подключен, потом выключен. Все корректно отображается.
    1.png
    Второй скриншот, когда ds.begin() внутри void init().
    2.png
     
  6. verzi

    verzi Новичок

    Сообщения:
    23
    Симпатии:
    1
    И еще. Попытался объединить два примера. ScreenOLED_SSD1306 и Temperature_DS1820.
    Код (раскрыть)

    Код (C):
    1. #include <user_config.h>
    2. #include <SmingCore/SmingCore.h>
    3. #include <Libraries/OneWire/OneWire.h>
    4. #include <Libraries/Adafruit_SSD1306/Adafruit_SSD1306.h>
    5.  
    6. Timer lcdTimer;
    7. Timer tempTimer;
    8. OneWire ds(12);
    9. float heatsinktemp;
    10.  
    11. /*
    12. * Hardware SPI mode:
    13. * GND      (GND)         GND
    14. * VCC      (VCC)         3.3v
    15. * D0       (CLK)         GPIO14
    16. * D1       (MOSI)        GPIO13
    17. * RES      (RESET)       GPIO16
    18. * DC       (DC)          GPIO0
    19. * CS       (CS)          GPIO2
    20. */
    21. // For spi oled module
    22. Adafruit_SSD1306 display(0, 16, 2);
    23.  
    24. //* For I2C mode:
    25. // Default I2C pins 0 and 2. Pin 4 - optional reset
    26. // Adafruit_SSD1306 display(4);
    27.  
    28. void lcdLoop(){
    29.         display.clearDisplay();
    30.         // text display tests
    31.         display.setTextSize(1);
    32.         display.setTextColor(WHITE);
    33.         display.setCursor(0,0);
    34.         display.println(rand());
    35.         display.display();
    36.  
    37. }
    38.  
    39. void tempLoop()
    40. {
    41.     ds.begin(); // It's required for one-wire initialization!
    42.  
    43.     byte i;
    44.     byte present = 0;
    45.     byte type_s;
    46.     byte data[12];
    47.     byte addr[8];
    48.  
    49.     if (!ds.search(addr))
    50.     {
    51.         heatsinktemp = -1;
    52.         debugf("No DS18B20 sensor found.");
    53.         ds.reset_search();
    54.         delay(250);
    55.         return;
    56.     }
    57.  
    58.     // the first ROM byte indicates which chip
    59.     switch (addr[0]) {
    60.     case 0x10:
    61.         type_s = 1; //Chip = DS18S20 or old DS1820
    62.     break;
    63.     case 0x28:
    64.         type_s = 0; //Chip = DS18B20
    65.     break;
    66.     case 0x22:
    67.         type_s = 0; //Chip = DS1822
    68.     break;
    69.     default:
    70.         debugf("Device is not a DS18x20 family device.");
    71.         return;
    72.     }
    73.  
    74.     ds.reset();
    75.     ds.select(addr);
    76.     ds.write(0x44, 1); // start conversion, with parasite power on at the end
    77.  
    78.     delay(750); // maybe 750ms is enough, maybe not
    79.     // we might do a ds.depower() here, but the reset will take care of it.
    80.  
    81.     present = ds.reset();
    82.     ds.select(addr);
    83.     ds.write(0xBE); // Read Scratchpad
    84.  
    85.     for ( i = 0; i < 9; i++)
    86.     {
    87.         data[i] = ds.read(); // we need 9 bytes
    88.     }
    89.  
    90.     // Convert the data to actual temperature
    91.     // because the result is a 16 bit signed integer, it should
    92.     // be stored to an "int16_t" type, which is always 16 bits
    93.     // even when compiled on a 32 bit processor.
    94.     int16_t raw = (data[1] << 8) | data[0];
    95.     if (type_s)
    96.     {
    97.         raw = raw << 3; // 9 bit resolution default
    98.         if (data[7] == 0x10)
    99.         {
    100.             // "count remain" gives full 12 bit resolution
    101.             raw = (raw & 0xFFF0) + 12 - data[6];
    102.         }
    103.     }
    104.     else
    105.     {
    106.         byte cfg = (data[4] & 0x60);
    107.         // at lower res, the low bits are undefined, so let's zero them
    108.         if (cfg == 0x00) raw = raw & ~7;  // 9 bit resolution, 93.75 ms
    109.         else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
    110.         else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
    111.         // default is 12 bit resolution, 750 ms conversion time
    112.     }
    113.  
    114.     heatsinktemp = (float)raw / 16.0;
    115.     Serial.println(heatsinktemp);
    116. }
    117. void init()
    118. {
    119.     Serial.begin(SERIAL_BAUD_RATE); // 115200 by default
    120.     Serial.systemDebugOutput(true); // Allow debug output to serial
    121.  
    122.     display.begin(SSD1306_SWITCHCAPVCC);
    123.  
    124.     display.display();
    125.     delay(2000);
    126.  
    127.     // Clear the buffer.
    128.     display.clearDisplay();
    129.  
    130.     // draw a circle, 10 pixel radius
    131.     display.fillCircle(display.width()/2, display.height()/2, 10, WHITE);
    132.     display.display();
    133.     delay(2000);
    134.     display.clearDisplay();
    135.  
    136.     // text display tests
    137.     display.setTextSize(1);
    138.     display.setTextColor(WHITE);
    139.     display.setCursor(0,0);
    140.     display.println("Sming Framework");
    141.     display.setTextColor(BLACK, WHITE); // 'inverted' text
    142.     display.setCursor(104, 7);
    143.     display.println("v1.0");
    144.     //----
    145.     display.setTextColor(WHITE);
    146.     display.println("Let's do smart things");
    147.     display.setTextSize(3);
    148.     display.print("IoT");
    149.     display.display();
    150.  
    151.     delay(2000);
    152.     lcdTimer.initializeMs(2000, lcdLoop).start();
    153.     tempTimer.initializeMs(1000, tempLoop).start();
    154. }
    155.  

    По отдельности и датчик температуры и дисплей работают корректно. Прямо в этом коде. Если закомментировать одну из последних строчек которые запускают таймер дисплея или датчика. А вот вместе нет. Начальная заставка (та что про "Let's do smart things") на дисплее появляется и все на этом, дисплей не обновляется. При этом даже через последовательный порт было не подцепиться, при попытке законектиться esp вис. Только что скачал последний sming, виснуть перестал. В консоли никаких ошибок, только значения температуры. Пробовал и SPI и I2C дисплеи (разные). Sming как я уже писал последний, UDK v2.0.2. Пробовал запускать другие примеры работы с датчиком температуры (из ардуино), не работают. В общем, моих знаний явно не хватает для того что бы разобраться что тут не так.
     
  7. JustACat

    JustACat Moderator Команда форума

    Сообщения:
    568
    Симпатии:
    121
    verzi, а если вызвать lcdLoop прямо из tempLoop (в конце нее), без второго таймера отдельного?
    Может просто они друг другу мешают, т.к. у вас у одного таймера 1 секунда, у второго 2 секунды - кратные интервалы получаются... (это догадки, я вообще без понятия, как оно внутри работает, если честно)
     
  8. verzi

    verzi Новичок

    Сообщения:
    23
    Симпатии:
    1
    Сами по себе несколько таймеров работают без проблем. Проблема в том, что после того как запускается опрос датчика температуры, дисплей перестает обновляться. Ваш совет проверил, не работает.
     
  9. anakod

    anakod Moderator Команда форума

    Сообщения:
    314
    Симпатии:
    100
    Пока железа под рукой нет, но попробуйте сменить номера пинов - для I2C вызовом Wire.pins(..) или для DS18B20.
     
  10. Def461

    Def461 Новичок

    Сообщения:
    15
    Симпатии:
    1
    Не получается отловить, что умудряется сбрасывать состояние GPIO

    При инициализации 1wire или сбросе шины - получаю полный сброс регистров GPIO, любых.
    Т.е. имеем лог."0" на GPIO, провел опрос датчиков - бац! GPIO сброшены.

    В какую сторону копать?

    P.S. Судя по всему у предыдущего оратора - тот же баг: после вызова 1wire отваливаются настроенные регистры у других протоколов.
     
    Последнее редактирование: 20 июн 2015
  11. Nikita

    Nikita Читатель

    Сообщения:
    21
    Симпатии:
    5
    Подтверждаю, при инициализации 1wire пропадает соединение с MQTT и больше не поднимается. После исключения из проекта кода относящееся к 1wire, опрос dht22 и bmp180 и публикация их результатов через MQTT работает сутками без проблем и сбоев.
     
  12. Nikita

    Nikita Читатель

    Сообщения:
    21
    Симпатии:
    5
    Еще одна проблема. Пробую использовать функцию system_get_vdd33() для чтения напряжения питания на esp, каждый вызов возвращает результат 1023. Если использую не ту функцию, пожалуйста, напишите корректную.
     
  13. pvvx

    pvvx Активный участник сообщества

    Сообщения:
    8.395
    Симпатии:
    1.271
    2C-ESP8266__SDK__Programming Guide__EN_v1.1.2.pdf:
    Function: system_get_vdd33
    Measure the power voltage of VDD3P3 pin 3 and 4, unit:1/1024 V
    Note:
    • system_get_vdd33 can only be called when TOUT pin is suspended
    • The 107th byte in esp_init_data_default.bin(0〜~127byte)is named as “vdd33_const“ , when TOUT pin is suspended vdd33_const must be set as 0xFF, that is 255.
    По русски - в зависимости как установлена данная константа (107 байт в esp_init_data_default.bin), то работает или system_get_vdd33() или system_adc_read().
    На сегодня, одновременно использовать в одном приложении чтение ADC и VDD можно только в моей Web свалке.
    vdd_adc.gif rf_data3.gif adc_vdd.gif
    Пробуйте использовать uint32 readvdd33(void) вместо system_get_vdd33() и сами пересчитывайте (калибруйте) коэффициент перевода в Вольты - он зависит от номинала резистора припаянного к ноге TOUT и от типа модуля (у ESP-01 вывод TOUT никуда не подключен)... Процесс измерения VDD в чипе происходит путем подачи на ножку TOUT тока внутренним ключом и замером полученного напряжения на ней.
     
    Последнее редактирование: 21 июн 2015
    Victor и Nikita нравится это.
  14. Def461

    Def461 Новичок

    Сообщения:
    15
    Симпатии:
    1
    Таймер, установленный на 600*1000 ms интервал, срабатывает не раз в 10 минут, а раз в шесть.
    Вроде ограничения для таймера быть не должно :(
    Таймер на 120 секунд взводится идеально, на 600 - некорректно.
    Код (Text):
    1. logserversTSTimer.initializeMs(600*1000, logserversTSUpdate).start();
     
    Последнее редактирование: 22 июн 2015
  15. FGX

    FGX Читатель

    Сообщения:
    100
    Симпатии:
    9
    Так сделайте таймер на 1 минуту, в нем заведите переменную и инкрементируйте ее при каждом вызове, как дойдет до 10 делайте что хотели и сбросьте ее в 0.. Зачем заводить кучу таймеров с разным временем, можно пару завести на 1с и 1 минуту, например, и делать все что хотели в них смотря на доп переменные.
     
  16. Def461

    Def461 Новичок

    Сообщения:
    15
    Симпатии:
    1
    Как решать вопрос при одном таймере на всю систему - я знаю.
    Не вижу смысла изобретать костыли, если framework подразумевает множественное количество таймеров штатными средствами.

    Кстати, вопрос был не в нескольких таймерах, а в том, что период в 120 секунд отрабатывает корректно, а этот же таймер на 600 - нет.
     
  17. FGX

    FGX Читатель

    Сообщения:
    100
    Симпатии:
    9
    Я думаю, что таймер нельзя задавать на бесконечно большой интервал, на 1 час, например, может просто кончился его предел. Я поэтому и предложил получить 10 минут из таймера на 1 минуту, тем более проверить переменную на мой взгляд проще для системы в целом чем делать кучу таймеров.
     
  18. Def461

    Def461 Новичок

    Сообщения:
    15
    Симпатии:
    1
    В примерах есть гораздо бОльшие интервалы, нежели 10 минут.
    Потому я и задал вопрос, что изменилось в коде библиотек, что таймер может не работать на разумном интервале.
     
  19. pvvx

    pvvx Активный участник сообщества

    Сообщения:
    8.395
    Симпатии:
    1.271
    @anakod не помогает это с WDT в новых SDK https://github.com/anakod/Sming/blob/master/Sming/system/flashmem.c#L100
    Стирание в spiffs на 16Mбайт Flash делать в цикле нельзя. Отключается WiFi и т.д. Делал стирание flash блоками по 64к. Без остановки WDT pp_soft_wdt_stop() и рестарта pp_soft_wdt_restart() не катит. Сильно не вдавался, но и остановка не решает проблемы вылета цикла по WDT. Требуется обновление вызова pp_soft_wdt_stop() через некоторое время...
    В общем spiffs не подходит к концепции оф. SDK. Надо включать второй процесс по типу RTOS, но простой - всего 2 - SDK и всё остальное :)
    PS: NodeMCU это Ад. не берите от туда ничего - смотреть можно, но копировать - нет.
     
    Последнее редактирование: 28 июн 2015
  20. Def461

    Def461 Новичок

    Сообщения:
    15
    Симпатии:
    1
    Еcть продолжение цирка с 1wire
    Библиотекой затрагивается именно GPIO14, даже если работа с далласами назначена на другой порт.

    Т.е. сегодня перекомпилил работу реле с GPIO14 на GPIO16 - при опросе 18В20 GPIO16 не затрагивается
    А вот I2C на "стандартных" GPIO12/14 перестает норально работать ровно после инициализации комплектной библиотеки 1Wire.

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

Поделиться этой страницей