Скетч Arduino с огромным числом датчиков DS18B20. TEST!!!
Модератор: immortal
-
- Сообщения: 52
- Зарегистрирован: Ср фев 04, 2015 12:28 am
- Благодарил (а): 54 раза
- Поблагодарили: 6 раз
Re: Скетч Arduino с огромным числом датчиков DS18B20. TEST!!
Глянул. Мне показалось, много лишнего кода у вас. Можно оптимизировать..
-
- Сообщения: 284
- Зарегистрирован: Сб ноя 24, 2012 11:47 am
- Благодарил (а): 28 раз
- Поблагодарили: 28 раз
Re: Скетч Arduino с огромным числом датчиков DS18B20. TEST!!
tsember писал(а):Немножко изменил код.СпойлерПоказатьКод: Выделить всё
/** * Универсальный контроллер сбора данных на базе Arduino (к проекту http://smartliving.ru/) * Platform: Arduino UNO R3 + EthernetShield W5100 * IDE: Arduino 1.6.1 * Автор: Петр Цембер. На форуме tsember. 2015. город Сыктывкар. **/ // ----==== ПОДКЛЮЧЕНИЕ БИБЛИОТЕК ====---- #include <Ethernet.h> // (Ethernet Shield) #include <SPI.h> // (Для работы с устройствами по протоколу SPI, например с Ethernet Shield) #include <Arduino.h> // (Основная библиотека Arduino) #include <OneWire.h> // (Шина 1-wire) #include <DallasTemperature.h> // (Датчик температуры DS18B20) // ----==== НАСТРОЙКИ СЕТИ ====---- byte mac[] = { 0xDE, 0xAD, 0xBE, 0xE4, 0xDE, 0x35 }; // MAC-адрес контроллера Arduino byte ip[] = { 192, 168, 1, 15 }; // ip-адрес контроллера Arduino byte subnet[] = { 255, 255, 255, 0 }; // Маска подсети byte gateway[] = { 192, 168, 1, 250 }; // ip-адрес основного шлюза byte dns_server[] = { 192, 168, 1, 250 }; // ip-адрес DNS-сервера byte rserver[] = { 192, 168, 1, 123 }; // ip-адрес сервера MajorDoMo char buf[100]; // Переменная для хранения GET запроса char ipbuff[16]; // Переменная для IP адреса EthernetClient rclient; // ----==== НАСТРОЙКИ ПОДКЛЮЧЕННЫХ УСТРОЙСТВ ====---- // Вход, на котором находится шина 1-wire с датчиками DS18S20 #define ONE_WIRE_BUS 2 // нога 2 // ----==== НАСТРОЙКИ ПЕРЕМЕННЫХ И МАССИВОВ ДАННЫХ ====---- float current_temp1; // Задаем переменную, в которой будем хранить текущую температуру float delta_temp = 0.2; // Дельта температур, при превышении которой следует отправлять данные на сервер МЖД long requestMillis; // Задаем переменную времени последней передачи данных на сервер long interval = 18000000; // Задаем максимальный интервал между передачами данных на сервер byte numberOfDevices; // Количество датчиков DS18B20 на шине 1-wire (Обновляется автоматически) DeviceAddress Termometers; // Массив с датчиками // Размер следующих массивов - предполагаемое максимальное количество датчиков DS18B20. // По умолчанию - 30. Нужно больше?! Увеличиваете числа и перезаливаете скетч byte na[30]; // Массив с порядковыми номерами датчиков температуры DS18B20 String aa[30]; // Массив с HEX-адресами датчиков температуры DS18B20 float ta[30]; // Массив с последней отправленной температурой датчиков DS18B20 // Инициализация веб-сервера на 80 порту, а так же шины 1-wire и датчиков температуры DS18B20 OneWire oneWire(ONE_WIRE_BUS); DallasTemperature sensors(&oneWire); // ---=== ПОИСК ДАТЧИКОВ ТЕМПЕРАТУРЫ DS18B20 НА ШИНЕ 1-WIRE ===--- void TempSensorSearch() { sensors.begin(); // Инициализация датчиков DS18B20 sensors.requestTemperatures(); // Перед каждым получением температуры надо ее запросить sensors.setResolution(Termometers, 12); // Установка чувствительности на 12 бит // Serial.print("Vsego datchikov: "); numberOfDevices = sensors.getDeviceCount(); // Serial.println(numberOfDevices); // вывод на экран общего количества найденых датчиков for(byte i=0;i<numberOfDevices; i++) { // цикл для записи в массивы данных if(sensors.getAddress(Termometers, i)) // если адрес датчика под индексом i определен, то: { String aba[8]; // Создаем массив с байтами адреса for (int i=0; i<8; i++) // цикл получения бит адреса { if (Termometers[i] < 16) { aba[i] = "0"+String(Termometers[i],HEX); } //если бит меньше 16, то дописываем в начале 0, так же конвертируем в шеснадцатиричный код else {aba[i] = String(Termometers[i],HEX);}// в противном случае просто конвертируем в 16ричный код и записываем байт в массив } aa[i] = aba[0]+aba[1]+aba[2]+aba[3]+aba[4]+aba[5]+aba[6]+aba[7]; // Записываем полный адрес в массив адресов aa[], в ячейку i. // Serial.print("Sensor "); Serial.print(i, DEC); Serial.print(" with address: "); // Датчик под номером i с адресом: // Serial.println(aa[i]); // Выводим на экран i ячейку с 16-ричным адресом устройства } } } // ---=== ПОЛУЧЕНИЕ И ОБРАБОТКА ТЕМПЕРАТУРЫ ===--- void TempSensorSend() { for(byte i=0;i<numberOfDevices; i++) { // цикл для получения, обработки, округления и отправки температуры каждого датчика DS18B20 int str_len = aa[i].length() + 1; char char_array[str_len]; aa[i].toCharArray(char_array, str_len); // Конвертируем строку с адресом в массив символов float tempC = sensors.getTempCByIndex(i); // Получим температуру от датчика (или ошибку) // Устройство отдало реальное значение температуры (или осталось старое) // Округление полученной температуры до десятых // Пример: 23.899 => 238.99 => 239.49 => 239 => 23.9) // При округлении изменился первый разряд, после запятой. Правило работает. tempC = sensors.getTempCByIndex(i) * 10; tempC = tempC + 0.5; tempC = (int)tempC; tempC = tempC / 10; float delta = fabsf(ta[i]-tempC); // Выделяем дельту температуры, между текущей и в последний раз отправленной темп. if (tempC < -70) { Serial.print("Temp sensor "); Serial.print(i); Serial.println(" is disconnected");} else if (tempC == 0) {Serial.print("Temp sensor "); Serial.print(i); Serial.println(" is disconnected");} else if ((delta > delta_temp) // Если разница между прошлым и текущим значением темп. больше обозначенной дельты и дельта не более 70... || ((millis() - requestMillis) > interval)) // Если последняя передача данных на сервер была более 30 минут назад (например температура не менялась)... { int temp1 = (tempC - (int)tempC) * 10; // выделяем дробную часть sprintf(buf, "GET /objects/?object=%s&op=m&m=tempChanged&t=%0d.%d", char_array, (int)tempC, abs(temp1)); // Формируем GET запрос sendHTTPRequest(); // И передаем на сервер requestMillis = millis(); // Засекаем время последней передачи данных на сервер ta[i]=tempC; // Задаем текущую температуру предыщущей. } } } // ---=== ФУНКЦИЯ ОТПРАВКИ ДАННЫХ (HTTP-ЗАПРОСА) НА СЕРВЕР MAJORDOMO ===--- void sendHTTPRequest() { Serial.println (buf); /* if (rclient.connect(rserver, 80)) { Serial.println("OK"); Serial.println(buf); // Вывод на экран сгенерированного GET запроса rclient.print(buf); rclient.println(" HTTP/1.0"); rclient.print("Host: "); sprintf(ipbuff, "%u.%u.%u.%u", ip[0], ip[1], ip[2], ip[3]); rclient.println(ipbuff); // ip адрес нашего контроллера в текстовом виде rclient.print("Content-Type: text/html\n"); rclient.println("Connection: close\n"); \(10); rclient.stop(); } else { Serial.println("FAILED SENDING"); } */ } // ---=== ФУНКЦИЯ НАСТРОЙКИ ===--- void setup() { Serial.begin(9600); // Инициализируем Serial (монитор последовательного порта) Serial.println("Start"); Ethernet.begin(mac, ip, dns_server, gateway, subnet); // Инициализируем Ethernet Shield/ Serial.print("server is at "); Serial.println(Ethernet.localIP()); } // ---=== ЦИКЛИЧЕСКАЯ ФУНКЦИЯ ===--- void loop() { TempSensorSearch(); TempSensorSend(); }
Обратно убрал проверку на отключение датчика. Объясняю. Так как поиск датчиков на шине повторяется циклически, вначале каждого цикла void loop, соответственно если датчик отключился, он просто удалится из массива с адресами датчиков. Выявить это просто! Не будут передаваться данные на сервер по этому датчику. Делаем вывод, что датчик отключился.
Так же, не знаю, по каким причинам, но иногда передается значение -127 с копейками градусов, так же бывает передается 0 градусов. Сделал проверку на эти показания, если температура равна 0, или температура ниже -70 градусов, игнорируем показания, в сериал монитор выводим сообщение об ошибке, ничего не отправляем на сервер.
Спасибо
У меня есть примерно такая же "железная приблуда", так у неё сделано так: если датчик пропал из сети то у него с каждым циклом уменьшается параметр "health" от 7 до 0, т.е. если health =0, то скорее всего датчик умер. При подключении датчика обратно, health снова увеличивается. А сама идея верная. Осталось сделать web-интерфейс, но тут проблема в том, что в коде есть delay (760), а в это время ардуина ни на что не реагирует.
-
- Сообщения: 52
- Зарегистрирован: Ср фев 04, 2015 12:28 am
- Благодарил (а): 54 раза
- Поблагодарили: 6 раз
Re: Скетч Arduino с огромным числом датчиков DS18B20. TEST!!
Задержки времени (delay) раньше не было. Как я уже писал выше, функция активации веб сервера конфликтует с одним циклом генерации адреса в массив. Я так и не разобрался, в чем проблема. Пришлось выбирать: наличие веб-сервера, или автоматическое подключение датчиков с генерацией его адреса и передача данных с него в МЖД с идентификацией по уникальному адресу.denis писал(а):tsember писал(а):Немножко изменил код.СпойлерПоказатьКод: Выделить всё
/** * Универсальный контроллер сбора данных на базе Arduino (к проекту http://smartliving.ru/) * Platform: Arduino UNO R3 + EthernetShield W5100 * IDE: Arduino 1.6.1 * Автор: Петр Цембер. На форуме tsember. 2015. город Сыктывкар. **/ // ----==== ПОДКЛЮЧЕНИЕ БИБЛИОТЕК ====---- #include <Ethernet.h> // (Ethernet Shield) #include <SPI.h> // (Для работы с устройствами по протоколу SPI, например с Ethernet Shield) #include <Arduino.h> // (Основная библиотека Arduino) #include <OneWire.h> // (Шина 1-wire) #include <DallasTemperature.h> // (Датчик температуры DS18B20) // ----==== НАСТРОЙКИ СЕТИ ====---- byte mac[] = { 0xDE, 0xAD, 0xBE, 0xE4, 0xDE, 0x35 }; // MAC-адрес контроллера Arduino byte ip[] = { 192, 168, 1, 15 }; // ip-адрес контроллера Arduino byte subnet[] = { 255, 255, 255, 0 }; // Маска подсети byte gateway[] = { 192, 168, 1, 250 }; // ip-адрес основного шлюза byte dns_server[] = { 192, 168, 1, 250 }; // ip-адрес DNS-сервера byte rserver[] = { 192, 168, 1, 123 }; // ip-адрес сервера MajorDoMo char buf[100]; // Переменная для хранения GET запроса char ipbuff[16]; // Переменная для IP адреса EthernetClient rclient; // ----==== НАСТРОЙКИ ПОДКЛЮЧЕННЫХ УСТРОЙСТВ ====---- // Вход, на котором находится шина 1-wire с датчиками DS18S20 #define ONE_WIRE_BUS 2 // нога 2 // ----==== НАСТРОЙКИ ПЕРЕМЕННЫХ И МАССИВОВ ДАННЫХ ====---- float current_temp1; // Задаем переменную, в которой будем хранить текущую температуру float delta_temp = 0.2; // Дельта температур, при превышении которой следует отправлять данные на сервер МЖД long requestMillis; // Задаем переменную времени последней передачи данных на сервер long interval = 18000000; // Задаем максимальный интервал между передачами данных на сервер byte numberOfDevices; // Количество датчиков DS18B20 на шине 1-wire (Обновляется автоматически) DeviceAddress Termometers; // Массив с датчиками // Размер следующих массивов - предполагаемое максимальное количество датчиков DS18B20. // По умолчанию - 30. Нужно больше?! Увеличиваете числа и перезаливаете скетч byte na[30]; // Массив с порядковыми номерами датчиков температуры DS18B20 String aa[30]; // Массив с HEX-адресами датчиков температуры DS18B20 float ta[30]; // Массив с последней отправленной температурой датчиков DS18B20 // Инициализация веб-сервера на 80 порту, а так же шины 1-wire и датчиков температуры DS18B20 OneWire oneWire(ONE_WIRE_BUS); DallasTemperature sensors(&oneWire); // ---=== ПОИСК ДАТЧИКОВ ТЕМПЕРАТУРЫ DS18B20 НА ШИНЕ 1-WIRE ===--- void TempSensorSearch() { sensors.begin(); // Инициализация датчиков DS18B20 sensors.requestTemperatures(); // Перед каждым получением температуры надо ее запросить sensors.setResolution(Termometers, 12); // Установка чувствительности на 12 бит // Serial.print("Vsego datchikov: "); numberOfDevices = sensors.getDeviceCount(); // Serial.println(numberOfDevices); // вывод на экран общего количества найденых датчиков for(byte i=0;i<numberOfDevices; i++) { // цикл для записи в массивы данных if(sensors.getAddress(Termometers, i)) // если адрес датчика под индексом i определен, то: { String aba[8]; // Создаем массив с байтами адреса for (int i=0; i<8; i++) // цикл получения бит адреса { if (Termometers[i] < 16) { aba[i] = "0"+String(Termometers[i],HEX); } //если бит меньше 16, то дописываем в начале 0, так же конвертируем в шеснадцатиричный код else {aba[i] = String(Termometers[i],HEX);}// в противном случае просто конвертируем в 16ричный код и записываем байт в массив } aa[i] = aba[0]+aba[1]+aba[2]+aba[3]+aba[4]+aba[5]+aba[6]+aba[7]; // Записываем полный адрес в массив адресов aa[], в ячейку i. // Serial.print("Sensor "); Serial.print(i, DEC); Serial.print(" with address: "); // Датчик под номером i с адресом: // Serial.println(aa[i]); // Выводим на экран i ячейку с 16-ричным адресом устройства } } } // ---=== ПОЛУЧЕНИЕ И ОБРАБОТКА ТЕМПЕРАТУРЫ ===--- void TempSensorSend() { for(byte i=0;i<numberOfDevices; i++) { // цикл для получения, обработки, округления и отправки температуры каждого датчика DS18B20 int str_len = aa[i].length() + 1; char char_array[str_len]; aa[i].toCharArray(char_array, str_len); // Конвертируем строку с адресом в массив символов float tempC = sensors.getTempCByIndex(i); // Получим температуру от датчика (или ошибку) // Устройство отдало реальное значение температуры (или осталось старое) // Округление полученной температуры до десятых // Пример: 23.899 => 238.99 => 239.49 => 239 => 23.9) // При округлении изменился первый разряд, после запятой. Правило работает. tempC = sensors.getTempCByIndex(i) * 10; tempC = tempC + 0.5; tempC = (int)tempC; tempC = tempC / 10; float delta = fabsf(ta[i]-tempC); // Выделяем дельту температуры, между текущей и в последний раз отправленной темп. if (tempC < -70) { Serial.print("Temp sensor "); Serial.print(i); Serial.println(" is disconnected");} else if (tempC == 0) {Serial.print("Temp sensor "); Serial.print(i); Serial.println(" is disconnected");} else if ((delta > delta_temp) // Если разница между прошлым и текущим значением темп. больше обозначенной дельты и дельта не более 70... || ((millis() - requestMillis) > interval)) // Если последняя передача данных на сервер была более 30 минут назад (например температура не менялась)... { int temp1 = (tempC - (int)tempC) * 10; // выделяем дробную часть sprintf(buf, "GET /objects/?object=%s&op=m&m=tempChanged&t=%0d.%d", char_array, (int)tempC, abs(temp1)); // Формируем GET запрос sendHTTPRequest(); // И передаем на сервер requestMillis = millis(); // Засекаем время последней передачи данных на сервер ta[i]=tempC; // Задаем текущую температуру предыщущей. } } } // ---=== ФУНКЦИЯ ОТПРАВКИ ДАННЫХ (HTTP-ЗАПРОСА) НА СЕРВЕР MAJORDOMO ===--- void sendHTTPRequest() { Serial.println (buf); /* if (rclient.connect(rserver, 80)) { Serial.println("OK"); Serial.println(buf); // Вывод на экран сгенерированного GET запроса rclient.print(buf); rclient.println(" HTTP/1.0"); rclient.print("Host: "); sprintf(ipbuff, "%u.%u.%u.%u", ip[0], ip[1], ip[2], ip[3]); rclient.println(ipbuff); // ip адрес нашего контроллера в текстовом виде rclient.print("Content-Type: text/html\n"); rclient.println("Connection: close\n"); \(10); rclient.stop(); } else { Serial.println("FAILED SENDING"); } */ } // ---=== ФУНКЦИЯ НАСТРОЙКИ ===--- void setup() { Serial.begin(9600); // Инициализируем Serial (монитор последовательного порта) Serial.println("Start"); Ethernet.begin(mac, ip, dns_server, gateway, subnet); // Инициализируем Ethernet Shield/ Serial.print("server is at "); Serial.println(Ethernet.localIP()); } // ---=== ЦИКЛИЧЕСКАЯ ФУНКЦИЯ ===--- void loop() { TempSensorSearch(); TempSensorSend(); }
Обратно убрал проверку на отключение датчика. Объясняю. Так как поиск датчиков на шине повторяется циклически, вначале каждого цикла void loop, соответственно если датчик отключился, он просто удалится из массива с адресами датчиков. Выявить это просто! Не будут передаваться данные на сервер по этому датчику. Делаем вывод, что датчик отключился.
Так же, не знаю, по каким причинам, но иногда передается значение -127 с копейками градусов, так же бывает передается 0 градусов. Сделал проверку на эти показания, если температура равна 0, или температура ниже -70 градусов, игнорируем показания, в сериал монитор выводим сообщение об ошибке, ничего не отправляем на сервер.
Спасибо
У меня есть примерно такая же "железная приблуда", так у неё сделано так: если датчик пропал из сети то у него с каждым циклом уменьшается параметр "health" от 7 до 0, т.е. если health =0, то скорее всего датчик умер. При подключении датчика обратно, health снова увеличивается. А сама идея верная. Осталось сделать web-интерфейс, но тут проблема в том, что в коде есть delay (760), а в это время ардуина ни на что не реагирует.
-
- Сообщения: 45
- Зарегистрирован: Вт июл 15, 2014 4:28 pm
- Благодарил (а): 79 раз
- Поблагодарили: 4 раза
Re: Скетч Arduino с огромным числом датчиков DS18B20. TEST!!
ув. tsember
Добрый день.
Не могли бы выложить пример (желательно с картинками) под ваш скетч, как получить данные в МЖД (как создать объект, класс, метод) по подробнее.
И еще где то читал ( https://arduino-info.wikispaces.com/Bri ... 0#multibus ) что можно сделать подключение DS18B20 по двум (нескольким) шинам можете попробовать сделать скетч для МЖД - это осень удобно если много темп. датчиков находящихся в разных направлениях
Добрый день.
Не могли бы выложить пример (желательно с картинками) под ваш скетч, как получить данные в МЖД (как создать объект, класс, метод) по подробнее.
И еще где то читал ( https://arduino-info.wikispaces.com/Bri ... 0#multibus ) что можно сделать подключение DS18B20 по двум (нескольким) шинам можете попробовать сделать скетч для МЖД - это осень удобно если много темп. датчиков находящихся в разных направлениях
Re: Скетч Arduino с огромным числом датчиков DS18B20. TEST!!
Спасибо за скетч. Переделал слегка под себя его, но вот досада, обнаружил такой баг:
если не меняется температура на датчиках, то по таймауту отправляется температура только 1-го датчика.
куда смотреть?
если не меняется температура на датчиках, то по таймауту отправляется температура только 1-го датчика.
куда смотреть?
-
- Сообщения: 19
- Зарегистрирован: Вт ноя 03, 2015 10:06 pm
- Благодарил (а): 6 раз
- Поблагодарили: 0
Re: Скетч Arduino с огромным числом датчиков DS18B20. TEST!!
Под последние версии IDE не идет ?
Что то ругается
Что то ругается
-
- Сообщения: 30
- Зарегистрирован: Вт фев 21, 2017 10:07 am
- Благодарил (а): 15 раз
- Поблагодарили: 0
Re: Скетч Arduino с огромным числом датчиков DS18B20. TEST!!
поддерживаю тоже хотелось быastotskiy писал(а):ув. tsember
Добрый день.
Не могли бы выложить пример (желательно с картинками) под ваш скетч, как получить данные в МЖД (как создать объект, класс, метод) по подробнее.
-
- Сообщения: 30
- Зарегистрирован: Вт фев 21, 2017 10:07 am
- Благодарил (а): 15 раз
- Поблагодарили: 0
Re: Скетч Arduino с огромным числом датчиков DS18B20. TEST!!
кто нибудь помогитеawladimer писал(а):поддерживаю тоже хотелось быastotskiy писал(а):ув. tsember
Добрый день.
Не могли бы выложить пример (желательно с картинками) под ваш скетч, как получить данные в МЖД (как создать объект, класс, метод) по подробнее.
- lanket
- Сообщения: 1168
- Зарегистрирован: Вт окт 14, 2014 11:27 pm
- Откуда: Санкт-Петербург
- Благодарил (а): 260 раз
- Поблагодарили: 163 раза
Re: Скетч Arduino с огромным числом датчиков DS18B20. TEST!!
Поставьте вопрос более подробно.awladimer писал(а):кто нибудь помогитеawladimer писал(а):поддерживаю тоже хотелось быastotskiy писал(а):ув. tsember
Добрый день.
Не могли бы выложить пример (желательно с картинками) под ваш скетч, как получить данные в МЖД (как создать объект, класс, метод) по подробнее.
Вам надо в МД получить данные снятые именно этим скетчем с датчиков температуры?
Для этого надо достучаться до обладателя этого решения.
Или подсказать полное решение передачи с датчика температуры в МД? Если так и Вам надо именно много датчиков температуры то смотрите в сторону 1wire с сетью ds1820. На один провод можно др 255 датчиков повесить.
Отправлено с моего Redmi Note 3 через Tapatalk
- Рейтинг: 1.16%
Разработка голосового асистента для Мажордомо по любому ключевому слову.
Обсужение
gitHub 2й версии терминала
GitHub модуля для МД
gitHub сырого модуля 2й версии
Connect
Rasberry Pi 2, MDM, MySensors. И говорящий апельсин.
Обсужение
gitHub 2й версии терминала
GitHub модуля для МД
gitHub сырого модуля 2й версии
Connect
Rasberry Pi 2, MDM, MySensors. И говорящий апельсин.
-
- Сообщения: 30
- Зарегистрирован: Вт фев 21, 2017 10:07 am
- Благодарил (а): 15 раз
- Поблагодарили: 0
Re: Скетч Arduino с огромным числом датчиков DS18B20. TEST!!
Действительно так мне нужно прописать их МД для получения данныхlanket писал(а):ув. tsember
Добрый день.
Не могли бы выложить пример (желательно с картинками) под ваш скетч, как получить данные в МЖД (как создать объект, класс, метод) по подробнее.
Поставьте вопрос более подробно.
Вам надо в МД получить данные снятые именно этим скетчем с датчиков температуры?
Для этого надо достучаться до обладателя этого решения.
Или подсказать полное решение передачи с датчика температуры в МД? Если так и Вам надо именно много датчиков температуры то смотрите в сторону 1wire с сетью ds1820. На один провод можно др 255 датчиков повесить.
Отправлено с моего Redmi Note 3 через Tapatalk