cancel
Showing results for 
Search instead for 
Did you mean: 

how to store signed hexadecimal data from a sensor and identify if the hex is negative or positive?

PCong.1
Associate II

I have a sensor that can communicate via UART, I send a command and the sensor answers me with a hexadecimal frame.

I can have distance, angle, velocity values.

0693W00000JQ2dNQAT.png0693W00000JQ2dIQAT.png0693W00000JQ2dXQAT.png 

I know how to store the frame in a buffer but I don't know how to store it in hexa to keep the form 0xFF6F and identify if the value is negative or positive.

There is the code i have made to identifier and read value inside the buffer

extern uint8_t flag;
extern UART_HandleTypeDef huart1;
 
//Initialisation des commandes capteur.
uint8_t INIT[12] = {0x49, 0x4E, 0x49, 0x54, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; // Init commande for the first communication and fix the Bauderate
uint8_t TDAT[12] = {0x47, 0x4E, 0x46, 0x44, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00}; // TDAT to detect target and get the rang and the angle
uint8_t GBYE[8] = {0x49, 0x4E, 0x49, 0x54, 0x00, 0x00, 0x00, 0x00}; // commande to disconnect the sensor
 
void sensor_init(void){
	HAL_UART_Transmit(&huart1, INIT, sizeof(INIT), 13);
	HAL_Delay(75);
}
 
void sensor_data(void){
	if (flag == 1) {
		HAL_UART_Transmit(&huart1, TDAT, sizeof(TDAT), 13);
		HAL_Delay(100);
		flag = 0;
	}
	distance = k_ld7_resp[8] + k_ld7_resp[9]*0x100;
	angle = (k_ld7_resp[12] + k_ld7_resp[13]*0x100) / 100;

The code for the uart callback

/*K_LD7 private variable*/
uint8_t flag = 0;
uint8_t rxByte;
 
char k_ld7_resp[RxBuff_SIZE];
char MainBuf_K_LD7[Main_buf_SIZE];
 
 
 
void Ringbuf_Reset(void){
	memset(MainBuf_K_LD7, '\0', Main_buf_SIZE);
	memset(k_ld7_resp, '\0', RxBuff_SIZE);
}
 
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size){
	if (huart->Instance == USART1) {
		memcpy(MainBuf_K_LD7, k_ld7_resp, Size);
		flag = 1;
		HAL_UARTEx_ReceiveToIdle_DMA(huart, k_ld7_resp, RxBuff_SIZE);
		 __HAL_DMA_DISABLE_IT(&hdma_usart1_rx, DMA_IT_HT);
	}
}

1 ACCEPTED SOLUTION

Accepted Solutions
MM..1
Chief II

you say something about hex but you send and rec over UART binary data.

In payload table you have info for types and conversions

simply use

int16_t angle;  //stored *100 value dont use float if not required
uint16_t distance;
 
angle = *((int16_t *)&k_ld7_resp[12]);
distance = *((uint16_t *)&k_ld7_resp[8]);

View solution in original post

6 REPLIES 6
MM..1
Chief II

you say something about hex but you send and rec over UART binary data.

In payload table you have info for types and conversions

simply use

int16_t angle;  //stored *100 value dont use float if not required
uint16_t distance;
 
angle = *((int16_t *)&k_ld7_resp[12]);
distance = *((uint16_t *)&k_ld7_resp[8]);

Nikita91
Lead II

Do not use payload bytes individually. Define a struct to receive the paylod:

typedef struct
{
    uint32_t  header ;
    uint32_t length ;
    uint16_t  distance ;
    int16_t    speed ;
    int16_t    angle ;
    uint16_t  mag ;
} msg_t ;
 
msg_t data  ;
 

If you use the data buffer to receive the sensor message, you can directly access each values.

If you have many messages types, define a struct for each message.

I tried with type int16 for the angle, now I have the negative sign but the value is completely wrong.

void sensor_data(void){
	if (flag == 1) {
		HAL_UART_Transmit(&huart1, TDAT, sizeof(TDAT), 13);
		HAL_Delay(100);
		flag = 0;
	}
	distance = k_ld7_resp[8] + k_ld7_resp[9]*0x100;
	angle = (*(int16_t*)&k_ld7_resp[12] + (*(int16_t*)&k_ld7_resp[13])*0x100) / 100;

0693W00000JQ3wVQAT.png

Your conversion is bad dont need handle [13]*256 use my syntax and if you need angle in debree add /100. You dont show how type is angle global in your code.

Thanks, it finally works and returns the right values

Ok if you need angle in float define as float and instead /100 add /100.0f