Buffer and/or C I2C problem

Asked

Viewed 114 times

3

I’m hoping to get some help here. I am programming for Beaglebone Black using I2C sensors via the Eclipse IDE for C/C++ Developers, Version: Luna Service Release 2 (4.4.2).

My problem is with code development for I2C, especially between functions initializingACC and readingDATA of my code. I think the problem is with the variable buf, I believe I am not using the buffer properly.

I developed the code below, where the command read (in function readingDATA) only works if I insert two lines above the last command write (in function initializingACC) who make the last command write stop working.

The aim of the latter write is to write the value 0x08 in the 0x2d register of the I2C 0x53 device. That’s why this write stops working when I insert the two lines (buf [0] = ACC_OUT_LSB_X; and buf [1 ] = NULL;). On the other hand, these lines do what the command read (in function readingDATA) work properly.

I have performed the tests using the commands below on the Linux terminal:

sudo i2cset -y 1 0x53 0x31 0x01 (Equivalente de primeira gravação para a função initializingACC)
sudo i2cset -y 1 0x53 0x08 0x2d (Equivalente de segunda gravação para a função initializingACC)
sudo i2cget -y 1 0x53 0x32 (Equivalente de ler para a função readingDATA)

Here is my code:

#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <linux/i2c-dev.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#define ACC_ADDRESS 0x53
#define ACC_READ_ADDR  0XA7
#define ACC_PWRCTRL_ADDR  0x2D
#define ACC_MEASURE_MODE  0x08
#define ACC_DATA_FORMAT  0x31
#define ACC_OUT_LSB_X 0x32
#define ACC_OUT_MSB_X 0x33
#define ACC_OUT_LSB_Y 0x34
#define ACC_OUT_MSB_Y 0x35
#define ACC_OUT_LSB_Z 0x36
#define ACC_OUT_MSB_Z 0x37

int i2cbus = 1;
int file;
char absolute_path[20];
char buf[10];

void settingIOCTL(){

    printf("Function to set the ioctl up\n");

    snprintf(absolute_path, 19, "/dev/i2c-%d", i2cbus);
    file = open(absolute_path, O_RDWR);
    if (file < 0) {
        // ERROR HANDLING; you can check errno to see what went wrong
        exit(1);
    }
    if (ioctl(file, I2C_SLAVE, ACC_ADDRESS) < 0) {
        // ERROR HANDLING; you can check errno to see what went wrong
        exit(1);
    }
    printf("Function to set the ioctl up processed\n");
}
void initializingACC(){

    printf("function to initialize\n");

    // Using I2C Write
    buf[0] = ACC_DATA_FORMAT;
    buf[1] = 0x01;
    if (write(file, buf, 2) != 2) { // Equivalent of sudo i2cset -y 1 0x53 0x31 0x01
        // ERROR HANDLING: i2c transaction failed
        }
    buf[0] = ACC_PWRCTRL_ADDR;
    buf[1] = ACC_MEASURE_MODE;

    /*These 2 lines below predictably make this function stop working (next writing)
      otherside, them make the next function (readingDATA/read) work properly*/
    buf[0] = ACC_OUT_LSB_X;
    buf[1] = NULL;

    if (write(file, buf, 2) != 2) { // Equivalent of sudo i2cset -y 1 0x53 0x2d 0x08
        // ERROR HANDLING: i2c transaction failed
        }
    printf("Function to initialize processed\n");
}

void readingDATA(int register_address){

    printf("Function to read\n");

    buf[0] = register_address; //I thought this line would be above the reading line but it makes the reading stop working
    // Using I2C Read
    if (read(file, buf, 1) != 1) { // Equivalent of sudo i2cset -y 1 0x53 0x2d 0x08
        // ERROR HANDLING: i2c transaction failed
     } else {
             // buf[0] contains the read byte
             printf("read byte: %x\n",buf[0]);
     }
  printf("Function to read processed\n");
}

int main(void){

      settingIOCTL();
      initializingACC();
      readingDATA(ACC_OUT_LSB_X);

      return 0;
}
  • +1 for having posted the complete code and detailing what you are doing with it and in a clear and well-written way. I so wanted all new users to be like this...

No answers

Browser other questions tagged

You are not signed in. Login or sign up in order to post.