Sunspot Home

Raspberry Pi with I2C devices

C code drivers based on my earlier tests on NSLU2 (the Debian Slug)


PCF8574 - switch the lines

This code compiles on the Pi

/*
PCF8574_addr_byteout_slug.c
-------------------------------------------
Send address and byte to switch lines on 8 line port of i2c bus PCF8574
----------------------------------------------------------------------------------------------------

1) send the i2c address
2) send byte to set the 8 port lines on or off

usage :- type with spaces but without the < >
<PCF8574_addr_byteout_slug> <decimal address> <decimal byte out 0-255>

*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/i2c-dev.h>
#define I2C_SLAVE 0x0703 /* Change slave address */

int i2c;
char filename[20];
unsigned long address;

int rc;
unsigned char data[1];

int main(int argc, char *argv[])
{
if (argc != 3) { /* error if we are not getting just 2 inputs after the program name */
fprintf(stderr, "usage: %s <address> <databyte>\n",argv[0]);
exit(1);
}

/* address is the first number after the program name */
address = atoi(argv[1]);
/* the byte to send out to the PC8574 is the second number
place it into the first element of the buf array */
data[0] = atoi(argv[2]);

i2c = open("/dev/i2c-0",O_RDWR); /* open the device dev/i2c-0 */

rc=ioctl(i2c,I2C_SLAVE,address); /* set the i2c chip address */

write(i2c,data,1) ; /* send the byte */

i2c = close(i2c);
return(0);
}

/* Sunspot and Google 090815 */

To compile do
gcc -o PCF8574_addr_byteout_slug PCF8574_addr_byteout_slug.c

 

PCF8574 - read the line states

/*
PCF8574_addr_read_pi.c
----------------------------------------
read the data on the 8 line port of an i2c bus PCF8574
--------------------------------------------------------------------------

1) set the i2c address of the PCF8574
2) send data 255 to turn off all 8 lines - make them inputs
3) read the data on the 8 port lines as a byte
usage :- type (without the < >)
<PCF8574_address_read_pi> <space> <i2c_bus_address_of_PCF8574_as_decimal>
*/

#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/i2c-dev.h>
#define I2C_SLAVE 0x0703 /* Change slave address */

int i2c;
char filename[20];
unsigned long address;
int rc;
unsigned char data[1];
int byte; /* the 8 bit byte that represents the data present on the 8 wire port */

int main(int argc, char ** argv)
{
if (argc != 2) { /* error if we are not getting just 1 input after the program name */
fprintf(stderr, "usage: %s <address> \n",argv[0]);
exit(1);
}

/* address is the first number after the program name */
address = atoi(argv[1]);

i2c = open("/dev/i2c-0",O_RDWR); /* open the device dev/i2c-0 */
rc=ioctl(i2c,I2C_SLAVE,address); /* set the i2c chip address */

data[0] = 255;
write(i2c,data,1); /* we send 255 to make all lines go off, ready for input data */

read(i2c,data,1); /* now data(0) contains the byte of data on the 8 port lines*/

byte = data[0];

printf("BYTE = %d \n", byte);
/* BYTE value is 0-256)*/

i2c = close(i2c);
return(0);
}

/* Sunspot and Google 090815 */


PCF8591
Read 1 of the 4 input channels and set the D to A voltage on the output pin

/*
PCF8591_address_channel_Vout.c
---------------------------------------------------
read the voltage on one A/D lines (0-3) and set the output voltage on the D/A pin
-------------------------------------------------------------------------------------------------------------

1) send the i2c address
2) choose channel 0-3
3) send byte for D/A out
3) read channel volts as ((0 to 255) / 255) x 5V

usage :- type with spaces but without the < >
<PCF8591_address_channel_Vout> <address as decimal> <channel 0-3> <D/A value as decimal 0-255>
(even if the D/A pin is unused type in any value 0-255)
*/

#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/i2c-dev.h>
#define I2C_SLAVE 0x0703 /* Change slave address */

int i2c;
int channel; /* line number 0-3 */
int V_out; /* value for the D/A out line */
unsigned char buf[1]; /* use to feed the i2c driver */
unsigned long address; /* i2c bus address */
int byte_in_0; /* the 8 bit byte that represents the voltage on the AD_line */
int AD_input; /* volts byte on chosen channel */

int rc;

int main(int argc, char** argv)
{
if (argc != 4) /* report error if we are not getting just 3 inputs after the program name */
{
printf("Error. usage: %s i2c_chip_address channel_to_read D/A_Vout(0-255)\n", argv[0]);
}

address = atoi(argv[1]); /* decimal address is the first number after the program name */
channel = atoi(argv[2]); /* choose A to D line to read 0-3 */
V_out = atoi(argv[3]); /* volts out as decimal 0-255 */

i2c = open("/dev/i2c-0",O_RDWR); /* open the device dev/i2c-0 */
rc=ioctl(i2c,I2C_SLAVE,address); /* set the i2c chip address */

channel = channel + 64; /* enable the D/A output */
buf[0] = channel; /* A/D input line number is the first data byte sent */
buf[1] = V_out; /* D/A out value is the second data byte sent */
write(i2c,buf,2); /* we send 2 bytes <control register> <D/A value> */
read(i2c,buf,1); /* buf(0) contains the byte of data in the chip cache */
usleep (1000); /* do it again */
read(i2c,buf,1); /* buf(0) now contains the byte of data from the most recent analogue input*/
AD_input = buf[0];


printf("%d", AD_input);

/*AD_line_x goes 0 to 255 as voltage input goes from 0 to supply voltage*/

i2c = close(i2c);
return(0);
}
/* Sunspot and Google 090815 */


LM75 I2C thermometer

/*
LM75 I2C thermometer
--------------------------------
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/i2c-dev.h>
#define I2C_SLAVE 0x0703 /* Change slave address */

int i2c;
char filename[20];
unsigned long address;
int rc;
unsigned char data[2];
int byte1;
int byte2;
int temperature;
double realtemp;
int main(int argc, char ** argv)
{
if (argc != 2) { /* error if we are not getting just 1 input after the program name */
fprintf(stderr, "usage: %s <address> \n",argv[0]);
exit(1);
}

/* address is the first number after the program name */
address = atoi(argv[1]);

i2c = open("/dev/i2c-0",O_RDWR); /* open the device dev/i2c-0 */
rc=ioctl(i2c,I2C_SLAVE,address); /* set the i2c chip address */

read(i2c,data,2);

byte1 = data[0];
byte2 = data[1];

temperature = byte1*256+byte2;
temperature >>=7;
if (temperature>512)
temperature &= -1;

realtemp = (double)temperature / 2;
printf("%.1f", realtemp);

i2c = close(i2c);
return(0);
}

/* Sunspot and Google 090815 */

 

SUNSPOT HOME

more to come . . .