From 04d4431d0d15c5f4ef77f43cb603dec014454885 Mon Sep 17 00:00:00 2001 From: Thomas Petig Date: Sun, 23 Jun 2024 04:02:13 +0200 Subject: [PATCH] clean up of modbus interface --- include/measurement.hpp | 21 ++++++++ include/modbus.hpp | 49 +++++++++++++++++ include/scd30.hpp | 116 ++++++++++++++++++---------------------- 3 files changed, 122 insertions(+), 64 deletions(-) create mode 100644 include/measurement.hpp diff --git a/include/measurement.hpp b/include/measurement.hpp new file mode 100644 index 0000000..766b76d --- /dev/null +++ b/include/measurement.hpp @@ -0,0 +1,21 @@ +#pragma once +#include + +typedef struct +{ + /** CO2 in ppm */ + float co2; + /** Temperatur in deg C */ + float temp; + /** Relative humidity in % */ + float hum; + /** 5 V system voltage measured */ + float v_sys; + /** measured cell voltage */ + float v_cell; +} measurement_t; + +void print_meas(const measurement_t& meas) +{ + printf("DATA,%f,V,%f,V,%f,ppm,%f,C,%f,%%",meas.v_cell, meas.v_sys, meas.co2, meas.temp, meas.hum); +} diff --git a/include/modbus.hpp b/include/modbus.hpp index 3013021..2fbd2b2 100644 --- a/include/modbus.hpp +++ b/include/modbus.hpp @@ -5,6 +5,7 @@ ** MODBUS interface */ #pragma once +#include "crc.h" /** ** Initialising modbus on UART0 @@ -43,3 +44,51 @@ void modbus_tx_enable() { gpio_put(UART0_RE_PIN, 1); gpio_put(UART0_DE_PIN, 1); } +uint8_t msb(uint16_t data) +{ + return (data >> 8) & 0xFF; +} +uint8_t lsb(uint16_t data) +{ + return data & 0xFF; +} + + +uint8_t tx_arr_crc(uart_inst_t* uartid, const uint8_t* ptr, int len) { + crc_t crc = crc_init (); + crc = crc_update (crc, ptr, len); + crc = crc_finalize(crc); + +#if 0 + for (int i = 0; i < len; i++) { + printf("%x,", (int)ptr[i]); + } + printf("%x,", crc & 0xFF); + printf("%x,", (crc >> 8) & 0xFF); + printf("\r\n"); +#endif + + uart_write_blocking(uartid, ptr, len); + uart_putc(uartid, lsb(crc)); + uart_putc(uartid, msb(crc)); + return 0; +} + +uint8_t readMultipleHoldingRegister (uart_inst_t* uartid, uint8_t slave, uint16_t address, uint16_t numreg) +{ + uint8_t func_code = 0x03; + uint8_t req[] = {slave, func_code, + msb(address), lsb(address), + msb(numreg), lsb(numreg)}; + tx_arr_crc (uartid, req, sizeof(req)); + return numreg * 2 + 5; +} +uint8_t writeSingleHoldingRegister (uart_inst_t* uartid, uint8_t slave, uint16_t address, uint16_t value) +{ + uint8_t func_code = 0x06; + uint8_t req[] = {slave, func_code, + msb(address), lsb(address), + msb(value), lsb(value)}; + tx_arr_crc (uartid, req, sizeof(req)); + return 2 * 2 + 5; +} diff --git a/include/scd30.hpp b/include/scd30.hpp index 561009b..27dcddd 100644 --- a/include/scd30.hpp +++ b/include/scd30.hpp @@ -1,25 +1,9 @@ #pragma once + #include "hardware/uart.h" #include "crc.h" +#include "measurement.hpp" -typedef struct -{ - /** CO2 in ppm */ - float co2; - /** Temperatur in deg C */ - float temp; - /** Relative humidity in % */ - float hum; - /** 5 V system voltage measured */ - float v_sys; - /** measured cell voltage */ - float v_cell; -} measurement_t; - -void print_meas(const measurement_t& meas) -{ - printf("DATA,%f,V,%f,V,%f,ppm,%f,C,%f,%%",meas.v_cell, meas.v_sys, meas.co2, meas.temp, meas.hum); -} const uint8_t start_cont[] = {0x61, 0x06, 0x00, 0x36, 0x00, 0x00, 0x60, 0x64}; const uint8_t stop_cont[] = {0x61, 0x06, 0x00, 0x37, 0x00, 0x01, 0xF0, 0x64}; @@ -49,84 +33,84 @@ class SCD30 { SCD30() {} int init() { - printf("Init SCD30 uart tx: %d, rx: %d, ch: %d\n\r", TX, RX, UART); gpio_set_function(TX, GPIO_FUNC_UART); gpio_set_function(RX, GPIO_FUNC_UART); uart_init(uart_id(), baud); - sleep_ms(10); uart_set_fifo_enabled(uart_id(), false); - sleep_ms(10); uart_set_hw_flow(uart_id(), false, false); - sleep_ms(10); // Set our data format //uart_set_format(uart_id(), 8, 1, UART_PARITY_NONE); // And set up and enable the interrupt hand - printf("Init SCD30 uart irq\n\r"); irq_set_exclusive_handler(uart_irq(), on_uart_rx); irq_set_enabled(uart_irq(), true); // Now enable the UART to send interrupts - uart_set_irq_enables(uart_id(), true, false); - printf("Init SCD30 done\n\r"); return 0; } void txReset() { - sleep_ms(10); resp_len = sizeof(soft_reset); - tx_arr(soft_reset, sizeof(soft_reset)); + wait_start = 0; + finished = 0; + tx_arr_crc(uart_id(), soft_reset, sizeof(soft_reset)-2); } + void txContStart() { - sleep_ms(10); resp_len = sizeof(start_cont); - tx_arr(start_cont, sizeof(start_cont)); + wait_start = 0; + finished = 0; + tx_arr_crc(uart_id(), start_cont, sizeof(start_cont)-2); } + + /** + ** Send measurement request. + */ void txMeas() { - sleep_ms(10); - resp_len = 17; - tx_arr(read_meas, sizeof(read_meas)); + wait_start = 0; + finished = 0; + resp_len = readMultipleHoldingRegister(uart_id(), 0x61, 0x28, 0x06); } - void getMeas(measurement_t& measurement) { + float getCO2 () { uint32_t co2 = ((uint32_t)raw_buffer[3]) << 24 | ((uint32_t)raw_buffer[4]) << 16 | ((uint32_t)raw_buffer[5]) << 8 | ((uint32_t)raw_buffer[6]); + float co2f = *(float*)&co2; + return co2f; + } + + float getTemp() { uint32_t temp = ((uint32_t)raw_buffer[7]) << 24 | ((uint32_t)raw_buffer[8]) << 16 | ((uint32_t)raw_buffer[9]) << 8 | ((uint32_t)raw_buffer[10]); + float tempf = *(float*)&temp; + return tempf; + } + + float getHum() { uint32_t hum = ((uint32_t)raw_buffer[11]) << 24 | ((uint32_t)raw_buffer[12]) << 16 | ((uint32_t)raw_buffer[13]) << 8 | ((uint32_t)raw_buffer[14]); - float co2f = *(float*)&co2; - float tempf = *(float*)&temp; float humf = *(float*)&hum; + return humf; + } - measurement.co2 = co2f; - measurement.temp = tempf; - measurement.hum = humf; + void getMeas(measurement_t& measurement) { + measurement.co2 = getCO2(); + measurement.temp = getTemp(); + measurement.hum = getHum(); } void printMeas(bool csv = false) { - uint32_t co2 = ((uint32_t)raw_buffer[3]) << 24 | - ((uint32_t)raw_buffer[4]) << 16 | - ((uint32_t)raw_buffer[5]) << 8 | - ((uint32_t)raw_buffer[6]); - uint32_t temp = ((uint32_t)raw_buffer[7]) << 24 | - ((uint32_t)raw_buffer[8]) << 16 | - ((uint32_t)raw_buffer[9]) << 8 | - ((uint32_t)raw_buffer[10]); - uint32_t hum = ((uint32_t)raw_buffer[11]) << 24 | - ((uint32_t)raw_buffer[12]) << 16 | - ((uint32_t)raw_buffer[13]) << 8 | - ((uint32_t)raw_buffer[14]); - float co2f = *(float*)&co2; - float tempf = *(float*)&temp; - float humf = *(float*)&hum; + float co2f = getCO2(); + float tempf = getTemp(); + float humf = getHum(); if (csv) { printf("%f,%f,%f", co2f, tempf, humf); } else { @@ -176,23 +160,23 @@ class SCD30 { return crc == 0; } - int check_resp(){ + int check_resp() { if (finished) { return check_crc(); } else { return 0; } } - int print_resp(){ + int print_resp() { if (finished) { - crc_t crc = crc_init(); - crc = crc_update(crc, raw_buffer, resp_len); - crc = crc_finalize(crc); + crc_t crc = crc_init (); + crc = crc_update (crc, raw_buffer, resp_len); + crc = crc_finalize (crc); for (int i = 0; i < chars_rxed; i++) { printf("%x,", (int)raw_buffer[i]); } - uart_puts(uart_id(), "\r\n"); + printf("\r\n"); finished= 0; chars_rxed = 0; printf("CRC %x\r\n", (int)crc); @@ -202,16 +186,20 @@ class SCD30 { for (int i = 0; i < chars_rxed; i++) { printf("%x,", (int)raw_buffer[i]); } - uart_puts(uart_id(), "\r\n"); + printf("\r\n"); return 0; } } private: - uint8_t tx_arr(const uint8_t* ptr, int len) { - wait_start = 0; - finished = 0; - uart_write_blocking(uart_id(), ptr, len); - return 0; + + + uint8_t msb(uint16_t data) + { + return (data >> 8) & 0xFF; + } + uint8_t lsb(uint16_t data) + { + return data & 0xFF; } static constexpr int baud = 19200; };