hi , new here ,
i am trying to connect hm-3301 sensor to raspberry pi
pi@raspberrypi:~ $ uname -a
Linux raspberrypi 5.15.61-v7+ #1579 SMP Fri Aug 26 11:10:59 BST 2022 armv7l GNU/Linux
i want to do it under c/c++
what i have done so far is as below.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <unistd.h>
#include <time.h>
#include <wiringPiI2C.h>
#include <wiringPi.h>
#define PM25_I2CADDR 0x40
typedef struct PMSAQIdata
{
u_int16_t framelen; ///< How long this data chunk is
u_int16_t pm10_standard, ///< Standard PM1.0
pm25_standard, ///< Standard PM2.5
pm100_standard; ///< Standard PM10.0
u_int16_t pm10_env, ///< Environmental PM1.0
pm25_env, ///< Environmental PM2.5
pm100_env; ///< Environmental PM10.0
u_int16_t particles_03um, ///< 0.3um Particle Count
particles_05um, ///< 0.5um Particle Count
particles_10um, ///< 1.0um Particle Count
particles_25um, ///< 2.5um Particle Count
particles_50um, ///< 5.0um Particle Count
particles_100um; ///< 10.0um Particle Count
u_int16_t unused; ///< Unused
u_int16_t checksum; ///< Packet checksum
} PM25_AQI_Data;
// Send the command to set i2c communication
bool select_comm(int handle)
{
int i = wiringPiI2CWriteReg8(handle, 0x80, 0x88);
//int i = wiringPiI2CWrite(handle, 0x88);
printf("device write: %d \n", i);
return i > 0;
}
int pm25_init()
{
int pm = wiringPiI2CSetup(PM25_I2CADDR);
printf("device handle: %d \n", pm);
if (!select_comm(pm))
{
printf("Failed to set i2c communication\n");
return -1;
}
return pm;
}
bool pm_read(int handle, PM25_AQI_Data *data)
{
u_int16_t sum = 0;
u_int8_t buffer[32];
// wiringPiI2CWrite(handle, 0x81);
read(handle, &buffer, 32);
if (buffer[0] != 0x42)
{
printf("First byte miss match\n");
return false;
}
for (u_int8_t i = 0; i < 30; i++)
{
sum += buffer[i];
printf("byte : %d | data : %d \n", i, buffer[i]);
}
// The data comes in endian'd, this solves it so it works on all platforms
u_int16_t buffer_u16[15];
for (u_int8_t i = 0; i < 15; i++)
{
buffer_u16[i] = buffer[2 + i * 2 + 1];
buffer_u16[i] += (buffer[2 + i * 2] << 8);
}
// put it into a nice struct :)
memcpy((void *)data, (void *)buffer_u16, 30);
if (sum != data->checksum)
{
printf("checksome error\n");
return false;
}
// success!
return true;
}
int main(int argc, char *argv[])
{
wiringPiSetup();
int pm = pm25_init();
if (pm == -1)
{
printf("failed to initialize HM3301 \n");
return 1;
}
else
{
printf("HM3301 device handle: %d \n", pm);
}
PM25_AQI_Data pmdata;
int times = 10;
while (times > 0)
{
if (!pm_read(pm, &pmdata))
{
printf("Could not read from AQI\n");
}
else
{
printf("PM 1.0: %d ", pmdata.pm10_standard);
printf("\tPM 2.5: %d ", pmdata.pm25_standard);
printf("\tPM 10: %d \n", pmdata.pm100_standard);
}
times--;
sleep(1);
}
}
but i am unable to communicate with the sensor properly.
pi@raspberrypi:~ $ gcc pmtest.c -lwiringPi -o pmtest
pi@raspberrypi:~ $ ./pmtest
device handle: 4
device write: 0
Failed to set i2c communication
failed to initialize HM3301
pi@raspberrypi:~ $
any help will be appreciated.