kopia lustrzana https://github.com/pimoroni/pimoroni-pico
				
				
				
			PMS5003: Basic PMS5003 active-mode only driver.
							rodzic
							
								
									8d329ccdd4
								
							
						
					
					
						commit
						c526c3ce6e
					
				| 
						 | 
					@ -34,3 +34,4 @@ add_subdirectory(encoder)
 | 
				
			||||||
add_subdirectory(motor)
 | 
					add_subdirectory(motor)
 | 
				
			||||||
add_subdirectory(vl53l5cx)
 | 
					add_subdirectory(vl53l5cx)
 | 
				
			||||||
add_subdirectory(pcf85063a)
 | 
					add_subdirectory(pcf85063a)
 | 
				
			||||||
 | 
					add_subdirectory(pms5003)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1 @@
 | 
				
			||||||
 | 
					include(pms5003.cmake)
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,10 @@
 | 
				
			||||||
 | 
					set(DRIVER_NAME pms5003)
 | 
				
			||||||
 | 
					add_library(${DRIVER_NAME} INTERFACE)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					target_sources(${DRIVER_NAME} INTERFACE
 | 
				
			||||||
 | 
					  ${CMAKE_CURRENT_LIST_DIR}/${DRIVER_NAME}.cpp)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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)
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,114 @@
 | 
				
			||||||
 | 
					#include "pico/stdlib.h"
 | 
				
			||||||
 | 
					#include "hardware/uart.h"
 | 
				
			||||||
 | 
					#include <cstring>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					constexpr char PMS5003_SOF[] = "\x42\x4d";
 | 
				
			||||||
 | 
					constexpr uint16_t PMS5003_SOFU = 0x424d;
 | 
				
			||||||
 | 
					constexpr char PMS5003_CMD_MODE_PASSIVE[] = "\xe1\x00\x00";
 | 
				
			||||||
 | 
					constexpr char PMS5003_CMD_MODE_ACTIVE[] = "\xe1\x00\x01";
 | 
				
			||||||
 | 
					constexpr char PMS5003_CMD_READ[] = "\xe2\x00\x00";
 | 
				
			||||||
 | 
					constexpr char PMS5003_CMD_SLEEP[] = "\xe4\x00\x00";
 | 
				
			||||||
 | 
					constexpr char PMS5003_CMD_WAKEUP[] = "\xe4\x00\x01";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					constexpr uint PMS5003_MAX_RESET_TIME = 20000;
 | 
				
			||||||
 | 
					constexpr uint PMS5003_MAX_RESP_TIME = 5000;
 | 
				
			||||||
 | 
					constexpr uint PMS5003_MIN_CMD_INTERVAL = 100;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class PMS5003 {
 | 
				
			||||||
 | 
					    public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma pack(push, 1)
 | 
				
			||||||
 | 
					        struct alignas(1) response_data {
 | 
				
			||||||
 | 
					            uint16_t pm_1_0;
 | 
				
			||||||
 | 
					            uint16_t pm_2_5;
 | 
				
			||||||
 | 
					            uint16_t pm_10;
 | 
				
			||||||
 | 
					            uint16_t pm_1_0_ao;
 | 
				
			||||||
 | 
					            uint16_t pm_2_5_ao;
 | 
				
			||||||
 | 
					            uint16_t pm_10_ao;
 | 
				
			||||||
 | 
					            uint16_t pm_0_3_1l;
 | 
				
			||||||
 | 
					            uint16_t pm_0_5_1l;
 | 
				
			||||||
 | 
					            uint16_t pm_1_0_1l;
 | 
				
			||||||
 | 
					            uint16_t pm_2_5_1l;
 | 
				
			||||||
 | 
					            uint16_t pm_5_1l;
 | 
				
			||||||
 | 
					            uint16_t pm_10_1l;
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					#pragma pack(pop)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        PMS5003(uart_inst_t *uart, uint pin_tx, uint pin_rx,
 | 
				
			||||||
 | 
					                uint pin_reset, uint pin_enable)
 | 
				
			||||||
 | 
					                : uart(uart),
 | 
				
			||||||
 | 
					                pin_tx(pin_tx),
 | 
				
			||||||
 | 
					                pin_rx(pin_rx),
 | 
				
			||||||
 | 
					                pin_reset(pin_reset),
 | 
				
			||||||
 | 
					                pin_enable(pin_enable) {
 | 
				
			||||||
 | 
					                    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();
 | 
				
			||||||
 | 
					                };
 | 
				
			||||||
 | 
					        ~PMS5003() {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        void reset() {
 | 
				
			||||||
 | 
					            sleep_ms(100);
 | 
				
			||||||
 | 
					            gpio_put(pin_reset, false);
 | 
				
			||||||
 | 
					            reset_input_buffer();
 | 
				
			||||||
 | 
					            sleep_ms(100);
 | 
				
			||||||
 | 
					            gpio_put(pin_reset, true);
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        bool read(response_data &data) {
 | 
				
			||||||
 | 
					            reset_input_buffer();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Read the 32 byte transaction - SOF + Size + Data + CRC
 | 
				
			||||||
 | 
					            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];
 | 
				
			||||||
 | 
					            uint16_t compare = 0;
 | 
				
			||||||
 | 
					            for(int i = 0; i < 30; i++) {
 | 
				
			||||||
 | 
					                compare += buffer[i];
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if(compare != checksum) {
 | 
				
			||||||
 | 
					                return false;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            // Copy the data into the result struct
 | 
				
			||||||
 | 
					            memcpy(&data, buffer + 4, sizeof(data));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Byteswap the results
 | 
				
			||||||
 | 
					            data.pm_1_0     = __builtin_bswap16(data.pm_1_0);
 | 
				
			||||||
 | 
					            data.pm_2_5     = __builtin_bswap16(data.pm_2_5);
 | 
				
			||||||
 | 
					            data.pm_10      = __builtin_bswap16(data.pm_10);
 | 
				
			||||||
 | 
					            data.pm_1_0_ao  = __builtin_bswap16(data.pm_1_0_ao);
 | 
				
			||||||
 | 
					            data.pm_2_5_ao  = __builtin_bswap16(data.pm_2_5_ao);
 | 
				
			||||||
 | 
					            data.pm_10_ao   = __builtin_bswap16(data.pm_10_ao);
 | 
				
			||||||
 | 
					            data.pm_0_3_1l  = __builtin_bswap16(data.pm_0_3_1l);
 | 
				
			||||||
 | 
					            data.pm_0_5_1l  = __builtin_bswap16(data.pm_0_5_1l);
 | 
				
			||||||
 | 
					            data.pm_1_0_1l  = __builtin_bswap16(data.pm_1_0_1l);
 | 
				
			||||||
 | 
					            data.pm_2_5_1l  = __builtin_bswap16(data.pm_2_5_1l);
 | 
				
			||||||
 | 
					            data.pm_5_1l    = __builtin_bswap16(data.pm_5_1l);
 | 
				
			||||||
 | 
					            data.pm_10_1l   = __builtin_bswap16(data.pm_10_1l);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return true;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private:
 | 
				
			||||||
 | 
					        uart_inst_t *uart;
 | 
				
			||||||
 | 
					        uint pin_tx;
 | 
				
			||||||
 | 
					        uint pin_rx;
 | 
				
			||||||
 | 
					        uint pin_reset;
 | 
				
			||||||
 | 
					        uint pin_enable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        uint8_t buffer[64];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        void reset_input_buffer() {
 | 
				
			||||||
 | 
					            while(uart_is_readable(uart)) {
 | 
				
			||||||
 | 
					                uart_getc(uart);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
| 
						 | 
					@ -22,6 +22,7 @@ add_subdirectory(breakout_bh1745)
 | 
				
			||||||
add_subdirectory(breakout_icp10125)
 | 
					add_subdirectory(breakout_icp10125)
 | 
				
			||||||
add_subdirectory(breakout_scd41)
 | 
					add_subdirectory(breakout_scd41)
 | 
				
			||||||
add_subdirectory(breakout_vl53l5cx)
 | 
					add_subdirectory(breakout_vl53l5cx)
 | 
				
			||||||
 | 
					add_subdirectory(breakout_pms5003)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
add_subdirectory(pico_display)
 | 
					add_subdirectory(pico_display)
 | 
				
			||||||
add_subdirectory(pico_display_2)
 | 
					add_subdirectory(pico_display_2)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,12 @@
 | 
				
			||||||
 | 
					set(OUTPUT_NAME 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})
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,40 @@
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include "pico/stdlib.h"
 | 
				
			||||||
 | 
					#include "common/pimoroni_common.hpp"
 | 
				
			||||||
 | 
					#include "hardware/uart.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <cstring>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "pms5003.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using namespace pimoroni;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					PMS5003 pms5003(uart1, 8, 9, 2, 3);
 | 
				
			||||||
 | 
					PMS5003::response_data data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main() {
 | 
				
			||||||
 | 
					  stdio_init_all();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  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;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Ładowanie…
	
		Reference in New Issue