mirror of
https://github.com/eddyem/eddys_snippets.git
synced 2025-12-06 02:35:12 +03:00
add AHT10
This commit is contained in:
parent
5c424fc617
commit
675b02f1a3
@ -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
109
I2Csensors/aht.c
Normal 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
22
I2Csensors/aht.h
Normal 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
14
I2Csensors/common_table
Normal 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
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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){
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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 |
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user