Receiving UART data as hex - STM32 - Page 1
Forum section: electronics / general

author: bborisov567
author_rank: Regular Contributor
timestamp: September 15, 2024, 08:16:03 pm
content: Hello, i am trying to inferface a PMS7003 sensor to a STM32f030c8t6. The sensor ( dataheet:https://download.kamami.pl/p564008-PMS7003%20series%20data%20manua_English_V2.5.pdf) sends 32 bytes of data for every measument. The terminal log shows that. The data should be read in hex format, not ascii. Currently i am trying to read the data in polling mode with the HAL_UART_RECEIVE() function. It is supposed to write the data in a string. When i display the data from the string i get only "BM", which is the ascii for the first two bytes(0x42 and 0x4d). No matter what i tried i cannot get it to read more bytes. Here is the code i use:Code:while (1){uint8_t Rx_data;HAL_UART_Receive(&huart2, Rx_data, 40, 1000);u8g2_ClearDisplay(&u8g2);u8g2_SetFont(&u8g2, u8g2_font_ncenB08_tr);u8g2_SetDrawColor(&u8g2, 1);u8g2_DrawStr(&u8g2, 3, 29, Rx_data);u8g2_SendBuffer(&u8g2);/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */}

author: mskeete
author_rank: Contributor
timestamp: September 15, 2024, 09:43:26 pm
content: You haven't converted the data to Hex.the data contains null bytes- e.g the 3rd byteThe u8g2_DrawStr function probably expects a standard null terminated string and stops when it encounters the 3rd byte.write a function to convert each byte of Rx_data to two ascii characters representing the hex value of the byte.store that in a new buffer. Add the null terminator at the end and pass that new buffer to u8g2_DrawStrThe new buffer should be at least 65 bytes in length

author: Doctorandus_P
author_rank: Super Contributor
timestamp: September 18, 2024, 03:01:53 pm
content: "Hex data" does not really exist. It's all ones and zero's, and those ones and zero's can be interpreted in different ways. So start by stopping to call your data hexadecimal, because it is not. Then you open some room to go figure out what the actual data format is. Bits, bytes, and how the data is encoded.

author: DavidAlfa
author_rank: Super Contributor
timestamp: September 18, 2024, 03:17:23 pm
content: You must convert it to string:Code:char buffer;const char b2h[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; // Look-up tablefor(uint8_t i=0; i<40; i++){buffer[i*3] = b2h[Rx_data>>4]; //Convert each char to hex stringbuffer[(i*3)+1] = b2h[Rx_data & 0xF];buffer[(i*3)+2] = ' '; // Add a space between chars} // i.e, 0x33 outputs "33 "buffer = 0; // null terminationu8g2_DrawStr(&u8g2, 3, 29, buffer);

author: ledtester
author_rank: Super Contributor
timestamp: September 18, 2024, 03:42:49 pm
content: Quote from: bborisov567 on September 15, 2024, 08:16:03 pmYou have to use the Appendix (starting on page 13) to decode the data.For instance, look at the first couple of bytes you received:0x42 0x4d 0x00 0x1c 0x00 0x08 0x00 0x0f ...The appendix says that after getting the 0x42 and 0x4d (the 'B' and 'M' characters) the next two bytes are the high and low bytes of the frame length which in your case are 0x00 and 0x1c corresponding to the 16-bit number 0x001c = 28 decimal.And the next two after that (the 0x00 0x08) are the 16-bit value of the PM1.0 concentration in micrograms per cubic meter and so this value is 0x0008 = 8.Likewise, the next two bytes (the 0x00 0x0f) are the PM2.5 concentration: 0x000f = 15.

author: mskeete
author_rank: Contributor
timestamp: September 18, 2024, 06:17:34 pm
content: Quote from: DavidAlfa on September 18, 2024, 03:17:23 pmDoes that code work for A to F?

author: DavidAlfa
author_rank: Super Contributor
timestamp: September 18, 2024, 06:38:46 pm
content: Sorry, no, fixed now. After 8h of hard of hard work diagnosing and fixing RF transceivers (Why I'm getting low SINAD, where's this out-of-nowhere modulation coming, why the hell do I have these armonics...?), only the 8yr-old neurons stay working (Though they're incredibly good at eating cheese and driking beer)Watch it working:https://www.jdoodle.com/ia/1hkq

author: mskeete
author_rank: Contributor
timestamp: September 18, 2024, 06:59:49 pm
content: No worries. I actually wrote some examples code the other night but decided not to post it and embarrass myself. Too many good C programmers around here.I notice that the 1st version explicitly terminates the string and the 2nd version doesn't?

author: DavidAlfa
author_rank: Super Contributor
timestamp: September 18, 2024, 07:09:27 pm
content: Yep, just another bug caused by the second beer, always terminate C strings or be prepared for the nasty consequences!Just joking, I'm a disaster without any "external" help

author: cv007
author_rank: Frequent Contributor
timestamp: September 18, 2024, 08:32:51 pm
content: An x86 example (so can produce output in online compiler)-https://godbolt.org/z/hGz94TKf8Suggest finding the start of the frame whether actually needed in this case or not so you do not end up processing data that is split among frames, checking HAL return values, and using snprintf when trying to format output in any way. The above example takes your data, simulates uart rx, validates the frame and converts the data to little endian, uses snprintf to format data in some way, and in this case the final output is printf but of course would be something else in your case (some display it would seem).