Nejdříve je potřeba povolit ovladač sběrnice I2C. Sběrnice I2C (I2C-bus, Inter-IC-bus) je dvouvodičové datové propojení mezi jedním nebo několika procesory (Master) a speciálními periferními součástkami (Slave). Všechny součástky jsou připojeny na téže sběrnici a jsou cíleně vybírány svými adresami. Adresy i data se přenášejí stejnými vodiči. Sběrnice umožňuje velmi jednoduché propojení mezi několika integrovanými obvody a bezproblémové dodatečné rozšiřování například expander, LCD displej atd...
1) POVOLENÍ SBĚRNICE
Pokud používáme Raspbian budeme muset otevřít LX Terminál a zadat tento příkaz:
sudo nano /etc/modules
a přidat tyto dva řádky na konec souboru:
i2c-bcm2708
i2c-dev
Pro uložení stiskeme Ctrl + O a [enter] následované Ctrl-X.
Dále provedeme restart systému (aby se načetla změna).
V závislosti na naší distribuci také můžeme mít v souboru / etc / modprobe.d / raspi-blacklist.conf zakázanou I2C sběrnici. Pokud tento soubor nemáme není potřeba nic dělat, ale pokud máme tento soubor musíme ho upravit a zakomentovat tyto řádky:
sudo nano /etc/modprobe.d/raspi-blacklist.conf
V editoru, který se tímto příkazem otevře, se musí zakomentovat dvě řádky (připsat před ně "dvojkřížek" # )
#blacklist spi-bcm2708
#blacklist i2c-bcm2708
Pro uložení stiskeme Ctrl + O a [enter] následované Ctrl-X.
Jakmile je vše hotovo, můžeme zadat následující příkaz pro zobrazení všech připojených zařízení (pokud používáme 512MB Raspberry Pi Model B):
Pokud máme problémy s I2C na Raspbianu, potom je potřeba aktualizovat na nejnovější verzi. I2C sběrnice umožňuje více zařízení připojených k RPI (každý s jedinečnou adresou, která může být nastaven změnou pozic jumperů na modulu.)
Je velmi užitečné mít možnost vidět, která zařízení jsou připojena k RPI. Způsob jak zařízení zjistit spočívá v instalaci I2C těchto nástrojů:
sudo apt-get install python-SMBus
sudo apt-get install i2c-tools
Provedeme restart systému pro načtení změn a můžeme testovat...
sudo i2cdetect -y 1
Pokud používáme jeden z prvních RPI (Raspberry Pi 256 MB Model B), pak budeme muset změnit příkaz:
sudo i2cdetect -y 0
Pozor! návrháři RPI prohodily I2C porty dle typu desky RPI 512M používá I2C port 1 a RPI 256M používá I2C port 0!
Výpis mé sběrnice I2C
adresa 48 = AD-DA převodník PCF8591, 68 = RTC reálný čas DS1307
2) OBVOD REÁLNÉHO ČASU DS1307
Z důvodu nízké ceny mini počítače RPI (Raspberry Pi) neobsahuje modul hodin reálného času (RTC). Namísto toho se očekává, že uživatel je vždy připojen k Wi-Fi nebo Ethernetu a čas kontroluje pomocí sítě (NTP). Protože chceme udržet čas v RPI i bez připojení k síti je nutné osadit obvod reálného času a tak uchovávat v zařízení přesný čas i po vypnutí/zapnutí napájení. Modul obvodu reálného času obsahuje pouze tyto díly: DS1307, krystal, baterii 3V. Pozor v žádném případě nepřipojujte pull-up rezistory 2,2K ke sběrnici I2C a napájení obvodu +5V (tak jak uvádí doporučené zapojení v katalogu). Budeme používat RPI 1.8K pull-up rezistory připojené na 3.3V. Pokud toto nedodržíme lze RPI trvale poškodit! RPI je napájen 3,3V nikoliv 5V jako například Arduino.
Připojíme VCC RTC na 5.0V pin RPI
Připojíme GND RTC na GND pin RPI
Připojíme SDA RTC na SDA0 pin RPI
Připojíme SCL RTC na SCL0 pin RPI
Ověříme HW zapojení spuštěním příkazu:
sudo i2cdetect -y 0
na příkazovém řádku bychom měli vidět ID # 68 - to je adresa RTC obvodu DS1307. Pokud máme RPI REV 2 budeme muset spustit:
sudo i2cdetect -y 1
Nyní, když máme modul RTC připojen a ověřen můžeme modul vidět pomocí i2cdetect (68 = RTC reálný čas DS1307).
Můžeme spustit RTC modul.
sudo modprobe rtc-ds1307
Dále jako root spustíme (zadáme sudo bash )
echo ds1307 0x68 > /sys/class/i2c-adapter/i2c-0/new_device ( pokud máme rev 1 Pi )
echo ds1307 0x68 > /sys/class/i2c-adapter/i2c-1/new_device ( pokud máme rev 2 Pi )
Dále zkontrolujeme čas pomocí:
sudo hwclock -r
Příkaz čte čas z DS1307 modulu. Pokud je to poprvé, kdy byl modul použit bude hlásit 01.1.2000 a budemee muset čas nastavit ručně.
Nejprve budeme muset nastavit správný čas v RPI (nejjednodušší způsob je se připojit do sítě Ethernet nebo WiFi a tak automaticky nastavit čas ze sítě). Jakmile je nastaven správný čas spustíme:
sudo hwclock -w
pro zapsání systémového času do RTC. Poté můžeme ověřit že je čas uložen v RTC:
sudo hwclock -r
Dále budeme jistě chtít přidat jádro RTC modulu do seznamu souboru /etc/modules když RPI zapneme (bootování).
Spustíme sudo nano /etc/modules a přidáme rtc-ds1307 na konec souboru a uložíme.
Dále vytvoříme startovací sekvenci v rc. local / etc / rc.local
sudo nano /etc/rc.local
a přidáme řádky:
echo ds1307 0x68 > /sys/class/i2c-adapter/i2c-0/new_device ( pokud máme rev 1 Pi)
echo ds1307 0x68 > /sys/class/i2c-adapter/i2c-1/new_device ( pokud máme rev 2 Pi)
sudo hwclock -s (pro obě verze )
před exit 0. Při příštím spuštění systému bude čas automaticky synchronizován z obvodu hodin RTC.
2b) jiný lepší způsob spouštění synchronizace času RPI-RTC-NTP
Otevřeme v editoru /lib/udev/hwclock-set:
sudo nano /lib/udev/hwclock-set
změníme výrazy z “—systz” na "—hctosys". (bez uvozovek)
Vytvoříme script /etc/init.d/rtcdev:
sudo nano /etc/init.d/rtcdev
Nastavíme práva souboru:
sudo chmod 755 /etc/init.d/rtcdev
Povolíme script:
sudo update-rc.d rtcdev defaults
sudo update-rc.d rtcdev enable
Restartujeme RPI:
sudo reboot
Zkontrolujeme čas v RTC:
sudo hwclock -r
Zkontrolujeme systémový čas:
date
Pokud je systémový čas OK uložíme ho do RTC:
sudo hwclock -w
Pokud jsou oba časy špatně nastavíme čas ručně (pokud v RTC nic není uloženo a nemáme připojení k Internetu):
sudo hwclock --set --date="yyyy-mm-dd hh:mm:ss"
příklad:
sudo hwclock --set --date="2014-06-13 10:29:05"
Vytvoříme cron script pro kalibraci RTC času ze systému každý týden:
sudo nano /etc/cron.weekly/calrtc
Tento script nastaví RTC ze systémového času. Tento skript by měl být použit pouze v případě, že RPI má připojení k internetu ve většině času. Jestliže ne, měli bychom občas nastavit RTC ručně.
Nastavíme soubrou práva:
sudo chmod 755 /etc/cron.weekly/calrtc
Pokud se skript nachází v adresáři / etc / chron.weekly / budou se tyto scripty spouštět automaticky jednou týdně. Žádné další nastavení nejsou potřeba.
Vytvoříme cron script pro nastavení RTC pro drift každý den (nepřesnost obvodu RTC se musí dolaďovat):
sudo nano /etc/cron.daily/adjrtc
Nastavíme soubrou práva:
sudo chmod 755 /etc/cron.daily/adjrtc
Takto bude hw čas RTC používat opravu zpoždění každý den.
Nastavíme program ntp pro nastavování RTC když je k dispozici Internetové připojení:
sudo nano /etc/ntp.conf
Najdeme řádek se servery a přidám řádky:
Dále uložíme soubor (CTRL+O) a restartujeme RPI.
Provedeme test:
ntpq -p
Mělo by se zobrazit něco jako toto:
==============================================================================
-50.7.254.4 147.231.2.6 2 u 37 64 377 24.412 -7.064 1.994
+mx2.hodor.cz 147.231.100.5 3 u 43 64 377 6.330 3.098 1.882
*u001.net.paskov 195.113.144.201 2 u 45 64 377 10.744 2.560 1.436
+50.7.252.194 195.154.243.19 3 u 39 64 377 24.266 0.301 1.487
LOCAL(1) .LOCL. 12 l 1191 64 0 0.000 0.000 0.000
Poslední řádek LOCAL(1) je RTC jako časový server. Toto bude použito pouze jako poslední možnost programu NTP. Ve skutečnosti program, který dělá práci, se nazývá Ntpd, což je démon, který běží na pozadí. Systém by měl nyní zachovat přesný čas systému a hardwaru (RTC hodiny). V případě delšího výpadku internetu bude RTC sloužit k udržení aktuálního času.
Veškeré podrobnosti o programu ntp viz:
http://doc.ntp.org/4.2.0/index.html#conf
Pro použití ntpdate:
sudo service ntp stop
sudo ntpdate |pool.ntp.org|
sudo service ntp start
3) AD-DA převodník PCF8591
Převodník má 4 AD vstupy a jeden DA výstup jeho rozlišení je 8 bitů. Adresa AD převodníku je 0x48 (pokud jsou vstupy A0-A3 připojeny na gnd).
Schema připojení převodníku ke sběrnici I2C
Program v Pythonu pro čtení AD vstupů:
# AD prevodnik PCF8591 (4x A/D + 1 x D/A)
#!/usr/bin/python
import smbus
import time
# I2C sbernice novejsi RPI=1 starsi RPI=0
ADC = smbus.SMBus(1)
# Rutina precteni AD
def ctiVSTUP(X): # X = cislo ad kanalu (1 - 4)
ADC.write_byte_data(0x48, (0x40 + X),X)
time.sleep(0.2)
hodnota = ADC.read_byte(0x48) # cteme A/D
return hodnota # vrati hodnotu daneho vstupu
# Rutina zapsani na vystup DA
def VYSTUP(Y):
ADC.write_byte_data(0x48, 0x40,Y)
time.sleep(0.2)
while True: # Smycka
an1 = ctiVSTUP(1)
an2 = ctiVSTUP(2)
an3 = ctiVSTUP(3)
an4 = ctiVSTUP(4)
print ("AD1, AD2, AD3, AD4")
print (an1,an2,an3,an4) # prectene hodnoty
print ("zapisuji 255 na DA")
VYSTUP(255) # zapsana hodnota napriklad 255
time.sleep(0.5)