RickG-VT
RickG-VT

Reputation: 1

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

Upvotes: 0

Views: 269

Answers (1)

RickG-VT
RickG-VT

Reputation: 1

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);
}

Upvotes: 0

Related Questions