Arduino: цифровой термометр с web-мониторингом
Недавно обнаружил удобный онлайн-сервис для ведения статистики любой числовой информации и отображение её в виде графиков. Немного подумав, решил на его основе сделать цифровой термометр.

Внимание! Содержимое данной статьи уже неактуально, так как сервис Pachube прекратил своё существование. Статья оставлена как есть просто для истории.
Необходимые компоненты:
- Arduino (Freeduino, *duino);
- Ethernet Shield;
- цифровой датчик температуры DS18B20;
- резистор 4.7 кОм;
- прямые руки 🙂
Вот собственно сам цифровой датчик DS18B20:

И его распиновка:

Его мы будем подключать по шине 1-wire по схеме с паразитным питанием. При этом, можно использовать несколько таких датчиков (все они соединяются параллельно двумя проводами) и считывать с каждого отдельную температуру. Таким образом, при желании, можно контролировать температуру в каждом уголке комнаты 🙂
Напоминаю, что Ethernet Shield использует для своих нужд пины 10, 11, 12 и 13, поэтому использовать их нельзя.


Теперь зальём в ардуино следующий скетч:
#include <ERxPachube.h> #include <Ethernet.h> #include <SPI.h> #include <OneWire.h> #include <DallasTemperature.h> //************************************************************************************ byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // MAC-адрес byte ip[] = { 192, 168, 1, 177 }; // IP-адрес #define PACHUBE_API_KEY "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890" // ВАШ PACHUBE_API_KEY #define PACHUBE_FEED_ID 00000 // ВАШ ID #define DATA_STREAM 1 //Номер PACHUME DATASTREAM #define ONE_WIRE_BUS 2 // Номер цифрового порта, к которому подключен термодатчик //************************************************************************************ ERxPachubeDataOut dataout(PACHUBE_API_KEY, PACHUBE_FEED_ID); OneWire oneWire(ONE_WIRE_BUS); DallasTemperature sensors(&oneWire); float SumTemp, CountTemp; unsigned long dt; void setup() { Serial.begin(9600); //для отладки Ethernet.begin(mac, ip); sensors.begin(); CountTemp = 0; SumTemp = 0; dt=millis(); dataout.addData(1); //добавляем поток данных } void loop() { //делаем синхронизацию и запрашиваем температуру sensors.setWaitForConversion(false); sensors.requestTemperatures(); sensors.setWaitForConversion(true); //разрешение датчика int resolution = 12; delay(750/ (1 << (12-resolution))); // получаем данные о температуре float fSensorData=sensors.getTempCByIndex(0); SumTemp=SumTemp+fSensorData; CountTemp++; //Раз в минуту усредняем данные и отправляем на сервер if (abs(millis()-dt)>=60000 ) { fSensorData=SumTemp/CountTemp; char test[20]; //обновляем данные dataout.updateData(1, floatToString(test, fSensorData, 2, 7)); int status = dataout.updatePachube(); //для отладки выводим показания в консоль Serial.println(fSensorData); CountTemp = 0; SumTemp = 0; dt=millis(); } delay(5000); } //функция для перевода из десятичной дроби в строковый вид char * floatToString(char * outstr, double val, byte precision, byte widthp) { char temp[16]; //increase this if you need more digits than 15 byte i; temp[0]='\0'; outstr[0]='\0'; if (val < 0.0) { strcpy(outstr,"-\0"); //print "-" sign val *= -1; } if (precision == 0) { strcat(outstr, ltoa(round(val),temp,10)); //prints the int part } else { unsigned long frac, mult = 1; byte padding = precision-1; while (precision--) mult *= 10; val += 0.5/(float)mult; // compute rounding factor strcat(outstr, ltoa(floor(val),temp,10)); //prints the integer part without rounding strcat(outstr, ".\0"); // print the decimal point frac = (val - floor(val)) * mult; unsigned long frac1 = frac; while(frac1 /= 10) padding--; while(padding--) strcat(outstr,"0\0"); // print padding zeros strcat(outstr,ltoa(frac,temp,10)); // print fraction part } // generate width space padding if ((widthp != 0)&&(widthp >= strlen(outstr))) { byte J=0; J = widthp - strlen(outstr); for (i=0; i< J; i++) { temp[i] = ' '; } temp[i++] = '\0'; strcat(temp,outstr); strcpy(outstr,temp); } return outstr; }
Обратите внимание на следующие строки:
//************************************************************************************ byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // MAC-адрес byte ip[] = { 192, 168, 1, 177 }; // IP-адрес #define PACHUBE_API_KEY "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890" // ВАШ PACHUBE_API_KEY #define PACHUBE_FEED_ID 00000 // ВАШ ID #define DATA_STREAM 1 //Номер PACHUME DATASTREAM #define ONE_WIRE_BUS 2 // Номер цифрового порта, к которому подключен термодатчик //************************************************************************************
Значения надо будет заменить своими данными. Вводим IP, который получит ардуина в локальной сети. С последним параметром (ONE_WIRE_BUS) надеюсь всё ясно — это номер цифрового порта Arduino, к которому подключен термодатчик.
Рассмотрим остальные параметры, которые вы получите на сайте pachube.com:
1. Регистрируемся на сайте pachube.com.
2. Создаём новую ленту (feed) в которой будут отображаться показания термодатчика. Для этого в правом меню выбираем «Create a feed»:

Вводим название ленты, описание, теги, при необходимости указываем местоположение.

Можно ввести адрес своего сайта и e-mail для связи.
Указываем, расположен ли датчик внутри помещения (indoor) или снаружи (outdoor), фиксированный (fixed) или мобильный (mobile), а также является ли он реальным (physical) или виртуальным (virtual).
После этого добавляем поток данных (Add a datastream), где вводим числовой ID (это как раз и будет параметром DATA_STREAM), теги, единицу измерения (Celsius) и символ (°C). Не забываем сохранить данные, нажав на кнопку «Save».

3. Теперь в правом меню выбираем «My keys». Затем «create a new key here».


Придумываем название ключа. Выбираем пункт «Use specific feed(s)», в выпадающем левом списке выбираем созданный ранее feed (Номер этой ленты будет параметром PACHUBE_FEED_ID). Если вы хотите, чтобы ключ работал только для одного потока данных, то в правом выпадающем списке выбираем конкретный номер потока. В параметрах доступа (Access Privileges) ставим галочки READ и UPDATE.
После этого жмём кнопку «Create».

Видим созданный нами ключик (это будет параметр PACHUBE_API_KEY). Не сообщайте его никому, он даёт доступ к обновлению данных.

Прошиваем скетч с вашими параметрами в ардуину, подключаем Ethernet Shield, термодатчик, ethernet-кабель. Включаем!
Опрос термодатчика происходит каждые 10 секунд. Один раз в минуту значения усредняются и отправляются на сервер. Следить за температурой можно по ссылке https://pachube.com/feeds/00000 , где вместо 00000 подставьте свой ID.
У меня график выглядел так:

P.S. данный сервис можно применять не только для контроля температуры, но и многих других данных: влажность, скорость ветра, энергопотребление и т.д.
Скетч
Библиотеки:
DallasTemperature
ERxPachube
Ethernet
OneWire
SPI
Работа проверялась с Arduino IDE v0.22
