diff --git a/node1.c b/node1.c index 258bb9e..01c69c2 100644 --- a/node1.c +++ b/node1.c @@ -6,32 +6,34 @@ #include "pms5003.h" int main() { - stdio_init_all(); + stdio_init_all(); - // Setup BME280 - bme280_config config; - bme280_init(&config, i2c1, 14, 15); - bme280_reading current_bem280_reading; + // Setup BME280 + bme280_config config; + bme280_init(&config, i2c1, 14, 15); + bme280_reading current_bem280_reading; - // Setup PMS5003 - pms5003_config pms_config; - pms5003_init(&pms_config, uart1, 20, 21); - pms5003_reading current_pms5003_reading; + // Setup PMS5003 + pms5003_config pms_config; + pms5003_init(&pms_config, uart1, 20, 21, 18, 19); + pms5003_reading current_pms5003_reading; - while (true) { - sleep_ms(5000); // wait 5 sec - printf("Making reading\n"); + while (true) { + // tight_loop_contents(); - // Read BME280 - current_bem280_reading = bme280_read(&config); - printf("Tempature: %.2f\n", current_bem280_reading.temperature); - printf("Pressure: %.2f\n", current_bem280_reading.pressure); - printf("Humidity: %.2f\n", current_bem280_reading.humidity); + sleep_ms(5000); // wait 5 sec + printf("Making reading\n"); - // Read PMS5003 - current_pms5003_reading = pms5003_read(&pms_config); - printf("PM1: %.2f\n", current_pms5003_reading.pm1); - printf("PM2.5: %.2f\n", current_pms5003_reading.pm2_5); - printf("PM10: %.2f\n", current_pms5003_reading.pm10); - } + // Read BME280 + current_bem280_reading = bme280_read(&config); + printf("Tempature: %.2f\n", current_bem280_reading.temperature); + printf("Pressure: %.2f\n", current_bem280_reading.pressure); + printf("Humidity: %.2f\n", current_bem280_reading.humidity); + + // Read PMS5003 + current_pms5003_reading = pms5003_read(&pms_config); + printf("PM1: %.2f\n", current_pms5003_reading.pm1); + printf("PM2.5: %.2f\n", current_pms5003_reading.pm2_5); + printf("PM10: %.2f\n", current_pms5003_reading.pm10); + } } diff --git a/pms5003.c b/pms5003.c index 0a99c81..2879acd 100644 --- a/pms5003.c +++ b/pms5003.c @@ -1,6 +1,8 @@ #include "pms5003.h" #include "hardware/uart.h" #include "pico/stdlib.h" +#include +#include #include #include @@ -14,21 +16,91 @@ Sourcces: https://shop.pimoroni.com/products/pms5003-particulate-matter-sensor-with-cable - https://github.com/pimoroni/pms5003-python/blob/main/pms5003/__init__.py - https://github.com/vogelrh/pms5003c/tree/master - - https://github.com/raspberrypi/pico-examples/blob/master/uart/hello_uart/hello_uart.c + - +https://github.com/raspberrypi/pico-examples/blob/master/uart/hello_uart/hello_uart.c */ -void pms5003_init(pms5003_config *new_config, uart_inst_t *uart, uint8_t tx_pin, - uint8_t rx_pin) { - uart_init(uart, 9600); - gpio_set_function(tx_pin, UART_FUNCSEL_NUM(uart, tx_pin)); - gpio_set_function(rx_pin, UART_FUNCSEL_NUM(uart, rx_pin)); - new_config->uart = uart; +static uint8_t rx_buf[32] = {0}; +static uint8_t rx_i = 0; + +static float last_pm1_reading = 0; +static float last_pm2_5_reading = 0; +static float last_pm10_reading = 0; + +static void extract_pm_values_from_rx_buf() { + uint8_t pm1_low = rx_buf[9]; + uint8_t pm1_high = rx_buf[10]; + uint16_t pm1 = ((uint16_t)pm1_high << 8) | pm1_low; + + uint8_t pm2_5_low = rx_buf[11]; + uint8_t pm2_5_high = rx_buf[12]; + uint16_t pm2_5 = ((uint16_t)pm2_5_high << 8) | pm2_5_low; + + uint8_t pm10_low = rx_buf[13]; + uint8_t pm10_high = rx_buf[14]; + uint16_t pm10 = ((uint16_t)pm10_high << 8) | pm10_low; + + last_pm1_reading = (float)pm1; + last_pm2_5_reading = (float)pm2_5; + last_pm10_reading = (float)pm10; } +static void on_uart_rx() { + while (uart_is_readable(uart1)) { + uint8_t ch = uart_getc(uart1); + // start of a message + if (ch == 0x42) { + printf("pms5003 reading received\n"); + rx_i = 0; + } + rx_buf[rx_i] = ch; + rx_i++; + // end of message + if (rx_i == 31) { + extract_pm_values_from_rx_buf(); + } + + // guard + if (rx_i > 32) { + rx_i = 0; + } + } +} + +static unsigned char pms5003_command_prefix[] = {0x42, 0x4D}; +void pms5003_init(pms5003_config *new_config, uart_inst_t *uart, uint8_t tx_pin, + uint8_t rx_pin, uint8_t enable_pin, uint8_t reset_pin) { + gpio_set_function(tx_pin, UART_FUNCSEL_NUM(uart, tx_pin)); + gpio_set_function(rx_pin, UART_FUNCSEL_NUM(uart, rx_pin)); + uart_init(uart, 9600); + uart_set_format(uart, 8, 1, UART_PARITY_NONE); + irq_set_exclusive_handler(UART1_IRQ, on_uart_rx); + irq_set_enabled(UART1_IRQ, true); + uart_set_irq_enables(uart, true, false); + + // high level or suspending is normal working status, while low level is sleeping mode. + gpio_init(enable_pin); + gpio_set_dir(enable_pin, GPIO_OUT); + gpio_put(enable_pin, 0); + + // low resets + // gpio_init(reset_pin); + // gpio_set_dir(reset_pin, GPIO_OUT); + // gpio_set_pulls(enable_pin, true, false); // pull up + // gpio_put(enable_pin, 1); + + new_config->uart = uart; + new_config->enable_pin = enable_pin; + new_config->reset_pin = reset_pin; +} + +/** + Reads should happen min of 30sec after waking the sensor +*/ pms5003_reading pms5003_read(pms5003_config *config) { pms5003_reading reading; - reading.pm1 = 0; - reading.pm2_5 = 0; - reading.pm10 = 0; + reading.pm1 = last_pm1_reading; + reading.pm2_5 = last_pm2_5_reading; + reading.pm10 = last_pm10_reading; return reading; } diff --git a/pms5003.h b/pms5003.h index 16cc66a..c101dcc 100644 --- a/pms5003.h +++ b/pms5003.h @@ -11,10 +11,12 @@ typedef struct { typedef struct { uart_inst_t *uart; + uint8_t enable_pin; + uint8_t reset_pin; } pms5003_config; void pms5003_init(pms5003_config *config, uart_inst_t *uart, uint8_t tx_pin, - uint8_t rx_pin); + uint8_t rx_pin, uint8_t enable_pin, uint8_t reset_pin); pms5003_reading pms5003_read(pms5003_config *config); #endif /* PMS5003_H */