changeset 779:0b5f45448eb6

Added UART multiplexer support for DiveO2: The existing autodetect function now includes a UART multiplexer. The datastructures and protocol handling has been adapted to support several DiveO2 sensors connected to the UART.
author Ideenmodellierer
date Tue, 23 May 2023 21:45:34 +0200
parents 74253a41cf80
children e40790a67165
files Small_CPU/Inc/externalInterface.h Small_CPU/Inc/uart.h Small_CPU/Src/externalInterface.c Small_CPU/Src/uart.c
diffstat 4 files changed, 343 insertions(+), 203 deletions(-) [+]
line wrap: on
line diff
--- a/Small_CPU/Inc/externalInterface.h	Mon May 22 09:15:09 2023 +0200
+++ b/Small_CPU/Inc/externalInterface.h	Tue May 23 21:45:34 2023 +0200
@@ -46,7 +46,10 @@
 	DETECTION_START,
 	DETECTION_ANALOG1,		/* check ADC channels for connected sensors */
 	DETECTION_ANALOG2,
-	DETECTION_DIGO2,		/* check UART channel for connected DigO2 sensor */
+	DETECTION_UARTMUX,		/* check if a uart multiplexer is present */
+	DETECTION_DIGO2_0,		/* check UART channel for connected DigO2 sensor */
+	DETECTION_DIGO2_1,
+	DETECTION_DIGO2_2,
 #ifdef ENABLE_CO2_SUPPORT
 	DETECTION_CO2,			/* check UART channel for connected CO2 sensor */
 #endif
@@ -81,7 +84,7 @@
 uint16_t externalInterface_GetCO2SignalStrength(void);
 void externalInterface_SetCO2State(uint16_t state);
 uint16_t externalInterface_GetCO2State(void);
-uint8_t externalInterface_GetSensorData(uint8_t* pDataStruct);
+uint8_t externalInterface_GetSensorData(uint8_t sensorId, uint8_t* pDataStruct);
 void externalInterface_SetSensorData(uint8_t dataId, uint8_t* pDataStruct);
 void externalInface_SetSensorMap(uint8_t* pMap);
 uint8_t* externalInterface_GetSensorMapPointer(uint8_t finalMap);
--- a/Small_CPU/Inc/uart.h	Mon May 22 09:15:09 2023 +0200
+++ b/Small_CPU/Inc/uart.h	Tue May 23 21:45:34 2023 +0200
@@ -92,6 +92,8 @@
 void UART_HandleSentinelData(void);
 #endif
 void UART_HandleDigitalO2(void);
+void UART_MapDigO2_Channel(uint8_t channel, uint8_t muxAddress);
+void UART_SetDigO2_Channel(uint8_t channel);
 uint8_t UART_isDigO2Connected();
 uint8_t UART_isCO2Connected();
 uint8_t UART_isSentinelConnected();
--- a/Small_CPU/Src/externalInterface.c	Mon May 22 09:15:09 2023 +0200
+++ b/Small_CPU/Src/externalInterface.c	Tue May 23 21:45:34 2023 +0200
@@ -67,8 +67,8 @@
 static uint16_t externalCO2SignalStrength;
 static uint16_t  externalCO2Status = 0;
 
-static uint8_t sensorDataId = 0;
-static SSensorDataDiveO2 sensorDataDiveO2;
+static uint8_t lastSensorDataId = 0;
+static SSensorDataDiveO2 sensorDataDiveO2[MAX_ADC_CHANNEL];
 static externalInterfaceAutoDetect_t externalAutoDetect = DETECTION_OFF;
 static externalInterfaceSensorType SensorMap[EXT_INTERFACE_SENSOR_CNT] ={ SENSOR_OPTIC, SENSOR_OPTIC, SENSOR_OPTIC, SENSOR_NONE, SENSOR_NONE};
 static externalInterfaceSensorType tmpSensorMap[EXT_INTERFACE_SENSOR_CNT];
@@ -331,7 +331,11 @@
 		case (EXT_INTERFACE_UART_CO2 >> 8):
 		case (EXT_INTERFACE_UART_O2 >> 8):
 		case (EXT_INTERFACE_UART_SENTINEL >> 8):
-				if((externalAutoDetect <= DETECTION_START) || ((protocol == EXT_INTERFACE_UART_O2 >> 8) && (externalAutoDetect == DETECTION_DIGO2))
+				if((externalAutoDetect <= DETECTION_START)
+															|| ((protocol == EXT_INTERFACE_UART_O2 >> 8) && (externalAutoDetect == DETECTION_DIGO2_0))
+															|| ((protocol == EXT_INTERFACE_UART_O2 >> 8) && (externalAutoDetect == DETECTION_DIGO2_1))
+															|| ((protocol == EXT_INTERFACE_UART_O2 >> 8) && (externalAutoDetect == DETECTION_DIGO2_2))
+															|| ((protocol == EXT_INTERFACE_UART_O2 >> 8) && (externalAutoDetect == DETECTION_UARTMUX))
 #ifdef ENABLE_CO2_SUPPORT
 															|| ((protocol == EXT_INTERFACE_UART_CO2 >> 8) && (externalAutoDetect == DETECTION_CO2))
 #endif
@@ -340,7 +344,7 @@
 #endif
 					)
 				{
-					sensorDataId = 0;
+					lastSensorDataId = 0;
 					externalUART_Protocol = protocol;
 					MX_USART1_UART_DeInit();
 					if( protocol != 0)
@@ -404,29 +408,34 @@
 }
 
 
-uint8_t externalInterface_GetSensorData(uint8_t* pDataStruct)
+uint8_t externalInterface_GetSensorData(uint8_t sensorId, uint8_t* pDataStruct)
 {
+	uint8_t localId = sensorId;
+	if(localId == 0)
+	{
+		localId = lastSensorDataId;
+	}
 
-	if((pDataStruct != NULL) && sensorDataId != 0)
+	if((pDataStruct != NULL) && (localId > 0) && (localId <= MAX_ADC_CHANNEL))
 	{
-		memcpy(pDataStruct, &sensorDataDiveO2, sizeof(sensorDataDiveO2));
+		memcpy(pDataStruct, &sensorDataDiveO2[localId-1], sizeof(SSensorDataDiveO2));
 	}
-	return sensorDataId;
+	return localId;
 }
 
 void externalInterface_SetSensorData(uint8_t dataId, uint8_t* pDataStruct)
 {
 	if(pDataStruct != NULL)
 	{
-		if(dataId != 0)
+		if((dataId != 0) && (dataId <= MAX_ADC_CHANNEL))
 		{
-			memcpy(&sensorDataDiveO2, pDataStruct, sizeof(sensorDataDiveO2));
+			memcpy(&sensorDataDiveO2[dataId-1], pDataStruct, sizeof(SSensorDataDiveO2));
 		}
 		else
 		{
 			memset(&sensorDataDiveO2,0,sizeof(sensorDataDiveO2));
 		}
-		sensorDataId = dataId;
+		lastSensorDataId = dataId;
 	}
 }
 
@@ -455,7 +464,9 @@
 
 void externalInterface_AutodetectSensor()
 {
-	static uint8_t	sensorIndex = 0;
+	static uint8_t tmpMuxMapping[MAX_ADC_CHANNEL];
+	static uint8_t sensorIndex = 0;
+	static uint8_t uartMuxChannel = 0;
 	uint8_t index = 0;
 
 	if(externalAutoDetect != DETECTION_OFF)
@@ -463,12 +474,18 @@
 		switch(externalAutoDetect)
 		{
 			case DETECTION_INIT:	sensorIndex = 0;
+									uartMuxChannel = 0;
 									tmpSensorMap[0] = SENSOR_OPTIC;
 									tmpSensorMap[1] = SENSOR_OPTIC;
 									tmpSensorMap[2] = SENSOR_OPTIC;
 									tmpSensorMap[3] = SENSOR_NONE;
 									tmpSensorMap[4] = SENSOR_NONE;
 
+									for(index = 0; index < MAX_ADC_CHANNEL; index++)
+									{
+										UART_MapDigO2_Channel(index,index);		/* request all addresses */
+										tmpMuxMapping[index] = 0xff;
+									}
 									if(externalInterfacePresent)
 									{
 										externalInterface_SwitchPower33(0);
@@ -504,10 +521,22 @@
 											tmpSensorMap[sensorIndex++] = SENSOR_NONE;
 										}
 									}
-									externalAutoDetect = DETECTION_DIGO2;
+									externalAutoDetect = DETECTION_UARTMUX;
 									externalInterface_SwitchUART(EXT_INTERFACE_UART_O2 >> 8);
+									UART_SetDigO2_Channel(3);
 				break;
-			case DETECTION_DIGO2:	if(UART_isDigO2Connected())
+			case DETECTION_UARTMUX:  	if(UART_isDigO2Connected())
+										{
+											uartMuxChannel = 1;
+										}
+										externalAutoDetect = DETECTION_DIGO2_0;
+										externalInterface_SwitchUART(EXT_INTERFACE_UART_O2 >> 8);
+										UART_SetDigO2_Channel(0);
+										
+				break;
+			case DETECTION_DIGO2_0:
+			case DETECTION_DIGO2_1: 
+			case DETECTION_DIGO2_2: if(UART_isDigO2Connected())
 									{
 										for(index = 0; index < 3; index++)	/* lookup a channel which may be used by digO2 */
 										{
@@ -523,14 +552,28 @@
 										else
 										{
 											tmpSensorMap[index] = SENSOR_DIGO2;
+											tmpMuxMapping[index] = externalAutoDetect - DETECTION_DIGO2_0;
 										}
+										UART_setTargetChannel(index);
 
-										UART_setTargetChannel(index);
 										/* tmpSensorMap[sensorIndex++] = SENSOR_DIGO2; */
 									}
+									if(uartMuxChannel)
+									{
+										externalInterface_SwitchUART(EXT_INTERFACE_UART_O2 >> 8);
+										UART_SetDigO2_Channel(uartMuxChannel);
+										uartMuxChannel++;
+									}
+									else
+									{
+										externalAutoDetect = DETECTION_DIGO2_2; /* skip detection of other serial sensors */
+									}
 									externalAutoDetect++;
 #ifdef ENABLE_CO2_SUPPORT
-									externalInterface_SwitchUART(EXT_INTERFACE_UART_CO2 >> 8);
+									if(externalAutoDetect == DETECTION_CO2)
+									{
+										externalInterface_SwitchUART(EXT_INTERFACE_UART_CO2 >> 8);
+									}
 				break;
 			case DETECTION_CO2:		if(UART_isCO2Connected())
 									{
@@ -554,8 +597,11 @@
 									externalAutoDetect++;
 #endif
 #ifdef ENABLE_SENTINEL_MODE
-									externalInterface_SwitchUART(EXT_INTERFACE_UART_SENTINEL >> 8);
-									UART_StartDMA_Receiption();
+									if(externalAutoDetect == DETECTION_SENTINEL)
+									{
+										externalInterface_SwitchUART(EXT_INTERFACE_UART_SENTINEL >> 8);
+										UART_StartDMA_Receiption();
+									}
 				break;
 
 			case DETECTION_SENTINEL:
@@ -571,29 +617,19 @@
 									externalAutoDetect++;
 #endif
 				break;
-			case DETECTION_DONE:	for(index = 0; index < EXT_INTERFACE_SENSOR_CNT; index++)
+			case DETECTION_DONE:	if(uartMuxChannel)
 									{
-										if(tmpSensorMap[index] != SENSOR_NONE)
-										{
-											break;
-										}
+										tmpSensorMap[EXT_INTERFACE_SENSOR_CNT-1] = SENSOR_MUX;
 									}
-
-									if(index != EXT_INTERFACE_SENSOR_CNT)		/* return default sensor map if no sensor at all has been detected */
+									for(index = 0; index < MAX_ADC_CHANNEL; index++)
 									{
-										while(sensorIndex < EXT_INTERFACE_SENSOR_CNT)
-										{
-											tmpSensorMap[sensorIndex++] = SENSOR_NONE;
-										}
+										UART_MapDigO2_Channel(index,tmpMuxMapping[index]);
 									}
-									else
-									{
-										tmpSensorMap[0] = SENSOR_OPTIC;
-										tmpSensorMap[1] = SENSOR_OPTIC;
-										tmpSensorMap[2] = SENSOR_OPTIC;
-									}
+									externalAutoDetect = DETECTION_OFF;
+									externalInterface_SwitchUART(0);
+									UART_SetDigO2_Channel(0);
 									memcpy(SensorMap, tmpSensorMap, sizeof(tmpSensorMap));
-									externalAutoDetect = DETECTION_OFF;
+
 				break;
 			default:
 				break;
--- a/Small_CPU/Src/uart.c	Mon May 22 09:15:09 2023 +0200
+++ b/Small_CPU/Src/uart.c	Tue May 23 21:45:34 2023 +0200
@@ -28,6 +28,7 @@
 
 #define CHUNK_SIZE			(25u)		/* the DMA will handle chunk size transfers */
 #define CHUNKS_PER_BUFFER	(5u)
+#define COMMAND_TX_DELAY	(30u)		/* The time the sensor needs to recover from a invalid command request */
 UART_HandleTypeDef huart1;
 
 DMA_HandleTypeDef  hdma_usart1_rx;
@@ -42,12 +43,14 @@
 static uint8_t SentinelConnected = 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 */
+static SSensorDataDiveO2 tmpSensorDataDiveO2;			/* intermediate storage for additional sensor data */
 
 char tmpRxBuf[30];
 uint8_t tmpRxIdx = 0;
 
 static uartO2Status_t Comstatus_O2 = UART_O2_INIT;
+static uint8_t activeSensor = 0;
+static uint8_t sensorMapping[MAX_ADC_CHANNEL];			/* The mapping is used to assign the visible sensor channel to the mux address (DiveO2) */
 
 float LED_Level = 0.0;							/* Normalized LED value which may be used as indication for the health status of the sensor */
 float LED_ZeroOffset = 0.0;
@@ -124,6 +127,27 @@
 }
 
 
+void DigitalO2_SelectSensor(uint8_t channel)
+{
+	uint8_t indexstr[4];
+	uint8_t muxAddress = 0;
+	indexstr[0] = '~';
+	indexstr[1] = '1';
+	indexstr[2] = 0x0D;
+	indexstr[3] = 0x0A;
+
+	if((channel < MAX_ADC_CHANNEL) && (sensorMapping[channel] != 0xff))
+	{
+			muxAddress = sensorMapping[channel];
+	}
+	else
+	{
+		muxAddress = MAX_ADC_CHANNEL;	/* default to mux */
+	}
+	indexstr[1] = '0' + muxAddress;
+	HAL_UART_Transmit(&huart1,indexstr,4,10);
+}
+
 void DigitalO2_SetupCmd(uint8_t O2State, uint8_t *cmdString, uint8_t *cmdLength)
 {
 	switch (O2State)
@@ -463,202 +487,277 @@
 	static uint8_t cmdLength = 0;
 	static uint8_t cmdString[10];
 	static uint8_t cmdReadIndex = 0;
+	static	uint32_t tickToTX =  0;
+	static uint32_t delayStartTick = 0;
 
+	uint8_t switchChannel = 0;
+	uint8_t index = 0;
 	uint32_t tmpO2 = 0;
 	uint32_t tmpData = 0;
 	uint8_t localRX = rxReadIndex;
 	uint32_t tick =  HAL_GetTick();
 
-
-	if(Comstatus_O2 == UART_O2_INIT)
-	{
-		memset((char*)&rxBuffer[rxWriteIndex],(int)0,CHUNK_SIZE);
-		memset((char*) &sensorDataDiveO2, 0, sizeof(sensorDataDiveO2));
-		externalInterface_SetSensorData(0,(uint8_t*)&sensorDataDiveO2);
+	uint8_t *pmap = externalInterface_GetSensorMapPointer(0);
 
-		lastAlive = 0;
-		curAlive = 0;
-
-		Comstatus_O2 = UART_O2_CHECK;
-		DigitalO2_SetupCmd(Comstatus_O2,cmdString,&cmdLength);
+	/* The channel switch will cause the sensor to respond with an error message. */
+	/* The sensor needs ~30ms to recover before he is ready to receive the next command => transmission delay needed */
+	if((tickToTX) && (time_elapsed_ms(delayStartTick,tick) >= tickToTX ))
+	{
 		HAL_UART_Transmit(&huart1,cmdString,cmdLength,10);
+		tickToTX = 0;
+	}
+	else
+	{
+		if(Comstatus_O2 == UART_O2_INIT)
+		{
+			memset((char*)&rxBuffer[rxWriteIndex],(int)0,CHUNK_SIZE);
+			memset((char*) &tmpSensorDataDiveO2, 0, sizeof(tmpSensorDataDiveO2));
+			externalInterface_SetSensorData(0,(uint8_t*)&tmpSensorDataDiveO2);
 
-		rxState = O2RX_CONFIRM;
-		cmdReadIndex = 0;
-		lastO2ReqTick = tick;
+			lastAlive = 0;
+			curAlive = 0;
 
-		UART_StartDMA_Receiption();
-	}
-	if(time_elapsed_ms(lastO2ReqTick,tick) > 1000)		/* repeat request once per second */
-	{
-		lastO2ReqTick = tick;
-		if(Comstatus_O2 == UART_O2_IDLE)				/* cyclic request of o2 value */
-		{
-			Comstatus_O2 = UART_O2_REQ_RAW;
+			Comstatus_O2 = UART_O2_CHECK;
+			DigitalO2_SetupCmd(Comstatus_O2,cmdString,&cmdLength);
+			DigitalO2_SelectSensor(activeSensor);
+			if(activeSensor < MAX_ADC_CHANNEL)
+			{
+				externalInterface_GetSensorData(activeSensor + 1, (uint8_t*)&tmpSensorDataDiveO2);
+			}
+			delayStartTick = tick;
+			tickToTX = COMMAND_TX_DELAY;
+
 			rxState = O2RX_CONFIRM;
-		}
-		DigitalO2_SetupCmd(Comstatus_O2,cmdString,&cmdLength);
-
-		HAL_UART_Transmit(&huart1,cmdString,cmdLength,10);
-	}
+			cmdReadIndex = 0;
+			lastO2ReqTick = tick;
 
-	while((rxBuffer[localRX]!=0))
-	{
-
-		lastReceiveTick = tick;
-		switch(rxState)
+			UART_StartDMA_Receiption();
+		}
+		if(time_elapsed_ms(lastO2ReqTick,tick) > 1000)		/* repeat request once per second */
 		{
-			case O2RX_CONFIRM:	if(rxBuffer[localRX] == '#')
-								{
-									cmdReadIndex = 0;
-								}
-								if(rxBuffer[localRX] == cmdString[cmdReadIndex])
-							    {
-								cmdReadIndex++;
-								if(cmdReadIndex == cmdLength - 1)
-								{
-									digO2Connected = 1;
-									tmpRxIdx = 0;
-									memset((char*) tmpRxBuf, 0, sizeof(tmpRxBuf));
-									switch (Comstatus_O2)
+			lastO2ReqTick = tick;
+			index = activeSensor;
+			if(Comstatus_O2 == UART_O2_IDLE)				/* cyclic request of o2 value */
+			{
+				if(pmap[EXT_INTERFACE_SENSOR_CNT-1] == SENSOR_MUX) /* select next sensor if mux is connected */
+				{
+					if(activeSensor < MAX_ADC_CHANNEL)
+					{
+						do
+						{
+							index++;
+							if(index == MAX_ADC_CHANNEL)
+							{
+								index = 0;
+							}
+							if(pmap[index] == SENSOR_DIGO2)
+							{
+								activeSensor = index;
+								switchChannel = 1;
+								break;
+							}
+						} while(index != activeSensor);
+					}
+				}
+
+				Comstatus_O2 = UART_O2_REQ_RAW;
+				rxState = O2RX_CONFIRM;
+			}
+			if(switchChannel)
+			{
+				delayStartTick = tick;
+				DigitalO2_SelectSensor(activeSensor);
+				externalInterface_GetSensorData(activeSensor + 1, (uint8_t*)&tmpSensorDataDiveO2);
+				tickToTX = COMMAND_TX_DELAY;
+				if(tmpSensorDataDiveO2.sensorId == 0)
+				{
+					Comstatus_O2 = UART_O2_REQ_ID;
+				}
+			}
+			else
+			{
+				HAL_UART_Transmit(&huart1,cmdString,cmdLength,10);
+			}
+			DigitalO2_SetupCmd(Comstatus_O2,cmdString,&cmdLength);
+		}
+
+		while((rxBuffer[localRX]!=0))
+		{
+			lastReceiveTick = tick;
+			switch(rxState)
+			{
+				case O2RX_CONFIRM:	if(rxBuffer[localRX] == '#')
 									{
-											case UART_O2_CHECK:	Comstatus_O2 = UART_O2_REQ_ID;
-																rxState = O2RX_CONFIRM;
-																DigitalO2_SetupCmd(Comstatus_O2,cmdString,&cmdLength);
-																HAL_UART_Transmit(&huart1,cmdString,cmdLength,10);
-												break;
-											case UART_O2_REQ_ID: rxState = O2RX_GETNR;
-												break;
-											case UART_O2_REQ_INFO: rxState = O2RX_GETTYPE;
-												break;
-											case UART_O2_REQ_RAW:
-											case UART_O2_REQ_O2:	rxState = O2RX_GETO2;
-												break;
-											default:	Comstatus_O2 = UART_O2_IDLE;
-														rxState = O2RX_IDLE;
+										cmdReadIndex = 0;
+									}
+									if(rxBuffer[localRX] == cmdString[cmdReadIndex])
+									{
+									cmdReadIndex++;
+									if(cmdReadIndex == cmdLength - 1)
+									{
+										digO2Connected = 1;
+										tmpRxIdx = 0;
+										memset((char*) tmpRxBuf, 0, sizeof(tmpRxBuf));
+										switch (Comstatus_O2)
+										{
+												case UART_O2_CHECK:	Comstatus_O2 = UART_O2_IDLE;
 													break;
-									}
-								}
-						  	}
-				break;
-
-			case O2RX_GETSTATUS:
-			case O2RX_GETTEMP:
-			case O2RX_GETTYPE:
-			case O2RX_GETVERSION:
-			case O2RX_GETCHANNEL:
-			case O2RX_GETSUBSENSORS:
-			case O2RX_GETO2:
-			case O2RX_GETNR:
-			case O2RX_GETDPHI:
-			case O2RX_INTENSITY:
-			case O2RX_AMBIENTLIGHT:
-			case O2RX_PRESSURE:
-			case O2RX_HUMIDITY:
-								if(rxBuffer[localRX] != 0x0D)
-								{
-									if(rxBuffer[localRX] != ' ')
-									{
-										tmpRxBuf[tmpRxIdx++] = rxBuffer[localRX];
-									}
-									else
-									{
-										if(tmpRxIdx != 0)
-										{
-											switch(rxState)
-											{
-												case O2RX_GETCHANNEL:	StringToInt(tmpRxBuf,&tmpData);
-																		rxState = O2RX_GETVERSION;
+												case UART_O2_REQ_ID: rxState = O2RX_GETNR;
+													break;
+												case UART_O2_REQ_INFO: rxState = O2RX_GETTYPE;
+													break;
+												case UART_O2_REQ_RAW:
+												case UART_O2_REQ_O2:	rxState = O2RX_GETO2;
+													break;
+												default:	Comstatus_O2 = UART_O2_IDLE;
+															rxState = O2RX_IDLE;
 														break;
-												case O2RX_GETVERSION:	StringToInt(tmpRxBuf,&tmpData);
-																		rxState = O2RX_GETSUBSENSORS;
-														break;
-												case O2RX_GETTYPE: 		StringToInt(tmpRxBuf,&tmpData);
-																		rxState = O2RX_GETCHANNEL;
-														break;
-
-												case O2RX_GETO2: 		StringToInt(tmpRxBuf,&tmpO2);
-																		setExternalInterfaceChannel(ppO2TargetChannel,(float)(tmpO2 / 10000.0));
-																		rxState = O2RX_GETTEMP;
-													break;
-												case O2RX_GETTEMP:		StringToInt(tmpRxBuf,(uint32_t*)&sensorDataDiveO2.temperature);
-																		rxState = O2RX_GETSTATUS;
-													break;
-												case O2RX_GETSTATUS:	StringToInt(tmpRxBuf,&sensorDataDiveO2.status);				/* raw data cycle */
-																		rxState = O2RX_GETDPHI;
-													break;
-												case O2RX_GETDPHI:		/* ignored to save memory and most likly irrelevant for diver */
-																		rxState = O2RX_INTENSITY;
-																									break;
-												case O2RX_INTENSITY:	StringToInt(tmpRxBuf,(uint32_t*)&sensorDataDiveO2.intensity);				/* raw data cycle */
-																		rxState = O2RX_AMBIENTLIGHT;
-																									break;
-												case O2RX_AMBIENTLIGHT:	StringToInt(tmpRxBuf,(uint32_t*)&sensorDataDiveO2.ambient);				/* raw data cycle */
-																		rxState = O2RX_PRESSURE;
-																									break;
-												case O2RX_PRESSURE:	StringToInt(tmpRxBuf,(uint32_t*)&sensorDataDiveO2.pressure);					/* raw data cycle */
-																		rxState = O2RX_HUMIDITY;
-																									break;
-												default:
-													break;
-											}
-											memset((char*) tmpRxBuf, 0, tmpRxIdx);
-											tmpRxIdx = 0;
 										}
 									}
 								}
-								else
-								{
-									switch (rxState)
+					break;
+
+				case O2RX_GETSTATUS:
+				case O2RX_GETTEMP:
+				case O2RX_GETTYPE:
+				case O2RX_GETVERSION:
+				case O2RX_GETCHANNEL:
+				case O2RX_GETSUBSENSORS:
+				case O2RX_GETO2:
+				case O2RX_GETNR:
+				case O2RX_GETDPHI:
+				case O2RX_INTENSITY:
+				case O2RX_AMBIENTLIGHT:
+				case O2RX_PRESSURE:
+				case O2RX_HUMIDITY:
+									if(rxBuffer[localRX] != 0x0D)
 									{
-										case O2RX_GETSTATUS:		StringToInt(tmpRxBuf,&sensorDataDiveO2.status);
-																	externalInterface_SetSensorData(1,(uint8_t*)&sensorDataDiveO2);
-																	Comstatus_O2 = UART_O2_IDLE;
-																	rxState = O2RX_IDLE;
-												break;
-										case O2RX_GETSUBSENSORS:	StringToInt(tmpRxBuf,&tmpData);
-																	Comstatus_O2 = UART_O2_IDLE;
-																	rxState = O2RX_IDLE;
+										if(rxBuffer[localRX] != ' ')		/* the following data entities are placed within the data stream => no need to store data at the end */
+										{
+											tmpRxBuf[tmpRxIdx++] = rxBuffer[localRX];
+										}
+										else
+										{
+											if(tmpRxIdx != 0)
+											{
+												switch(rxState)
+												{
+													case O2RX_GETCHANNEL:	StringToInt(tmpRxBuf,&tmpData);
+																			rxState = O2RX_GETVERSION;
+															break;
+													case O2RX_GETVERSION:	StringToInt(tmpRxBuf,&tmpData);
+																			rxState = O2RX_GETSUBSENSORS;
+															break;
+													case O2RX_GETTYPE: 		StringToInt(tmpRxBuf,&tmpData);
+																			rxState = O2RX_GETCHANNEL;
+															break;
+
+													case O2RX_GETO2: 		StringToInt(tmpRxBuf,&tmpO2);
+																			setExternalInterfaceChannel(activeSensor,(float)(tmpO2 / 10000.0));
+																			rxState = O2RX_GETTEMP;
+														break;
+													case O2RX_GETTEMP:		StringToInt(tmpRxBuf,(uint32_t*)&tmpSensorDataDiveO2.temperature);
+																			rxState = O2RX_GETSTATUS;
+														break;
+													case O2RX_GETSTATUS:	StringToInt(tmpRxBuf,&tmpSensorDataDiveO2.status);				/* raw data cycle */
+																			rxState = O2RX_GETDPHI;
+														break;
+													case O2RX_GETDPHI:		/* ignored to save memory and most likly irrelevant for diver */
+																			rxState = O2RX_INTENSITY;
+																										break;
+													case O2RX_INTENSITY:	StringToInt(tmpRxBuf,(uint32_t*)&tmpSensorDataDiveO2.intensity);				/* raw data cycle */
+																			rxState = O2RX_AMBIENTLIGHT;
+																										break;
+													case O2RX_AMBIENTLIGHT:	StringToInt(tmpRxBuf,(uint32_t*)&tmpSensorDataDiveO2.ambient);				/* raw data cycle */
+																			rxState = O2RX_PRESSURE;
+																										break;
+													case O2RX_PRESSURE:	StringToInt(tmpRxBuf,(uint32_t*)&tmpSensorDataDiveO2.pressure);					/* raw data cycle */
+																			rxState = O2RX_HUMIDITY;
+																										break;
+													default:
+														break;
+												}
+												memset((char*) tmpRxBuf, 0, tmpRxIdx);
+												tmpRxIdx = 0;
+											}
+										}
+									}
+									else
+									{							/* the following data items are the last of a sensor respond => store temporal data */
+										switch (rxState)
+										{
+											case O2RX_GETSTATUS:		StringToInt(tmpRxBuf,&tmpSensorDataDiveO2.status);
+																		externalInterface_SetSensorData(activeSensor+1,(uint8_t*)&tmpSensorDataDiveO2);
+																		Comstatus_O2 = UART_O2_IDLE;
+																		rxState = O2RX_IDLE;
+													break;
+											case O2RX_GETSUBSENSORS:	StringToInt(tmpRxBuf,&tmpData);
+																		Comstatus_O2 = UART_O2_IDLE;
+																		rxState = O2RX_IDLE;
+													break;
+											case O2RX_HUMIDITY:			StringToInt(tmpRxBuf,(uint32_t*)&tmpSensorDataDiveO2.humidity);				/* raw data cycle */
+																		externalInterface_SetSensorData(activeSensor+1,(uint8_t*)&tmpSensorDataDiveO2);
+																		Comstatus_O2 = UART_O2_IDLE;
+																		rxState = O2RX_IDLE;
+													break;
+											case  O2RX_GETNR: 			StringToUInt64((char*)tmpRxBuf,&tmpSensorDataDiveO2.sensorId);
+																		externalInterface_SetSensorData(activeSensor+1,(uint8_t*)&tmpSensorDataDiveO2);
+																		index = activeSensor;
+
+																		if(switchChannel == 0)
+																		{
+																			Comstatus_O2 = UART_O2_IDLE;
+																			rxState = O2RX_IDLE;
+																		}
 												break;
-										case O2RX_HUMIDITY:	StringToInt(tmpRxBuf,(uint32_t*)&sensorDataDiveO2.humidity);				/* raw data cycle */
-																	externalInterface_SetSensorData(1,(uint8_t*)&sensorDataDiveO2);
-																	Comstatus_O2 = UART_O2_IDLE;
-																	rxState = O2RX_IDLE;
-																							break;
-										case  O2RX_GETNR: 			StringToUInt64((char*)tmpRxBuf,&sensorDataDiveO2.sensorId);
-											/* no break */
-										default:		Comstatus_O2 = UART_O2_IDLE;
-														rxState = O2RX_IDLE;
-											break;
+											default:		Comstatus_O2 = UART_O2_IDLE;
+															rxState = O2RX_IDLE;
+												break;
+										}
 									}
-								}
+						break;
+				default:				rxState = O2RX_IDLE;
 					break;
-			default:				rxState = O2RX_IDLE;
-				break;
 
+			}
+			rxBuffer[localRX] = 0;
+			localRX++;
+			rxReadIndex++;
+			if(rxReadIndex >= CHUNK_SIZE * CHUNKS_PER_BUFFER)
+			{
+				localRX = 0;
+				rxReadIndex = 0;
+			}
 		}
-		rxBuffer[localRX] = 0;
-		localRX++;
-		rxReadIndex++;
-		if(rxReadIndex >= CHUNK_SIZE * CHUNKS_PER_BUFFER)
+
+		if((digO2Connected) && time_elapsed_ms(lastReceiveTick,HAL_GetTick()) > 4000)	/* check for communication timeout */
 		{
-			localRX = 0;
-			rxReadIndex = 0;
+			digO2Connected = 0;
+			if(curAlive == lastAlive)
+			{
+				setExternalInterfaceChannel(ppO2TargetChannel,0.0);
+			}
+			lastAlive = curAlive;
+		}
+		if((dmaActive == 0)	&& (externalInterface_isEnabledPower33()))	/* Should never happen in normal operation => restart in case of communication error */
+		{
+			UART_StartDMA_Receiption();
 		}
 	}
+}
 
-	if((digO2Connected) && time_elapsed_ms(lastReceiveTick,HAL_GetTick()) > 4000)	/* check for communication timeout */
+void UART_SetDigO2_Channel(uint8_t channel)
+{
+	if(channel <= MAX_ADC_CHANNEL)
 	{
-		digO2Connected = 0;
-		if(curAlive == lastAlive)
-		{
-			setExternalInterfaceChannel(ppO2TargetChannel,0.0);
-		}
-		lastAlive = curAlive;
+		activeSensor = channel;
 	}
-	if((dmaActive == 0)	&& (externalInterface_isEnabledPower33()))	/* Should never happen in normal operation => restart in case of communication error */
+}
+void UART_MapDigO2_Channel(uint8_t channel, uint8_t muxAddress)
+{
+	if((channel < MAX_ADC_CHANNEL) && (muxAddress < MAX_ADC_CHANNEL))
 	{
-		UART_StartDMA_Receiption();
+		sensorMapping[channel] = muxAddress;
 	}
 }