В общем переписал код. Пока только для 2 датчиков, остальные добавлю по аналогии.
Разбил работу с датчиками на этапы между задержками. Сами задержки вынес в основной цикл. На скорую руку получилось следующее:
#include "bmp280.h"
#include "aht20.h"
#define _I2C_CLOCK_ 200000L
#define _SERIAL_BAUD_RATE_ 19200
TwoWire i2c;
BMP280 bmp(&i2c, BMP280_I2C_ADDR_SEC);
AHT20 aht(&i2c, AHT20_I2C_ADDR_PRIM);
void aht_variables_init(void);
int8_t aht_begin(uint8_t &delay_in_ms);
int8_t aht_init(uint8_t &delay_in_ms);
int8_t aht_start(uint8_t &delay_in_ms);
int8_t aht_end(uint8_t &delay_in_ms);
int8_t (*aht_states[])(uint8_t &) = { aht_begin, aht_init, aht_start, aht_end };
int8_t (*aht_exec)(uint8_t &);
void bmp_variables_init(void);
int8_t bmp_begin(uint8_t &delay_in_ms);
int8_t bmp_start(uint8_t &delay_in_ms);
int8_t bmp_end(uint8_t &delay_in_ms);
int8_t (*bmp_states[])(uint8_t &) = { bmp_begin, bmp_start, bmp_end };
int8_t (*bmp_exec)(uint8_t &);
int8_t aht_status, bmp_status;
uint8_t aht_state_id, bmp_state_id;
uint8_t aht_delay_ms, bmp_delay_ms;
uint8_t aht_iteration_cnt, bmp_iteration_cnt;
uint32_t aht_start_time_ms, bmp_start_time_ms;
value_t aht_temperature, aht_humidity;
value_t bmp_temperature, bmp_pressure;
void setup() {
Serial.begin(_SERIAL_BAUD_RATE_);
i2c.begin(_I2C_CLOCK_);
}
void loop() {
uint32_t msec = millis();
aht_variables_init();
bmp_variables_init();
while (aht_exec != nullptr || bmp_exec != nullptr) {
// working with AHT20 sensor
if (aht_exec != nullptr) {
if (aht_delay_ms == 0) {
// executing the current operation
// returns the exit code (status) and the duration of the delay
aht_status = aht_exec(aht_delay_ms);
if (aht_status == AHT20_OK) {
// iteration completed successfully
if (++aht_state_id < sizeof(aht_states) / sizeof(aht_states[0])) {
// next operation
aht_exec = aht_states[aht_state_id];
} else {
// all operations completed, read measured values
aht_status = aht.read_values(aht_temperature, aht_humidity);
// finish working with the sensor
aht_exec = nullptr;
}
} else {
if (aht_status == AHT20_E_NEXT_ITERATION) {
// next iteration of the current operation
if (++aht_iteration_cnt >= AHT20_MAX_ITER_CNT) {
// measurement timeout exceeded, no reason to continue
aht_status = AHT20_E_MEASUREMENT_TIMEOUT;
aht_exec = nullptr;
} else {
// delay start time
aht_start_time_ms = millis();
}
} else {
// sensor error, no reason to continue
aht_exec = nullptr;
}
}
} else {
// delay end check
if ((uint8_t) (millis() - aht_start_time_ms) >= aht_delay_ms) {
// delay completed, reset the variable
aht_delay_ms = 0;
}
}
}
// working with BMP280 sensor
if (bmp_exec != nullptr) {
if (bmp_delay_ms == 0) {
// executing the current operation
// returns the exit code (status) and the duration of the delay
bmp_status = bmp_exec(bmp_delay_ms);
if (bmp_status == BMP280_OK) {
// iteration completed successfully
if (++bmp_state_id < sizeof(bmp_states) / sizeof(bmp_states[0])) {
// next operation
bmp_exec = bmp_states[bmp_state_id];
} else {
// all operations completed, read measured values
bmp_status = bmp.read_values(bmp_temperature, bmp_pressure);
// finish working with the sensor
bmp_exec = nullptr;
}
} else {
if (bmp_status == BMP280_E_NEXT_ITERATION) {
// next iteration of the current operation
if (++bmp_iteration_cnt >= BMP280_MAX_ITER_CNT) {
// measurement timeout exceeded, no reason to continue
bmp_status = BMP280_E_MEASUREMENT_TIMEOUT;
bmp_exec = nullptr;
} else {
// delay start time
bmp_start_time_ms = millis();
}
} else {
// sensor error, no reason to continue
bmp_exec = nullptr;
}
}
} else {
// delay end check
if ((uint8_t) (millis() - bmp_start_time_ms) >= bmp_delay_ms) {
// delay completed, reset the variable
bmp_delay_ms = 0;
}
}
}
}
msec = millis() - msec;
Serial.printf("Time passed: %lu msec\r\n", msec);
if (aht_status == AHT20_OK) {
Serial.print("Temperature: "); Serial.print(aht_temperature.value, 2); Serial.println(" *C");
Serial.print("Humidity: "); Serial.print(aht_humidity.value, 2); Serial.println(" %");
} else {
Serial.printf("AHT20 error: %d\r\n", aht_status);
}
if (bmp_status == BMP280_OK) {
Serial.print("Temperature: "); Serial.print(bmp_temperature.value, 2); Serial.println(" *C");
Serial.print("Pressure: "); Serial.print(bmp_pressure.value, 2); Serial.println(" mmHg");
} else {
Serial.printf("BMP280 error: %d\r\n", bmp_status);
}
Serial.println();
delay(2000);
}
void aht_variables_init(void)
{
aht_status = 0;
aht_state_id = 0;
aht_delay_ms = 0;
aht_iteration_cnt = 0;
aht_start_time_ms = 0;
aht_exec = aht_states[aht_state_id];
}
void bmp_variables_init(void)
{
bmp_status = 0;
bmp_state_id = 0;
bmp_delay_ms = 0;
bmp_iteration_cnt = 0;
bmp_start_time_ms = 0;
bmp_exec = bmp_states[bmp_state_id];
}
Работает, общее время опроса датчиков сократилось в разы. Всем спасибо.