made serial output optional, added error codes and error reporting

This commit is contained in:
2EEEB 2020-04-19 12:34:41 +02:00
parent 120f60df8d
commit 8f8ae4fbc8
Signed by: 2EEEB
GPG Key ID: 8F12BD6D9D435DB2
2 changed files with 168 additions and 49 deletions

View File

@ -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();

View File

@ -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);