User avatar
joan
Posts: 15844
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: C language program reading UART loses characters

Tue Feb 02, 2016 6:17 pm

You can configure the speed of the UART with stty.

E.g. to set 9600 bps

stty -F /dev/ttyAMA0 9600

You can then view the received characters with the cat command, e.g.

cat /dev/ttyAMA0 # if text

or

cat /dev/ttyAMA0 | od -x # if binary

Does this simple test show what you expect? If it doesn't you might need to reset the serial settings if you have set them to a odd state.

User avatar
gordon@drogon.net
Posts: 2023
Joined: Tue Feb 07, 2012 2:14 pm
Location: Devon, UK
Contact: Website Twitter

Re: C language program reading UART loses characters

Tue Feb 02, 2016 7:22 pm

I've had a look and can't see what sort of data you are expecting from the sensor (I may have missed it), however if it's all non-printing data then its possible that minicom and screen simply won't display it.

The input buffer inside the kernel in (I think) 256 bytes for an open serial port, so you really shouldn't be losing any data.

A different approach might be to use someone elses library of serial stuff and just write the bare-minimal of test programs.

Try this:

Code: Select all

#include <stdio.h>
#include <string.h>
#include <errno.h>

#include <wiringSerial.h>

int main ()
{
  int fd ;
  int c, i ;

  if ((fd = serialOpen ("/dev/ttyAMA0", 115200)) < 0)
  {
    fprintf (stderr, "Unable to open serial device: %s\n", strerror (errno)) ;
    return 1 ;
  }

  for (i = 0 ;;)
  {
    c = serialGetchar (fd) ;
    if (c == -1)
      printf ("<timeout>\n") ;
    else
      printf (" %2X", c) ;

    if (++i == 16)
    {
      i = 0 ;
      printf ("\n") ;
    }
  }
}
To compile you'll need wiringPi installed which contains my dumbed-down serial code:

Code: Select all

gcc -Wall -o test test.c -lwiringPi
run it:

Code: Select all

./test
and see what happens...

One thing to note: my serialGetchar() will time-out after 10 seconds and return -1 so with nothing connected then every 10 seconds it will print the timeout message.

-Gordon
--
Gordons projects: https://projects.drogon.net/

danjperron
Posts: 3903
Joined: Thu Dec 27, 2012 4:05 am
Location: Québec, Canada

Re: C language program reading UART loses characters

Tue Feb 02, 2016 7:58 pm

This is my code to check my gps data output.

Like Gordon said, use another's one code the check.

Mine use the same method but I convert the i/o handle into stream. This way I could use fgets to grab the full line which ends by a '\n' (new line).

I modified the code to get ridd of the line checking.The thing that you complain about my post. This way it should print out the line it receives.

Code: Select all

cd
wget https://dl.dropboxusercontent.com/u/48891705/rpi/misc/readGPS.c
gcc -lpthread -o readGPS readGPS.c
It is set to 9600 baud.

Entropia
Posts: 13
Joined: Mon Feb 01, 2016 2:11 pm

Re: C language program reading UART loses characters

Tue Feb 02, 2016 8:31 pm

Thanks guys. I will test tomorrow and report back!

User avatar
jojopi
Posts: 3586
Joined: Tue Oct 11, 2011 8:38 pm

Re: C language program reading UART loses characters

Tue Feb 02, 2016 9:18 pm

Entropia wrote:How can I check if any other process is accessing the port?

Code: Select all

sudo apt-get install lsof
sudo lsof /dev/ttyAMA0
If you see "agetty" in the results, that is definitely your problem.

(When multiple processes are reading simultaneously from the same terminal device, the kernel allocates the bytes to whichever reader is scheduled next. agetty wants to read one byte at a time, because it is expecting a human to log in. Your program wants to read up to 255 bytes. I believe the UART FIFO is 16 bytes and the hardware is programmed to interrupt the OS when it is half full. Therefore it is quite plausible that agetty will tend to consume the first byte and you will get the other seven.)

Entropia
Posts: 13
Joined: Mon Feb 01, 2016 2:11 pm

Re: C language program reading UART loses characters

Wed Feb 03, 2016 7:14 am

jojopi wrote:
Entropia wrote:How can I check if any other process is accessing the port?

Code: Select all

sudo apt-get install lsof
sudo lsof /dev/ttyAMA0
If you see "agetty" in the results, that is definitely your problem.

(When multiple processes are reading simultaneously from the same terminal device, the kernel allocates the bytes to whichever reader is scheduled next. agetty wants to read one byte at a time, because it is expecting a human to log in. Your program wants to read up to 255 bytes. I believe the UART FIFO is 16 bytes and the hardware is programmed to interrupt the OS when it is half full. Therefore it is quite plausible that agetty will tend to consume the first byte and you will get the other seven.)
lsof gives me the following output:

Code: Select all

COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
getty   3288 root    0u   CHR 204,64      0t0 1026 /dev/ttyAMA0
getty   3288 root    1u   CHR 204,64      0t0 1026 /dev/ttyAMA0
getty   3288 root    2u   CHR 204,64      0t0 1026 /dev/ttyAMA0
test    4041 root    3u   CHR 204,64      0t0 1026 /dev/ttyAMA0
test is my own program. Is getty comparable to agetty? I tried to kill process 3288 but it hung up the UART entirely and the system restarted the three gettys again (PID changed though).

User avatar
gordon@drogon.net
Posts: 2023
Joined: Tue Feb 07, 2012 2:14 pm
Location: Devon, UK
Contact: Website Twitter

Re: C language program reading UART loses characters

Wed Feb 03, 2016 7:38 am

Entropia wrote:

Code: Select all

COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
getty   3288 root    0u   CHR 204,64      0t0 1026 /dev/ttyAMA0
getty   3288 root    1u   CHR 204,64      0t0 1026 /dev/ttyAMA0
getty   3288 root    2u   CHR 204,64      0t0 1026 /dev/ttyAMA0
test    4041 root    3u   CHR 204,64      0t0 1026 /dev/ttyAMA0
test is my own program. Is getty comparable to agetty? I tried to kill process 3288 but it hung up the UART entirely and the system restarted the three gettys again (PID changed though).
Ah.
You need to disable it in inittab. Run sudo raspi-config and go through the options to disable it.

-Gordon
--
Gordons projects: https://projects.drogon.net/

Entropia
Posts: 13
Joined: Mon Feb 01, 2016 2:11 pm

Re: C language program reading UART loses characters

Wed Feb 03, 2016 7:44 am

gordon@drogon.net wrote:
Entropia wrote:

Code: Select all

COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
getty   3288 root    0u   CHR 204,64      0t0 1026 /dev/ttyAMA0
getty   3288 root    1u   CHR 204,64      0t0 1026 /dev/ttyAMA0
getty   3288 root    2u   CHR 204,64      0t0 1026 /dev/ttyAMA0
test    4041 root    3u   CHR 204,64      0t0 1026 /dev/ttyAMA0
test is my own program. Is getty comparable to agetty? I tried to kill process 3288 but it hung up the UART entirely and the system restarted the three gettys again (PID changed though).
Ah.
You need to disable it in inittab. Run sudo raspi-config and go through the options to disable it.

-Gordon
Yes, just found this out too by googling. I manually edited /etc/inittab and removed the getty respawning. PROBLEM SOLVED! I still get the incoming message in blocks of eight bytes but this not a problem. No more dropped bytes!

So, PeterO was right. :-) Also, the tutorial link in my original posting has incomplete information. I should probably inform them and save other people the trouble.

I'd like to say a big thank you to everyone who contributed! I would have given up real fast without help.

User avatar
rurwin
Forum Moderator
Forum Moderator
Posts: 4257
Joined: Mon Jan 09, 2012 3:16 pm
Contact: Website

Re: C language program reading UART loses characters

Wed Feb 03, 2016 8:41 am

The tutorial does say (in greyed-out text):
You also need to edit this file <<This is no longer present with Raspbian Jessie:

Code: Select all

sudo nano /etc/inittab
Search for the serial port usage by using CTRL+W and typing:

Code: Select all

ttyAMA0
This should find the line of the file specifying the serial port (if there is one). Use "#" at the start of the line to comment it out. Then press CTRL+X to save and exit.
On my Jessie system lsof does list the same three entries that you see, but they are agetty, not getty. In fact I don't have an /etc/inittab file at all. I just tried it, and editing cmdline.txt is all I need to do to stop the agetty's appearing.

I surmise that you are using Raspbian Wheezy. Reading back, that is the one question we didn't ask. One to remember for next time. It might be good too if the tutorial was a litle more long-winded in explaining when that step is necessary and didn't grey it out until Jessie was more mainstream.

Entropia
Posts: 13
Joined: Mon Feb 01, 2016 2:11 pm

Re: C language program reading UART loses characters

Wed Feb 03, 2016 8:59 am

Upon closer inspection, yes, I indeed do have Raspbian Wheezy. D'oh.

User avatar
gordon@drogon.net
Posts: 2023
Joined: Tue Feb 07, 2012 2:14 pm
Location: Devon, UK
Contact: Website Twitter

Re: C language program reading UART loses characters

Wed Feb 03, 2016 9:56 am

Entropia wrote:Upon closer inspection, yes, I indeed do have Raspbian Wheezy. D'oh.
Wheezy is fine. Nothing wrong with it. I'm still using it and plan to keep on using it for some time yet.

-Gordon
--
Gordons projects: https://projects.drogon.net/

User avatar
PeterO
Posts: 6095
Joined: Sun Jul 22, 2012 4:14 pm

Re: C language program reading UART loses characters

Wed Feb 03, 2016 10:41 am

viewtopic.php?f=33&t=134752#p897774 Smug Grin :D
I'd like to say a big thank you to everyone who contributed! I would have given up real fast without help.
That's what we're here for 8-)
PeterO
Discoverer of the PI2 XENON DEATH FLASH!
Interests: C,Python,PIC,Electronics,Ham Radio (G0DZB),1960s British Computers.
"The primary requirement (as we've always seen in your examples) is that the code is readable. " Dougie Lawson

Return to “C/C++”