Pomocí i2cdetect si vyhledáme dostupná zařízení:
root@OpenWrt:/tmp# i2cdetect -y 0
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- 19 -- -- -- -- 1e --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- 6b -- -- -- --
70: -- -- -- -- -- -- -- --
Akcelerometr má dle dokumentace adresu 00011001=0x19, digitální kompas 00001110=0x1e a nakonec gyroskop 1101010=0x6A nebo 1101011=0x6B, v závislosti na zapojení adresního pinu. Nejnižší bit adresy gyroskopu tvoří právě stav nožičky SDO.
Nyní si již stačí prostudovat významy registrů a můžeme začít laborovat s daty. Dále následuje jednoduchý příklad čtení hodnot X, Z a Y z kompasu.
#/bin/ash
# inicializace
# CRA_REG_M (00h)
# TEMP_EN | 0 | 0 | DO2 | DO1 | DO0 | 0 | 0 |
# DO2 | DO1 | DO0 | Minimum data output rate (Hz)
# 0
| 0 |
0 | 0.75
# 0
| 0 |
1 | 1.5
# 0
| 1 |
0 | 3.0
# 0
| 1 |
1 | 7.5
# 1
| 0 |
0 | 15
# 1
| 0 |
1 | 30
# 1
| 1 |
0 | 75
# 1
| 1 |
1 | 220
i2cset -y 0 0x1e 0x00 0x9c # 220 Hz, teploměr
povolen
# CRB_REG_M (01h)
# GN2 | GN1 | GN0 | 0 | 0 | 0 | 0 | 0 |
# GN2 | GN1 | GN0 | Sensor input field range [Gauss] | Gain X, Y, and Z
[LSB/Gauss] | Gain Z [LSB/Gauss]
# 0
| 0 |
1 | +-1.3 | 1100 | 980
# 0
| 1 |
0 | +-1.9 | 855 | 760
# 0
| 1 |
1 | +-2.5 | 670 | 600
# 1
| 0 |
0 | +-4.0 | 450 | 400
# 1
| 0 |
1 | +-4.7 | 400 | 355
# 1
| 1 |
0 | +-5.6 | 330 | 295
# 1
| 1 |
1 | +-8.1 | 230 | 205
i2cset -y 0 0x1e 0x1 0xE0 # +-8.1 Gauss
# MR_REG_M (02h)
# 0 | 0 | 0 | 0 | 0 | 0 | MD1 | MD0 |
# MD1 | MD0 | Mode |
# 0
| 0 | Continuous-conversion mode
# 0
| 1 | Single-conversion mode
# 1
| 0 | Sleep mode. Device is placed in sleep mode
# 1
| 1 | Sleep mode. Device is placed in sleep mode
i2cset -y 0 0x1e 0x2 0x00 # Continuous-conversion
mode
while true; do
X=`i2cget -y 0 0x1e 0x3
w` # Xsová osa
Z=`i2cget -y 0 0x1e 0x5
w` # Zetová osa
Y=`i2cget -y 0 0x1e 0x7
w` # Ylonová osa
Teplota=`i2cget -y 0 0x1e
0x31 w` # teplota
#echo "X=$X,Z=$Z,Y=$Y"
echo -e "$X\t$Z\t$Y\t$Teplota"
done
Obrázek znázorňuje zápis na adresu 0x00, zápis je uvozen start bitem, dále následuje 7bitů adresy, příznak čtení či zápisu (log. 1 = čtení, log. 0 = zápis) a potvrzení od senzoru (ACK). Dalším bajtem je adresa, tedy 0x00, a zapisovaná hodnota 0x9C, každý přijatý bajt je se slavem potvrzen.
Tento obrázek naopak znázorňuje čtení jedné hodnoty intenzity magnetického pole z registrů 0x03 a 0x04, načtená hodnota je 0xfdff. Nejprve je zaslána (zapsána) adresa a poté už čteme data.
Obrázek znázorňuje zápis na adresu 0x00, zápis je uvozen start bitem, dále následuje 7bitů adresy, příznak čtení či zápisu (log. 1 = čtení, log. 0 = zápis) a potvrzení od senzoru (ACK). Dalším bajtem je adresa, tedy 0x00, a zapisovaná hodnota 0x9C, každý přijatý bajt je se slavem potvrzen.
Tento obrázek naopak znázorňuje čtení jedné hodnoty intenzity magnetického pole z registrů 0x03 a 0x04, načtená hodnota je 0xfdff. Nejprve je zaslána (zapsána) adresa a poté už čteme data.
Nyní bude potřeba se naučil používat matematické funkce, jako je například arkus tangens. K tomu stačí donistalovat knihovnu bc (opkg install bc). Dále je nutné příkaz správně zapsat, vypočteme si tedy sinus 0 a Ludolfova čísla. Parametr s znamená funkce sinus, přepínač -l tyto funkce "zapíná":
root@OpenWrt:/tmp# echo "s(0)" | bc -l
0
root@OpenWrt:/tmp# echo "s(3.14/2)" | bc -l
.99999968293183462021
Funguje to, jdeme na arkus tangens. Pomocí následujícího výpočtu tedy získáme úhel, kde máme zrovna sever. Ano dělení pro X=0 to nepůjde ale naštěstí se to tak často nestává (:-)
echo "180*a($Y/$X)/3.14" | bc -l
A máme jednoduchý kompas, výsledný cyklus bude tedy vypadat takto:
Jak otestovat funkčnost? Pokoušel jsem se přibližovat magnet po Zetové ose (červená), z obrázku je patrné jak dochází k ovlivňování všech os. Ale Zetová přeteče nejdříve a má také nejstrmější nárůst.
Pokračování? Co to takhle z legrace napsat v céčku?root@OpenWrt:/tmp# echo "s(0)" | bc -l
0
root@OpenWrt:/tmp# echo "s(3.14/2)" | bc -l
.99999968293183462021
Funguje to, jdeme na arkus tangens. Pomocí následujícího výpočtu tedy získáme úhel, kde máme zrovna sever. Ano dělení pro X=0 to nepůjde ale naštěstí se to tak často nestává (:-)
echo "180*a($Y/$X)/3.14" | bc -l
A máme jednoduchý kompas, výsledný cyklus bude tedy vypadat takto:
while true; do
X=`i2cget -y 0 0x1e 0x3
w` # Xsová osa
Z=`i2cget -y 0 0x1e 0x5
w` # Zetová osa
Y=`i2cget -y 0 0x1e 0x7
w` # Ylonová osa
Teplota=`i2cget -y 0 0x1e
0x31 w` # teplota
#echo "X=$X,Z=$Z,Y=$Y"
Xhex="${X//0x/}" # nahradíme 0x za nic
Zhex="${Z//0x/}"
Yhex="${Y//0x/}"
Xvalue=$(echo "ibase=16; $Xhex"
| bc) # HEX na BIN
Xhex="$(echo
$Xhex | tr [a-f] [A-F])"
Zhex="$(echo $Zhex | tr [a-f] [A-F])"
Yhex="$(echo $Yhex | tr [a-f] [A-F])"
Zvalue=$(echo
"ibase=16; $Zhex" | bc)
Yvalue=$(echo
"ibase=16; $Yhex" | bc)
echo -e "$Xvalue\t$Zvalue\t$Yvalue\t$Teplota"
echo "180*a($Yvalue/$Xvalue)/3.14" | bc -l
done
Jak otestovat funkčnost? Pokoušel jsem se přibližovat magnet po Zetové ose (červená), z obrázku je patrné jak dochází k ovlivňování všech os. Ale Zetová přeteče nejdříve a má také nejstrmější nárůst.
Datasheet k LSM303DLHC
Datasheet L3GD20
Počítání v příkazové řádce
Žádné komentáře:
Okomentovat