From 8f8ae4fbc8bc6ea31e1281a367e17362aba86d94 Mon Sep 17 00:00:00 2001 From: 2EEEB <192235@vutbr.cz> Date: Sun, 19 Apr 2020 12:34:41 +0200 Subject: [PATCH] made serial output optional, added error codes and error reporting --- bc_co2_module_arduino.cpp | 173 +++++++++++++++++++++++++++----------- bc_co2_module_arduino.h | 44 +++++++++- 2 files changed, 168 insertions(+), 49 deletions(-) diff --git a/bc_co2_module_arduino.cpp b/bc_co2_module_arduino.cpp index a077cfe..72daa30 100644 --- a/bc_co2_module_arduino.cpp +++ b/bc_co2_module_arduino.cpp @@ -11,13 +11,22 @@ #define MODBUS_READ 0x44 #define INITIAL_MEASUREMENT 0x10 #define SEQUENTIAL_MEASUREMENT 0x20 -#define RX_CONC (3 + 0x9a - 0x80) +#define _BC_LP8_RX_ERROR_STATUS0 (3 + 0xa7 - 0x80) +#define _BC_LP8_RX_ERROR_STATUS1 (3 + 0xa6 - 0x80) +// #define RX_CONC (3 + 0x9a - 0x80) //no pressure correction or noise filtering +// #define RX_CONC (3 + 0x9c - 0x80) //pressure correction no noise filtering +// #define RX_CONC (3 + 0xa8 - 0x80) //no pressure correction, noise filtered +#define RX_CONC (3 + 0xaa - 0x80) //pressure correction and noise filtering static struct lp8_t sensor; unsigned long delay_started = 0; bool delay_running = false; +static bool diag; -bool init_module() { +bool init_co2_module(long baudrate) { + if(baudrate > 0) { + diag = true; + } //init comms Serial1.begin(9600, SERIAL_8N2); //init Serial comm to lp8 sensor, 8data bits 2 stop bits, no parity Wire.begin(); //init arduino i2c @@ -31,6 +40,7 @@ bool reset_module() { sensor.first_measurement_done = false; //no state writeback sensor.calibration_run = false; sensor.pressure = 10124; + sensor.valid = false; //set appropriate port directions tca_set_direction(0x00); @@ -40,7 +50,7 @@ bool reset_module() { tca_set_port(0xee); //charge the cap tca_set_port(0xe8); - //non blocking 15second delay to charge the cap + //start non blocking delay to charge the cap delay_started = millis(); delay_running = true; @@ -57,26 +67,32 @@ static void measure(){ switch (sensor.state) { case LP8_STATE_ERROR: { - //DIAG - Serial.println(sensor.state); + if(diag) { + Serial.println(sensor.state); + Serial.print("error_state: "); + Serial.println(sensor.error); + } reset_module(); goto start; } case LP8_STATE_READY: { - //DIAG - Serial.println(sensor.state); + if(diag) { + Serial.println(sensor.state); + } + i = 0; tca_set_direction(0x00); - // tca_set_direction(0x08); tca_set_port(0xee); + sensor.state = LP8_STATE_INITIALIZE; goto start; } case LP8_STATE_INITIALIZE: { - //DIAG - Serial.println(sensor.state); + if(diag) { + Serial.println(sensor.state); + } //wait 15s to ensure cap is sufficiently charged if(delay_running && ((millis() - delay_started) >= 15000)) { delay_running = false; @@ -93,8 +109,9 @@ static void measure(){ } case LP8_STATE_PRECHARGE: { - //DIAG - Serial.println(sensor.state); + if(diag) { + Serial.println(sensor.state); + } tca_set_port(0xe8); sensor.state = LP8_STATE_CHARGE; @@ -102,8 +119,9 @@ static void measure(){ } case LP8_STATE_CHARGE: { - //DIAG - Serial.println(sensor.state); + if(diag) { + Serial.println(sensor.state); + } tca_set_port(0xe0); sensor.state = LP8_STATE_BOOT; @@ -111,14 +129,17 @@ static void measure(){ } case LP8_STATE_BOOT: { - //DIAG - Serial.println(sensor.state); + if(diag) { + Serial.println(sensor.state); + } while(get_ready_state() != 0) { delay(10); i++; - if(i > 70) { - //DIAG - Serial.println("tout!"); + if(i >= 21) { //210ms wait for ready pin + if(diag) { + Serial.println("boot_tout!"); + } + sensor.error = LP8_ERROR_BOOT_TIMEOUT; sensor.state = LP8_STATE_ERROR; goto start; } @@ -134,8 +155,9 @@ static void measure(){ sensor.tx_buffer[5] = INITIAL_MEASUREMENT; sensor.tx_buffer[6] = 0x28; sensor.tx_buffer[7] = 0x7e; - //DIAG - Serial.println("initial_measure"); + if(diag) { + Serial.println("initial_measure"); + } length = 8; } else { @@ -149,13 +171,15 @@ static void measure(){ if(sensor.calibration_run == true){ sensor.tx_buffer[5] = sensor.calibration; - //DIAG - Serial.println("calibration_data"); + if(diag) { + Serial.println("calibration_data"); + } } else { sensor.tx_buffer[5] = SEQUENTIAL_MEASUREMENT; - //DIAG - Serial.println("seq_measure"); + if(diag) { + Serial.println("seq_measure"); + } } // memcpy(sensor.tx_buffer[6], sensor.sensor_state, 23); @@ -163,32 +187,42 @@ static void measure(){ sensor.tx_buffer[6 + i] = sensor.sensor_state[i]; i++; } - Serial.println("memcpyied"); + if(diag) { + Serial.println("memcpyied"); + } sensor.tx_buffer[29] = sensor.pressure >> 8; sensor.tx_buffer[30] = sensor.pressure; crc16 = calculate_crc16(sensor.tx_buffer, 31); - Serial.println("calc_crc"); + + if(diag) { + Serial.println("calc_crc"); + } sensor.tx_buffer[31] = crc16; sensor.tx_buffer[32] = crc16 >> 8; - Serial.println("buffer_made"); + + if(diag) { + Serial.println("buffer_made"); + } i = 0; length = 33; } Serial1.write(sensor.tx_buffer, length); - delay(100); + delay(75); //need time to process transmission sensor.state = LP8_STATE_BOOT_READ; goto start; } case LP8_STATE_BOOT_READ: { - //DIAG - Serial.println(sensor.state); + if(diag) { + Serial.println(sensor.state); + } + while(1) { rxbuf = Serial1.read(); sensor.rx_buffer[i] = rxbuf; @@ -198,14 +232,17 @@ static void measure(){ } } if(sensor.rx_buffer[0] != MODBUS_ADDR) { + sensor.error = LP8_ERROR_BOOT_READ_DEVICE_ADDRESS; sensor.state = LP8_STATE_ERROR; goto start; } if(sensor.rx_buffer[1] != sensor.tx_buffer[1]) { + sensor.error = LP8_ERROR_BOOT_READ_COMMAND; sensor.state = LP8_STATE_ERROR; goto start; } if(calculate_crc16(sensor.rx_buffer, 4) != 0){ + sensor.error = LP8_ERROR_BOOT_READ_CRC; sensor.state = LP8_STATE_ERROR; goto start; } @@ -216,12 +253,18 @@ static void measure(){ } case LP8_STATE_MEASURE: { - //DIAG - Serial.println(sensor.state); + if(diag) { + Serial.println(sensor.state); + } + while(get_ready_state() != 1){ - delay(10); + delay(10); //blocking, there is nothing else to do while measuring anyway i++; - if(i>50){ + if(i >= 25){ //timeout after 250ms + if(diag) { + Serial.println("read_tout!"); + } + sensor.error = LP8_ERROR_MEASURE_SIGNAL_RDY_TIMEOUT; sensor.state = LP8_STATE_ERROR; goto start; } @@ -240,14 +283,15 @@ static void measure(){ length = 7; Serial1.write(sensor.tx_buffer, length); - delay(100); + delay(75); //need time to process transmission sensor.state = LP8_STATE_MEASURE_READ; } case LP8_STATE_MEASURE_READ: { - //DIAG - Serial.println(sensor.state); + if(diag) { + Serial.println(sensor.state); + } while(1) { rxbuf = Serial1.read(); sensor.rx_buffer[i] = rxbuf; @@ -256,29 +300,64 @@ static void measure(){ break; } } - //DIAG - Serial.println("read_resp"); + if(diag) { + Serial.println("read_resp"); + } i = 0; + tca_set_port(0xee); //turn off vbb + if(sensor.rx_buffer[0] != MODBUS_ADDR){ + sensor.error = LP8_ERROR_MEASURE_READ_DEVICE_ADDRESS; sensor.state = LP8_STATE_ERROR; goto start; } if(sensor.rx_buffer[1] != sensor.tx_buffer[1]){ + sensor.error = LP8_ERROR_MEASURE_READ_COMMAND; sensor.state = LP8_STATE_ERROR; goto start; } if(calculate_crc16(sensor.rx_buffer, 49) != 0){ - //DIAG - Serial.println("bad_recv_crc"); + if(diag) { + Serial.println("bad_recv_crc"); + } + sensor.error = LP8_ERROR_MEASURE_READ_CRC; + sensor.state = LP8_STATE_ERROR; + goto start; + } + if(diag) { + Serial.print("error0: "); + Serial.println(sensor.rx_buffer[_BC_LP8_RX_ERROR_STATUS0]); + Serial.print("error1: "); + Serial.println(sensor.rx_buffer[_BC_LP8_RX_ERROR_STATUS1]); + } + + + if (sensor.rx_buffer[_BC_LP8_RX_ERROR_STATUS0] == 32) { + sensor.error = LP8_ERROR_MEASURE_READ_OOR; + sensor.state = LP8_STATE_ERROR; + goto start; + } + if (sensor.rx_buffer[_BC_LP8_RX_ERROR_STATUS1] == 4) { + sensor.error = LP8_ERROR_MEASURE_READ_STATUS1_ADC; + sensor.state = LP8_STATE_ERROR; + goto start; + } + if (sensor.rx_buffer[_BC_LP8_RX_ERROR_STATUS1] == 2) { + sensor.error = LP8_ERROR_MEASURE_READ_STATUS1_VCAP2; + sensor.state = LP8_STATE_ERROR; + goto start; + } + if (sensor.rx_buffer[_BC_LP8_RX_ERROR_STATUS1] == 1) { + sensor.error = LP8_ERROR_MEASURE_READ_STATUS1_VCAP1; sensor.state = LP8_STATE_ERROR; goto start; } - // memcpy(sensor.sensor_state, sensor.rx_buffer[4], 23); - //DIAG - Serial.println("save_state"); + if(diag) { + Serial.println("save_state"); + } while(i < 24) { sensor.sensor_state[i] = sensor.rx_buffer[4 + i]; i++; @@ -291,7 +370,7 @@ static void measure(){ sensor.valid = (sensor.concentration >= 0) && (sensor.concentration < 10000); - tca_set_port(0xee); + // tca_set_port(0xee); sensor.state = LP8_STATE_READY; return; @@ -302,7 +381,7 @@ static void measure(){ } -int16_t get_concentration(uint16_t pressure = 10124) { +int16_t get_co2_concentration(uint16_t pressure) { sensor.pressure = pressure; measure(); diff --git a/bc_co2_module_arduino.h b/bc_co2_module_arduino.h index e4c2066..b5a38fe 100644 --- a/bc_co2_module_arduino.h +++ b/bc_co2_module_arduino.h @@ -15,6 +15,45 @@ typedef enum } lp8_state_t; +typedef enum +{ + LP8_ERROR_INITIALIZE = 0, + LP8_ERROR_PRECHARGE = 1, + + LP8_ERROR_CHARGE_CHARGE_ENABLE = 2, + LP8_ERROR_CHARGE_DEVICE_ENABLE = 3, + + LP8_ERROR_BOOT_SIGNAL_READY = 4, + LP8_ERROR_BOOT_TIMEOUT = 5, + LP8_ERROR_BOOT_UART_ENABLE = 6, + LP8_ERROR_BOOT_UART_WRITE = 7, + + LP8_ERROR_BOOT_READ_UART_ENABLE = 8, + LP8_ERROR_BOOT_READ_DEVICE_ADDRESS = 9, + LP8_ERROR_BOOT_READ_COMMAND = 10, + LP8_ERROR_BOOT_READ_CRC = 11, + LP8_ERROR_BOOT_READ_TIMEOUT = 12, + + LP8_ERROR_MEASURE_SIGNAL_RDY = 13, + LP8_ERROR_MEASURE_SIGNAL_RDY_TIMEOUT = 14, + LP8_ERROR_MEASURE_UART_ENABLE = 15, + LP8_ERROR_MEASURE_UART_WRITE = 16, + + LP8_ERROR_MEASURE_READ_UART_ENABLE = 17, + LP8_ERROR_MEASURE_READ_DEVICE_ENABLE = 18, + LP8_ERROR_MEASURE_READ_DEVICE_ADDRESS = 19, + LP8_ERROR_MEASURE_READ_COMMAND = 20, + LP8_ERROR_MEASURE_READ_CRC = 21, + LP8_ERROR_MEASURE_READ_CALIBRATION_RUN = 22, + LP8_ERROR_MEASURE_READ_OOR = 23, + LP8_ERROR_MEASURE_READ_STATUS1 = 24, + LP8_ERROR_MEASURE_READ_STATUS1_ADC = 25, + LP8_ERROR_MEASURE_READ_STATUS1_VCAP1 = 26, + LP8_ERROR_MEASURE_READ_STATUS1_VCAP2 = 27, + LP8_ERROR_MEASURE_READ_TIMEOUT = 28 + +} lp8_error_t; + typedef enum { //Background calibration using unfiltered data @@ -39,6 +78,7 @@ typedef enum struct lp8_t { lp8_state_t state; + lp8_error_t error; bool first_measurement_done; lp8_calibration_t calibration; bool calibration_run; @@ -50,10 +90,10 @@ struct lp8_t { uint16_t pressure; }; -bool init_module(); +bool init_co2_module(long baudrate = 0); bool reset_module(); uint8_t get_ready_state(); uint16_t calculate_crc16(uint8_t *buffer, uint8_t length); bool tca_set_port(uint8_t port); bool tca_set_direction(uint8_t dir); -int16_t get_concentration(uint16_t pressure = 10124); +int16_t get_co2_concentration(uint16_t pressure = 10124);