Forum: PC-Programmierung I2C read mit C-Programm Raspberry PI


von Epi K. (epi_k)


Lesenswert?

Hallo, ich möchte ein I2C Touch mit einem C-Programm auslesen (mit 
i2cdump -y 1 0x24 i erhalte ich Daten) aber mit folgenden Programm Code 
siehe unten erhalte ich nichts, d.h:
Data read:
Data read:
Data read:

Erwarten tue ich aber mindestens Hex-Werte wie 0x00 oder 00... aber gar 
nichts?
Ist die Variable "buffer" vom falschen Typ?


Hier mein C-Code:
**************************
#include <stdio.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/i2c-dev.h>

int file_i2c;
int length;
int i;
unsigned char buffer[2] = {0};


//----- OPEN THE I2C BUS -----
int readi2cbus()
{
        char *filename = (char*)"/dev/i2c-1";
        if ((file_i2c = open(filename, O_RDWR)) < 0)
        {
                //ERROR HANDLING: you can check errno to see what went 
wrong
                printf("Failed to open the i2c bus");
                return;
        }


        int addr = 0x24;          //<<<<<The I2C address of the slave
        if (ioctl(file_i2c, I2C_SLAVE, addr) < 0)
        {
                printf("Failed to acquire bus access and/or talk to 
slave.\n");
                //ERROR HANDLING; you can check errno to see what went 
wrong
                return;
        }


        //----- READ BYTES -----
        length = sizeof(buffer);                        //<<< Number of 
bytes to read
        if (read(file_i2c, buffer, length) != length)           //read() 
returns the number of bytes actually read, if it doesn't match t$
        {
                //ERROR HANDLING: i2c transaction failed
                printf("Failed to read from the i2c bus.\n");
        }
        else
        {
                for(i=0;i<=length;i++)
                {
                printf("Data read: %c\n", buffer[i]);
                }
        }
}

//----- WRITE BYTES -----
int writei2cbus()
{
        buffer[0] = 0x00;
        buffer[1] = 0x00;
        length = 2;                     //<<< Number of bytes to write
        if (write(file_i2c, buffer, length) != length) 
//write()      returns the number of bytes actually written, if it 
doesn't mat$
        {
                /* ERROR HANDLING: i2c transaction failed */
                printf("Failed to write to the i2c bus.\n");
        }
}



int main()
{

        writei2cbus();
        readi2cbus();

//      return 0;
}

von Jim M. (turboj)


Lesenswert?

Kann nicht tun, du versuchst auf den nicht geöffneten Filedeskriptor 
file_i2c zu schreiben, da könnte das Programm schon aussteigen - wenn fd 
0 nicht "zufällig" valide wäre (ist er leider).

Mach mal
1
int file_i2c = -1;

von Epi K. (epi_k)


Lesenswert?

Hoi, habs mal auf -1 geändert, aber ich erhalte immer noch nichts..

Data read:
Data read:
Data read:

von Rolf M. (rmagnus)


Lesenswert?

Epi K. schrieb:
> printf("Data read: %c\n", buffer[i]);

%c interpretiert das, was du übergibst, als Zeichen und gibt das dann 
aus. Wenn du es als Zahl haben willst, wäre %d richtig, bzw. %x für 
hexadezimale Darstellung.

: Bearbeitet durch User
von seit_z80 (Gast)


Lesenswert?

Ich benutze immer http://wiringpi.com/ für so etwas, um z.B. den TSL2561 
auszulesen.

von tictactoe (Gast)


Lesenswert?

Ich schlage vor, du spaltest eine openi2cbus()-Funktion von deiner 
readi2cbus() Funktion ab und rufst diese in main() auf. Dann wirst du 
draufkommen, dass du derzeit in writei2cbus() auf den i2cbus schreibst, 
und ihn aber erst später in readi2cbus() öffnest.

von Epi K. (epi_k)


Lesenswert?

Rolf M. schrieb:
> aus. Wenn du es als Zahl haben willst, wäre %d richtig, bzw. %x für
> hexadezimale Darstellung.

vielen Dank, das war die Lösung.

tictactoe schrieb:
> Ich schlage vor, du spaltest eine openi2cbus()-Funktion von deiner
> readi2cbus() Funktion ab und rufst diese in main() auf. Dann wirst du
> draufkommen, dass du derzeit in writei2cbus() auf den i2cbus schreibst,
> und ihn aber erst später in readi2cbus() öffnest.

stimmt, ganz anfangs hatte ich aber keine Funktionen und es hatte 
trotzdem nicht funktioniert, also sicher das mit %x die Lösung, aber das 
mit den Funktionen ein weiterer Fehler. Danke :-)

hier der funktionierende Code:
*********************************

#include <stdio.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/i2c-dev.h>

int file_i2c = -1;
int length;
int i;
unsigned char buffer[40] = {0};


//----- OPEN THE I2C BUS -----
int openi2cbus()
{
        char *filename = (char*)"/dev/i2c-1";
        if ((file_i2c = open(filename, O_RDWR)) < 0)
        {
                //ERROR HANDLING: you can check errno to see what went 
wrong
                printf("Failed to open the i2c bus");
                return;
        }
}

int readi2cbus()
{
        int addr = 0x24;          //<<<<<The I2C address of the slave
        if (ioctl(file_i2c, I2C_SLAVE, addr) < 0)
        {
                printf("Failed to acquire bus access and/or talk to 
slave.\n");
                //ERROR HANDLING; you can check errno to see what went 
wrong
                return;
        }


        //----- READ BYTES -----
        length = sizeof(buffer);                        //<<< Number of 
bytes to read
        if (read(file_i2c, buffer, length) != length)           //read() 
returns the number of bytes actually read, if it doesn't match then an 
error oc$
        {
                //ERROR HANDLING: i2c transaction failed
                printf("Failed to read from the i2c bus.\n");
        }
        else
        {
                for(i=0;i<=length;i++)
                {
                printf("Data read: %x\n", buffer[i]);
                }
        }
}

//----- WRITE BYTES -----
int writei2cbus()
{
        buffer[0] = 0x00;
        buffer[1] = 0x00;
        length = 2;                     //<<< Number of bytes to write
        if (write(file_i2c, buffer, length) != length) 
//write() returns the number of bytes actually written, if it doesn't 
match then an erro$
        {
                /* ERROR HANDLING: i2c transaction failed */
                printf("Failed to write to the i2c bus.\n");
        }
}



int main()
{
        openi2cbus();
        writei2cbus();
        readi2cbus();

//      printf("Hello, World! \n");
        return 0;
}
*****************************************

von Rolf M. (rmagnus)


Lesenswert?

Wenn du deinen Funktionen schon int als Returntyp gibst, sollten sie 
auch einen Wert zurückgeben. Außer main() tut das aber keine der 
Funktionen.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.