Samotné Raspíčko neumí zpracovávat analogové signály.
Stačí k němu ale připojit jeden obvod a okamžitě je k dispozici 8
analogových vstupů. Takže se dá RasPi použít
jako osminásobný voltmetr. Pokud se přidělají ještě nějaké vstupní
převodníky, bude možné měřit nejen napětí, ale také třeba proud,
odpor nebo i střídavé signály a jiné elektrické veličiny. Tato rozšíření
zde ale nebudu uvádět. Zaměřím se jen na ten základ, a to je osminásobný
stejnosměrný voltmetr.
Hned na začátku musím upozornit, že přesnost měření závisí hodně
na referenčním napětí, které je přivedeno na vývod č.15 A/D převodníku.
V následujícím popisu je tento vývod připojen na napájecí napětí
3,3V. Toto napětí ale není úplně přesné a také trochu kolísá
podle aktuálního výkonu procesoru a podle počtu a stavu připojených
periférií. Pokud byste chtěli větší přesnost, muselo by se na tento
referenční vstup připojit přesné a stabilní napětí. Například
pomocí napěťové reference (vysvětlení třeba zde: hw.cz).
Při zprovozňování A/D převodníku jsem vycházel z těchto stránek:
http://learn.adafruit.com/reading-a-analog-in-and-controlling-audio-volume-with-the-raspberry-pi/overview
Místo převodníku MCP3008, který je tam uvedený, jsem použil
MCP3208. Je podobný a má i stejně zapojené vývody.
Liší se pouze v rozlišení. MCP3008 je desetibitový a MCP3208 je dvanáctibitový.
To znamená, že pokud je referenční napětí nastaveno na 3,3V, odpovídá změna čísla
A/D převodu o jedničku u desetibitového obvodu MCP3008 změně napětí asi 3,2mV. U dvanáctibitového obvodu MCP3208 je to asi 0,8mV.
Jako vstup jsem použil víceotáčkový trimr, který jsem zapojil jako dělič
napětí a připojil jsem ho jedním koncem na napájecí napětí (3,3V)
a druhým koncem na GND (0V). Střední vodič jsem pak přímo přivedl
na první vstup A/D převodníku (CH0), takže se na tomto vstupu
mohlo plynule regulovat napětí od 0 do 3,3V. Zároveň jsem na tomto
vstupu kontroloval napětí multimetrem.
Protože jsem chtěl pouze měřit napětí, přeskočil jsem z výše
uvedeného návodu všechny kroky, které se zabývaly ovládáním hlasitosti.
Takže zbylo jen toto:
1) Nainstalovat nejnovější Python:
sudo apt-get install python-dev |
2) Pokud není nainstalována Pythoní podpora pro GPIO z minulých příkladů, tak je třeba jí doinstalovat:
sudo apt-get install python-pip
sudo pip install rpi.gpio |
3) Vytvořit soubor v /home/pi/ a nazvat ho třeba adc.py
sudo nano /home/pi/adc.py |
... a vložit do něj kód z těchto stránek:
http://learn.adafruit.com/reading-a-analog-in-and-controlling-audio-volume-with-the-raspberry-pi/script
Pak uložit a zavřít (Ctrl+X, Y, Enter)
Protože jsem už měl nějaké GPIO obsazené z předchozích pokusů (připojení displeje), musel jsem trochu upravit zapojení na volné GPIO porty a v konfiguraci skriptu jsem tyto nově zapojené porty musel nadefinovat:
Změny byly v těchto 4 vodičích:
- noha 13 u MCP3208 (CLK) byla původně GPIO18 (pin12) a já to změnil na GPIO11 (pin23)
- noha 12 u MCP3208 (DOUT) byla původně GPIO23 (pin16) a já to změnil na GPIO9 (pin21)
- noha 11 u MCP3208 (DIN) byla původně GPIO24 (pin18) a já to změnil na GPIO10 (pin19)
- noha 10 u MCP3208 (CS) byla původně GPIO25 (pin22) a já to změnil na GPIO21 (pin13)
A protože nechci řídit hlasitost, tak jsem vyházel kusy kódu, které se o tu hlasitost staraly.
Nechal jsem jen zobrazovat hodnotu A/D převodníku a přepočtenou hodnotu napětí.
Také jsem musel ve skriptu změnit o dva bity rozlišení převodníku.
Takže celý upravený skript vypadá takto:
#!/usr/bin/env python
import time
import os
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
# read SPI data from MCP3008 chip, 8 possible adc's (0 thru 7)
def readadc(adcnum, clockpin, mosipin, misopin, cspin):
if ((adcnum > 7) or (adcnum < 0)):
return -1
GPIO.output(cspin, True)
GPIO.output(clockpin, False) # start clock low
GPIO.output(cspin, False) # bring CS low
commandout = adcnum
commandout |= 0x18 # start bit + single-ended bit
commandout <<= 3 # we only need to send 5 bits here
for i in range(5):
if (commandout & 0x80):
GPIO.output(mosipin, True)
else:
GPIO.output(mosipin, False)
commandout <<= 1
GPIO.output(clockpin, True)
GPIO.output(clockpin, False)
adcout = 0
# read in one empty bit, one null bit and 12 ADC bits
# pro desetibitovy prevodnik tu bylo puvodne cislo 12
for i in range(14):
GPIO.output(clockpin, True)
GPIO.output(clockpin, False)
adcout <<= 1
if (GPIO.input(misopin)):
adcout |= 0x1
GPIO.output(cspin, True)
adcout >>= 1 # first bit is 'null' so drop it
return adcout
# change these as desired - they're the pins connected from the
# SPI port on the ADC to the Cobbler
SPICLK = 11 # zmena z puvodniho 18
SPIMISO = 9 # zmena z puvodniho 23
SPIMOSI = 10 # zmena z puvodniho 24
SPICS = 21 # zmena z puvodniho 25
# set up the SPI interface pins
GPIO.setup(SPIMOSI, GPIO.OUT)
GPIO.setup(SPIMISO, GPIO.IN)
GPIO.setup(SPICLK, GPIO.OUT)
GPIO.setup(SPICS, GPIO.OUT)
# 10k trim pot connected to adc #0
potentiometer_adc = 0;
while True:
# a tady jen cyklicke cteni dat a prepocet trojclenkou na napeti
# vsechno ostatni jsem vyhazel
trim_pot = readadc(potentiometer_adc, SPICLK, SPIMOSI, SPIMISO, SPICS)
# 3,3V je reference (rozsah mereni), 4095 je maximalni hodnota prevodniku
napeti = 3.3 * trim_pot / 4095
print "Digital:", trim_pot , "\t Napeti:", round(napeti,3), "V"
time.sleep(0.5)
exit (0)
|
Proměnná potentiometer_adc udává, ze kterého vstupu se má napětí převádět.
Je možné měřit až 8 nezávislých vstupů se společnou zemí (0 až 7).
V návodu se píše, že má mít skript nastaven atribut
spustitelnosti, ale fungovalo to i když jsem ho nenastavoval.
Na závěr už stačí skript spustit a koukat, jak převodník při otáčení
trimru měří napětí.
sudo python /home/pi/adc.py |
(Ukončení běhu skriptu se provede klávesami Ctrl+C)
Když už jsem měl program vyzkoušený, upravil jsem ho tak, aby
napětí a hodnotu A/D převodníku zobrazoval přímo na připojeném displeji.
Protože referenční napětí nebylo přesně 3,3V, upravil jsem v kódu
hodnotu reference na skutečné napětí (3,32V)
Tady je úprava hlavní smyčky výše uvedeného programu pro zobrazení
hodnoty na displeji:
while True:
trim_pot0 = readadc(0, SPICLK, SPIMOSI, SPIMISO, SPICS)
napeti0 = round(3.32 * trim_pot0 / 4095 ,2)
prikaz = "sudo python /home/pi/display 'Napeti = " + str(napeti0) + " V' 'Digit = " + str(trim_pot0) + "'"
os.system (prikaz)
time.sleep (0.5)
|
A tady je video (asi 6MB):
Pokud vám stačí měřit pouze jeden napěťový kanál,
popisuji v článku 57) A/D převodník
MCP3021