changeset 1072:8b97003dbb60 Icon_Integration

Improve CO2 calibration: The most common calibration environment for diving is fresh air => ~400ppm co2. Some sensors do not have this setting as default => Calibration to 0ppm. To make sure that a proper calibration reference is set the common used value of 400ppm is not set before starting the calibration. For implementation new states were added to the co2 protocol state maschine. In addition the rx processor is now able to handle two responds parameters.
author Ideenmodellierer
date Thu, 19 Feb 2026 21:37:34 +0100
parents b4a79464caf7
children 734f84b72b30
files Small_CPU/Inc/uartProtocol_Co2.h Small_CPU/Src/externalInterface.c Small_CPU/Src/uartProtocol_Co2.c
diffstat 3 files changed, 91 insertions(+), 25 deletions(-) [+]
line wrap: on
line diff
--- a/Small_CPU/Inc/uartProtocol_Co2.h	Thu Feb 19 13:28:37 2026 +0100
+++ b/Small_CPU/Inc/uartProtocol_Co2.h	Thu Feb 19 21:37:34 2026 +0100
@@ -39,7 +39,9 @@
  	UART_CO2_SETUP = 10,	/* collecting data needed to be read out of the sensor once at startup */
 	UART_CO2_MODE,			/* set operation mode for sensor */
   	UART_CO2_OPERATING,		/* normal operation */
-	UART_CO2_CALIBRATE		/* request calibration */
+	UART_CO2_CALIBRATE_H,	/* request calibration */
+	UART_CO2_CALIBRATE_L,
+	UART_CO2_CALIBRATE
   } uartCO2Status_t;
 
   typedef enum
@@ -68,7 +70,9 @@
  {
  	CO2CMD_MODE_POLL,		/* Set operation mode of sensor to polling => only send data if requested */
  	CO2CMD_MODE_STREAM,		/* Set operation mode of sensor to streaming => send data every two seconds */
- 	CO2CMD_CALIBRATE,		/* Calibrate sensor */
+ 	CO2CMD_CALIBRATE_H,		/* Calibrate sensor, send HIGH reference */
+	CO2CMD_CALIBRATE_L,		/* Send low reference */
+	CO2CMD_CALIBRATE,		/* Execute calibration */
  	CO2CMD_GETSCALE,		/* Get scaling factor */
  	CO2CMD_GETDATA			/* Read sensor data */
  } co2SensorCmd_t;
--- a/Small_CPU/Src/externalInterface.c	Thu Feb 19 13:28:37 2026 +0100
+++ b/Small_CPU/Src/externalInterface.c	Thu Feb 19 21:37:34 2026 +0100
@@ -1062,7 +1062,7 @@
 										}
 										if(SensorMap[index] == SENSOR_CO2)
 										{
-											externalInterface_SensorState[index] = UART_CO2_CALIBRATE;
+											externalInterface_SensorState[index] = UART_CO2_CALIBRATE_H;
 										}
 			break;
 		case EXT_INTERFACE_O2_INDICATE:	index = (Cmd >> 8) & 0x000F;
--- a/Small_CPU/Src/uartProtocol_Co2.c	Thu Feb 19 13:28:37 2026 +0100
+++ b/Small_CPU/Src/uartProtocol_Co2.c	Thu Feb 19 21:37:34 2026 +0100
@@ -42,15 +42,19 @@
 
 	switch (CO2Cmd)
 	{
-		case CO2CMD_MODE_POLL:		*cmdLength = snprintf((char*)cmdString, 10, "K 2\r\n");
+		case CO2CMD_MODE_POLL:		*cmdLength = snprintf((char*)cmdString, 20, "K 2\r\n");
 				break;
-		case CO2CMD_MODE_STREAM:	*cmdLength = snprintf((char*)cmdString, 10, "K 1\r\n");
+		case CO2CMD_MODE_STREAM:	*cmdLength = snprintf((char*)cmdString, 20, "K 1\r\n");
+				break;
+		case CO2CMD_CALIBRATE_H:	*cmdLength = snprintf((char*)cmdString, 20, "P 10 1\r\n");		/* set 400ppm as reference => 1 (256) and 144 */
 				break;
-		case CO2CMD_CALIBRATE:		*cmdLength = snprintf((char*)cmdString, 10, "G\r\n");
+		case CO2CMD_CALIBRATE_L:	*cmdLength = snprintf((char*)cmdString, 20, "P 11 144\r\n");
+				break;
+		case CO2CMD_CALIBRATE:		*cmdLength = snprintf((char*)cmdString, 20, "G\r\n");
 				break;
-		case CO2CMD_GETDATA:		*cmdLength = snprintf((char*)cmdString, 10, "Q\r\n");
+		case CO2CMD_GETDATA:		*cmdLength = snprintf((char*)cmdString, 20, "Q\r\n");
 				break;
-		case CO2CMD_GETSCALE:		*cmdLength = snprintf((char*)cmdString, 10, ".\r\n");
+		case CO2CMD_GETSCALE:		*cmdLength = snprintf((char*)cmdString, 20, ".\r\n");
 				break;
 		default: *cmdLength = 0;
 			break;
@@ -64,7 +68,7 @@
 
 void uartCo2_Control(void)
 {
-	static uint8_t cmdString[10];
+	static uint8_t cmdString[20];
 	static uint8_t cmdLength = 0;
 	static uint8_t lastComState = UART_CO2_INIT;
 
@@ -97,6 +101,10 @@
 			break;
 		case UART_CO2_MODE:		uartCo2_SendCmd(CO2CMD_MODE_POLL, cmdString, &cmdLength);
 			break;
+		case UART_CO2_CALIBRATE_H:	uartCo2_SendCmd(CO2CMD_CALIBRATE_H, cmdString, &cmdLength);
+			break;
+		case UART_CO2_CALIBRATE_L:	uartCo2_SendCmd(CO2CMD_CALIBRATE_L, cmdString, &cmdLength);
+			break;
 		case UART_CO2_CALIBRATE:	uartCo2_SendCmd(CO2CMD_CALIBRATE, cmdString, &cmdLength);
 									localComState = UART_CO2_IDLE;
 			break;
@@ -125,7 +133,8 @@
 void uartCo2_ProcessData(uint8_t data)
 {
 	static uint8_t dataType = 0;
-	static uint32_t dataValue = 0;
+	static uint32_t dataValue[3];
+	static uint8_t dataIndex = 0;
 	uint8_t activeSensor = externalInterface_GetActiveUartSensor();
 	uartCO2Status_t localComState = externalInterface_GetSensorState(activeSensor + EXT_INTERFACE_MUX_OFFSET);
 
@@ -133,6 +142,7 @@
 	{
 		switch(data)
 		{
+			case 'P':
 			case 'G':
 			case 'K':
 			case 'l':
@@ -140,7 +150,8 @@
 			case 'Z':
 			case '.':			dataType = data;
 								rxState = CO2RX_Data0;
-								dataValue = 0;
+								dataValue[0] = 0;
+								dataIndex = 0;
 				break;
 			case '?':			localComState = UART_CO2_ERROR;
 								rxState = CO2RX_Ready;
@@ -151,17 +162,36 @@
 	}
 	else if((data >= '0') && (data <= '9'))
 	{
-		if((rxState >= CO2RX_Data0) && (rxState <= CO2RX_Data4))
+		if((rxState >= CO2RX_Data0) && (rxState <= CO2RX_Data9))
 		{
-			dataValue = dataValue * 10 + (data - '0');
+			dataValue[dataIndex] = dataValue[dataIndex] * 10 + (data - '0');
 
-			if((rxState == CO2RX_Data4))
+			switch (dataType)
 			{
-				rxState = CO2RX_DataComplete;
-			}
-			else
-			{
-				rxState++;
+				case 'G':
+				case 'K':
+				case 'l':
+				case 'D':
+				case 'Z':
+				case '.':
+				default:	if((rxState == CO2RX_Data4))
+							{
+								rxState = CO2RX_DataComplete;	/* just one value to be received */
+							}
+							else
+							{
+								rxState++;
+							}
+					break;
+				case 'P':		if(rxState == CO2RX_Data9)		/* get second parameter */
+								{
+									rxState = CO2RX_DataComplete;
+								}
+								else
+								{
+									rxState++;
+								}
+						break;
 			}
 		}
 		else	/* protocol error data has max 5 digits */
@@ -184,31 +214,63 @@
 											localComState = UART_CO2_MODE;
 										}
 					break;
-				case UART_CO2_MODE:		if((dataType == 'K') && (dataValue == 2))
+				case UART_CO2_MODE:		if((dataType == 'K') && (dataValue[dataIndex] == 2))
 										{
 											localComState = UART_CO2_IDLE;
 										}
 					break;
+				case UART_CO2_CALIBRATE_H:	if((dataType == 'P') && (dataValue[0] == 10) && (dataValue[1] == 1))
+											{
+												localComState = UART_CO2_CALIBRATE_L;
+											}
+											else
+											{
+												localComState = UART_CO2_IDLE;
+											}
+					break;
+				case UART_CO2_CALIBRATE_L:	if((dataType == 'P') && (dataValue[0] == 11) && (dataValue[1] == 144))
+											{
+												localComState = UART_CO2_CALIBRATE;
+											}
+											else
+											{
+												localComState = UART_CO2_IDLE;
+											}
+					break;
 				default: localComState = UART_CO2_IDLE;
 					break;
 			}
 
 			switch(dataType)
 			{
-				case 'D':			externalInterface_SetCO2SignalStrength(dataValue);
+				case 'D':			externalInterface_SetCO2SignalStrength(dataValue[dataIndex]);
 					break;
-				case 'l':			LED_ZeroOffset = dataValue;
+				case 'l':			LED_ZeroOffset = dataValue[dataIndex];
 					break;
-				case 'Z':			externalInterface_SetCO2Value(dataValue);
+				case 'Z':			externalInterface_SetCO2Value(dataValue[dataIndex]);
 					break;
-				case '.':			externalInterface_SetCO2Scale(dataValue);
+				case '.':			externalInterface_SetCO2Scale(dataValue[dataIndex]);
 					break;
 				default:			rxState = CO2RX_Ready;
 					break;
 			}
 			rxState = CO2RX_Ready;
 		}
-		if(rxState != CO2RX_Data0)	/* reset state machine because message in wrong format */
+		else	/* multi parameter */
+		{
+			if(rxState == CO2RX_Data5)
+			{
+				switch(dataType)
+				{
+					case 'P':	dataIndex++;
+								dataValue[dataIndex] = 0;
+						break;
+					default:
+						break;
+				}
+			}
+		}
+		if((rxState != CO2RX_Data0) && (rxState != CO2RX_Data5))	/* reset state machine because message in wrong format */
 		{
 			rxState = CO2RX_Ready;
 		}