I2C dla RPI i WiringPi

Dziś postanowiłem pokazać jak obsłużyć szeregową szynę TWI (Two Wire, która wykorzystuje tylko 2 piny), czyli popularny I2C. Transmisja szeregowa jest bardzo użyteczna ponieważ RPI ma bardzo mało pinów, a dzięki tej transmisji będziemy mogli podłączyć praktycznie nieograniczoną ilość urządzeń.

W Linuxie oczywiście już ktoś zaimplementował biblioteki tej transmisji, dlatego nie będę wymyślał koła od nowa, ale pokaże jak korzystać z dobrodziejstw internetu i obsłużę w najprostszy sposób układ ADXL345 za pomocą bibliotek WiringPi. Żeby tego dokonać należy zainstalować biblioteki WiringPi i I2C. Całość można znaleźć tu: https://projects.drogon.net/raspberry-pi/wiringpi/i2c-library/

Następnie dobrze jest uruchamiać I2C przy starcie systemu:

Należy zmodyfikować plik:

sudo nano /etc/modules

Wpisać należy tam wiersze (pierwszy zazwyczaj wystarcza):

i2c-bcm2708
i2c-dev

Po zapisaniu tego pliku należy edytować zbiór:.

sudo nano /etc/modprobe.d/raspi-blacklist.conf

Należy zakomentować linie dotyczącą I2C wpisując znak '#' na jej początku:

#blacklist i2c-bcm2708

Teraz wystarczy tylko podłączyć nasz układ:

i zainstalować biblioteki:

sudo apt-get install libi2c-dev

oraz odpalić I2C z konsoli:

gpio load i2c

Jak ktoś chciałby ten układ, to można go dostać ze sklepu:

http://botland.com.pl/akcelerometry-moduly/1912-adxl345-3-osiowy-akcelerometr-cyfrowy-i2c-spi-modul.html

Po tych czynnościach należy użyć komendy:

i2cdetect -y 0 # dla Rev 1
i2cdetect -y 1 # dla Rev 2

Powyższa komenda jest po to aby dowiedzieć się jaki adres ma nasz układ. Wszystkie te informację są w nocie katalogowej danego układu:

http://www.analog.com/static/imported-files/data_sheets/ADXL345.pdf

Powinniście mieć taki efekt:

Liczba 53 jest adresem szesnastkowym naszego urządzenia. Teraz wystarczy napisać program w C do obsługi naszego urządzenia. Aby tego dokonać trzeba przestudiować notę katalogową i odnaleźć rejestry uruchamiające odczyt. Na stronie 23 mamy opis wszystkich  rejestrów:

Aby uruchomić pomiar należy w rejestrze 0x2D załączyć bit measure.

Czyli po prostu wysłać do 0x2D liczbę 8.

Z noty wiemy, że rejestr 0x32, 0x34 i 0x36 (dziesiętnie 50, 52, 54) odpowiedzialne są za dane z akcelerometru. Czyli, aby odczytać dane z urządzenie wystarczy pobrać dane z tych rejestrów.

Cały kod w C powinien wyglądać tak:

/*
* i2c.c:
* Simple test I2C. Device ADXL 345
***********************************************************************
*/
 
#include <wiringPi.h>
#include <wiringPiI2C.h>
#include <softPwm.h>
 
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
 
 
int main (void)
{
int fd, dane, idDev=0x53;
FILE *fp;
 
 
if(wiringPiSetup() == -1)
 exit(1);
 
if((fd=wiringPiI2CSetup(idDev)) == -1){
 printf("error initialize I2C");
 exit(1);
}
printf(" I2C modul ADXL 345");
 
 //Start measure
 wiringPiI2CWriteReg8(fd, 0x2D, 8);
 
//read X
 dane = wiringPiI2CReadReg8(fd,50);
 printf("\ndane x: %d",dane);
 //read Y
 dane = wiringPiI2CReadReg8(fd,52);
 printf("\ndane y: %d",dane);
 //read Z
 dane = wiringPiI2CReadReg8(fd,54);
 printf("\ndane z: %d",dane);
 delay (100) ; 
return 0 ;
}