Мониторинг температуры: TEMPer + DIR-320

в 10:05, , рубрики: diy или сделай сам, Песочница, термометр, метки: ,

Я давно хотел заменить обычный термометр за окошком на что-то более современное – на цифровой. Но который будет не просто показывать температуру в более удобном формате, но и записывать её значение в базу данных (например, чтобы потом построить красивый график).

Паять что-то самому не хотелось, поэтому стояла задача обойтись готовыми решениями. Что получилось, читайте под катом.

1. Датчик

В качестве датчика был выбран TEMPer1. Ни по какой-то особенной причине, просто он попался мне первым. Был заказан на eBay у китайских друзей за $10. Первая проверка под виндой показала, что датчик отлично справляется со своей функцией – измеряет температуру. ;)

Поскольку рядом есть как минимум два устройства с линуксом на борту (роутер и спутниковый ресивер), для работы с датчиком захотелось использовать именно их. Покопав немного софт ресивера, я не нашёл там libusb для работы с USB, а вот для роутера эта библиотека была, так что выбор пал на него.

2. DIR-320 и libusb

Итак, я остановился на том, чтобы подключить датчик к имеющемуся DIR-320. После перепрошивки (DD-WRT v24-sp2 mini-usb-ftp, 18946 NEWD), TEMPer появился в /proc/bus/usb/devices:

T: Bus=02 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 14 Spd=1.5 MxCh= 0
D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1
P: Vendor=0c45 ProdID=7401 Rev= 0.01
S: Manufacturer=RDing
S: Product=TEMPer1V1.2
C:* #Ifs= 2 Cfg#= 1 Atr=a0 MxPwr=100mA

Чтобы считать с него показания, понадобится крохотная программа, использующая libusb для работы с USB. Сама libusb входит в стандартные пакеты, так что выполнив
ipkg install libusb
мы получим libusb-0.1.so.4 в /jffs/usr/lib/.

Поскольку нам нужен заголовочный файл usb.h, качаем исходник библиотеки. Сколько я ни пытался, заставить собраться программу с готовой libusb у меня не получилось (интересно, почему?) – линкер упорно матерился, поэтому распаковав исходник, пришлось собрать libusb самостоятельно. Для кросс-компиляции под MIPS был использован toolchain (gcc 4.3.5 uClibc 0.9.30.1) x86 build 2010.12.24. Взять можно здесь. Процесс стандартный: configure и затем make. В результате получилась libusb в два раза больше по размеру, но зато рабочая. Заливаем в роутер, заменяя существующий файл libusb-0.1.so.4.4.2.

3. Софт

На pcsensor.com несложно найти исходник программы, которая считывает показания с датчика. Он и был взят за основу. Была добавлена обработка ошибок и кусок, отправляющий данные на сервер (через простой GET запрос). Вот, что получилось. Компилируем, заливаем на роутер, проверяем – всё отлично работает.

Сама программа запускается примитивным скриптом через cron:

#!/bin/sh

LD_LIBRARY_PATH=/jffs/usr/lib
export LD_LIBRARY_PATH

LIMIT=10
a=1
while [ "$a" -le $LIMIT ]
do
    /jffs/temp --report
    if [ $? -eq 0 ]; then break; fi

    echo "temp failed, run again in 5 sec"
    sleep 5
    let "a+=1"
done

Цикл пришлось намудрить, поскольку по неизвестным причинам изредка считать показания не удаётся (кто виноват – роутер или сам датчик, не знаю).

На сервере значение температуры заносится в базу с помощью простого перлового скрипта. Как использовать эти данные, зависит, конечно, от задачи. Я просто строю графики колебаний температуры за окном (по часам, по суткам).

4. Калибровка датчика

На сайте производителя заявлена разрешающая способность 0.06°C и точность ±2°C. Для бытовых целей вполне достаточно. Интересно проверить, насколько выдаваемые датчиком значения температуры соответствуют реальным. В домашних условиях навскидку можно предложить три источника известной (с небольшими погрешностями) температуры: морозилка (вода со льдом, 0°C), чайник (кипящая вода, 100°C) и ртутный градусник (34-42°C).

Наиболее близкие значения дала такая поправка (см. исходный код):

int t = a[3] + (a[2] << 8);
t += 208;
float temp = t * (125.0 / 32000.0) * 1.045;

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

Таким образом, подключив дешёвый USB-термометр к роутеру, получили автономное решение для измерения температуры за окошком, внутри системного блока или ещё где-то. Надеюсь, кому-то это решение пригодится.

Автор: EvgeshaS

Поделиться

  1. Vitali:

    Как компилировать приложение и Libusb? Распишите пожалуйста подробнее, желательно под Windows.

  2. Konstantin:

    Доброй ночи.

    Собрал libusb таким образом:

    AR=/dop/current-toolchains/toolchain-mipsel_gcc4.1.2/bin/mipsel-linux-ar \
    AS=/dop/current-toolchains/toolchain-mipsel_gcc4.1.2/bin/mipsel-linux-as \
    LD=/dop/current-toolchains/toolchain-mipsel_gcc4.1.2/bin/mipsel-linux-ld \
    NM=/dop/current-toolchains/toolchain-mipsel_gcc4.1.2/bin/mipsel-linux-nm \
    CC=/dop/current-toolchains/toolchain-mipsel_gcc4.1.2/bin/mipsel-linux-gcc \
    CPP=»/dop/current-toolchains/toolchain-mipsel_gcc4.1.2/bin/mipsel-linux-gcc -E» \
    GCC=/dop/current-toolchains/toolchain-mipsel_gcc4.1.2/bin/mipsel-linux-gcc \
    CXX=/dop/current-toolchains/toolchain-mipsel_gcc4.1.2/bin/mipsel-linux-g++ \
    RANLIB=/dop/current-toolchains/toolchain-mipsel_gcc4.1.2/bin/mipsel-linux-ranlib \
    STRIP=/dop/current-toolchains/toolchain-mipsel_gcc4.1.2/bin/mipsel-linux-strip \
    CPPFLAGS=»-O2 -pipe» \
    ./configure \
    —build=i386-pc-linux-gnu \
    —host=mipsel-linux \
    —target=mipsel-linux \
    —disable-udev

    Скопировал libusb.h в /dop/current-toolchains/toolchain-mipsel_gcc4.1.2/include/
    Скопировал libusb-1.0.so.0.1.0, libusb-1.0.so в /dop/current-toolchains/toolchain-mipsel_gcc4.1.2/lib/

    https://github.com/ermolenkom/noolite
    Заменил в makefile псс на toolchain-mipsel_gcc
    export LD_LIBRARY_PATH=/dop/current-toolchains/toolchain-mipsel_gcc4.1.2/lib/:$LD_LIBRARY_PATH
    export PATH=$PATH:/dop/current-toolchains/toolchain-mipsel_gcc4.1.2/bin/
    export SDL_INCLUDE=-I/dop/current-toolchains/toolchain-mipsel_gcc4.1.2/include/
    export SDL_LIB=-L/dop/current-toolchains/toolchain-mipsel_gcc4.1.2/lib/

    Получаю:
    /dop/current-toolchains/toolchain-mipsel_gcc4.1.2/bin/mipsel-linux-gcc -o noolitepc noolitepc.o -lusb-1.0
    /dop/current-toolchains/toolchain-mipsel_gcc4.1.2/bin/../lib/gcc/mipsel-linux-uclibc/4.1.2/../../../../mipsel-linux-uclibc/lib/libusb-1.0.so: undefined reference to `pthread_create’
    /dop/current-toolchains/toolchain-mipsel_gcc4.1.2/bin/../lib/gcc/mipsel-linux-uclibc/4.1.2/../../../../mipsel-linux-uclibc/lib/libusb-1.0.so: undefined reference to `pthread_mutexattr_destroy’
    /dop/current-toolchains/toolchain-mipsel_gcc4.1.2/bin/../lib/gcc/mipsel-linux-uclibc/4.1.2/../../../../mipsel-linux-uclibc/lib/libusb-1.0.so: undefined reference to `pthread_mutexattr_settype’
    /dop/current-toolchains/toolchain-mipsel_gcc4.1.2/bin/../lib/gcc/mipsel-linux-uclibc/4.1.2/../../../../mipsel-linux-uclibc/lib/libusb-1.0.so: undefined reference to `pthread_mutexattr_init’
    /dop/current-toolchains/toolchain-mipsel_gcc4.1.2/bin/../lib/gcc/mipsel-linux-uclibc/4.1.2/../../../../mipsel-linux-uclibc/lib/libusb-1.0.so: undefined reference to `pthread_mutex_trylock’
    /dop/current-toolchains/toolchain-mipsel_gcc4.1.2/bin/../lib/gcc/mipsel-linux-uclibc/4.1.2/../../../../mipsel-linux-uclibc/lib/libusb-1.0.so: undefined reference to `pthread_join’
    collect2: ld returned 1 exit status
    make: *** [noolitepc] Ошибка 1

    Как победить?

* - обязательные к заполнению поля