This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Manipulate data receive from serial NRF52840

I have succeed transferred data from PC to NRF52840 dongle and managed to receive it back on the PC.

But i want to be available to manipulate the data in NRF52840 dongle before send it back. 

My data types is float and i use Python.serial to send and receive data from PC. 

Attached is my python code and SES main code snippet

static char m_cdc_data[512]; 
 
 
 case APP_USBD_CDC_ACM_USER_EVT_RX_DONE:
        {
            ret_code_t ret;
            static uint8_t index = 0;
            index++;
            NRF_LOG_INFO("Bytes waiting: %d", app_usbd_cdc_acm_bytes_stored(p_cdc_acm));
            do
            {
                if ((m_cdc_data[index-1] == '\n') || 
                (m_cdc_data[index-1] == '\r') || 
                (index >= (255)))
                {
                  if (index>1)
                  {
                    NRF_LOG_DEBUG("Ready to send data");
                    NRF_LOG_HEXDUMP_DEBUG(m_cdc_data, index);
                      
                      uint16_t length = (uint16_t)index;
                      if (length + sizeof(ENDLINE_STRING)<255)
                      {
                        memcpy(m_cdc_data + length, ENDLINE_STRING, sizeof(ENDLINE_STRING));
                        length += sizeof(ENDLINE_STRING);
                      }

                      //m_cdc_data = 
          
                      ret = app_usbd_cdc_acm_write(&m_app_cdc_acm,m_cdc_data, length);

                  }

                  index = 0;

                }

                /*Get amount of data transfered*/
                size_t size = app_usbd_cdc_acm_rx_size(p_cdc_acm);
                NRF_LOG_INFO("RX: size: %lu char: %c", size, m_cdc_data[index-1]);

                /* Fetch data until internal buffer is empty */
                ret = app_usbd_cdc_acm_read(&m_app_cdc_acm,
                                            &m_cdc_data[index],
                                            READ_SIZE);

                if (ret == NRF_SUCCESS)
                {
                  index++;
                }

                /*for (int i = 0; i < size; i++)
                {
                  m_cdc_data[i] = m_cdc_data[i] + 10;
                }*/
            
            } 
            while (ret == NRF_SUCCESS);

            bsp_board_led_invert(LED_CDC_ACM_RX);
            break;
        }

i used USB CDC ACM example from NRF5SDK with some modifications. 

# -*- coding: utf-8 -*-
"""
Created on Tue Aug 17 03:18:43 2021

@author: owner
"""

import serial
import pandas as pd
import numpy as np
import scipy.io
import io
import struct

ser=serial.Serial("COM5",115200,timeout=1)  # Open the port

fout = open("./OUTPUT.txt", "w")

a15 = scipy.io.loadmat("a17_s2_t3_inertial.mat")

data=a15['d_iner']
x1=data[:,0]
y1=data[:,1]
z1=data[:,2]
x2=data[:,3]
y2=data[:,4]
z2=data[:,5]

d = len(data)



x11 = struct.pack('39f', *x1)




ser.write(x11)			# Send data to the port
k = ser.readlines()							# Receive data from the port


fout.write(str(k))    								# Write the received data to OUTPUT

fin.close()
fout.close()

ser.close()

  • Hi 

    How does the data that you send to the dongle look?

    Are the float values encoded in binary format, or as strings?

    Maybe you can send me an example of such an update, then it is easier to know how best to do the conversion. 

    Best regards
    Torbjørn

  • Hi. 

    1) I cannot check how the data in the dongle look, but i believe it is saves as char in the dongle

    2) the float are encode in bytes type before sending it to the serial by python, so the dongle receive the bytes in char format. And the char are send back through serial to python and python reads the char as bytes. 

    my input is an array of float with 39 rows and one column

    I attached snippet of the input and output file below. 

    Input after encode to bytes:

    b'\xd4\x82Z@\xd4\x82Z@\x8c\x0c\x84@\x8c\x0c\x84@n<\xa2@n<\xa2@.\xc4\xca@.\xc4\xca@\x9e\xba\xdd@\x9e\xba\xdd@\xacW\xc1@\xacW\xc1@\x16\x89\xb7@\x16\x89\xb7@\x1a\xe8\xba@\x1a\xe8\xba@\x06\xa8\xdc@\x06\xa8\xdc@\x8e\xd2\xec@\x8e\xd2\xec@\xb5\x00\x06A\xb5\x00\x06A\x94\xb8\xdf@\x94\xb8\xdf@x@\xeb@x@\xeb@\xc2O\xdc@\xc2O\xdc@4+\xe3@4+\xe3@J\xbd\xe4@J\xbd\xe4@^j\xf2@^j\xf2@f!\xe3@f!\xe3@ZN\xe7@ZN\xe7@\x921\xf0@'

    Ouput file:

    [b'\x00\x82Z@\xd4\x82Z@\x8c\x0c\x84@\x8c\x0c\x84@n<\xa2@n<\xa2@.\xc4\xca@.\xc4\xca@\x9e\xba\xdd@\x9e\xba\xdd@\xacW\xc1@\xacW\xc1@\x16\x89\xb7@\x16\x89\xb7@\x1a\xe8\xba@\x1a\xe8\xba@\x06\xa8\xdc@\x06\xa8\xdc@\x8e\xd2\xec@\x8e\xd2\xec@\xb5\x00\x06A\xb5\x00\x06A\x94\xb8\xdf@\x94\xb8\xdf@x@\xeb@x@\xeb@\xc2O\xdc@\xc2O\xdc@4+\xe3@4+\xe3@J\xbd\xe4@J\xbd\xe4@^j\xf2@^j\xf2@f!\xe3@f!\xe3@ZN\xe7@ZN\xe7@\x921\xf0@\x00\x82Z@\xd4\x82Z@\x8c\x0c\x84@\x8c\x0c\x84@n<\xa2@n<\xa2@.\xc4\xca@.\xc4\xca@\x9e\xba\xdd@\x9e\xba\xdd@\xacW\xc1@\xacW\xc1@\x16\x89\xb7@\x16\x89\xb7@\x1a\xe8\xba@\x1a\xe8\xba@\x06\xa8\xdc@\x06\xa8\xdc@\x8e\xd2\xec@\x8e\xd2\xec@\xb5\x00\x06A\xb5\x00\x06A\x94\xb8\xdf@\x94\xb8\xdf@x@\xeb']

  • Hi 

    If each float is converted to 4 bytes it should be relatively easy to convert it on the dongle side. 

    Can you confirm that the encoded string is 39*4 = 156 bytes long?

    In order to convert a uint8_t array to float in this case it should be sufficient to create a union type, like this:

    union 
    {
        float values_fl[39];
        uint8_t values_char[39*4];
    } char_to_float_t;

    Write the char values from the cdc_acm class into the values_char field, and read them out as float from the values_fl field. 

    Please note that it is important to make sure that you get a full sequence before you do the conversion, in case some bytes still haven't been received. 

    In order to test if everything works OK you can apply some simple calculation to all the float values and send them back. 

    Best regards
    Torbjørn

Related