Author Topic: Python -> USB2TTL -> STM32 UART Serial Communication  (Read 489 times)

0 Members and 1 Guest are viewing this topic.

Offline AlwaysAbiaTopic starter

  • Newbie
  • Posts: 8
  • Country: ge
Python -> USB2TTL -> STM32 UART Serial Communication
« on: September 05, 2024, 10:35:42 am »
I am working on a project where I need to send serial data to an STM32F103 USART using a USB2TTL module.

I want to be able to send numbers and have the stm32 parse the numbers and use them for a certain task. I've accomplished this by having the USARTx_IRQHandler parse the data it receives character by character and append the numbers to a buffer, which gets moved to a variable after the stm receives a delimiting character (In this case i chose 'a' as the delimiting character for no particular reason).

Code: [Select]
void USART3_IRQHandler(void)
{
/* USER CODE BEGIN USART3_IRQn 0 */

  /* USER CODE END USART3_IRQn 0 */
  HAL_UART_IRQHandler(&huart3);
  /* USER CODE BEGIN USART3_IRQn 1 */

if(RX_Char == 'a'){
newLineCount++;

    if(newLineCount == 2){
    // Assign the buffered values to the setpoints
        baseSetPoint = baseBuffer;
        tiltSetPoint = tiltBuffer;

        // Reset the buffers
        baseBuffer = 0;
        tiltBuffer = 0;
        newLineCount = 0;
    }
}else if(RX_Char >= '0' && RX_Char <= '9'){
    // Convert character to digit
int currDigit = RX_Char - '0';
    if(newLineCount == 0) {
    // Update base buffer
        baseBuffer = baseBuffer * 10 + currDigit;
    }else{
    // Update tilt buffer
        tiltBuffer = tiltBuffer * 10 + currDigit;
    }
}
//Ignore other characters
  /* USER CODE END USART3_IRQn 1 */
}

Now here's the problem, this setup works perfectly when I connect to the STM32 using a Teraterm terminal, but when i send the serial data from a python script, it doesn't seem to work. It seems that the teraterm terminal is setup to follow each character with a CR (I am not quite sure about this, the setup tab has dropdown menus for transmit and receive, both of which have CR selected), so i tried following each character with '\r' in python, and also sending them with small delays because I thought maybe the stm32 didn't have enough time to register the character (Might've been a stretch given im running on 72Mhz but im new to this so im not sure).

Code: [Select]
ser = serial.Serial(
    port='COM12',  # Replace with your actual COM port
    baudrate=9600,
    parity=serial.PARITY_NONE,
    stopbits=serial.STOPBITS_ONE,
    bytesize=serial.EIGHTBITS,
    timeout=1
)

dataString = "2000a400a"
for char in dataString:
     ser.write((char + '\r').encode('utf-8'))
     time.sleep(0.01)

these are the relevant lines of code.

Question: How do I configure my python script to send the serial data that the stm32 can understand, just as it can understand it when I send it the data from my teraterm terminal, what am I doing wrong?

Note: I can read the data coming from the STM32 in python just fine, it's only the sending that is the problem.

Thanks in advance. :) |O
« Last Edit: September 05, 2024, 10:46:14 am by AlwaysAbia »
 

Offline pcprogrammer

  • Super Contributor
  • ***
  • Posts: 4249
  • Country: nl
Re: Python -> USB2TTL -> STM32 UART Serial Communication
« Reply #1 on: September 05, 2024, 10:43:26 am »
Please use the code button to separate the code lines from the post. It will make things better readable for us.


Online thephil

  • Regular Contributor
  • *
  • Posts: 85
  • Country: de
    • Techbotch
Re: Python -> USB2TTL -> STM32 UART Serial Communication
« Reply #2 on: September 05, 2024, 01:49:30 pm »
I had a look at your code:

Code: [Select]
dataString = "2000a400a"
for char in dataString:
     ser.write((char + '\r').encode('utf-8'))
     time.sleep(0.01)

A few guesses:

Is there a reason, you are sending the data string char by char? I would have guessed you need to send the entire string at once and then add the \r at the end. But, of course that will depend on what the receiving side expects.

The receiver may expect something else than \r as a line terminator – e.g. \n or \r\n. So you could play with that.

Are you sure your device can handle utf-8? Most embedded things I have played with only supported ASCII. (although that would not matter for the specific string you provided.)

Is the data supposed to be hexadecimal, by any chance? In that case you would have to convert to bytes and send that.



EDIT:

Ah - just realized you also control the receiver code (although I didn't read it thoroughly, yet). I think the easiest way would be to stick to a conventional \r instead of the letter 'a' on both sides. Otherwise you need to deal with both the CR and the 'a' on the receiver side.
« Last Edit: September 05, 2024, 02:16:16 pm by thephil »
It's never too late for a happy childhood!
 
The following users thanked this post: AlwaysAbia

Online Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6788
  • Country: fi
    • My home page and email address
Re: Python -> USB2TTL -> STM32 UART Serial Communication
« Reply #3 on: September 05, 2024, 07:22:19 pm »
I would recommend using pattern

    ser.write(b'2000a400a')
    ser.flush()

i.e. use bytes and not strings, and to ensure the message is sent to the device and not buffered, do a flush() after each complete message or request.  For example, to send a single (signed) integer followed by the 'a' separator, I'd recommend using

    ser.write(b'%da' % value)
    ser.flush()

(Because of poor quality implementation of Python serial libraries for POSIXy systems (namely, poor error checking and ubiquitous assumptions of "short writes and reads never occur"), I prefer to use termios instead; but obviously, termios isn't available on Windows.)
« Last Edit: September 05, 2024, 07:24:06 pm by Nominal Animal »
 
The following users thanked this post: Smokey, AlwaysAbia

Offline AlwaysAbiaTopic starter

  • Newbie
  • Posts: 8
  • Country: ge
Re: Python -> USB2TTL -> STM32 UART Serial Communication
« Reply #4 on: September 08, 2024, 12:04:59 pm »
Code: [Select]
dat = "abcabca"
ser.write(dat.encode())
ser.flush()

I got it working, in the end I used the pattern above, although the main problem was on the STM32 side, the way I was trying to receive data was wrong, so I corrected it and then I moved to using DMA instead of interrupts.

thanks to everyone who replied.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf