raspberry-pii2cwiringpi

RPi Wiringpi fails to read i2c correctly


I have an AHT21 that communicates over i2c: I send 3 bytes and get back 6. The arduino sketch works but the RPi does not. What is wrong with WiringPi i2c syntax? I want to convert this arduino sketch to RPi c++ program using WiringPi. This works:

#include <Wire.h>
#define AHT21 0x38

void setup() {
  // put your setup code here, to run once:
  Wire.begin(); // the SDA and SCL
  Serial.begin(9600);
  uint8_t rawData[7] = {0,0,0,0,0,0,0};
  Wire.beginTransmission(AHT21);
  Wire.write(0xAC);  //send measurement command, start measurement
  Wire.write(0x33);  //send measurement control
  Wire.write(0x00);  //send measurement NOP control
  Wire.endTransmission();
  delay(100);
  Wire.requestFrom(AHT21, 6);
  for (uint8_t i = 0; i < 6; i++)
  {
    rawData[i] = Wire.read();
    Serial.print(i);Serial.print(": ");
    Serial.println(rawData[i]);
  }
}
void loop() {}

Gives:
0: 28
1: 106
2: 90
3: 117
4: 126
5: 70


This RPI code fails giving the status byte over and over:


#include <wiringPi.h>
#include <wiringPiI2C.h>
#include <stdio.h>
#include <stdint.h>
#include <math.h>

#define Address 0x38

int main (int argc, char **argv)
{
  int fd = wiringPiI2CSetup(Address);
  uint8_t rawData[7] = {0,0,0,0,0,0,0};
  wiringPiI2CWrite(fd,0xAC);  //send measurement command, start measurement
  wiringPiI2CWrite(fd,0x33);  //send measurement control
  wiringPiI2CWrite(fd,0x00);  //send measurement NOP control
  delay(100);
  for (uint8_t i = 0; i < 6; i++)
  {
    rawData[i] = wiringPiI2CRead(fd);
    printf("%d: %d\n",i,rawData[i]);
  }
}
Gives:
    ./aht21 
0: 28
1: 28
2: 28
3: 28
4: 28
5: 28

Solution

  • I abandoned WiringPi and went with ioctl and i2c-dev.h. Works fine:

    //gcc -g -Wall -Wextra -pedantic -std=c11 -D_DEFAULT_SOURCE -D_BSD_SOURCE -o aht21 aht21.c
    #include <stdio.h>
    #include <sys/ioctl.h>
    #include <fcntl.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <unistd.h>    // read/write usleep
    #include <stdlib.h>    // exit function
    #include <inttypes.h>  // uint8_t, etc
    #include <linux/i2c-dev.h> // I2C bus definitions
    
    int main (int argc, char **argv)
    {
      float  ahtTemp, ahtHum;
      uint8_t rawData[7] = {0, 0, 0, 0, 0, 0, 0};
      // Create I2C bus
      int fd;
      char *bus = "/dev/i2c-1";
      if ((fd = open(bus, O_RDWR)) < 0)
      {
        printf("Failed to open the bus. \n");
        exit(1);
      }
      // Get I2C device,
      ioctl(fd, I2C_SLAVE, 0x38);
    
      char TriggerCMD[3] = {0};
      TriggerCMD[0] = 0xAC;
      TriggerCMD[1] = 0x33;
      TriggerCMD[2] = 0x00;
      write(fd, TriggerCMD, 3);
      sleep(1);
    
      if (read(fd, rawData, 7) != 7)
      {
        printf("Error : Input/Output Error \n");
      }
      else
      {
        uint32_t humidity = rawData[1];            //20-bit raw humidity data
        humidity <<= 8;
        humidity  |= rawData[2];
        humidity <<= 4;
        humidity  |= rawData[3] >> 4;
    
        uint32_t temperature = rawData[3] & 0x0F;   //20-bit raw temperature data
        temperature <<= 8;
        temperature  |= rawData[4];
        temperature <<= 8;
        temperature  |= rawData[5];
        
        ahtHum = ((float)humidity / 0x100000) * 100.0;
        ahtTemp = (((float)temperature / 0x100000) * 200.0 - 50.0) * 1.8 + 32.0;
        printf("%.2f,%.2f\n", ahtHum, ahtTemp);
       }
       close(fd);
    }