Чудит ардуинка
- Войдите на сайт для отправки комментариев
Здравствуйте.
Подскажите пожалуйста по коду. Ардуино нано с шилдом на ENC28J60. Стоит в бане (предбанник, герметичный корпус). Общается с mqtt сервером, подключены 2 датчика ds18b20, кнопка (выключатель) и релюшка. Китай. Реле рулит светом 220.
Роль: с определенной периодичностью посылать по mqtt температуру с двух мест, дергать релюшкой.
Не хочет нормально работать. После перезагрузки корректно реагирует на нажатие выключателя, посылает темепературу. Но без какой-то системы прекращает слать температуру, на выключатель тоже раза в 5-10 реагирует. Может так же без системно дернуть релюшкой и выключить свет, т.е живет своей жизнью. Может день нормально проработать, а может через 10 минут закапризничать.
Менял шилд, ардуинку, блок питания, отключал ds18b20. Думал может расстояние витой пары для шилда велико (20 метров), рядом с ардуинкой поставил свитч - не помогло.
Может что в коде не верно. Но этот код - клон такой же системы, управляющей светом в доме, но без температуры - без проблем работает.
#include <UIPEthernet.h> #include <Bounce2.h> #include <OneWire.h> #include <DallasTemperature.h> #include <PubSubClient.h> // ======================================================================= // Конфигурация устройства MQTT: uint8_t mac[6] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xE2 }; uint8_t myIP[4] = {192, 168, 1, 72}; uint8_t myDNS[4] = {192, 168, 1, 1}; uint8_t myGW[4] = {192, 168, 1, 1}; uint8_t myMASK[4] = {255, 255, 255, 0}; const char *mqtt_server = "192.168.1.70"; // Имя сервера MQTT const int mqtt_port = 1883; // Порт для подключения к серверу MQTT const char *mqtt_user = "yunin"; // Логи от сервер const char *mqtt_pass = "yunindenis"; // Пароль от сервера EthernetClient ethClient; PubSubClient clientMqtt(ethClient); // ======================================================================= //ds18b20 OneWire oneWire(4); // вход датчиков 18b20 DallasTemperature ds(&oneWire); DeviceAddress ds_t_out = {0x28, 0xFF, 0x9A, 0x28, 0x72, 0x16, 0x04, 0xA9}; DeviceAddress ds_t_banya = {0x28, 0xFF, 0x91, 0x5C, 0x72, 0x16, 0x05, 0x21}; //DeviceAddress ds_t_banya = {0x28, 0xFF, 0x33, 0xD0, 0x72, 0x16, 0x05, 0x5A}; int t_out; int t_out_old = 0; int t_banya; int t_banya_old = 0; byte i = 0; boolean flag_light_banya = false; char buff[15]; //выходы нагрузки const byte outPin1 = 5; // свет предбанник //кнопки const byte inButton1 = 6; //вход кнопка boolean buttonState = false; //состояние выключателя //создаем объект класса Bounce. Указываем пин, к которому подключена кнопка, и время дребезга в мс. Bounce debouncer1 = Bounce(); //подсчет времени //опрос датчиков long previousMillis_sensor = 0; // храним время последнего опроса датчиков long interval_sensor = 60000; //интервал //mqtt broker long previousMillis_mqtt_connect = 0; // храним время последнего подключения long interval_mqtt_connect = 60000; //интервал unsigned long currentMillis_mqtt_connect = 0; // ======================================================================= // Функция получения данных от сервера void callback(char* topic, byte* payload, unsigned int length) { //-------------------------------------------------------------------------------------- //свет баня if (String(topic) == "ihouse/svet/banya") { if ((char)payload[0] == '1') flag_light_banya = true; if ((char)payload[0] == '0') flag_light_banya = false; digitalWrite(outPin1, flag_light_banya); } } // ======================================================================= void mqtt_reconnect() { unsigned long currentMillis_mqtt_connect = millis(); // подключаемся к MQTT серверу if (currentMillis_mqtt_connect - previousMillis_mqtt_connect >= interval_mqtt_connect) { String clientId = "nanobanya-"; clientId += String(random(0xffff), HEX); if (clientMqtt.connect(clientId.c_str(), mqtt_user, mqtt_pass)) { //подписываемся по топики clientMqtt.subscribe("ihouse/svet/banya"); clientMqtt.loop(); } previousMillis_mqtt_connect = currentMillis_mqtt_connect; } } // ======================================================================= void setup() { Ethernet.begin(mac, myIP, myDNS, myGW, myMASK); delay(10); clientMqtt.setServer(mqtt_server, mqtt_port); clientMqtt.setCallback(callback); delay(10); ds.begin(); //для релюшек pinMode(outPin1, OUTPUT); digitalWrite(outPin1, LOW); pinMode(inButton1, INPUT_PULLUP); debouncer1.attach(inButton1); debouncer1.interval(5); } //-------------------------------------------------------------------------------------- void loop() { unsigned long currentMillis_sensor = millis(); //-------------------------------------------------------------------------------------- if (!clientMqtt.connected()) { mqtt_reconnect(); } //-------------------------------------------------------------------------------------- //проверка состояния кнопки1 - предбанник if (debouncer1.update()) { //факт нажатия if (debouncer1.fell()) { flag_light_banya = !flag_light_banya; digitalWrite(outPin1, flag_light_banya); } //факт отпускания if (debouncer1.rose()) { itoa(flag_light_banya, buff, 10); clientMqtt.publish("ihouse/svet/banya", buff); clientMqtt.publish("ihouse/svet/banya/button", "1"); } } //-------------------------------------------------------------------------------------- //температура if (currentMillis_sensor - previousMillis_sensor > interval_sensor) { previousMillis_sensor = currentMillis_sensor; i++; } //dallas подготовка if (i == 1) { ds.requestTemperatures(); // считываем температуру с датчиков } //dallas считывание if (i == 2) { if (ds.getTempC(ds_t_out) <= 50) t_out = ds.getTempC(ds_t_out) - 3; if (ds.getTempC(ds_t_banya) <= 80) t_banya = ds.getTempC(ds_t_banya); i = 0; if (t_out != t_out_old) { itoa(t_out, buff, 10); clientMqtt.publish("ihouse/climat/out/temp", buff); t_out_old = t_out; } if (t_banya != t_banya_old) { itoa(t_banya, buff, 10); clientMqtt.publish("ihouse/climat/banya/temp", buff); t_banya_old = t_banya; } } clientMqtt.loop(); }
благодарю
абясни, что у тебя со 152 строки происходит?
Ну, значит, тебе так надо. Вопросов больше не имею.
В коде есть логические бонбы, ищи тогда сам.
Семен, извините, не мог следить за темой - работа.
Со 152 строки идет подготовка и считывание показаний с ds18b20. Натыкался на мнение, что этот датчик чуть тормознутый. ему нужно дать паузу между подготовкой и непосредственно считыванием. Вот со 152 строки сначала готовим данные, потом их считываем.
Ну чтобы не долбить mqtt одинаковыми значениями температуры, запоминаю значение, при следующем цикле считывания проверяю, если температура изменилась - послать в mqtt.
Ну теперь смотрим, что происходит на самом деле
когда i==1
дальше продолжать7
Ну теперь смотрим, что происходит на самом деле
когда i==1
дальше продолжать7
Семен, там комментарии неверны. Надо так:
ds.requestTemperatures(); // подготавливаем температуру с датчиков
Дед тебе пишет, что пока (currentMillis_sensor - previousMillis_sensor > interval_sensor) ардуина будет долбить ежемиллисекундно в шину командами на конверсию.
Семен, там комментарии неверны.
мои - верны. Потомушо это я их написал.
за твои -нинаю.
Дед тебе пишет, что пока (currentMillis_sensor - previousMillis_sensor > interval_sensor) ардуина будет долбить ежемиллисекундно в шину командами на конверсию.
Она выполнив это новое значение previousMillis_sensor принимает:
previousMillis_sensor = currentMillis_sensor;
Дед тебе пишет, что пока (currentMillis_sensor - previousMillis_sensor > interval_sensor) ардуина будет долбить ежемиллисекундно в шину командами на конверсию.
Она выполнив это новое значение previousMillis_sensor принимает:
previousMillis_sensor = currentMillis_sensor;
А, ну ладно, тогда. Няхай.
Она выполнив это новое значение previousMillis_sensor принимает:
Ок, чудите с ардуинкой дальше.
Смотрим строки 055 и059 и не наблюдаем unsigned безнаковой. Для использования millis() это грубая ошибка.
Враги поставили } на 156 строку.
вот теперь как бы это Дениске обьяснить?
можно поподробнее. не знаю это.
сенк
вот теперь как бы это Дениске обьяснить?
семен, я не считаю себя правым. реально не пойму косяка.
вот теперь как бы это Дениске обьяснить?
семен, я не считаю себя правым. реально не пойму косяка.
дабы не играться с отсутствующими у меня библиотеками урезал ваш код и уменьшил интервал чтобы не ждать минуту. Запустите его и посмотрите в сериале что происходит
а потом запустите его же, но с закомментированной строкой 67 и раскомментированной 82
Все, мужики, понял. Дэбил иваныч. Долбил ардуинку подготовкой датчика.
спасибо всем.
А как с этим зверем быть: unsigned безнаковой
long у всего, что хранит интервалы, замени на uint32_t
Все, мужики, понял.
спасибо всем.
Да ты еще погоди, этот касяк не последний.
Все, мужики, понял.
спасибо всем.
Да ты еще погоди, этот касяк не последний.
весь во внимании
ты пока это исправь, проверь и доложи.
ты пока это исправь, проверь и доложи.
у меня таким же шаблоном еще несколько контроллеров работает. везде исправил. пока фурычит.
и long на uint32_t исправил?
и long на uint32_t исправил?
да
ну, значить, падаждём.
Анекдот. Один случайный человек наблюдал такую картину. Сидит программист за компьютером а потом как вскочет и махая руками с матом начал резво круги возле компьютера наварачивать. О-как выганятся баги из программ. Я тоже кричать и бегать. Пойду в программисты.