diff --git a/src/aht.c b/src/aht.c index e523ae3..7c4fa2d 100644 --- a/src/aht.c +++ b/src/aht.c @@ -13,12 +13,12 @@ void getAHTData(i2c_inst_t *i2c, double *t, double *h) { uint32_t temperature; uint32_t humidity; - i2c_write_blocking(i2c, AHT_ADDR, AHT_MEASURE, 3, - false); // trigger measurement + i2c_write_timeout_us(i2c, AHT_ADDR, AHT_MEASURE, 3, false, + 1200); // trigger measurement // now we must delay ~100ms sleep_ms(100); - i2c_read_blocking(i2c, AHT_ADDR, result, 6, - false); // read 6 bytes back + i2c_read_timeout_us(i2c, AHT_ADDR, result, 6, false, + 3000); // read 6 bytes back humidity = (result[1] << 12) | (result[2] << 4) | (result[3] & 0xF0) >> 4; temperature = (result[3] & 0x0F) << 16 | (result[4] << 8) | result[5]; *t = (((double)temperature / 1048576.0f) * 200.0f) - 50.0f; diff --git a/src/main.c b/src/main.c index e3e41bf..d3ad376 100644 --- a/src/main.c +++ b/src/main.c @@ -18,8 +18,6 @@ * the readings to Adafruit IO over MQTT using the Pico W. ******************************************************************************/ -#include "hardware/gpio.h" -#include "hardware/i2c.h" #include "include/aht.h" #include "include/bmp.h" #include "include/credentials.h" @@ -29,6 +27,8 @@ #include "pico/cyw43_arch.h" #include "pico/stdlib.h" // IWYU pragma: keep #include +#include +#include #include #include #include @@ -85,6 +85,15 @@ int main(void) { static const char etoh_topic[] = ADAFRUIT_IO_USERNAME "/feeds/ensaht.etoh"; static const char eco2_topic[] = ADAFRUIT_IO_USERNAME "/feeds/ensaht.eco2"; static const char prs_topic[] = ADAFRUIT_IO_USERNAME "/feeds/ensaht.pressure"; + static const char valid_topic[] = + ADAFRUIT_IO_USERNAME "/feeds/ensaht.datavalid"; + OPT4048_Data lightData = { + .x = 0, + .y = 0, + .z = 0, + .lux = 0, + }; + float lightch0, lightch1, lightch2; uint16_t tvoc, eco2, etoh, avg_tvoc, avg_eco2, avg_etoh; uint8_t aqi, validData; double t, h, avg_t, avg_h, avg_bmp_t, avg_bmp_p; @@ -139,7 +148,7 @@ int main(void) { if (mqtt_err != ERR_OK) { printf("MQTT connect start failed: %d\n", mqtt_err); } - i2c_init(i2c_default, 400 * 1000); // start i2c0 at 400khz + i2c_init(i2c_default, 100 * 1000); // start i2c0 at 400khz gpio_set_function(PICO_DEFAULT_I2C_SCL_PIN, GPIO_FUNC_I2C); gpio_set_function(PICO_DEFAULT_I2C_SDA_PIN, GPIO_FUNC_I2C); gpio_pull_up(PICO_DEFAULT_I2C_SCL_PIN); @@ -148,22 +157,18 @@ int main(void) { bi_decl(bi_2pins_with_func(PICO_DEFAULT_I2C_SDA_PIN, PICO_DEFAULT_I2C_SCL_PIN, GPIO_FUNC_I2C)); - i2c_init(i2c1, - 100 * 1000); // start i2c1 at 100kHz -- this is the stemma chain - gpio_set_function(I2C1_SDA_PIN, GPIO_FUNC_I2C); - gpio_set_function(I2C1_SCL_PIN, GPIO_FUNC_I2C); - gpio_pull_up(I2C1_SDA_PIN); - gpio_pull_up(I2C1_SCL_PIN); - bi_decl(bi_2pins_with_func(I2C1_SDA_PIN, I2C1_SCL_PIN, GPIO_FUNC_I2C)); - initBMP(i2c1); + activateENS(i2c_default); + initBMP(i2c_default); + initOPT(i2c_default); printf("\x1b[2J"); // clear screen uint8_t i = 0; uint8_t sample_count = 0; - activateENS(i2c_default); while (1) { // cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 1); + getOPTData(i2c_default, &lightch0, &lightch1, &lightch2); + getBMPData(i2c_default, &bmpT, &bmpP); getAHTData(i2c_default, &t, &h); - getBMPData(i2c1, &bmpT, &bmpP); + lightData = calculate_color_data(lightch0, lightch1, lightch2); t_avg[i] = t; h_avg[i] = h; bmpt_avg[i] = bmpT; @@ -178,6 +183,8 @@ int main(void) { printf("\x1b[H\x1b[JTemperature %0.2f C Humidity %0.2f%%\n", avg_t, avg_h); printf("BMP Temperature %0.2f C Pressure %0.2f kPa\n", avg_bmp_t, avg_bmp_p / 1000.0); + printf("Light: CIE Coords: %0.2fX %0.2fY %0.2fZ %0.2fLux\n", lightData.x, + lightData.y, lightData.z, lightData.lux); validData = getENSData(i2c_default, &avg_bmp_t, &avg_h, &aqi, &tvoc, &eco2, &etoh); tvoc_avg[i] = tvoc; @@ -186,6 +193,9 @@ int main(void) { avg_tvoc = average_uint16(tvoc_avg, sample_count); avg_eco2 = average_uint16(eco2_avg, sample_count); avg_etoh = average_uint16(etoh_avg, sample_count); + snprintf(payload, sizeof(payload), "%d", validData); + ensaht_mqtt_publish_client(&mqtt, valid_topic, payload, strlen(payload), + NULL, NULL); if (!validData) { printf("!! "); } diff --git a/src/opt4048.c b/src/opt4048.c index d736841..ce73a79 100644 --- a/src/opt4048.c +++ b/src/opt4048.c @@ -2,6 +2,7 @@ // SPDX-FileCopyrightText: 2026 A.M. Rowsell #include "include/opt4048.h" +#include OPT4048_Data calculate_color_data(float ch0, float ch1, float ch2) { OPT4048_Data result; @@ -36,10 +37,9 @@ int initOPT(i2c_inst_t *i2c) { // Need to init regs as follows: // write setup to CONFIG (0x0A/0x0B) // this sets it to 100ms sample time, auto-range lux - static const uint8_t config[5] = {0x0A, 0b00110010, 0b00001000, 0b10000000, - 0b00011101}; + static const uint8_t config[5] = {0x0A, 0x32, 0x08, 0x80, 0x1D}; // we'll be doing single-shot measurements - bytesWritten = i2c_write_blocking(i2c, OPT_ADDR, config, 4, false); + bytesWritten = i2c_write_timeout_us(i2c, OPT_ADDR, config, 5, false, 300); result = (bytesWritten == 4) ? 0 : 1; return result; } @@ -54,20 +54,21 @@ int getOPTData(i2c_inst_t *i2c, float *ch0, float *ch1, float *ch2) { uint8_t exponentCH0 = 0; uint8_t exponentCH1 = 0; uint8_t exponentCH2 = 0; - static const uint8_t triggerMeas[2] = {0x0B, 0b00101000}; + static const uint8_t triggerMeas[3] = {0x0B, 0x80, 0x28}; static const uint8_t dataReg = 0x00; // force a one-shot measurement - bytesWritten = i2c_write_blocking(i2c, OPT_ADDR, triggerMeas, 2, false); + bytesWritten = i2c_write_timeout_us(i2c, OPT_ADDR, triggerMeas, 3, false, + 1000); // 1ms timeout if (bytesWritten != 2) { result = 1; } - sleep_ms(410); // 4 channels @ 100ms each plus a little buffer time + sleep_ms(500); // 4 channels @ 100ms each plus a little buffer time - bytesWritten = i2c_write_blocking(i2c, OPT_ADDR, &dataReg, 1, true); + bytesWritten = i2c_write_timeout_us(i2c, OPT_ADDR, &dataReg, 1, true, 1000); if (bytesWritten != 1) { result = 1; } - bytesRead = i2c_read_blocking(i2c, OPT_ADDR, lightData, 16, false); + bytesRead = i2c_read_timeout_us(i2c, OPT_ADDR, lightData, 16, false, 2000); if (bytesRead != 16) { result = 1; }