diff --git a/drivers/pms5003/pms5003.cmake b/drivers/pms5003/pms5003.cmake index 3593ea6b..2c59bb2e 100644 --- a/drivers/pms5003/pms5003.cmake +++ b/drivers/pms5003/pms5003.cmake @@ -7,4 +7,4 @@ target_sources(${DRIVER_NAME} INTERFACE target_include_directories(${DRIVER_NAME} INTERFACE ${CMAKE_CURRENT_LIST_DIR}) # Pull in pico libraries that we need -target_link_libraries(${DRIVER_NAME} INTERFACE pico_stdlib hardware_uart hardware_gpio) +target_link_libraries(${DRIVER_NAME} INTERFACE pico_stdlib pimoroni_i2c hardware_uart hardware_gpio) diff --git a/drivers/pms5003/pms5003.hpp b/drivers/pms5003/pms5003.hpp index f5f07fb3..f1d7c979 100644 --- a/drivers/pms5003/pms5003.hpp +++ b/drivers/pms5003/pms5003.hpp @@ -1,5 +1,7 @@ #include "pico/stdlib.h" #include "hardware/uart.h" +#include "common/pimoroni_common.hpp" +#include "common/pimoroni_i2c.hpp" #include constexpr char PMS5003_SOF[] = "\x42\x4d"; @@ -14,6 +16,8 @@ constexpr uint PMS5003_MAX_RESET_TIME = 20000; constexpr uint PMS5003_MAX_RESP_TIME = 5000; constexpr uint PMS5003_MIN_CMD_INTERVAL = 100; +const uint8_t PMSA003I_DEFAULT_I2C_ADDRESS = 0x12; + class PMS5003 { public: @@ -45,11 +49,14 @@ class PMS5003 { uart_init(uart, 9600); gpio_init(pin_tx);gpio_set_function(pin_tx, GPIO_FUNC_UART); gpio_init(pin_rx);gpio_set_function(pin_rx, GPIO_FUNC_UART); - gpio_init(pin_reset);gpio_set_function(pin_reset, GPIO_FUNC_SIO);gpio_set_dir(pin_reset, GPIO_OUT);gpio_put(pin_reset, false); - gpio_init(pin_enable);gpio_set_function(pin_enable, GPIO_FUNC_SIO);gpio_set_dir(pin_enable, GPIO_OUT);gpio_put(pin_enable, true); - reset(); + common_init(); }; + + PMS5003(pimoroni::I2C *i2c, uint pin_reset, uint pin_enable) : i2c(i2c), pin_reset(pin_reset), pin_enable(pin_enable) { + common_init(); + } + ~PMS5003() {}; void reset() { @@ -58,13 +65,20 @@ class PMS5003 { reset_input_buffer(); sleep_ms(100); gpio_put(pin_reset, true); + if(i2c) { + sleep_ms(1000); + } }; bool read(response_data &data) { reset_input_buffer(); // Read the 32 byte transaction - SOF + Size + Data + CRC - uart_read_blocking(uart, buffer, 32); + if(i2c) { + i2c->read_blocking(PMSA003I_DEFAULT_I2C_ADDRESS, buffer, 32, false); + } else { + uart_read_blocking(uart, buffer, 32); + } // test the checksum matches, if not quit early with a false return value uint16_t checksum = (buffer[30] << 8) | buffer[31]; @@ -98,17 +112,28 @@ class PMS5003 { } private: - uart_inst_t *uart; - uint pin_tx; - uint pin_rx; + // I2C mode + pimoroni::I2C *i2c = nullptr; + + // UART mode + uart_inst_t *uart = nullptr; + uint pin_tx = pimoroni::PIN_UNUSED; + uint pin_rx = pimoroni::PIN_UNUSED; uint pin_reset; uint pin_enable; uint8_t buffer[64]; void reset_input_buffer() { + if(i2c) return; while(uart_is_readable(uart)) { uart_getc(uart); } }; + + void common_init() { + gpio_init(pin_reset);gpio_set_function(pin_reset, GPIO_FUNC_SIO);gpio_set_dir(pin_reset, GPIO_OUT);gpio_put(pin_reset, false); + gpio_init(pin_enable);gpio_set_function(pin_enable, GPIO_FUNC_SIO);gpio_set_dir(pin_enable, GPIO_OUT);gpio_put(pin_enable, true); + reset(); + }; }; \ No newline at end of file diff --git a/examples/breakout_pms5003/CMakeLists.txt b/examples/breakout_pms5003/CMakeLists.txt index 7b63b787..ead02ec3 100644 --- a/examples/breakout_pms5003/CMakeLists.txt +++ b/examples/breakout_pms5003/CMakeLists.txt @@ -1,12 +1,7 @@ -set(OUTPUT_NAME pms5003_demo) +add_executable(pms5003_demo pms5003_demo.cpp) +target_link_libraries(pms5003_demo pico_stdlib pms5003) +pico_add_extra_outputs(pms5003_demo) -add_executable( - ${OUTPUT_NAME} - pms5003_demo.cpp -) - -# Pull in pico libraries that we need -target_link_libraries(${OUTPUT_NAME} pico_stdlib pms5003) - -# create map/bin/hex file etc. -pico_add_extra_outputs(${OUTPUT_NAME}) +add_executable(pmsa003i_demo pmsa003i_demo.cpp) +target_link_libraries(pmsa003i_demo pico_stdlib pms5003) +pico_add_extra_outputs(pmsa003i_demo) diff --git a/examples/breakout_pms5003/pmsa003i_demo.cpp b/examples/breakout_pms5003/pmsa003i_demo.cpp new file mode 100644 index 00000000..e0e61a8b --- /dev/null +++ b/examples/breakout_pms5003/pmsa003i_demo.cpp @@ -0,0 +1,45 @@ +#include +#include "pico/stdlib.h" +#include "common/pimoroni_common.hpp" +#include "common/pimoroni_i2c.hpp" + +#include + +#include "pms5003.hpp" + +using namespace pimoroni; + +I2C i2c(4, 5, 100000); +PMS5003 pms5003(&i2c, 9, 10); +PMS5003::response_data data; + +int main() { + stdio_init_all(); + + // Enable Enviro power supply! + gpio_init(11); + gpio_set_dir(11, GPIO_OUT); + gpio_put(11, true); + + while(true){ + bool result = pms5003.read(data); + if(result){ + printf("%04x ", data.pm_1_0); // PM1.0 ug/m3 (ultrafine particles) + printf("%04x ", data.pm_2_5); // PM2.5 ug/m3 (combustion particles, organic compounds, metals) + printf("%04x ", data.pm_10); // PM10 ug/m3 (dust, pollen, mould spores) + printf("%04x ", data.pm_1_0_ao); // PM 1.0 under atmospheric environment + printf("%04x ", data.pm_2_5_ao); // PM 2.5 under atmospheric environment + printf("%04x ", data.pm_10_ao); // PM 10 under atmospheric environment + printf("%04x ", data.pm_0_3_1l); // PM 0.3 in 0.1L of air + printf("%04x ", data.pm_0_5_1l); // PM 0.5 in 0.1L of air + printf("%04x ", data.pm_1_0_1l); // PM 1.0 in 0.1L of air + printf("%04x ", data.pm_2_5_1l); // PM 2.5 in 0.1L of air + printf("%04x ", data.pm_5_1l); // PM 5 in 0.1L of air + printf("%04x ", data.pm_10_1l); // PM 10 in 0.1L of air + printf("\n"); + } + sleep_ms(100); + }; + + return 0; +} \ No newline at end of file