WstępCzasami zachodzi konieczność pomiarów wielkości analogowych jak napięcie, prąd. Chciałbym przedstawić na kilku praktycznych przykładach wykorzystania przetwornika analogowo-cyfrowego w routerze z zainstalowanym firmware OpenWrt. W tym artykule wykorzystano przetwornik NXP PCF8591P komunikujący się z routerem po szynie danych I2C. Do poprawności działania potrzebujemy dwa wolne punkty GPIO lub (niepotwierdzone) konwerter USB- I2C ze strony
http://www.harbaum.org/till/i2c_tiny_usb/index.shtmlUWAGA:Na początku chciałbym poinformować, że przetwornik PCF8591P według dokumentacji wymaga napięcia zasilania w zakresie 2.5V – 6V. Z do końca nie wiadomych mi jak dotąd przyczyn moje egzemplarze działają poprawnie tylko przy +5V, niższego nie akceptują. Ciężko mi stwierdzić czy trafiłem na taką partię czy tak powinno być, a dokumentacja “kłamie”. Jeżeli w przyszłości trafie na egzemplarze akceptujące niższe napięcie( w tym preferowane 3.3V) zmodyfikuje opis. W takiej sytuacji musimy albo skorzystać z zasilania +5V z USB, lub zasilacza (po zastosowaniu stabilizatora 5V jeżeli to konieczne).
Trochę teoriiPrzetwornik analogowo-cyfrowy pomijając wszelkie matematyczne aspekty zamienia wielkość analogową(ciągłą) w postać cyfrową (zerojedynkową). Jednym z istotnych parametrów takiego przetwornika jest rozdzielczość, która określa dokładność mierzonych wielkości.
Przetwornik PCF8591P jest przetwornikiem 8-bitowym, oznacza to, że potrafi przetworzyć próbkę na jedną z 256 wartości liczbowych. Do zastosowań jakie niżej zostaną przedstawione jest wystarczająca.
Podstawowy schemat połączeń jakie będzie obowiązywał dla wszystkich przedstawionych przykładów znajduje się poniżej.

Wyjaśnienia wymagają piny A0-A2, które w zależności jaki stan wpiszemy(0-masa, 1- plus) ustawią adres pod jakim nasz przetwornik będzie widoczny w systemie. Domyślnie ustawiamy wszystkie na zera, więc nasz przetwornik w OpenWrt będzie widoczny pod adresem 0x48. Innymi słowy możemy ustawić jeden z 8 adresów.
Pin VREF stanowi napięcia odniesienia w stosunku do którego nasze pomiary będą robione, u nas 5V. Zastosowany przetwornik wyposażony jest w cztery kanały do pomiaru wielkości analogowych.
PCF8591 w OpenWrtDo poprawnej pracy potrzebujemy moduł kernela
kmod-i2c-gpio-custom, który jest domyślnie dostępny w repozytorium OpenWrt. Moduł
kmod-hwmon-pcf8591 jest opcjonalny, gdyż można posiłkować się narzędziami
i2c-tools i odwoływać się do konkretnych rejestrów. Jednak w opisie decyduje się korzystać z tego modułu, gdyż praca z nim jest przyjemniejsza.
# opkg update
# opkg install kmod-i2c-gpio-custom
# opkg install http://openwrt.pl/dl/pakiety/kmod-hwmon-pcf8591_2.6.32.27-1_ar71xx.ipk
ustawiamy punkty GPIO jako SDA i SCL
# insmod i2c-gpio-custom bus0=0,6,7
lub
# echo "i2c-gpio-custom bus0=0,6,7" > /etc/modules.d/i2c-gpio-custom
Po chwili lub restarcie przetwornik jest widoczny w
sysfs pod
/sys/class/i2c-dev/i2c-0/device/0-0048/ # ls /sys/class/i2c-dev/i2c-0/device/0-0048/
driver in1_input in3_input name out0_output uevent
in0_input in2_input modalias out0_enable subsystem
Prosty skrypt odczytujący co sekundę w niskończoność wartość na wyjściu 0 przetwornika A/D:
#!/bin/sh
while true
do
raw=`cat /sys/class/i2c-dev/i2c-0/device/0-0048/in0_input`
echo $raw
sleep 1
done
W/w skrypt będzie rozszerzany w konkretnych zastosowaniach.
Pomiar napięcia baterii/akumulatoraPierwszy przykład to pomiar napięcia baterii. Wykorzystano tutaj dwie baterie paluszki NiMH połączone szeregowo.
Do przetwornika podłączamy po prostu – masa baterii do masy oraz plus do A0 przetwornika.
Skrypt mierzący napięcie może wyglądać:
#!/bin/sh
while true
do
raw=`cat /sys/class/i2c-dev/i2c-0/device/0-0048/in0_input`
echo $raw | awk '{printf "%.2fV\n", $1*5/2560}'
sleep 1
done
Wynik:
2.60V
2.60V
2.60V
Tą samą baterię pomierzyłem zwykłym multimetrem i wskazania były bardzo zbliżone.
Może zajść konieczność pomiaru napięcia większego niż 5V, wówczas musimy zrobić prosty dzielnik napięcia z dwóch rezystorów, tak aby dostosować do napięcia referencyjnego (5V). Schemat pomiaru napięcia do 20V będzie wyglądał następująco:

Modyfikujemy skrypt:
#!/bin/sh
while true
do
raw=`cat /sys/class/i2c-dev/i2c-0/device/0-0048/in0_input`
echo $raw | awk '{printf "%.2fV\n", $1*5/2550/0.25}'
sleep 1
done
Wyniki:
13.73V
13.73V
13.73V
Cały wynik dzielimy dodatkowo przez 0.25, gdyż tyle wynosi stosunek zastosowanych rezystorów (R2/R1+R2). Więcej o dzielnikach napięcia na
WikipediiZastosowanie: pomiar baterii zasilania routera, pomiar baterii słonecznej.
Pomiar temperatury czujnikiem LM35Czujnik LM35 jest analogowym czujnikiem temperatury firmy National Semiconductors. Zakres mierzonych temperatur -55 do +150*C. Na wyjściu czujnika otrzymujemy 10mV na każdy stopień Celsiusza. Z powodu niedostępności napięcia ujemnego, przykład będzie dotyczył pomiaru temperatur dodatnich.

Zmodyfikowany skrypt:
#!/bin/sh
while true
do
raw=`cat /sys/class/i2c-dev/i2c-0/device/0-0048/in0_input`
echo $raw | awk '{printf "%.f*C\n", ($1*5*100)/2550}'
sleep 2
done
Wynik:
27*C
27*C
27*C
Pomiar nasłonecznieniaFotorezystor to taki element, który w zależności od światła przyjmuje odpowiednia rezystancję. W połączeniu w rezystorem tworzy dynamiczny dzielnik napięcia. Na wyjściu otrzymujemy napięcie, które po kalibracji można przypisać do tekstowego opisu pory dnia. Duże nasłonecznienie powoduje ze napięcie spada do wartości bliskich zera.

Skrypt:
#!/bin/sh
while true
do
raw=`cat /sys/class/i2c-dev/i2c-0/device/0-0048/in0_input`
echo $raw | awk '{printf "%.2fV\n", $1*5/2550}'
sleep 1
done
Wynik:
2.73V
2.75V
3.37V
3.31V
2.78V
Zastosowanie: Uzależnienie pracy aplikacji od pory dnia, pomiar nasłonecznienia.
PodsumowaniePrzykłady można mnożyć, dlatego też temat nie został całkowicie wyczerpany. Na rynku jest szereg czujników, urządzeń analogowych, które można w ten sposób "badać".