add AHT10

This commit is contained in:
Edward Emelianov 2025-10-11 01:17:59 +03:00
parent 5c424fc617
commit 675b02f1a3
10 changed files with 178 additions and 3 deletions

View File

@ -147,6 +147,7 @@ static int BMP180_init(){
DBG("B1=%d, B2=%d", CaliData.B1, CaliData.B2);
DBG("MB=%d, MC=%d, MD=%d", CaliData.MB, CaliData.MC, CaliData.MD);
}
bmpstatus = SENS_RELAX;
return TRUE;
}
@ -245,7 +246,7 @@ ret:
// read data & convert it
static int BMP180_getdata(sensor_data_t *d){
if(!d) return FALSE;
if(!d || bmpstatus != SENS_RDY) return FALSE;
d->T = Tmeasured;
d->P = Pmeasured / 100.; // convert Pa to hPa
bmpstatus = SENS_RELAX;

109
I2Csensors/aht.c Normal file
View File

@ -0,0 +1,109 @@
/*
* Copyright 2025 Edward V. Emelianov <edward.emelianoff@gmail.com>.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <usefull_macros.h>
#include "aht.h"
#include "i2c.h"
static uint8_t addr = 0x38;
static sensor_status_t status = SENS_NOTINIT;
enum{
ISAHT10,
ISAHT15,
ISAHT21b
};
static uint32_t rawH = 0, rawT = 0;
#define AHT_CMD_INITIALIZE 0xE1
#define AHT_CMD_MEASURE 0xAC
#define AHT_CMD_SOFT_RESET 0xBA
static int s_init(){
status = SENS_NOTINIT;
if(!i2c_write_reg8(AHT_CMD_SOFT_RESET, 0)){
DBG("Can't reset");
return FALSE;
}
uint8_t data[3] = {AHT_CMD_INITIALIZE, 0x08, 0};
if(!i2c_write_raw(data, 3)){
DBG("Can't init");
return FALSE;
}
status = SENS_RELAX;
return TRUE;
}
static int s_start(){
if(status != SENS_RELAX) return FALSE;
uint8_t data[3] = {AHT_CMD_MEASURE, 0x33, 0};
if(!i2c_write_raw(data, 3)){
DBG("Can't start measuring");
return FALSE;
}
return TRUE;
}
static sensor_status_t s_process(){
uint8_t data[6];
//if(!i2c_read_data8(0, 6, data)) return (status = SENS_ERR);
if(!i2c_read_raw(data, 6)) return (status = SENS_ERR);
#ifdef EBUG
printf("Got data: "); for(int i = 0; i < 6; ++i) printf(" %02X", data[i]); printf("\n");
if(data[0] & 0x80) printf("BUSY ");
static const char *modes[] = {"NOR", "CYC", "CMD", "CMD"};
printf("MODE=%s ", modes[(data[0] >> 6)&3]);
printf("%sCALIBRATED\n", data[0] & 8 ? "" : "NOT ");
#endif
if(data[0] & 0x80) return (status = SENS_BUSY); // still measuring
rawH = ((uint32_t)data[1] << 12) | ((uint32_t)data[2] << 4) | (data[3] >> 4);
rawT = ((uint32_t)(data[3] & 0x0F) << 16) | ((uint32_t)data[4] << 8) | data[5];
DBG("rawH=%d, rawT=%d", rawH, rawT);
return (status = SENS_RDY);
}
static int s_getdata(sensor_data_t *d){
if(!d || status != SENS_RDY) return FALSE;
d->T = rawT * 200.0 / 1048576.0 - 50.0;
d->H = rawH * 100.0 / 1048576.0;
return TRUE;
}
static sensor_props_t s_props(){
sensor_props_t p = {.T = 1, .H = 1, .P = 0};
return p;
}
static uint8_t address(uint8_t new){
if(new) addr = new;
return addr;
}
sensor_t AHT10 = {
.name = "AHT10",
.private = ISAHT10,
.address = address,
.init = s_init,
.start = s_start,
.process = s_process,
.properties = s_props,
.get_data = s_getdata
};

22
I2Csensors/aht.h Normal file
View File

@ -0,0 +1,22 @@
/*
* Copyright 2025 Edward V. Emelianov <edward.emelianoff@gmail.com>.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "sensor.h"
extern sensor_t AHT10;

14
I2Csensors/common_table Normal file
View File

@ -0,0 +1,14 @@
Датчики влажности[-температуры[-давления]]
# датчик = паспортная точность по влажности/температуре/давлению = доступные ID = максимальная скорость = примечание
AM2320 = 3%/0.5°/- = 0x5C = 100k* = (*) модбас (!!!) поверх I2C; желательно питать 5В, хоть вроде должен и от 3.3
AHT10 = 2%/0.3°/- = 0x38/0x39 = 400k = ADDR выбирает младший бит
AHT15 = 2%/0.3°/- = 0x38 = 400k = непонятно, чем от 10 отличается
AHT21b = 3%/0.5°/- = 0x38 = 400k =
BMP180 = -/1°/12Pa = 0x77 = 3.4M = есть вариант с SPI, но не в общем случае
BME280 = 3%/1°/0.2Pa = 0x76/77 = 3.4M = выбор младшего бита ногой SDO, есть SPI
HTU21d = 3-5%/0.3°/- = 0x40 = 400k = в зависимости от маркировки точность 3-5%RH, бывают ШИМ и др. интерфейсы
HTU32d = 2%/0.2°/- = 0x40/0x41 = 10M = младший бит адреса выбирается ногой ADDR
SHT30 = 3%/0.3°/- = 0x44/0x45 = 1M = у SHT31 заявленная точность по влажности: 2%; младший бит адреса выбирается ногой ADDR; есть программируемая нога ALERT!
SHT4x = * = 0x44/0x45** (*) 40: 2-4%/>0.2-0.4°, 41: 2-2.5%/0.2-0.4°, 45: 1-2%/0.1-0.3°; (**) адрес зависит от маркировки (A/B); есть нагреватель; есть команда reset (0x06) по адресу 0
SI7005 = 4.5%/1°/- = 0x40 = 400k = возможен выбор с помощью ноги ~CS

View File

@ -28,6 +28,29 @@
static uint8_t lastaddr = 0;
static int I2Cfd = -1;
static int i2c_rw(uint8_t *data, int len, uint16_t flags){
struct i2c_msg m;
struct i2c_rdwr_ioctl_data x = {.msgs = &m, .nmsgs = 1};
m.addr = lastaddr;
m.flags = flags; // 0 for w and I2C_M_RD for read
m.len = len;
m.buf = data;
if(ioctl(I2Cfd, I2C_RDWR, &x) < 0){
WARN("i2c_read_reg16, ioctl()");
return FALSE;
}
return TRUE;
}
int i2c_write_raw(uint8_t *data, int len){
if(!data || I2Cfd < 1 || len < 1) return FALSE;
return i2c_rw(data, len, 0);
}
int i2c_read_raw(uint8_t *data, int len){
if(!data || I2Cfd < 1 || len < 1) return FALSE;
return i2c_rw(data, len, I2C_M_RD);
}
/**
* @brief i2c_read_reg8 - read 8-bit addressed register (8 bit)
* @param regaddr - register address

View File

@ -29,6 +29,8 @@
int i2c_open(const char *path);
void i2c_close();
int i2c_set_slave_address(uint8_t addr);
int i2c_write_raw(uint8_t *data, int len);
int i2c_read_raw(uint8_t *data, int len);
int i2c_read_reg8(uint8_t regaddr, uint8_t *data);
int i2c_write_reg8(uint8_t regaddr, uint8_t data);
int i2c_read_data8(uint8_t regaddr, uint16_t N, uint8_t *array);

View File

@ -19,12 +19,13 @@
#include <string.h>
#include <usefull_macros.h>
#include "aht.h"
#include "BMP180.h"
#include "i2c.h"
#include "sensor.h"
// NULL-terminated list of all supported sensors
static const sensor_t* supported_sensors[] = {&BMP180, NULL};
static const sensor_t* supported_sensors[] = {&AHT10, &BMP180, NULL};
// just two stupid wrappers
int sensors_open(const char *dev){

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 17.0.2, 2025-10-10T23:37:48. -->
<!-- Written by QtCreator 17.0.2, 2025-10-11T01:16:49. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>

View File

@ -1,5 +1,7 @@
BMP180.c
BMP180.h
aht.c
aht.h
i2c.c
i2c.h
main.c

Before

Width:  |  Height:  |  Size: 55 B

After

Width:  |  Height:  |  Size: 67 B

View File

@ -44,6 +44,7 @@ typedef struct{
typedef struct{
const char *name; // name
uint32_t private; // private information (e.g. for almost similar sensors with some slight differences)
uint8_t (*address)(uint8_t new);// set/get sensor's address (get - if `new`==0)
int (*init)(); // init device - only @ start after POR
int (*start)(); // start measuring