changeset 729:d646a0f724a7

Added auto detection functionality for sensors connected to the external interface: O2 sensors may be connected to the analog input as well as to the UART. The GUI visualization provides three slots for ppo2 display. Beside detection of sensor kind the task of the function is to place the available sensor in this three slots. CO2 has its own communication slot outside the ppo2 channel. The result of the automatic detection is communicated via the sensor map.
author Ideenmodellierer
date Sat, 14 Jan 2023 20:46:17 +0100
parents 5143e927219f
children 9c65d226f4f6
files Small_CPU/Inc/externalInterface.h Small_CPU/Inc/uart.h Small_CPU/Src/externalInterface.c Small_CPU/Src/scheduler.c Small_CPU/Src/uart.c
diffstat 5 files changed, 309 insertions(+), 100 deletions(-) [+]
line wrap: on
line diff
--- a/Small_CPU/Inc/externalInterface.h	Sat Jan 14 20:41:36 2023 +0100
+++ b/Small_CPU/Inc/externalInterface.h	Sat Jan 14 20:46:17 2023 +0100
@@ -34,6 +34,22 @@
 
 #define EXT33V_CONTROL_PIN				GPIO_PIN_7	/* PortC */
 
+#define MIN_ADC_VOLTAGE_MV	(5.0f)		/* miminal voltage to rate an ADC channel as active */
+
+
+ typedef enum
+ {
+    DETECTION_OFF = 0,		/* no detection requested */
+	DETECTION_INIT,			/* prepare external interface for operation if not already activated */
+	DETECTION_ANALOG,		/* check ADC channels for connected sensors */
+	DETECTION_DIGO2,		/* check UART channel for connected DigO2 sensor */
+	DETECTION_CO2,			/* check UART channel for connected CO2 sensor */
+	DETECTION_DONE
+ } externalInterfaceAutoDetect_t;
+
+
+
+
 void externalInterface_Init(void);
 void externalInterface_InitPower33(void);
 uint8_t externalInterface_StartConversion(uint8_t channel);
@@ -56,7 +72,9 @@
 uint16_t externalInterface_GetCO2State(void);
 uint8_t externalInterface_GetSensorData(uint8_t* pDataStruct);
 void externalInterface_SetSensorData(uint8_t dataId, uint8_t* pDataStruct);
-
+void externalInface_SetSensorMap(uint8_t* pMap);
+uint8_t* externalInterface_GetSensorMapPointer(void);
+void externalInterface_AutodetectSensor(void);
 void externalInterface_ExecuteCmd(uint16_t Cmd);
 
 #endif /* EXTERNAL_INTERFACE_H */
--- a/Small_CPU/Inc/uart.h	Sat Jan 14 20:41:36 2023 +0100
+++ b/Small_CPU/Inc/uart.h	Sat Jan 14 20:46:17 2023 +0100
@@ -61,7 +61,7 @@
 
  typedef enum
   {
-	O2RX_IDLE = 0,			/* no receiption pending */
+	O2RX_IDLE = 0,			/* no reception pending */
 	O2RX_CONFIRM,			/* check the command echo */
 	O2RX_GETNR,				/* extract the sensor number */
 	O2RX_GETO2,				/* extract the ppo2 */
@@ -78,17 +78,25 @@
 	O2RX_HUMIDITY			/* extract humidity within the sensor housing */
   } uartO2RxState_t;
 
+
+
 void MX_USART1_UART_Init(void);
 void MX_USART1_UART_DeInit(void);
 void MX_USART1_DMA_Init(void);
 uint8_t UART_ButtonAdjust(uint8_t *array);
 #ifdef ENABLE_CO2_SUPPORT
-void HandleUARTCO2Data(void);
+void UART_HandleCO2Data(void);
 #endif
 #ifdef ENABLE_SENTINEL_MODE
-void HandleUARTSentinelData(void);
+void UART_HandleSentinelData(void);
 #endif
-void HandleUARTDigitalO2(void);
+void UART_HandleDigitalO2(void);
+
+uint8_t UART_isDigO2Connected();
+uint8_t UART_isCO2Connected();
+void UART_setTargetChannel(uint8_t channel);
+
+
 
 #ifdef __cplusplus
 }
--- a/Small_CPU/Src/externalInterface.c	Sat Jan 14 20:41:36 2023 +0100
+++ b/Small_CPU/Src/externalInterface.c	Sat Jan 14 20:46:17 2023 +0100
@@ -65,6 +65,10 @@
 
 static uint8_t sensorDataId = 0;
 static SSensorDataDiveO2 sensorDataDiveO2;
+static externalInterfaceAutoDetect_t externalAutoDetect = DETECTION_OFF;
+static externalInterfaceSensorType SensorMap[EXT_INTERFACE_SENSOR_CNT] ={ SENSOR_ANALOG, SENSOR_ANALOG, SENSOR_ANALOG, SENSOR_NONE, SENSOR_NONE};
+static externalInterfaceSensorType tmpSensorMap[EXT_INTERFACE_SENSOR_CNT];
+static externalInterfaceSensorType MasterSensorMap[EXT_INTERFACE_SENSOR_CNT];
 
 
 void externalInterface_Init(void)
@@ -84,6 +88,7 @@
 	externalCO2Value = 0;
 	externalCO2SignalStrength = 0;
 	externalCO2Status = 0;
+	externalAutoDetect = DETECTION_OFF;
 }
 
 
@@ -105,26 +110,35 @@
 uint8_t externalInterface_ReadAndSwitch()
 {
 	uint8_t retval = EXTERNAL_ADC_NO_DATA;
+	uint8_t nextChannel;
+	uint8_t* psensorMap = externalInterface_GetSensorMapPointer();
 
-	if(externalInterfacePresent)
+	if(externalADC_On)
 	{
 		if(I2C_Master_Receive(DEVICE_EXTERNAL_ADC, recBuf, ADC_ANSWER_LENGTH) == HAL_OK)
 		{
 			if((recBuf[ANSWER_CONFBYTE_INDEX] & ADC_START_CONVERSION) == 0)		/* !ready set => received data contains new value */
 			{
 				retval = activeChannel;										/* return channel number providing new data */
-				activeChannel++;
-				if(activeChannel == MAX_ADC_CHANNEL)
+				nextChannel = activeChannel + 1;
+				if(nextChannel == MAX_ADC_CHANNEL)
 				{
-					if(externalUART_Protocol == (EXT_INTERFACE_UART_O2 >> 8))		/* mixed mode digital and analog o2 sensors => channel 0 is reserved for digital sensor */
+					nextChannel = 0;
+				}
+
+				while((psensorMap[nextChannel] != SENSOR_ANALOG) && (nextChannel != activeChannel))
+				{
+					if(nextChannel == MAX_ADC_CHANNEL)
 					{
-						activeChannel = 1;
+						nextChannel = 0;
 					}
 					else
 					{
-						activeChannel = 0;
+						nextChannel++;
 					}
 				}
+
+				activeChannel = nextChannel;
 				externalInterface_StartConversion(activeChannel);
 				timeoutCnt = 0;
 			}
@@ -258,30 +272,47 @@
 	uint8_t loop = 0;
 	if((state) && (externalInterfacePresent))
 	{
-		externalInterface_StartConversion(activeChannel);
-		externalADC_On = 1;
+		if(externalADC_On == 0)
+		{
+			activeChannel = 0;
+			externalInterface_StartConversion(activeChannel);
+			externalADC_On = 1;
+		}
 	}
 	else
 	{
-		externalADC_On = 0;
-		for(loop = 0; loop < MAX_ADC_CHANNEL; loop++)
+		if(externalAutoDetect == DETECTION_OFF)			/* block deactivation requests if auto detection is active */
 		{
-			externalChannel_mV[loop] = 0;
+			externalADC_On = 0;
+			for(loop = 0; loop < MAX_ADC_CHANNEL; loop++)
+			{
+				externalChannel_mV[loop] = 0;
+			}
 		}
 	}
 }
 
 void externalInterface_SwitchUART(uint8_t protocol)
 {
-	if(protocol < 0x08)
+	switch(protocol)
 	{
-		sensorDataId = 0;
-		externalUART_Protocol = protocol;
-		MX_USART1_UART_DeInit();
-		if( protocol != 0)
-		{
-			MX_USART1_UART_Init();
-		}
+		case 0:
+		case (EXT_INTERFACE_UART_CO2 >> 8):
+		case (EXT_INTERFACE_UART_O2 >> 8):
+				if((externalAutoDetect == DETECTION_OFF) || ((protocol == EXT_INTERFACE_UART_CO2 >> 8) && (externalAutoDetect == DETECTION_CO2))
+														 || ((protocol == EXT_INTERFACE_UART_O2 >> 8) && (externalAutoDetect == DETECTION_DIGO2)))
+				{
+					sensorDataId = 0;
+					externalUART_Protocol = protocol;
+					MX_USART1_UART_DeInit();
+					if( protocol != 0)
+					{
+						MX_USART1_UART_Init();
+					}
+				}
+			break;
+		default:
+			break;
 	}
 }
 
@@ -343,15 +374,146 @@
 	}
 }
 
+void externalInface_SetSensorMap(uint8_t* pMap)
+{
+	if(pMap != NULL)
+	{
+		memcpy(MasterSensorMap, pMap, 5);		/* the map is not directly copied. Copy is done via cmd request */
+	}
+
+}
+uint8_t* externalInterface_GetSensorMapPointer()
+{
+	uint8_t* pret;
+
+	if(externalAutoDetect != DETECTION_OFF)
+	{
+		pret = tmpSensorMap;
+	}
+	else
+	{
+		pret = SensorMap;
+	}
+	return pret;
+}
+
+void externalInterface_AutodetectSensor()
+{
+	static uint8_t	sensorIndex = 0;
+	uint8_t index = 0;
+
+	if(externalAutoDetect != DETECTION_OFF)
+	{
+		switch(externalAutoDetect)
+		{
+			case DETECTION_INIT:	sensorIndex = 0;
+									tmpSensorMap[0] = SENSOR_ANALOG;
+									tmpSensorMap[1] = SENSOR_ANALOG;
+									tmpSensorMap[2] = SENSOR_ANALOG;
+									tmpSensorMap[3] = SENSOR_NONE;
+									tmpSensorMap[4] = SENSOR_NONE;
+
+									externalInterface_SwitchADC(1);
+									externalAutoDetect = DETECTION_ANALOG;
+				break;
+			case DETECTION_ANALOG:	for(index = 0; index < MAX_ADC_CHANNEL; index++)
+									{
+										if(externalChannel_mV[index] > MIN_ADC_VOLTAGE_MV)
+										{
+											tmpSensorMap[sensorIndex++] = SENSOR_ANALOG;
+										}
+										else
+										{
+											tmpSensorMap[sensorIndex++] = SENSOR_NONE;
+										}
+									}
+									externalAutoDetect = DETECTION_DIGO2;
+									externalInterface_SwitchUART(EXT_INTERFACE_UART_O2 >> 8);
+				break;
+			case DETECTION_DIGO2:	if(UART_isDigO2Connected())
+									{
+										for(index = 0; index < 3; index++)	/* lookup a channel which may be used by digO2 */
+										{
+											if(tmpSensorMap[index] == SENSOR_NONE)
+											{
+												break;
+											}
+										}
+										if(index == 3)
+										{
+											tmpSensorMap[2] = SENSOR_DIGO2;  /* digital sensor overwrites ADC */
+										}
+										else
+										{
+											tmpSensorMap[index] = SENSOR_DIGO2;
+										}
+
+										UART_setTargetChannel(index);
+										/* tmpSensorMap[sensorIndex++] = SENSOR_DIGO2; */
+									}
+									externalAutoDetect = DETECTION_CO2;
+									externalInterface_SwitchUART(EXT_INTERFACE_UART_CO2 >> 8);
+				break;
+			case DETECTION_CO2:		if(UART_isCO2Connected())
+									{
+										for(index = 0; index < 3; index++)	/* lookup a channel which may be used by CO2*/
+										{
+											if(tmpSensorMap[index] == SENSOR_NONE)
+											{
+												break;
+											}
+										}
+										if(index == 3)
+										{
+											tmpSensorMap[sensorIndex++] = SENSOR_CO2;  /* place Co2 sensor behind O2 sensors (not visible) */
+										}
+										else
+										{
+											tmpSensorMap[index] = SENSOR_CO2;
+										}
+
+									}
+									externalAutoDetect = DETECTION_DONE;
+				break;
+			case DETECTION_DONE:	while(sensorIndex < 5)
+									{
+										tmpSensorMap[sensorIndex++] = SENSOR_NONE;
+									}
+									memcpy(SensorMap, tmpSensorMap, sizeof(tmpSensorMap));
+									externalAutoDetect = DETECTION_OFF;
+				break;
+			default:
+				break;
+		}
+	}
+}
+
+
 void externalInterface_ExecuteCmd(uint16_t Cmd)
 {
 	char cmdString[10];
 	uint8_t cmdLength = 0;
+	uint8_t index;
 
 	switch(Cmd & 0x00FF)		/* lower byte is reserved for commands */
 	{
+		case EXT_INTERFACE_AUTODETECT:	externalAutoDetect = DETECTION_INIT;
+			break;
 		case EXT_INTERFACE_CO2_CALIB:	cmdLength = snprintf(cmdString, 10, "G\r\n");
 			break;
+		case EXT_INTERFACE_COPY_SENSORMAP:	if(externalAutoDetect == DETECTION_OFF)
+											{
+												memcpy(SensorMap, MasterSensorMap, 5);
+												for(index = 0; index < 3; index++)
+												{
+													if(SensorMap[index] == SENSOR_DIGO2)
+													{
+														break;
+													}
+												}
+												UART_setTargetChannel(index); /* if no slot for digO2 is found then the function will be called with an invalid parameter causing the overwrite function to fail */
+											}
+			break;
 		default:
 			break;
 	}
--- a/Small_CPU/Src/scheduler.c	Sat Jan 14 20:41:36 2023 +0100
+++ b/Small_CPU/Src/scheduler.c	Sat Jan 14 20:46:17 2023 +0100
@@ -315,7 +315,7 @@
 
 	if(((global.dataSendToSlave.data.externalInterface_Cmd & EXT_INTERFACE_ADC_ON) != 0) != externalInterface_isEnabledADC())
 	{
-		externalInterface_SwitchADC(global.dataSendToSlave.data.externalInterface_Cmd && EXT_INTERFACE_ADC_ON);
+		externalInterface_SwitchADC(1-externalInterface_isEnabledADC());
 	}
 
 	if(((global.dataSendToSlave.data.externalInterface_Cmd >> 8) & 0x0F) != externalInterface_GetUARTProtocol())
@@ -323,6 +323,7 @@
 		externalInterface_SwitchUART((global.dataSendToSlave.data.externalInterface_Cmd >> 8) & 0x0F);
 	}
 
+	externalInface_SetSensorMap(global.dataSendToSlave.data.externalInterface_SensorMap);
 	if(global.dataSendToSlave.data.externalInterface_Cmd & 0x00FF)	/* lowest nibble for commands */
 	{
 		externalInterface_ExecuteCmd(global.dataSendToSlave.data.externalInterface_Cmd);
@@ -518,18 +519,18 @@
 #ifdef ENABLE_CO2_SUPPORT
 		if(global.dataSendToSlave.data.externalInterface_Cmd & EXT_INTERFACE_UART_CO2)
 		{
-			HandleUARTCO2Data();
+			UART_HandleCO2Data();
 		}
 #endif
 #ifdef ENABLE_SENTINEL_MODE
 		if(global.dataSendToSlave.data.externalInterface_Cmd & EXT_INTERFACE_UART_SENTINEL)
 		{
-			HandleUARTSentinelData();
+			UART_HandleSentinelData();
 		}
 #endif
 		if(global.dataSendToSlave.data.externalInterface_Cmd & EXT_INTERFACE_UART_O2)
 		{
-			HandleUARTDigitalO2();
+			UART_HandleDigitalO2();
 		}
 
 		if(ticksdiff >= Scheduler.counterSPIdata100msec * 100 + 10)
@@ -838,21 +839,21 @@
 		}
 
 #ifdef ENABLE_CO2_SUPPORT
-		if(global.dataSendToSlave.data.externalInterface_Cmd & EXT_INTERFACE_UART_CO2)
+		if(externalInterface_GetUARTProtocol() & (EXT_INTERFACE_UART_CO2 >> 8))
 		{
-			HandleUARTCO2Data();
+			UART_HandleCO2Data();
 		}
 #endif
 #ifdef ENABLE_SENTINEL_MODE
 		if(global.dataSendToSlave.data.externalInterface_Cmd & EXT_INTERFACE_UART_SENTINEL)
 		{
-			HandleUARTSentinelData();
+			UART_HandleSentinelData();
 		}
 #endif
 
-		if(global.dataSendToSlave.data.externalInterface_Cmd & EXT_INTERFACE_UART_O2)
+		if(externalInterface_GetUARTProtocol() & (EXT_INTERFACE_UART_O2 >> 8))
 		{
-			HandleUARTDigitalO2();
+			UART_HandleDigitalO2();
 		}
 
 		/* Evaluate received data at 10 ms, 110 ms, 210 ms,... duration ~<1ms */
@@ -1001,6 +1002,7 @@
 					}
 				}
 			}
+			externalInterface_AutodetectSensor();
 		}
 
 		if(ticksdiff >= 1000)
@@ -1734,6 +1736,7 @@
 		global.dataSendToMaster.data[boolADCBuffer && DATA_BUFFER_ADC].extADC_voltage[channel] = value;
 	}
 	global.dataSendToMaster.data[boolADCBuffer && DATA_BUFFER_ADC].externalInterface_SensorID = externalInterface_GetSensorData((uint8_t*)&global.dataSendToMaster.data[boolADCBuffer && DATA_BUFFER_ADC].sensor_data);
+	memcpy(global.dataSendToMaster.data[boolADCBuffer && DATA_BUFFER_ADC].sensor_map,externalInterface_GetSensorMapPointer(),EXT_INTERFACE_SENSOR_CNT);
 	global.dataSendToMaster.boolADCO2Data |= boolADCBuffer;
 }
 
--- a/Small_CPU/Src/uart.c	Sat Jan 14 20:41:36 2023 +0100
+++ b/Small_CPU/Src/uart.c	Sat Jan 14 20:46:17 2023 +0100
@@ -33,10 +33,13 @@
 DMA_HandleTypeDef  hdma_usart1_rx;
 
 uint8_t rxBuffer[CHUNK_SIZE * CHUNKS_PER_BUFFER];		/* The complete buffer has a X * chunk size to allow fariations in buffer read time */
-static uint8_t rxWriteIndex;					/* Index of the data item which is analysed */
-static uint8_t rxReadIndex;						/* Index at which new data is stared */
-static uint8_t lastCmdIndex;					/* Index of last command which has not been completly received */
-static uint8_t dmaActive;						/* Indicator if DMA receiption needs to be started */
+static uint8_t rxWriteIndex;							/* Index of the data item which is analysed */
+static uint8_t rxReadIndex;								/* Index at which new data is stared */
+static uint8_t lastCmdIndex;							/* Index of last command which has not been completly received */
+static uint8_t dmaActive;								/* Indicator if DMA reception needs to be started */
+static uint8_t digO2Connected = 0;						/* Binary indicator if a sensor is connected or not */
+static uint8_t CO2Connected = 0;						/* Binary indicator if a sensor is connected or not */
+static uint8_t ppO2TargetChannel = 0;					/* The OSTC4 supports three slots for visualization of the ppo2. This one is reserved for the digital sensor */
 
 static SSensorDataDiveO2 sensorDataDiveO2;		/* intermediate storage for additional sensor data */
 
@@ -80,6 +83,8 @@
   lastCmdIndex = 0;
   rxWriteIndex = 0;
   dmaActive = 0;
+  digO2Connected = 0;
+  CO2Connected = 0;
   Comstatus_O2 = UART_O2_INIT;
 }
 
@@ -115,6 +120,56 @@
   HAL_NVIC_EnableIRQ(DMA2_Stream5_IRQn);
 }
 
+
+void DigitalO2_SetupCmd(uint8_t O2State, uint8_t *cmdString, uint8_t *cmdLength)
+{
+	switch (O2State)
+	{
+		case UART_O2_CHECK:		*cmdLength = snprintf((char*)cmdString, 10, "#LOGO");
+			break;
+		case UART_O2_REQ_INFO: 	*cmdLength = snprintf((char*)cmdString, 10, "#VERS");
+					break;
+		case UART_O2_REQ_ID: 	*cmdLength = snprintf((char*)cmdString, 10, "#IDNR");
+			break;
+		case UART_O2_REQ_O2: 	*cmdLength = snprintf((char*)cmdString, 10, "#DOXY");
+			break;
+		case UART_O2_REQ_RAW:	*cmdLength = snprintf((char*)cmdString, 10, "#DRAW");
+			break;
+		default: *cmdLength = 0;
+			break;
+	}
+	if(*cmdLength != 0)
+	{
+		cmdString[*cmdLength] = 0x0D;
+		*cmdLength = *cmdLength + 1;
+	}
+}
+
+void StringToInt(char *pstr, uint32_t *puInt32)
+{
+	uint8_t index = 0;
+	uint32_t result = 0;
+	while((pstr[index] >= '0') && (pstr[index] <= '9'))
+	{
+		result *=10;
+		result += pstr[index] - '0';
+		index++;
+	}
+	*puInt32 = result;
+}
+
+void StringToUInt64(char *pstr, uint64_t *puint64)
+{
+	uint8_t index = 0;
+	uint64_t result = 0;
+	while((pstr[index] >= '0') && (pstr[index] <= '9'))
+	{
+		result *=10;
+		result += pstr[index] - '0';
+		index++;
+	}
+	*puint64 = result;
+}
 void ConvertByteToHexString(uint8_t byte, char* str)
 {
 	uint8_t worker = 0;
@@ -140,7 +195,7 @@
 
 
 #ifdef ENABLE_CO2_SUPPORT
-void HandleUARTCO2Data(void)
+void UART_HandleCO2Data(void)
 {
 	uint8_t localRX = rxReadIndex;
 	uint8_t dataType = 0;
@@ -177,6 +232,7 @@
 				if(rxState == RX_Data5)
 				{
 					rxState = RX_DataComplete;
+					CO2Connected = 1;
 				}
 			}
 			else	/* protocol error data has max 5 digits */
@@ -221,6 +277,7 @@
 	if(time_elapsed_ms(lastReceiveTick,HAL_GetTick()) > 2000)	/* check for communication timeout */
 	{
 		externalInterface_SetCO2State(0);
+		CO2Connected = 0;
 	}
 
 	if((dmaActive == 0)	&& (externalInterface_isEnabledPower33()))	/* Should never happen in normal operation => restart in case of communication error */
@@ -234,7 +291,7 @@
 #endif
 
 #ifdef ENABLE_SENTINEL_MODE
-void HandleUARTSentinelData(void)
+void UART_HandleSentinelData(void)
 {
 	uint8_t localRX = rxReadIndex;
 	static uint8_t dataType = 0;
@@ -386,57 +443,9 @@
 }
 #endif
 
-void DigitalO2_SetupCmd(uint8_t O2State, uint8_t *cmdString, uint8_t *cmdLength)
-{
-	switch (O2State)
-	{
-		case UART_O2_CHECK:		*cmdLength = snprintf((char*)cmdString, 10, "#LOGO");
-			break;
-		case UART_O2_REQ_INFO: 	*cmdLength = snprintf((char*)cmdString, 10, "#VERS");
-					break;
-		case UART_O2_REQ_ID: 	*cmdLength = snprintf((char*)cmdString, 10, "#IDNR");
-			break;
-		case UART_O2_REQ_O2: 	*cmdLength = snprintf((char*)cmdString, 10, "#DOXY");
-			break;
-		case UART_O2_REQ_RAW:	*cmdLength = snprintf((char*)cmdString, 10, "#DRAW");
-			break;
-		default: *cmdLength = 0;
-			break;
-	}
-	if(*cmdLength != 0)
-	{
-		cmdString[*cmdLength] = 0x0D;
-		*cmdLength = *cmdLength + 1;
-	}
-}
+
 
-void StringToInt(char *pstr, uint32_t *puInt32)
-{
-	uint8_t index = 0;
-	uint32_t result = 0;
-	while((pstr[index] >= '0') && (pstr[index] <= '9'))
-	{
-		result *=10;
-		result += pstr[index] - '0';
-		index++;
-	}
-	*puInt32 = result;
-}
-
-void StringToUInt64(char *pstr, uint64_t *puint64)
-{
-	uint8_t index = 0;
-	uint64_t result = 0;
-	while((pstr[index] >= '0') && (pstr[index] <= '9'))
-	{
-		result *=10;
-		result += pstr[index] - '0';
-		index++;
-	}
-	*puint64 = result;
-}
-
-void HandleUARTDigitalO2(void)
+void UART_HandleDigitalO2(void)
 {
 	static uint32_t lastO2ReqTick = 0;
 
@@ -505,6 +514,7 @@
 								cmdReadIndex++;
 								if(cmdReadIndex == cmdLength - 1)
 								{
+									digO2Connected = 1;
 									tmpRxIdx = 0;
 									memset((char*) tmpRxBuf, 0, sizeof(tmpRxBuf));
 									switch (Comstatus_O2)
@@ -565,7 +575,7 @@
 														break;
 
 												case O2RX_GETO2: 		StringToInt(tmpRxBuf,&tmpO2);
-																		setExternalInterfaceChannel(0,(float)(tmpO2 / 10000.0));
+																		setExternalInterfaceChannel(ppO2TargetChannel,(float)(tmpO2 / 10000.0));
 																		rxState = O2RX_GETTEMP;
 													break;
 												case O2RX_GETTEMP:		StringToInt(tmpRxBuf,(uint32_t*)&sensorDataDiveO2.temperature);
@@ -624,7 +634,7 @@
 				break;
 
 		}
-
+		rxBuffer[localRX] = 0;
 		localRX++;
 		rxReadIndex++;
 		if(rxReadIndex >= CHUNK_SIZE * CHUNKS_PER_BUFFER)
@@ -634,13 +644,12 @@
 		}
 	}
 
-	if(time_elapsed_ms(lastReceiveTick,HAL_GetTick()) > 4000)	/* check for communication timeout */
+	if((digO2Connected) && time_elapsed_ms(lastReceiveTick,HAL_GetTick()) > 4000)	/* check for communication timeout */
 	{
+		digO2Connected = 0;
 		if(curAlive == lastAlive)
 		{
-			setExternalInterfaceChannel(0,0.0);
-			setExternalInterfaceChannel(1,0.0);
-			setExternalInterfaceChannel(2,0.0);
+			setExternalInterfaceChannel(ppO2TargetChannel,0.0);
 		}
 		lastAlive = curAlive;
 	}
@@ -654,6 +663,20 @@
 	}
 }
 
+uint8_t UART_isDigO2Connected()
+{
+	return digO2Connected;
+}
+uint8_t UART_isCO2Connected()
+{
+	return CO2Connected;
+}
+
+
+void UART_setTargetChannel(uint8_t channel)
+{
+		ppO2TargetChannel = channel;
+}
 
 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
 {
@@ -681,9 +704,4 @@
 
 
 
-
-
-
-
-
 /************************ (C) COPYRIGHT heinrichs weikamp *****END OF FILE****/