2024-10-16 01:11 AM - last edited on 2024-10-16 01:20 AM by Andrew Neil
Hi, I have a buffer with 65000 values in 16 bits from the ADC read that I need to provide to my computer running a python code.
Any suggestion how can I handle this in both sides?
I'm trying to use this function but I'm getting weird data when I'm listening the COM port with Putty.
// Generalized function to transmit any 16bits buffer over USB
void send_16b_buffer_over_usb(uint16_t *buffer, uint32_t buffer_size)
{
uint32_t total_bytes = buffer_size * BYTES_PER_SAMPLE; // Total size of the buffer in bytes
uint32_t bytes_sent = 0;
uint8_t result = USBD_OK;
// Send the buffer in chunks
while (bytes_sent < total_bytes)
{
// Calculate the remaining bytes to be sent
uint32_t bytes_to_send = (total_bytes - bytes_sent > CHUNK_SIZE) ? CHUNK_SIZE : (total_bytes - bytes_sent);
// Send the current chunk of data
result = CDC_Transmit_HS((uint8_t*)&buffer[bytes_sent / BYTES_PER_SAMPLE], bytes_to_send);
// Wait for the USB transmission to complete
while (result == USBD_BUSY)
{
result = CDC_Transmit_HS((uint8_t*)&buffer[bytes_sent / BYTES_PER_SAMPLE], bytes_to_send);
}
// If the transmission was successful, update the sent bytes counter
if (result == USBD_OK)
{
bytes_sent += bytes_to_send;
}
else
{
// Handle transmission failure (optional)
break;
}
}
}
If I do something simple like this it work fine:
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
uint8_t *data = "Hello World from USB CDC\n";
/* USER CODE END 0 */
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USB_DEVICE_Init();
while (1)
{
CDC_Transmit_FS(data, strlen(data));
HAL_Delay (1000);
}
}
Thank you.
Solved! Go to Solution.
2024-10-20 12:21 PM
With this code I was able to read the correct values.
Thank you for the support.
def read_serial_data(buffer_size, output_file):
# Buffer to store the received binary data
buffer = bytearray()
while len(buffer) < buffer_size:
# Read binary data from UART
data = ser.read(buffer_size - len(buffer)) # Read only the remaining bytes needed to fill the buffer
if data:
buffer.extend(data) # Append received data to the buffer
print(f"Received {len(data)} bytes, total: {len(buffer)} bytes")
if len(buffer) >= buffer_size:
print("Buffer filled.")
break
# Convert the buffer to a hexadecimal string
hex_data = buffer.hex()
# Insert commas between every four hexadecimal characters
formatted_hex_data = ','.join(hex_data[i:i + 4] for i in range(0, len(hex_data), 4))
# Save the formatted hexadecimal string to a text file
with open(output_file + "_hex.txt", "w") as f:
f.write(formatted_hex_data)
print(f"Saved {len(formatted_hex_data)} characters to '{output_file}_hex.txt'")
# Convert groups of four hex values to 16-bit numbers and then to decimal
decimal_values = []
for i in range(0, len(hex_data), 4): # Process 8 hex characters (4 bytes) at a time
if i + 4 <= len(hex_data):
low_part = hex_data[i:i + 2]
high_part = hex_data[i + 2:i + 4]
combined_value = int(high_part + low_part, 16)
decimal_values.append(combined_value)
# Save the decimal values to a new file
with open(output_file + "_decimal.txt", "w") as f:
for value in decimal_values:
f.write(f"{value}\n")
print(f"Saved {len(decimal_values)} decimal values to '{output_file}_decimal.txt'")
2024-10-16 01:14 AM
@fposser wrote:I'm trying to use this function but I'm getting weird data when I'm listening the COM port with Putty.
Define "weird".
You're sending raw binary data - so that would not be expected to appear as readable text on a terminal!
2024-10-16 01:19 AM
Yes, you are right. I will try to catch this with Python to see if I can read the values.
What is the highest speed I can communicate on the COM Port using this USB?
2024-10-16 01:24 AM - edited 2024-10-16 01:36 AM
Or you could try RealTerm - it is able to display binary data.
No doubt there are also others ...
@fposser wrote:What is the highest speed I can communicate on the COM Port using this USB?
No idea.
PS:
But the H7 family seems to have various USB options - so you'd probably need to say which part you're using...
2024-10-16 04:53 AM
Im using the NUCLEO-H723ZG
2024-10-16 07:13 AM - edited 2024-10-16 07:15 AM
1. The baud rate setting is meaningless for VCP (unless you pass the traffic from/to a real UART) and does not influence the USB transfer speed.
2. Calling the function from main loop will sooner or later freeze the USB stack. The code must be rewritten so that Transmit call is made with interrupts locked or from an ISR of the same priority as USB interrupt.
2024-10-16 07:16 AM
@gbm wrote:1. The baud rate setting is meaningless for VCP (unless you pass the traffic from/to a real UART) and does not influence the USB transfer speed.
True, but still leaves the question, "What is the USB transfer speed?"
2024-10-20 12:21 PM
With this code I was able to read the correct values.
Thank you for the support.
def read_serial_data(buffer_size, output_file):
# Buffer to store the received binary data
buffer = bytearray()
while len(buffer) < buffer_size:
# Read binary data from UART
data = ser.read(buffer_size - len(buffer)) # Read only the remaining bytes needed to fill the buffer
if data:
buffer.extend(data) # Append received data to the buffer
print(f"Received {len(data)} bytes, total: {len(buffer)} bytes")
if len(buffer) >= buffer_size:
print("Buffer filled.")
break
# Convert the buffer to a hexadecimal string
hex_data = buffer.hex()
# Insert commas between every four hexadecimal characters
formatted_hex_data = ','.join(hex_data[i:i + 4] for i in range(0, len(hex_data), 4))
# Save the formatted hexadecimal string to a text file
with open(output_file + "_hex.txt", "w") as f:
f.write(formatted_hex_data)
print(f"Saved {len(formatted_hex_data)} characters to '{output_file}_hex.txt'")
# Convert groups of four hex values to 16-bit numbers and then to decimal
decimal_values = []
for i in range(0, len(hex_data), 4): # Process 8 hex characters (4 bytes) at a time
if i + 4 <= len(hex_data):
low_part = hex_data[i:i + 2]
high_part = hex_data[i + 2:i + 4]
combined_value = int(high_part + low_part, 16)
decimal_values.append(combined_value)
# Save the decimal values to a new file
with open(output_file + "_decimal.txt", "w") as f:
for value in decimal_values:
f.write(f"{value}\n")
print(f"Saved {len(decimal_values)} decimal values to '{output_file}_decimal.txt'")
2024-10-20 10:46 PM - edited 2024-10-20 10:55 PM
Finally found some time to do VCOM benchmarks using my device stack and TeraTerm 5.3.
The results are the same for VCOM baud rate setting of 9600 and 921600. VCOM data endpoint size is 64 B.
STM32U575 (160 MHz, OTG FS peripheral in Full-Speed mode): receiving from PC: 507..530 kB/s, sending: 309..326 kB/s
STM32C071 (48 MHz, DRD peripheral, Full-Speed mode): receiving from PC: 230 kB/s, sending: 300..303 kB/s.
2024-10-21 01:18 AM
@fposser wrote:With this code I was able to read the correct values.
Excellent - please mark the solution:
https://community.st.com/t5/community-guidelines/help-others-to-solve-their-issues/ta-p/575256
That's the PC-side code - yes?
So the STM32 code was working all along - the problem was the PC side interpreting it?