Скетч Arduino с огромным числом датчиков DS18B20. TEST!!!
Модератор: immortal
-
- Сообщения: 52
- Зарегистрирован: Ср фев 04, 2015 12:28 am
- Благодарил (а): 54 раза
- Поблагодарили: 6 раз
Скетч Arduino с огромным числом датчиков DS18B20. TEST!!!
Здравствуйте.
Начал осваивать МЖД. Купил ардуино, датчики 18B20. Загрузил скетч (http://smartliving.ru/Main/ArduinoSchema).
Для освоения скетч хороший. Но меня не устраивало, что при подключении нового датчика, постоянно требовалось вносить изменения в код и перезаливать его в плату Arduino (перед этим отключив все шилды), что, согласитесь, крайне не удобно.
Решил написать универсальный скетч (который бы и команды на реле посылал, и всевозможные датчики бы контролировал, а самое главное - чтоб умел самостоятельно найти, определить и отсылать информацию на сервер MJD).
Представляю Вашему вниманию Universal Arduino sketch for MajorDoMo: https://github.com/petertsermber/arduin ... orDoMo.ino
Пока работает только с датчиками 18B20 (но я в ближайшем будущем добавлю поддержку распространенных датчиков: DHT (влажности и температуры), BPM085 (давления и температуры, PIR (датчик движения), а так же модуля управления реле на 4 канала).
Ардуино ищет подключенные с 1-wire шине датчики, определяет их адреса, заносит в массив.
Далее по циклу, с каждого датчика получаем температуру, округляем ее до десятых, сравниваем с прошлой отправленной на сервер температурой. Если дельта больше 0,3 градуса, то отправляем данные на сервер МЖД. Идентификатором на сервере служит адрес датчика в HEX формате. Затем цикл повторяется.
Для "горячего" подключения датчиков требуется всего лишь "железно" подцепить датчик к шине, а в МажорДоМо добавить новый объект с именем типа 28156B15060000A7 (Адрес нового датчика можно узнать в стандартной программе типа Hyper Terminal), в котором существует свойство temp. Ну и должен присутствовать стандартный метод tempSensors-> tempChanged (который присутствует в стандартном дистрибутиве MJD). ВСЕ! Никаких перепрограммирований, перепрошиваний и прочего!
P.S. Я не программист, си++ вообще впервые увидел три недели назад, если что в коде не так, прошу сильно не ругать, а здесь написать.
Спасибо.
Начал осваивать МЖД. Купил ардуино, датчики 18B20. Загрузил скетч (http://smartliving.ru/Main/ArduinoSchema).
Для освоения скетч хороший. Но меня не устраивало, что при подключении нового датчика, постоянно требовалось вносить изменения в код и перезаливать его в плату Arduino (перед этим отключив все шилды), что, согласитесь, крайне не удобно.
Решил написать универсальный скетч (который бы и команды на реле посылал, и всевозможные датчики бы контролировал, а самое главное - чтоб умел самостоятельно найти, определить и отсылать информацию на сервер MJD).
Представляю Вашему вниманию Universal Arduino sketch for MajorDoMo: https://github.com/petertsermber/arduin ... orDoMo.ino
Пока работает только с датчиками 18B20 (но я в ближайшем будущем добавлю поддержку распространенных датчиков: DHT (влажности и температуры), BPM085 (давления и температуры, PIR (датчик движения), а так же модуля управления реле на 4 канала).
Ардуино ищет подключенные с 1-wire шине датчики, определяет их адреса, заносит в массив.
Далее по циклу, с каждого датчика получаем температуру, округляем ее до десятых, сравниваем с прошлой отправленной на сервер температурой. Если дельта больше 0,3 градуса, то отправляем данные на сервер МЖД. Идентификатором на сервере служит адрес датчика в HEX формате. Затем цикл повторяется.
Для "горячего" подключения датчиков требуется всего лишь "железно" подцепить датчик к шине, а в МажорДоМо добавить новый объект с именем типа 28156B15060000A7 (Адрес нового датчика можно узнать в стандартной программе типа Hyper Terminal), в котором существует свойство temp. Ну и должен присутствовать стандартный метод tempSensors-> tempChanged (который присутствует в стандартном дистрибутиве MJD). ВСЕ! Никаких перепрограммирований, перепрошиваний и прочего!
P.S. Я не программист, си++ вообще впервые увидел три недели назад, если что в коде не так, прошу сильно не ругать, а здесь написать.
Спасибо.
- Рейтинг: 5.81%
-
- Сообщения: 39
- Зарегистрирован: Чт окт 16, 2014 11:12 pm
- Благодарил (а): 5 раз
- Поблагодарили: 0
- Контактная информация:
Re: Скетч Arduino с огромным числом датчиков DS18B20. TEST!!
Интересно!
посмотрим что и как
посмотрим что и как
Windows7 + MajorDoMo.
HP laptop, MegaD modules, Arduino Megas, DS18B20, DHT-11 and other sensors.
DSC Alarm + envisalink 3
Connect
HP laptop, MegaD modules, Arduino Megas, DS18B20, DHT-11 and other sensors.
DSC Alarm + envisalink 3
Connect
-
- Сообщения: 64
- Зарегистрирован: Пт фев 21, 2014 10:56 am
- Откуда: Днепропетровск
- Благодарил (а): 1 раз
- Поблагодарили: 5 раз
Re: Скетч Arduino с огромным числом датчиков DS18B20. TEST!!
))) Это, конечно не влияет на функциональность, но в комментарии к 20-ой строке ip-адрес сервера MajorDoMo лучше заменить на маска подсети (netmask)
2*MegaD328, Система на Raspberry Pi 2
-
- Сообщения: 5
- Зарегистрирован: Вс мар 29, 2015 9:34 pm
- Благодарил (а): 0
- Поблагодарили: 0
Re: Скетч Arduino с огромным числом датчиков DS18B20. TEST!!
крутой скетч. Даже удивительно что не программист. При отключении датчика температуры от ардуины, мажор домо показывает ноль градусов. Как доработать скетч что бы при отключении была температура -100 допустим или +300, явно невозможная, сигнализирующая, что датчик неисправен?
-
- Сообщения: 52
- Зарегистрирован: Ср фев 04, 2015 12:28 am
- Благодарил (а): 54 раза
- Поблагодарили: 6 раз
Re: Скетч Arduino с огромным числом датчиков DS18B20. TEST!!
Была такая проверка. При температуре DEVICE_DISCONNECTED на сервер отправлялся гет запрос с температурой 200 градусов (предварительно в методе changeTemp увеличил максимальную температуру до 200). Тем самым я понимаю, что датчик отвалился.Lordserdjo писал(а):крутой скетч. Даже удивительно что не программист. При отключении датчика температуры от ардуины, мажор домо показывает ноль градусов. Как доработать скетч что бы при отключении была температура -100 допустим или +300, явно невозможная, сигнализирующая, что датчик неисправен?
Но отказался от этого, так как посчитал, что при отключении датчика мы уберем его и с МЖД?!
Я думал, что скетч никого не заинтересует, поэтому на форуме не появлялся. Рассказываю дальше.
А дальше я пошел еще дальше:
Захотелось мне добавить к объектам температуры свойство с дельтой, при превышении которой идет отправка данных на сервер. У каждого датчика температуры должна быть своя дельта. У одного - 0,2 градуса (минимальная адекватная чувствительность 18в20), у другого - 2 градуса. Для чего это?! Например, один датчик у нас установлен на улице, второй - в комнате.
Первым мы просто регистрируем уличную температуру, а из второго делаем ВЫСОКОТОЧНЫЙ комнатный термостат.
Понятное дело, что и дельта для них должна быть разная.
Думал, чтоб при GET отправке температуры на сервер, так же отправлялась текущая дельта для ДАННОГО датчика. Сервер сравнивает дельты текущую в ардуинке и прописанную в МЖД. Если они не совпадают - отправляем новую дельту на ардуино, а там запускается обработка по присвоению новой дельты для текущего датчика. Как то так.
Но планам не суждено было сбыться.
Если на ардуино запускать web-server (webduino), то по каким то причинам не работает цикл:
for (int i=0; i<8; i++) // цикл получения бит адреса
{
if (Termometers < 16) { aba = "0"+String(Termometers,HEX); } //если бит меньше 16, то дописываем в начале 0, так же конвертируем в шеснадцатиричный код
else {aba = String(Termometers,HEX);}// в противном случае просто конвертируем в 16ричный код и записываем байт в массив
Смысл его в чем: получает каждый байт адреса датчика температуры, переводит его в шеснадцатиричный код, если цифра получилась одна, то добавляем нолик впереди, и записываем каждый байт адреса в HEX формате в i-ячейку массива адреса.
После склеивания всех ячеек:
aa = aba[0]+aba[1]+aba[2]+aba[3]+aba[4]+aba[5]+aba[6]+aba[7]
получалась переменная aa , в которой содержалось имя датчика , например 28156B15060000A7.
Дак вот. Это цикл никак не хочет дружить с функцией webserver.processConnection(buff, &len); , которая следит за входящими подключениями к ардуино.
Что только не перепробовал. Результата нет.
Решил, что будет 2 ардуино: один - контроллер датчиков, другой - исполнительное устройство .
Конечно можно было сервер оставить, и сделать одно устройство, но тогда бы я лишился фишки, ради которой я все это задумал - отправку адреса датчика на сервер МЖД.
Дельта пока установлена на 0,3 градуса (если дельта 0,4 и более - отправляем новую т.)
Вот такие вот пока дела.
-
- Сообщения: 5
- Зарегистрирован: Вс мар 29, 2015 9:34 pm
- Благодарил (а): 0
- Поблагодарили: 0
Re: Скетч Arduino с огромным числом датчиков DS18B20. TEST!!
можно вас попросить выложить скетч, где при отваливании датчика посылается на мажордомо 200 градусов
-
- Сообщения: 52
- Зарегистрирован: Ср фев 04, 2015 12:28 am
- Благодарил (а): 54 раза
- Поблагодарили: 6 раз
Re: Скетч Arduino с огромным числом датчиков DS18B20. TEST!!
Код: Выделить всё
/**
* Универсальный контроллер сбора данных и исполительное устройство на базе Arduino (к проекту http://smartliving.ru/)
* Platform: Arduino UNO R3 + EthernetShield W5100
* IDE: Arduino 1.6.1
* Author: Peter Tsember by Syktyvkar. 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 }; // ip-адрес сервера MajorDoMo
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.3; // Дельта температур, при превышении которой следует отправлять данные на сервер МЖД
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
{
// Устройство отдало реальное значение температуры (или осталось старое)
// Округление полученной температуры до десятых
// Пример: 23.899 => 238.99 => 239.49 => 239 => 23.9) // При округлении изменился первый разряд, после запятой. Правило работает.
float tempC = sensors.getTempCByIndex(i) * 10;
tempC = tempC + 0.5;
tempC = (int)tempC;
tempC = tempC / 10;
float delta = fabsf(ta[i]-tempC); // Выделяем дельту температуры, между текущей и в последний раз отправленной темп.
if ((delta > delta_temp) // Если разница между прошлым и текущим значением темп. больше обозначенной дельты...
|| ((millis() - requestMillis) > interval)) // Если последняя передача данных на сервер была более 30 минут назад (например температура не менялась)...
{
int temp1 = (tempC - (int)tempC) * 10; // выделяем дробную часть
int str_len = aa[i].length() + 1; char char_array[str_len]; aa[i].toCharArray(char_array, str_len); // Конвертируем строку с адресом в массив символов
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();
}
А если хотите проверить на условие дисконнекта, тогда в функции TempSensorSend() (смотрите по текущему моему скетчу) вначале нужно проверить:
Код: Выделить всё
if (tempC == DEVICE_DISCONNECTED) {
// Устройство отсоединено
Serial.println("Termometer is DEVICE_DISCONNECTED");
// формирование запроса на сервер, что датчик не отвечает
tempC = 200;
sprintf(buf, "GET /objects/?object=%s&op=m&m=tempChanged&t=%0d.%d", (int)tempC, abs(temp1)); // Формируем GET запрос
sendHTTPRequest(); // И передаем на сервер
requestMillis = millis(); // Засекаем время последней передачи данных на сервер
ta[i]=tempC;
} else { ...
дальше пошел основной код
Иными словами: перед тем, как округлять температуру до десятых и формировать запрос на ее отправку, мы сначала проверяем не отключен ли датчик. Если отключен, библиотека отправит сообщение DEVICE_DISCONNECTED. Если так, то отправляем на сервер 200 градусов. Надеюсь, я ответил на Ваш вопрос?!
-
- Сообщения: 52
- Зарегистрирован: Ср фев 04, 2015 12:28 am
- Благодарил (а): 54 раза
- Поблагодарили: 6 раз
Re: Скетч Arduino с огромным числом датчиков DS18B20. TEST!!
P.S. Я не программист, серьезно, просто через чур развито "чувство прекрасного". Люблю когда все красиво. Стараюсь сразу делать хорошо, а плохо и так получится.Lordserdjo писал(а):крутой скетч. Даже удивительно что не программист.
-
- Сообщения: 52
- Зарегистрирован: Ср фев 04, 2015 12:28 am
- Благодарил (а): 54 раза
- Поблагодарили: 6 раз
Re: Скетч Arduino с огромным числом датчиков DS18B20. TEST!!
tsember писал(а):Код: Выделить всё
// ---=== ФУНКЦИЯ ОТПРАВКИ ДАННЫХ (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"); } */ } [/quote] В настоящее время ардуино передает данные через USB через arduino gate. Поэтому основная функция отправки по ethernet закоментирована.
-
- Сообщения: 5
- Зарегистрирован: Вс мар 29, 2015 9:34 pm
- Благодарил (а): 0
- Поблагодарили: 0
Re: Скетч Arduino с огромным числом датчиков DS18B20. TEST!!
спасибо большое, буду изучать. Ощущаю что надо закупаться книгами по С++. С точки разбора можно понять, а что бы написать такое пока для меня и думаю для многих просто космос.