-1

I'm trying to read and send data with a STM32F429ZI using a RS232-USB cable.

For the hardware, I'm using a RS232 DB9 to TTL MAX3232 converter connected to the UART2 ports PA2 and PA3 of the STM32. I don't know if this is relevant, but I'm using a couple of 10 cm long cables to connect the TX-RX of the RS232 module to the STM32.

Then, I'm trying to use the Linux terminal on Kubuntu to send and read data from the uC. These are the steps I'm following to configure the connection:

  • Using ls -lah /dev/ I look where the RS232-USB is connected. In my case, I can see that it connects to /dev/ttyUSB0.
  • Then I give my user permissions to read and write the USB port using sudo chmod o+rw /dev/ttyUSB0.
  • After that, I configure the baud rate of the connection with the stty command. In my case, I'm configuring the STM32 to work at 9600 bauds per second, so stty -F /dev/ttyUSB0 9600. Using stty -F /dev/ttyUSB0 -a, I can see that the speed is actually 9600 bauds per second.

So far so good. I can send data from my computer to the STM32 with no problems. To test this, I'm doing the following:

  • I have a 2x16 LCD display connected to the STM32, where I print the data I send from my computer.
  • To send data from the terminal, I'm just doing echo -n 'a' > /dev/ttyUSB. This seems to work just fine, as I can print the data in the LCD display correctly.
  • I have even tested a program to count the characters on a file and the time the operations takes, in order to corroborate the 9600 baud rate. To do this, I created a file with 9600 characters and I used cat test.txt | tr '\n' '#' > /dev/ttyUSB0 to send the file to the STM32. This is working mostly fine, I usually get the correct answer but other times I don't. Nonetheless, the times it doesn't work are quite low, so I'm assuming it is due to noise.

So, having tested I can actually send data from my computer to the STM32, I tried to do the opposite: to send data from the STM32 to my computer. But this doesn't seem to work, as I can't really read anything in my computer.

I have read in several forums that to read data from the serial on the Linux console, one just has to use the cat command on the device. So, I tried that in several ways but I just couldn't read anything:

  • cat /dev/ttyUSB0 shows nothing and I have to quit with Ctrl+C.
  • cat -v /dev/ttyUSB0 shows nothing and I have to quit with Ctrl+C.
  • cat < /dev/ttyUSB0 shows nothing and I have to quit with Ctrl+C.
  • cat /dev/ttyUSB0 & just shows a number and it finishes.

So, I don't know if I'm just using the cat command wrong or if it is a hardware problem or why I can send data from my computer but not read.

Here is the part of the program (in C) I'm using in the STM32 to read and send data:

while(1)
    {
        if (USART_GetFlagStatus(USART2, USART_FLAG_RXNE) != RESET)
        {
            Data = USART_ReceiveData(USART2);

            while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET)
                USART_SendData(USART2, Data);
        }
    }

If someones needs it, I can upload the configuration of the USART ports, but I don't know if it will be relevant considering I can read data just fine.

Any help is appreciated.

Thanks in advance.

Edit: here's the current project - https://github.com/AugustoRiedinger/06TP_E02 ; and the project to read data https://github.com/AugustoRiedinger/06TP_E01

riedaug
  • 15
  • 6
  • *"Then I give my user permissions to read and write the USB port..."* -- Improper; instead add your username to the group that own that device, e.g. the `dialout` group. *"I configure the baud rate..."* -- You also need to match char size, parity, stop bits, and flow control (aka handshake). You probably need to inspect the serial line signals with an oscilloscope, in order to verify that your MAX3232 is installed correctly – sawdust Oct 12 '21 at 01:49
  • @sawdust How can I perform this handshake? And if I can receive data on the STM32, doesn't that mean that the MAX3232 is properly installed? Or do you think the error might be just on the TX? – riedaug Oct 12 '21 at 02:26
  • There's hardware (e.g. RTS/CTS) and software (XON/XOFF) versions of handshake. You would only use handshake to control throughput; test without any handshake. You presumably didn't implement anything on the STM32; use `stty raw -F /dev/ttyUSB0` for the PC. Receiving does not validate transmission; RS-232 uses independent channels for each direction. Checking with a 'scope is going to be the fastest method of narrowing down possible issues. And for some issues, only a 'scope is going to reveal them. – sawdust Oct 12 '21 at 03:02
  • I would advise that you use something more "interactive" than `cat` for debugging. Several options suggested at https://developer.toradex.com/knowledge-base/serial-terminal-emulator for example. – Clifford Oct 12 '21 at 13:16
  • Have you performed all necessary USART, RCC and GPIO initialisation? – Clifford Oct 12 '21 at 17:03
  • @Clifford I think I have. I haven't posted it in the question because it is pretty much recipe, but you can take a look at it in the GIT project if you want. I initialized the pin PA2 as an USART-TX and that it's pretty much it. Then, I initialized the LCD display and the INT_Handler of TIM3 in order to clear the display, but those are just for testing. – riedaug Oct 12 '21 at 17:39
  • https://stackoverflow.com/questions/48262902/problems-reading-an-echo-with-the-cat-command-in-a-serial-port may answer your remaining issue - though the answer is in a comment and the OP never revealed if it solved the problem. Also https://unix.stackexchange.com/questions/42376/reading-from-serial-from-linux-command-line/42377 may be useful. – Clifford Oct 13 '21 at 09:20

1 Answers1

1

Your loop says "as long as it is not possible to send a byte, repeatedly try to send it anyway, as soon as it is possible to send a byte, discard it without sending"

Change:

       while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET)
            USART_SendData(USART2, Data);

To:

       while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);
       USART_SendData(USART2, Data);
Tom V
  • 4,827
  • 2
  • 5
  • 22
  • I tried this but unfortunately it was no good. On one console, I just sent characters to the STM with `echo -n 'a' > /dev/ttyUSB0`, and those characters were stored on the `Data` variable defined just as `char Data;`. Then, I printed `Data` on a display and it was just fine, the chars were correctly recognized by the STM. On another console, I just had `cat /dev/ttyUSB0` and then `cat < /dev/ttyUSB0`, but couldn't see the chars on `Data`. I even tried on the main loop `while(1){USART_SendData(USART2, Data);}` but couldn't see anything in the console either with `cat /dev/ttyUSB0`. – riedaug Oct 12 '21 at 12:55
  • Or preferably `while(...)` NEW LINE then (indented) `;` or `{}` so that the code turns self-documenting - the semicolon or `{}` was added there on purpose and we can rule out a possibly accidental semicolon. Good compilers warn against sloppy one-liner loops. – Lundin Oct 12 '21 at 12:55
  • @Lundin do you mean something like this [Screenshot](https://imgur.com/a/hmQ4H4s)? I'm using Atollic TRUE Studio to debug the STM. – riedaug Oct 12 '21 at 13:09
  • @riedaug : It is incorrect to suggest this change is "no good". If after correcting the code as suggested it _still_ does not work, then clearly you have more than one problem. Apply appropriate debug techniques to verify first that the code that receives and transmits the character is actually executed. Then verify there is a signal on data lines at the appropriate baud rate. Verify you have connected Rx/Tx appropriately (Null Modem connection). Another possibility is that the terminal is line-buffered so nothing is input or output until . – Clifford Oct 12 '21 at 13:11
  • @riedaug Yes that's proper style. – Lundin Oct 12 '21 at 13:13
  • @riedaug : That is exactly what he means, but that is just good advice, not a solution to your problem. – Clifford Oct 12 '21 at 13:13
  • Also, some 90% of all UART problems come from mixing up rx and tx signals. Missing signal ground is another common one. – Lundin Oct 12 '21 at 13:14
  • @Clifford You are right, it's incorrect to suggest that the change is no good. I think that the problem might be on the Linux console. What do you mean that the terminal is line-buffered? For what is worth, I have to use `-n` whenever I send data to the STM with the command `echo`, which means `-n: do not output the trailing newline`. I don't use `echo -n` when sending data, I can't read anything on the STM. So, maybe I have to do something like that with the `cat` command? – riedaug Oct 12 '21 at 14:31
  • @Lundin I have verified that the RX and TX are connected properly. PA3 (where the RX is connected) is next to PA2 (where the TX is connected), and those are the only two connections I have on that CN. Then, the RS232 module is grounded to the STM. I don't have access to an oscilloscope, as universities are still closed on my country, but I tried to measure the output with a voltmeter and I can read 3.3V on the TX (the program is constantly sending data). I updated the question with an edit to the full project. – riedaug Oct 12 '21 at 14:36
  • If all you have is a voltmeter then I suggest sending characters with lots of zeros repeatedly and see if you can read a lower voltage. eg: send '\0' in a loop without reading. If you can't detect this then there is probably something wrong with your UART or GPIO configuration. – Tom V Oct 12 '21 at 14:58
  • To configure the port I suggest you use a terminal emulator such as putty which gives you clear access to all the settings that you may need to configure. Once you have got it working in putty then if you are still desperate to use command line tools then you can use stty to read back the configuration that putty has made. – Tom V Oct 12 '21 at 14:58
  • @riedaug You may have missed the point about the connection. The Rx of the STM32 needs to be connected to the TX of the PC and vice versa. You have not made it clear that that is the case. In this scenario both ends are DTE, no a null-modem connection is required. – Clifford Oct 12 '21 at 15:16
  • @TomV Ok, I tested sending just `/0` in a loop, and I can read a drop to 0.31V in the voltage of the TX pin, in comparison to the 3.3V I had when sending an `a`. And I actually used a terminal emulator, picocom, and I can now see things in the console! I'm not doing much crazy things with picocom, just `picocom -b 9600 /dev/ttyUSB0` and it shows me what I want to see. So, I don't get why can't I do the same with the `cat` command. Here is a [screenshot](https://imgur.com/a/IazBofb) of the configuration picocom shows at the start. – riedaug Oct 12 '21 at 16:48
  • @Clifford [This](https://imgur.com/a/PcXlUNj) is a picture of the RS232 module I'm using. I have the RX of the module connected to an USART-RX pin of the STM (PA3), and the TX of the module to an USART-TX pin PA2. – riedaug Oct 12 '21 at 16:51
  • @riedaug I was asking about the end-to-end connection (actually I an not asking, U am just pointing out the many ways other than the code that it could be wrong). The DCE connection to the transceiver is correct as you describe it. But if your hardware is at fault, it is not a question for SO in any case. Currently you have too many unknowns. You need a more methodical approach. Not your Tx being at the high logic level suggests there is no data. The meter will average the signal to something between high and low. The presence of a start bit alone will will reduce the average. – Clifford Oct 12 '21 at 17:01
  • @Clifford I see. I assumed that the end-to-end connection was correct, as the module should take care of that, but I will look for a way to test this. Using `picocom -b 9600 /dev/ttyUSB0` I can see the things I send from the STM to my computer. So, doesn't that rule out a hardware-problem? I just can't see anything using the `cat` command. The configuration `picocom` shows is in [this](https://imgur.com/a/IazBofb) screenshot. – riedaug Oct 12 '21 at 17:18
  • 1
    @riedaug I think if the voltage is changing and you can see things on picocom then the original question is solved based on the change I suggested to your code in the answer above. If you agree can you please accept the answer with the tick mark on the left. If you want to ask what cat does not do that picocom does then that should be a separate new question, not in comments on an answer. – Tom V Oct 12 '21 at 18:55
  • @riedaug If picocom works and cat does not, then clearly that is now a different question - and not an [embedded] code issue. SO is not a discussion forum; Tom V's answer is now overloaded with discussion. You need to post a new and different question to solve the next problem. – Clifford Oct 13 '21 at 09:08