Bei den meisten Sensor- oder Roboteranwendungen müssen analoge Werte eingelesen und verarbeitet werden. Leider besitzt der Raspberry Pi keinen eingebauten Analog-Digital-Wandler (ADC). Mit dem ADS1015 von Texas Instruments kann so einer leicht nachgerüstet werden.
Gehäuse und Anschluss
Der ADS1015 kommt in einem 10 pinnigen VSSOP-Gehäuse. Das ist zwar schon relativ klein, kann aber noch von Hand gelötet werden. Alternativ gibt es von Adafruit ein Breakout-Board .
I2C-Bus
Der ADS1015 wird an den I2C-Bus angeschlossen und hat in der Grundkonfiguration mit dem ADDR-Pin auf Masse die Adresse 0×48.
Eigenschaften des AD-Wandlers
Der ADC vom ADS1015 hat 12 bit Auflösung und 4 Kanäle, die entweder einzeln ausgewertet werden können oder jeweils zwei Kanäle können als differentielle Eingänge verwendet werden. Der Chip hat eine interne Referenzspannung und funktioniert mit einer Versorgungsspannung von 2,0 bis 5,5 V. Beim Raspberry Pi bietet es sich an, ihn mit 3,3 V zu betreiben.
Ansteuerung
Wenn man nur in regelmäßigen Abständen einzelne Werte auslesen möchte, bietet es sich an, den single shot Modus zu verwenden. Dazu wird vor einer Wandlung der entsprechende Kanal ausgewählt und das Bit 15 / OS gesetzt, dass eine Wandlung gestartet wird. Außerdem kann der gain amplifier entsprechend gesetzt werden. Wenn einzelne Kanäle bei einer Versorgungsspannung von 3,3 V gemessen werden sollen, bietet es sich an +-4,096 V (also 001) einzustellen. Somit muss zum Beispiel um eine Wandlung auf Kanal 0 zu starten C383 hex ins config register geschrieben werden. Danach muss das config register regelmäßig ausgelesen werden, bis Bit 15 gesetzt ist. Dann ist die Wandlung fertig und der Wert kann aus dem conversion register ausgelesen werden.
Beispielprogramm
Das komplette Programm für einen Raspberry Pi findest du hier:
#include <stdio.h> #include <stdlib.h> #include <sys/stat.h> #include <linux/i2c-dev.h> #include <fcntl.h> #include <unistd.h>
unsigned short int swap_bytes(unsigned short int input) { return (((input & 0xff) << 8) | ((input >> 8) & 0xff)); }
int read_channel(unsigned int channel, int file) { int adc_data=0,x=0;
if(channel>3) return -1; i2c_smbus_write_word_data(file,0x01,swap_bytes((0xc383|(channel<<12)))); do { x=swap_bytes(i2c_smbus_read_word_data(file, 0x01)); // config register printf("Config register: 0x%04x\n", x); } while(!(x&0x8000)); adc_data=swap_bytes(i2c_smbus_read_word_data(file, 0x00)); // conversion register printf("Conversion register (channel %i): 0x%04x = %i\n\n", channel, adc_data,adc_data); return adc_data; }
int main(void) { int file;
printf("Texas Instruments ADS1015\n\n"); if((file=open("/dev/i2c-1",O_RDWR))<0) // open i2c-bus { perror("cannot open i2c-1"); exit(1); } if(ioctl(file, I2C_SLAVE, 0x48)<0) // open slave, address ADS1015 = 0x48 with ADDR grounded { perror("cannot open slave address"); exit(1); }
read_channel(0,file); read_channel(1,file); read_channel(2,file); read_channel(3,file);
close(file);
return 0; }
Kommentare
Kommentarfunktion für diesen Artikel geschlossen.