WiringPi includes a simplified serial port handling library. It can use the on-board serial port, or any USB serial device with no special distinctions between them. You just specify the device name in the initial open function.
To use, you need to make sure your program includes the following file:
#include <wiringSerial.h>
Then the following functions are available:
- int serialOpen (char *device, int baud) ;
This opens and initialises the serial device and sets the baud rate. It sets the port into “raw” mode (character at a time and no translations), and sets the read timeout to 10 seconds. The return value is the file descriptor or -1 for any error, in which case errno will be set as appropriate.
- void serialClose (int fd) ;
Closes the device identified by the file descriptor given.
- void serialPutchar (int fd, unsigned char c) ;
Sends the single byte to the serial device identified by the given file descriptor.
- void serialPuts (int fd, char *s) ;
Sends the nul-terminated string to the serial device identified by the given file descriptor.
- void serialPrintf (int fd, char *message, …) ;
Emulates the system printf function to the serial device.
- int serialDataAvail (int fd) ;
Returns the number of characters available for reading, or -1 for any error condition, in which case errno will be set appropriately.
- int serialGetchar (int fd) ;
Returns the next character available on the serial device. This call will block for up to 10 seconds if no data is available (when it will return -1)
- void serialFlush (int fd) ;
This discards all data received, or waiting to be send down the given device.
Note: The file descriptor (fd) returned is a standard Linux file descriptor. You can use the standard read(), write(), etc. system calls on this file descriptor as required. E.g. you may wish to write a larger block of binary data where the serialPutchar() or serialPuts() function may not be the most appropriate function to use, in which case, you can use write() to send the data.
Advanced Serial Port Control
The wiringSerial library is intended to provide simplified control – suitable for most applications, however if you need advanced control – e.g. parity control, modem control lines (via a USB adapter, there are none on the Pi’s on-board UART!) and so on, then you need to do some of this the “old fashioned” way.
For example – To set the serial line into 7 bit mode plus even parity, you need to do this…
In your program:
#include <termios.h>
and in a function:
struct termios options ; tcgetattr (fd, &options) ; // Read current options options.c_cflag &= ~CSIZE ; // Mask out size options.c_cflag |= CS7 ; // Or in 7-bits options.c_cflag |= PARENB ; // Enable Parity - even by default tcsetattr (fd, &options) ; // Set new options
The ‘fd’ variable above is the file descriptor that serialOpen() returns.
Please see the man page for tcgetattr for all the options that you can set.
man tcgetattr
Dear Gordon
First of all I have to thank for all your work to build wiring libraries
I am very interested in using wiringSerial library becase I want to communicate with several devices like: GPS, Xbee transceivers, etc
I have downloaded and installed succesfully this library but when I don´t know how to open uart:
serialOpen(*char_device, int baud)
What is char_device that indentifies uart?
I removed serial console following this tutorial: http://www.irrational.net/2012/04/19/using-the-raspberry-pis-serial-port/
Thanks in advance and regards.
A very quick example:
handle = serialOpen ("/dev/ttyAMA0", 115200) ;
that will open the on-board serial port. It you want to talk to a USB serial, then you need to identify its device – usually /dev/ttyUSB0 or /dev/ttyACM0, and use that in the open call:
handle = serialOpen ("/dev/ttyUSB0", 9600) ;
for example.
Then you can use
handle
in subsequent calls – e.g.data = serialGetchar (handle) ;
and so on.
Hope this helps.
-Gordon
Hello Gordon.
Thanks. Now works fine, and I can read serial port without problem.
Regards
Hi,
I am trying to do like you said about serialOpen but that’s not working. I just want to comunicate with my xbee wich is into my rasp and I have many errors when I am builind the program (excuse me for my bad english, I am French).
I have started to do an initialisation with Setup, then I want to do serial open with the baude 57600 (best speed for my two xbees).
I continue with a while contening a serialgetchar then my programm.
I just want to switch on a Led link to the rasp, from my computer through the xbee.
Thank you in advance
Schaad Julie
PS : My xbee is not connected by the USB com of the Rasp but with a module add in the GPIOs. So, I have starded to code with GPIOs, with digitialRead(16) but that’s not working neither…
I have just find the problem. The driver wasn’t in my rasp. By con, now it is the reading that not working XD
Hi Gordon,
How can I select a specific usb port with whom I would like to communicate.
Cause the two ports are used: in the first port, I used to connect a usb Camera and in the other port I used to connect another peripheral with whom I would like to communicate.
How can I do that ?!
Regards
The USB serial ports are usually /dev/ttyUSB0, /dev/ttyUSB1, etc. or sometimes /dev/ttyACM0, etc. however they’ll be in a different order if you plug them in in a different order, so what you can additionally do is look in /dev/serial/by-id/ and look for the links of the names to the devices – these names should be unique for each device and should always point to the relevant /dev/ttyUSBx device, so you need to identify this name and use that in your programs.
(I think this is what you’re after, anyway)
e.g. on a PC I’m using (not a Pi, but it’s running Debian, so still the same):
lrwxrwxrwx 1 root root 13 Dec 2 09:23 usb-FTDI_FT232R_USB_UART_A1012650-if00-port0 -> ../../ttyUSB1
lrwxrwxrwx 1 root root 13 Dec 2 09:23 usb-FTDI_FT232R_USB_UART_A10126Z6-if00-port0 -> ../../ttyUSB0
In my programs, I use /dev/serial/by-id/usb-FTDI_FT232R_USB_UART_A1012650-if00-port0 which I know is a particular device (these are usb power controllers that look like serial ports), but when this PC reboots sometimes the actual /dev/ttyUSB entry changes, but by using the /dev/serial name I always get the right on.
-Gordon
Hi Gorden,
first i also have to thank you for your great work. Is there a possibility to define the port more specific (i need a parity bit 🙁 )
I’ll put it on the ‘to do’ list!
-Gordon
hi,
I have a short question. When I send a string to serial port, it always starts with F8. For example:
serialPrintf(handle, “this is a test stream\n”);
the result on serial buffor is:
F8 74 68 69 73 20 69 73 20 …
t h i s i s …
Why F8 is added at the beginning of the stream?
thanks
I’m scratching my head… I’m as surprised to see this as you are. I’ve used my own libraries to exchange data with an Arduino in the past, but maybe I need to hook something else up to it to double check.
Have you checked with other functions – e.g. using serialPutchar () for every character in the message?
-Gordon
Thanks for your reply.
It only happens when baudrate is set to 115200; it works well on 9600bps (!)
I also get the same problem on my RPi. It is ok at 9600 but at faster speeds the file open command generates one or two spurious characters. It does the same on a USB serial device as well as ttyAMA0.
Same to mee with 115200.
Any idea?
Dear Gordon,
thanks for this library.
I use a TTL-232R-RPI cable of FTDI to communicate between Raspberry and my windows computer. But i have a problem, the computer receive the information send by the Raspberry, but the Raspberry not Receive the information by the PC.
Please help me in my problem.
Thank you and Regards.
I’d start by making sure the link is working – if you’ve not done this already… You can use minicom on the Pi side and something like hyperterm on the PC side – then just type characters at each end to make sure you can get data going both ways…
Once you’re sure that’s working, then we can look deeper..
-Gordon
Dear Filk,
I’m using the same hardware (TTL-232R-RPI cable of FTDI)as you did and I’ve got the same problem:
RPi —–> PC is ok,
RPi <—– PC fails.
Can you please let me know, how you solved your problem – if you had?
Regards and thanks in advance!
Ralph
Hi, could you send us a little example of stream receive by serial ? thx
Have a look at: serialRead.c
-Gordon
Hi Gordon
i am just start with PI, how I can compile your source code serialRead.c
and make an executable program.
best regards
You should be able to simply:
cd examples
make serialRead
and that’ll compile it.
If you want to compile ‘by hand’, then:
cc -o serialRead serialRead.c -lwiringPi
ought to do it.
-Gordon
Hi Gordon. I tried a simple program but it is not as expected. I connected the RX and TX header together just for testing this program:
int fid = serialOpen(“/dev/ttyAMA0”,9600);
serialPutchar(fid, ‘k’);
printf(“%d\n”,serialGetchar(fid));
But the outcome is always -1. Help?
A quick thought – do you have permissions to access the serial port? try running it as root – sudo ./test …
-Gordon
Worked! Is it because serialOpen requires root access? Thanks!
You can use it without sudo if you add yourself into the dialout group. either edit /etc/group, or use the usermod command. (and logout/login again)
-Gordon
does not worked for me!!! i’m executing with sudo but still always i get -1
You’re going to have to give me more information that that I’m afraid.
-Gordon
I connected the pins TX and RX on the same raspberry to test it.
then the code is:
#include
#include
#include
#include
#include
#include “global.h”
#include “main.h”
using namespace std;
/*
*
*/
int main() {
int fd;
if ((fd = serialOpen(device, 9600))<0) {
fprintf(stderr, "unable to open serial device");
return 1;
}
if (wiringPiSetup () == -1)
{
fprintf (stdout, "Unable to start wiringPi: %s\n", strerror (errno)) ;
return 1 ;
}
serialPutchar(fd, 'k');
fprintf(stdout, "%d\n", serialGetchar(fd));
serialClose(fd);
}
Its cpp because i want to use it inside a c++ script.
I compiled with the comand : g++ -o main maincpp -lwiringPi -lpthread
And always i'm getting -1
Thanks in advance!!!
Ok – still need more information – e.g. where is it returning -1? Is it the serialOpen() or the wiringPiSetup()
I really can’t tell.
However, you’ve not declared ‘device’ anywhere?
Or is it in global.h or main.h ?
If so, then what is it set to?
-Gordon
i don’t know how to comment after my previous comment, sorry.
Anyway, i missed to remove the serial console. Now is fine!!! Thanks a lot for your contribution :-).
Glad it’s going now.
-Gordon
Hi..
am trying to create a program of image processing. am actually using ubuntu as OS, eclipse as IDE and c++ as programming langage.
Unfortunately, I can’t find a pratic method that allows me to access to the GPIO of my raspberry Pi.
please i need your help as soon as possible.
Not sure how you are running Ubuntu on the Pi – I didn’t realise they had a release for it. Sure you’re not running Raspbian?
However, wiringPi is writtne in C and runs under C++ without any issues. You just need to work out how to link it in using Eclipse – which I’ve never used, so I really can’t help you there.
-Gordon
thanks for the attention Mr Gordon.
in fact, i am using ubuntu in my PC in order to develop the application, and then implement it in the raspberry wich is turning under Raspbian.
so please can you send me the download link of the library “wiringSerial.h” and if you don’t mind, would you stand by me and help me to fulfill my project?
Just download wiringPi as normal (using GIT) and it will include the wiringSerial library.
-Gordon
hi
when i call serialGetchar it allways waits 10s and return -1 another functions works
i can send data from /dev/ttyAMA0 to my serial terminal but it don’t recieve any byte
i am sending it with 1 stop bit 8 bits and no parity
i just call your function and write result on display
Yes, it will wait 10 seconds then return -1 if there are no characters recieved. It’s meant to do that. If you need to wait a long time, then just put it in a loop.
I’d suggest there might be a connectivity problem though. Use mincom on the Pi to check the connection to the remote end.
-Gordon
i know that waits only 10s
if i short tx and rx together after max232 converter it works (in minicon) and i just used resistor divider to convert it into 3v3 logic
it is connected like this http://img846.imageshack.us/img846/173/rpi.png
and if i short Tx and Rx on gpio it dont work
If I have time today I’ll put together some simple serial testing programs.
-Gordon
hi
this was my problem http://www.irrational.net/2012/04/19/using-the-raspberry-pis-serial-port/
Looks like a solution to me, rather than a problem…
Or am I missing something?
-Gordon
hi
why is my last reply still awaiting moderation (for 3 days)?
I do this in my spare time, so when I’m busy, I often skip a message or 2.
-Gordon
yes it is solution because i don’t know how should i call that problem
Ca nyou let me know exactly what state you’re at now please? I’ve really no idea if you have sorted your issues out or not…
-Gordon
it works now but it is little slow
OK, Good. Just slow because of the data rate? 115200 baud is 11K Bytes/sec – slow compared to Ethernet…
-Gordon
i know that waits only 10s
if i short tx and rx together after max232 converter it works (in minicon) and i just used resistor divider to convert it into 3v3 logic
it is connected like this http://img846.imageshack.us/img846/173/rpi.png
Hi Gordon,
Hi Gordon.,
I installed library and copied the first examples with the GPIO. Works great!
I have now tried anzusprechne UART and without success
I compile with the
g++ name.c -o name -l wiringPi
try to do with sudo ./name
Tx and Rx are crossed
Code is
#include
#include
#include
//#include
//#include
#include
int main (void)
{
printf (“Raspberry Pi wiringPi Serial test program\n”) ;
char * Device;
sprintf(Device,”/dev/ttyUSB0″);
int fd = serialOpen(Device, 9600);
if (fd < 0)
{
printf ("Unable to open serial device: %s\n") ;
}
else printf ("serial device is open\n");
serialPutchar(fd, '1');
printf("%d\n",serialGetchar(fd));
serialClose(fd);
return 0 ;
}
Please help!
do you have a some examples as Code?
Thanks a lot
That should work OK. Can you try it with the on-board UARt though? usr /dev/ttyAMA0 and jumper the Tx & Rx on the gPIO connector?
I’ll post some loopback-test code later today.
-Gordon
I’ll be putting this in the next release of wiringPi, but for anyone who wants it:
wget http://unicorn.drogon.net/serialTest.c
and compile it with the usual:
cc -o serialTest serialTest.c -lwiringPi
and run it with:
sudo ./serialTest
You’ll need to loop-back the serial port before running it.
When running, it will output bytes to the port and read them back in again. If you get nothing in, then you have a problem (probably).
to make it work on a USB serial port, just edit the file and change the device definition.
-Gordon
Hi Gordon,
I have faced some strange things using current release of WiringPi which are probable bugs.
Common conditions: RaspberryPi B 256MB rev. 1, with lastest Raspbian.
1) Mystical 0xFF
Conditions: Default configuration at 115200, etc. Serial terminal is disabled. RX wired to TX with a short (10cm) wire.
Symptoms: When I access serial port with wiringPi, it occasionaly (per several seconds) reads 0xFF byte from the port. I’m sure I send nothing.
2) serialDataAvail() always returns 0
Conditions: the same.
Symptoms: Also serialDataAvail() always returns zero, no matter what’s on input. Even if I perform {a1 = serialDataAvail(); b = serialGetchar(fd); a2 = serialDataAvail();} and read actual data into b, a1 and a2 are 0.
3) delayMicroseconds() doesn’t work
Conditions: the same.
Symptoms: The functions does nothing. Ex, delayMicroseconds(1000000L); should cause one second delay. But doesn’t. However, delay() works.
Regards, Ilya
Sorry, at 2) wiringPi actually returns -1, and it is not a bug.
at 2-) serialDataAvail(fd) command always returns 0 .I searched everything but ı cant find anything.Is there anyone who can help for this issue?
0 is false. It means there is no data available.
-Gordon
The Mysical 0xFF (sometimes 0xF1) is (I think) an issue with the SoC’s serial port, or the kernel driver. Hard to tell. I’ve seen it myself and I’m fairly sure there is nothing in my code that’s doing it.
2 – you posted again – it returns true/false – it’ll never block. serialGetchar() will block, but only for 10 seconds. Try looping until serialDataAvail() returns true… and have a look at:
3 – you need to have called wiringPiSetup() before this will work
-Gordon
1 – The Mysical 0xFF doesn’t appear when I open a port “classic” way via open(). So the issue is probably on the wiringPi side?
3 – wiringPiSetup() is being called before. I’m sure.
Regards, Ilya
my serial library does use the “classic” open() way to open the port, however I also do some attribute setting too, but that really shouldn’t have any issues. I will check though – but maybe you can check my code too? It’s not complex at all – and I use the same code in other applicaitons – and have been using it under Linux for many years now with both on-board serial port and USB serial ports, however please check it and make suggestions!
-Gordon
I apologise for I’m not able to perform the tests required for now. If I get opportunity and find something interesting, I will let you know.
Regards, Ilya
Hi Gordon, I have found your wiringPi library like an extension of my arm over the previous few months. (august 2012 i had never written a C program now i have binary counters, serial outputs and other brilliant stuff on my pi) I wanted to add a raspberry pi to a PIC running a serial program. The PIC is set to 9600 8E1.
If i change the ‘termios options’ can i still use the
fd = serialOpen (“/dev/ttyAMA0”, 9600)
and
serialPrintf (int fd, char *message, …)
Thanks
Sure. You use the ‘fd’ returned from serialOpen(), and I’ve been trying to update the documentation recently too, so if you have a look at: https://projects.drogon.net/raspberry-pi/wiringpi/serial-library/ which almost does what you need too.
8E1? That’s an interesting/unusual combination though!
-Gordon
Hi, after a long struggle i managed to init the Bluetoohsystem on the PI and read some stuff from a Bluetooth GPS transmitter. Things regarding the init and receiving via wiringPi serial lib are working. Not very reliable but they work. But the most disappointing situation was when the really simple program could not be run as supposed. Maybe you can help to solve this problem. After reading a line into inData i wanted to compare the “$GPGGA” string. But nothing happens. I tried a lot of things to get something out of the string but no chance.
Here is my program as it is working at the moment:
/*
* gpsRead.c:
* Program to read bytes from Bluetooth GPS receiver
* First call ./reset.sh to activate Bluetooth
*
*/
#include
#include
#include
#include
#include
//—————————————————————————–
char *gpsString; // a string to hold incoming data
char inData[255]; // Allocate some space for the string
char inChar = -1; // Where to store the character read
int spos = 0; //Index into array; where to store the character
//—————————————————————————–
int main (void)
{
int fd ; // Handler
printf (“Raspberry Pi wiringPi GPS program\n”) ;
if (wiringPiSetup () < 0) // Setup wiringPi
return -1 ;
if ((fd = serialOpen ("/dev/rfcomm0", 9600)) < 0)
{
fprintf (stderr, "Unable to open device: %s\n", strerror (errno)) ;
return 1 ;
} else
{
printf("rfcomm0 init ok\n");
}
// Loop, getting and printing characters
for (;;)
{
while (serialDataAvail(fd)) {
inChar = (serialGetchar(fd));
// fprintf(stdout,"%c",inChar);
inData[spos]= inChar;
spos++;
inData[spos]= '';
if (inChar == 13) {
printf("%s",inData);
if (strncmp(inData,"$GPG",4) == 0) {
printf("*********** GPGGA found ************\n\n");
}
spos = 0;
fflush (stdout) ;
} // if (inChare == 13
} // while
} //for
}
WordPress doesn’t like < symbols, so it messes them all up, but I can see what you’re intending…
Firstly, I’d probably split the program and hae a function that reads in the string and a separate function that decodes it. However the first thing to do might be to print out each character as it’s stored into the inData[] array. So – does the line really end with a 13 (CR), or is it 10 (LF)? (does the printf after the compare for 13 print anything?)
If it’s not printing anything at that point (before the strcmp()) then it’s possibly not detecting the end of line correctly?
Anyway, that would be my first line of attack – check each character as its being stored and make sure you see the end of the line. It looks like you’ve already got some of that in, but to double check, print it out as an integer too:
printf (“%c – %d\n”, inChar, inChar) ;
Also you really should have a check in there to make sure you’re not reading in too many characters – just in-case some random garbage comes down the line and exceeds the 256 byte size you’ve allocated for the buffer.
One thing it might be doing is sending characters with partiy – in which case 13 will print out as 13+128 = 141 (for even parity). If that’s the case, then you can simply ignore the parity with something like:
inChar = serialGetchar(fd) & 0x7F ;
-Gordon
It is unbelievable but my mistake was that the line ended up with a 10(LF). As i am working with a Mac i just checked it out with CootTerm switching on the Hex output feature and watching the NMEA string sent from the GPS.
Thanks for your tip. I swill tay in touch since this will not be my last faux pas with wiringPI.
Glad you’re sorted now!
-Gordon
Hello Gordons!I’m really appreciate your nice wrok for a great number of Raspi Fans!And I have a question on using Raspi’s uart fuction:First,where can I get or download your library?Second,in this page I know it’s possible to use Raspi’s on board uart,but if I disable Raspi’s on board uart,I cannot control Raspi by SSH at all,because I haven’t a display so I have to communicate with Raspi by SSH.Can I able Raspi’s uart on the 26 IDE pins and how should I do with your serial library?Thank you and wait for your reply 🙂
wiringPi is avalable here: https://projects.drogon.net/raspberry-pi/wiringpi/download-and-install/ it contains the serial library.
You can use the on-board UART and SSH at the same time. The two are not related in any way.
-Gordon
Thank you,I’ll try 😉
ooops I cant see my program – I’ll cut out the comments and resent
Cheers
There is something wrong with your copy&paste – that program will not compile. Best email it to me.
-Gordon
Hi ive been looking at serialRead.c.
and i have noticed a function(?) i am not familiar with fflush().
From watching your code execute i can see that the code is reading the serial port and outputting the character to the (stdout) in this case the terminal client.
my question is how would i take the input from the serial port and output it to a bit in an Array
i have tried
putchar (serialGetchar (fd)) ;
fflush (F[1]) ;
but i must be missunderstanding the fflush function. thanks
fflush() is used to empty the buffers associated with the filehandle passed into it. When printing to a terminal under Linux, the output is normally buffered up until you print a newline – calling fflush() forces the output to be sent to the terminal immdiately.
If you want to store, then you need to read into a variable – so e.g.
c = serialGetchar (fd) ;
array [pointer] = c ;
putchar (c) ;
fflush (stdout) ;
will so what you need – you’ll need to declare the array and increment the pointer every time round the loop.
-Gordon
Hi Gordon very good library
I have been looking at wiringSerial.c and i saw that the function “serialGetchar” return -1 after 10 seconds. i want to change this time to 1 seconds for example, how do i change the function code?
int serialGetchar (int fd){
uint8_t x;
if (read (fd, &x, 1) !=1) return -1;
return ((int)x) &0xFF;
}
thanks
Rather than change the serialGetchar() code, change the serialOpen() instead. In there, look for the line:
options.c_cc [VTIME] = 100 ; // Ten seconds (100 deciseconds)
into
options.c_cc [VTIME] = 10 ; // One second (10 deciseconds)
-Gordon
thanks
now i have to recompile wiringserial.c or no?
Yes. just type
make
then
sudo make install
which will install your new version.
-Gordon
Hi Gordon
I have a big problem. I must use the function serialPuts to send an hexadecimal string that can have the number 0 within. In this case doesn’t send the entire string but send the character until the null char.
how can i do?
thanks
You need to convert the number into printable representation first, (I guess), so if you need to send the number 65 as hex characters, then it’s 41… (presuming that’s you intention)
So to convert numbers there is the generic sprintf () function, however with wiringSerial, you can just:
serialPrintf (fd, “%02X”, number) ;
and that will send 2 HEX digits down the serial port. Change the formatting to suit the number range.
-Gordon
thanks for answer
however my problem isn’t convert a number in a hexa string but is the nul-terminated character of string for example if i want send FF:00:FF
my string is:
string=”??” and serialPuts sends only “?”
You can’t use puts then. You need to send it character at a time. C strings are NUL terminated, not set by length.
However… If you have the data already in an array and you know its length (you must know it’s length as its now arbitary binary data, not a string!), then use the write() system call.
So to write a (unsiged char) buffer of 3 bytes, 255,0,255, then:
buf [0] = 255 ;
buf [1] = 0 ;
buf [2] = 255 ;
write (fd, buf, 3) ;
will do what you need to do. the ‘fd’ is the usual one returned by serialOpen()
-Gordon
thanks Gordon
now i tried it
hello Gordon~
I have two questions. Please help me~
1. How can I set the baudrate more fast than 230400?
2. How can I check the complete of transmit?
1. You can’t using the standard system. That’s the limit.
2. You need to write a protocol to exchange data with the other end to let it tell you it got the data OK.
-Gordon
Thanks~ Gordon.
Sorry, I have more questions.
Firstly, I explain my system.
My RPI is connected to Dynamixel actuator.
And the actuator uses RS-485 communications.
So, I connected Rx,Tx line to Max3485 IC.
This IC need GPIO to control direction of communication.
So, I want to know the complete of transmit for changing GPIO signal.
These are my new questions.
When I see the ‘termios.h’ file of raspberry pi, there defined the max baudrate is 4000000.
Can’t I set the baudrate to 4000000?
And Can’t I read transmit buffer? or remained transmit data length?
You can try, but I don’t think it will work to go that fast.
I don’t know how to read the transmit buffer – I presume you mean to read it to see how many characters have actually been sent from your last write?
-Gordon
Thank you for your kind. Gordon~
Have a good day~^^
Hi, there? Thank you for your library.
But I got the problem. When I use the “serialRead.c” first some times good, but later, randomly serial connection be crazy! 🙁
Pi gives me “ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ” What happen?
And i can’t send data. On “serialTest.c”, serialPutchar() and serialPuts() are doesn’t work. How do i solve??
I’ve no idea how you solve your issues – there’s just too many things that could be wrong – your program could be wrong, the device your talking to could be wrong, the Pi could be wrong and so on. You’ll have to learn to break down your problem into managable steps and test them one at a time.
But start with the Pi: Have you remove the kernel serial port access in /boot/cmdline.txt and /etc/inittab ? If not, then remove kernel access there.
Next try a simple loop-back test.
Then connect your device, but first try it with minicom before moving onto another program on the Pi.
And so on.
-Gordon
Wow! Thank you~ You are genius. I missed cmdline.txt and inittab.
Thank you again and your translation skill(Because my sloppy english writing skill).
Have a good day.
Hey Gordon!
H-Hey!
Thank you for putting effort and time into the Raspberry Pi, very much appreciated!
Gordon,
Thanks so much for your great Raspi support. I’m using all aspects (wiringPi, I2C, and serial).
I have a question: I’m trying to drive a serial 20×2 LCD. I can send std ASCII characters fine, but need to send various ‘control characters’ such as 0xFE in order to clear the display, move cursors and such, but when I send something other than ASCII, the char gets echoed to stdout and it does not seem to get sent over serial. I have already interfaced to the same LCD using Arduino with no problem.
Any ideas? Thanks again…
Okay, I figured out my problem. The problem was that a global var for the serial fd was not set with the correct value (so it was still just initialized to zero) and therefore the function that was setting the control characters obviously couldn’t send the special data to the LCD.
Anyway, thanks again for wiringPi!
Glad you’re going now!
-Gordon
¿Do you know how to activate the mark parity?
Thanks. 🙂
I’ve replied on the raspberrypi.org forum for this.
-Gordon
Thank you very much,
Right now I’m going to raspberrypi.org. 🙂
Hi Gordon,
I have installed your latest version and have attempted to run your serialTest program. I get absolutely no output from the console. After some debugging I have found that it never finishes opening the serial port. It halts on the first if statement if I do not run with sudo, but I do use sudo, it never passes the if statement. I’m stumped, any ideas what could be wrong?
Thank you
Gordon,
Realized that the problem was the kernel serial console. Working fine now, thank you.
Kyle
If using sudo solves it, then use sudo…
Or make sure the user on the Pi (probaly ‘pi’) is a member of the ‘dialout’ group. See /etc/group (and edit it if needed)
-Gordon
Hi Gordon,
Many thanks for the amazing work on the WiringPi library. Its been incredibly useful!
I was hoping you can help me on one issue: I got the serial communication working just fine by compiling/running your example SerialRead code with a buadrate of 9600. However, it fails to run (error: unable to open serial device) when I set the BaudRate to 4800 and recompile/run (4800 is required for the peripheral Im trying to connect to eventually). Any thoughts on why Im getting this error or how to make it work?
Thanks!
Looks like I’ve accidentally left the 4800 baud definition out of the setup code. If you edit the wiringSerial.c file inside wiringPi, search for 9600, you’ll see what to do – just copy & paste the 9600 line and change it for 4800, then
make
sudo make install
will get it going for you.
I’ve fixed it in my sources and will push it out when I next do an update in a day or 2’s time.
-Gordon
That did the trick! Thanks for the quick reply!
Hey Gordon ,,
I have a dimmer light that controlled by serial data for example by using UART pin from the Raspberry pi to send 8 bits for each command
I need a way to know how to send (00000001) and any 8 bits pettern out of the TxD ?
Thank you 🙂
It would look something like:
fd = serialOpen (“/dev/ttyAMA0”, 9600) ;
then:
serialPutchar (fd, 1) ;
You can put any value from 0 to 255 using serialPutchar () ;
-Gordon
now I want to test the serial port directly with the raspberry pi to check whether the sent data is correct using TxD and RxD pins of the same raspberry pi to toggle a GPIO pins just for testing if prossible
I don’t know how to read and make actions based on the received data through Rx ,, if you have example or basic details ,, and sorry am still a noob xD
There are 2 serial test programs – one is serialRead.c and the other is serialTest.c – look at them and they might give you some clues.
-Gordon
You could toggle hte pins, but you’re better off running the serialtest program that’s in the examples directory that comes with wiringPi.
Short the serial pins together then first run minicom and make sure you see what you type, then you can run the serialTest program.
-Gordon
Hi.
I am trying to write a program to open the serial port so I can talk Modbus over my GPIO pins using a converter I built. When I include the wiringSerial.h in my code and compile using gcc I get the following error:
/tmp/ccQLooGe.o: In function `main’:
test1.c:(.text+0x4c): undefined reference to `serialOpen’
collect2: ld returned 1 exit status
I think it has to do with the linking of the libraries. I have run ldconfig and included the files in a file in /etc/ld.so.conf.d/
Please help!
Thanks
Peter
make sure you have:
-lwiringPi
on the command line – you may also need -L/usr/local/lib too
-Gordon
That worked!
Thanks
By the way, you are doing great work, thanks
Gordon,
Thanks for all the work you’ve made available to us. I’m using the wiringpi-python library and was wondering where I could find similar python commands to implement parity mode and others for error checking. Thanks!
I’m not sure – I don’t maintain the Python wrappers for wiringPi – although it looks like a few people have asked now, so I’ll see what I can do – it’s easy from C though, but I’ve no idea how to get that through from Python.
-Gordon
I’ll have to work on contacting that individual ooes wrap for python. Also, the post below me concerns the form of data from wiringpi. You’ve said it is 8n1. I’m assuming this probably the same for the wiringpi-python.
I’m trying to understand. For every byte sent, there are actually 10 bits? 1 start bit, 8 bits of data, and 1 stop bit?
Yes 10 bits is more or less standard 1 start bit, 8 data bits and one stop bit. This is typical in (rs232) asynchronous serial communications. Some hardware supports 8 data bits plus one parity bit as well as 7 data bits plus one parity bit but most newer things these days ignore parity – it was useful in the days of slow modem communications.
So 8n1 is 8 data bits, no parity and 1 stop bit. (There is always one start bit)
If you study the hardware you’ll see references to 1.5 or 2 stops bits, but these are not used these days.
-Gordon
Hi Gordon,
Thanks for your hard work on this. I’m attempting communicate between an AVR microcontroller and a Pi using your library. I’m having issues getting any data from either side. I’ve come to the conclusion that the problem is not hardware related and know that the code I’m using on my AVR works. I am suspecting that maybe the format of the data being sent is different on one side. Just to clarify, what format does wiringPi set the Pi in? I am expecting 1 start bit, 8 data bits, 0 parity bit, and 1 stop bit.
Thank you
8n1 (what you described) is the default.
I’d start by running minicom on the Pi side of things – use device /dev/ttyACM0 for an Uno or /dev/ttyUSB0 for a demiulanove (or older). Check the baud rate too.
-Gordon
Hi Gordon,
First of all, thanks a lot for your usefull information in this web portal.
I´m trying to develop a serial port project. I´m using a FTDI usb to serial converter. Raspberry fin it correctly, because typing:
dmesg | grep – i tty
I receive thr following info about ttys:
[ 0.000000] console [tty1] enabled
[ 0.584327] dev:f1: ttyAMA0 at MMIO 0x20201000 (irq = 83) is a PLO11 rev3
[ 0.908147] console [ttyAMA0] enabled
[ 17.730668] usb 1-1.2.1: FTDI USB Serial Device converter now attached to ttyUSB0
Then I have installed minicom. When I try to execute it using the following command:
sudo minicom -b 9600 -o -D /dev/ttyAMA0
… the port is opened but the raspberry is hung.
Could you help me?
Thanks in advance
Read the very last line if the dmesg output.. it’s /dev/ttyUSB0. /dev/ttyAMA0 is the Pi’s on-board UART. USB uarts will usuall be /dev/ttyUSB0 or /dev/ttyACM0 depending on the type of adapter.
-Gordon
Sorry Gordon.
But it was a mistake typing.
I´m trying
sudo minicom -b 9600 -o -D /dev/ttyUSB0
I Know that my FTDI is this because if I unplugged it I get in the dmeg command line “… now unconnected…”
But the Raspberry is hung using this ttyUSB0
Thanks for your quick response.
try just minicom -s (as root, via sudo)
then setup the serial port settings, device, speed, etc. and save it as something. Then use that profile.
-Gordon
Hi again Gordon.
I have done the following command and it works properly un ttyAMA0:
minicom -b 115200 -o -D /dev/ttyAMA0
I have tied RxD and TxD in the GPIO, and when I push the keyboard I can see the key in the screen. If I disconnect RxD and TxD, obviously the keys pushed don´t apeear in the screen.
Then I leave minicom push Ctrl-A x
But if I try to run:
minicom -b 115200 -o -D /dev/ttyUSB0
…the Raspberry Pi doesn´t response and freezes.
I will develop the project with a breakout RS232 board attached to AMA0, but I would like to understand what´s happening with the FTDI attached to USB.
Best regards.
I’m surprised it freezes. I’ve not had that experience myself. I have had lockups with minicom on other platforms though – usually when they’re waiting for some hardware signal.
fwiw: I never use the command-line to set parameters, but create profiles using minicom -s
Control-A q
is my usual way of exiting minicom.
-Gordon
Thanks a lot Gordon.
Finally I will develop the project using AMA0.
I imagine that the trouble is based on I´m connecting, in the same usb port, the keyborad, the mouse and the usb to rs232 FTDI device, through an old usb hub. The different devices are not in the same usb version and probably this hung the raspberry.
If finally I find the solution I will keep you informed. Best regards.
Hello MR Gordon:
can you please put an example of serial pi sending the letter “i” to the serial interface.I need to see it as simple as that to learn.
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <wiringSerial.h>
int main ()
{
int fd ;
if ((fd = serialOpen ("/dev/ttyAMA0", 115200)) < 0) { fprintf (stderr, "Unable to open serial device: %s\n", strerror (errno)) ; return 1 ; } serialPutchar (fd, 'i') ; return 0 ; }
thank you…works
Hi Gordon,
I’m trying to send data from pi to a picaxe over an rf link. I’m using an NKM2401 on the pi’s end to encode the serial data so that it can be understood by the picaxe rfin command. I’m feeding the NKM2401 with 8 bytes @ 2400 baud, but I get some strange data on the receiver’s end (picaxe).
For example, I’m sending this string “S0111111”. When I’m using a loopback on the pi, I see the data is being sent and received correctly by the pi. But on the receiver, I get 0xFF as the first byte, as mentioned here before. But that’s not the biggest problem. After that first “thought up” byte, I get 3 bytes correctly, i.e. S01, but the rest is mangled in some way, usually from the upper half of the ascii table (>125) as if there is some strange bit shifting going on…
If I send the string several times in a cycle, the 0xFF only appears on the first transmission (first 8 bytes), but the mangled bytes remain.
I know there’s a lot that could be wrong here, but I’d still like to ask you whether this rings any bells. The fact that the corruption always starts at the fourth byte is very suspicious.
There are some issues with the Pi’s on-board serial port – and I’ve seen it myself too – on the very first open, a spurious byte is sent down the line – however this seems to be baud-rate dependant – I see it at 115200 baud, but not at 9600 baud for example…
You may need to cope with this and keep the serial port open once you’ve established communication.
But other than that first initial duff byte I’ve not had any subsequent issues when using the serial port for many things like uploading code to an ATmega, and communicating with serial display units, etc.
-Gordon
Thanks for reply Gordon.
I think I figured it out. The data stream is just too fast for the NKM2401 to handle properly when using serialPuts. I tried serialPutchar with a delay of 10ms after each byte and the data is no longer mangled. Without the delay both Puts and Putchar routines produced garbage on the output of the encoder. I also worked around the spurious first byte.
Thanks for your great work that made my experiments a breeze to implement!
A nearly invaluable tool for monitoring device-to-device comms would be two spare serial ports on your pc (PCI card is easy way to go) and a couple of microclip-DB9 adapters to pick up TxD and Gnd from either agent, and monitoring software such as Realterm (http://sourceforge.net/projects/realterm/) to watch as the data goes by. If the data looks all good on the Tx side and it’s garbled on the Rx end, it’s buffering.
Hope this is useful.
John
Hi Gordon
I’m using your library for my robot and I need to know when every byte has sent through the serial (when the write buffer is empty)
I’ve looked in sys/ioctl.h but I haven’t found anything… Can you help me?
Thanks
There are 2 ways – the first is to have the remote device send back some sort of acknowledgement once its recieved all its data, the other is to get Linux to wait until all the data has been sent – you can do the latter with the
tcdrain() ;
function. It’s a standard system call, but to use it you’ll need to have the following at the start of your program:
#include <termios.h>
#include <unistd.h>
and pass in the file-descriptor that serialOpen() returned to you – e.g.
fd = serialOpen ("/dev/ttyAMA0", 9600) ;
...
... send some data
...
tcdrain (fd) ; // Wait for all data to be sent
-Gordon
I need it to send an ack and generate an interrupt on the slave device, so the 2nd way is what I need, thanks! I think I’ll put it in another thread (thanks to your piThread library!)
Thanks again!
Hi there,
I am trying to connect a GPS module to the Raspberry PI by using your serial library. I am having a little trouble on setting the correct parameters of parity, bits and stop-bits.
My GPS works fine using minicom with 8N1 and 4600 baudrate.
I have read on your description of the lib that you can adjust theses parameteres by the usage of termios.h. I’ve been braking my brains in order to introduce into your serialRead example the proper lines of the termios.h for dealing with this.
Could you please show an example of my particular case?
Thanks in advance
Sure it’s not 4800 baud?
That’ll work right out of the box and 8N1 is the default…. So:
fd = serialOpen (“/dev/ttyAMA0”, 4800) ;
should be fine.
-Gordon
As I posted the comment I realized that the baudrate was posted wrong. It’s 4800 as you say.
If I try what you are saying, using it by default 8n1, this is the message that appears in the screen:
“Unable to open serial device: Succeed”
I have tryed to delete the return 1 of the function, as it looks like the connection can be done, but when I do this, thousands of interrogation marks appear in the screen.
Any idea?
Thanks for the propmt reply
OK – this is most likely to be premission now.
ls -l /dev/ttyACM0
and it’s probably had group ID of “dialer”.
So you need to run as root, or add the pi user into the dialer group – edit /etc/group and look for the dialler entry and add pi to it.
-Gordon
I have tryed it as root and even adding the pi user to the group.
The thing is I am not using the ttyACM0 but the ttyUSB0 port as I am connecting the GPS directly via USB. The port works on minicom running on the PI.
Could this be the problemo?
the device name shouldn’t be an issue – Linux treats all serial devices – on-board or USB as the same. If it works with minicom, then try running your program as root – ie. with sudo…
-Gordon
Forgot! Thanks a lot for the lib! The other modules work great!
Hi Gordon, and thank you for your work!
I use the serial libray in a C program, and I am concerned by the CPU usage. With the serialRead example, the CPU is at 100%. Is it due to the library itself? Can it be improved?
Thanks for your help.
I’d need to refresh my memory on it, but if it’s the example serialRead.c then it should wait for characters and print them – it shoudn’t use any cpu while waiting.
-Gordon
Thank you for your answer. You’re right, the serialRead example uses no CPU (0..1%). I ommitted to say that I modified the code so now it calls serialDataAvail() at each loop, and this is what raises the CPU use up to 100%. Actually I need to gather several bytes to recompose the transmitted message, this is why I use serialDataAvail(). I will work it out!
There are other ways to accomplish this with little cpu overhead, but you need to do more reading about Linux/Unix serial handling and use the select() or poll() system calls, or use Posix thread sand call serialRead – which will timeout after 10 seconds if there are no characters to read.
However, what you might do is sit in a loop, and delay(1) between each call to serialDataAvail() – then call serialRead and then serialDataAvail for each byte – so you read in all characters that are waiting, then go back to the lazy loop with a 1mS delay in it. That’s not perfect, but it might help if you have other things running.
-Gordon
Thank you very much for the hint. I will try this out, and maybe get more deeply into the Linux serial communication.
Hello Gordon,
I use the library “wiringSerial” for communicate with a GPS module by the Uart GPIO port.
I have done disable the serial consol and i do:
if(fd = serialOpen(“/dev/ttyAMA0”, 4800) < 0) // Configure the Serial port
printf ("\nUnable to open serial device \n");
else
{
printf ("\nUnable to open serial device \n");
}
Hello Gordon,
I use the library “wiringSerial” for communicate with a GPS module by the Uart GPIO port of the raspberry pi.
I have done disable the serial consol and i do:
if(fd = serialOpen(“/dev/ttyAMA0″, 4800) 0)
{
serialdata2[i] = serialGetchar(fd);
i++;
}
if(strstr(serialdata2,”$GPRMC”) != NULL)
if(strstr(serialdata2,”*”) != NULL)
flagGPS = 0;
}
No information arrive. fd return by serial open = 0
I have found the problem: fd must be equal 4 for communicate with the GPS.
Why?
The value of ‘fd’ will not be predictable – it will be any number above 2 though.
and wordpress removes a lot of formatting, so it’s hard to make out what that program is doing, however I guess its missing a loop.
I’d start by simply printing out the string serialdata2 to see if it’s gotten what you want.
-Gordon
Hi!
I have had the same issue and what works best with GPS serial readings is using http://gpsd.berlios.de/
With this lib python and c++ bindings can be used, so little programs can be run in order to get only the parameters you want from the GPS, such as the ground speed.
http://blog.perrygeo.net/2007/05/27/python-gpsd-bindings/
Ok Thanks for replys.
For me the solution was to force the handler fd = 4. but it’s no very clean.
Something like that:
if(fd = serialOpen(“/dev/ttyAMA0″, 4800) 0)
{
serialdata2[i] = serialGetchar(fd);
i++;
}
if(strstr(serialdata2,”$GPRMC”) != NULL)
if(strstr(serialdata2,”*”) != NULL)
flagGPS = 0;
}
}
Sorry not good display
1- fd = serialopen()
2- fd = 4
3- serialputs(fd,””)
4- while(finish){
c = serialgetchar(fd)
if(strstr(c,””))
}
IF you fix it at 4 then something will break at some point. That’s really not the way to do it.
-Gordon
Hello Gordon,
could you please show me how to send x and receive y?
Each natural number (x) typed on the Pi keyboard is sent to the Matto (micro controller) using the chosen serial. There it is encrypted by applying the function
y= (525 x + 101)
and the result (y) is returned to the Pi over the same interface and displayed.
You need to know the range – so if ‘y’s is a 1-bit number then you can transmit it as 2 x 8 bit bytes – but the program running on the Pi has to be compatible with the program running on the microcontroller. Just invent your own coding and send the bytes.
-Gordon
hi Gordon i’m new for using raspberryPi, i following ur page to learn to use it and i have problem in using serial.
can i use serialgets(fd,char a); function.
if not how i receive a complete string using serial in raspberryPi.
You have to write a program to do it for you. You read characters into a string (character array) until you get the terminating character or you exceede the length of the array (or have read as many bytes as you need to).
You get a huge amount of flexibility with C, but you also have to do a little more work.
-Gordon
Thank u gordon for ur reply and i have one more silly doubt, what is the purpose of using fflush(stdout);
function in the serialTest example
flush() is generally the system call to force all data that’s waiting to be sent to whatever device you refer to. The ‘f’ libraries are also known as the buffered IO libraries – which means that they buffer data until the buffers are full, then they write the entier buffer in one operation – this generally means things go a lot faster, however when it comes to things like terminal output, it can mean that you wait a long time before seeing anything – so with terminal output, the buffers are flushed automatically when the buffer is full, when you print a new line, or when input is expected – to make it output anything pending then you use fflush().
So:
putchar (‘a’) ;
won’t show anything immediately, but add fflush (stdout); after it, then you’ll see the character.
-Gordon
Hi Gordon,
Firstly, really great job you did! thx so much !
although I encounter an issue:
I setup your wiringserial lib, as shown on this page, run the test, run some of your examples, it works great ! However, I’m currently trying to do a nice UI on Qt (4.8) on my Raspbian, which uses the UART; when I include & , Qt is happy, it even auto-completes before I type it all : the lib is recognized by Qt and if I compile, Qt is fine with that. BUT now if I use any function of wiringPi.h or wiringSerial.h, Qt gives me errors that I don’t undertand why:
undefined reference to ‘serialOpen’ (or any others)
Any ideas?
Thanks a lot again!
(ps: I’m french, sorry if my english is a bit dodgy sometimes)
errata :
installation as shown on That page : https://projects.drogon.net/raspberry-pi/wiringpi/download-and-install/
BTW : Qt is C++ environment, but accept C and I notice the c++ wrappers which should ensure the code to work…
BTW2: the error comes on :
int fd = serialOpen (“/dev/ttyAMA0″, 115200);
Thx again for your support
You need to add -lwiringPi to the compile line. e.g.
gcc -o myprog myprog.c -lwiringPi
-Gordon
Hi Gordon,
Is there anyway in that I could change the pins that the WiringSerial is using?
I was hoping I could somehow use serial in the PiFace. Otherwise I would have to rewrite my code and stop using Piface.
Thank you.
No. It’s fixed in the Pi’s hardware. You can still use serial with the PiFace – but you’ll need to solder wires onto the Piface board to get access to those pins.
-Gordon
Hi,
I’m seeing some strange behaviour with serialTest that maybe someone can help me with? I ran the example code and nothing was happening, it just froze, so I added some debugging lines and the strange thing is they only appear if I run the program without using sudo. I’ve tried to break the problem down as much as possible, so if you look at my below code, running ./test will print the line 0, and then fail to connect to the serial port, whereas running sudo ./test won’t even print the debug “0”. I’ve had this working previously, and so I thought maybe I’d blown the serial port up (connecting to my arduino), so I’ve bought a new pi and it’s still doing the same.
#include
#include
#include
#include
int main()
{
printf(“0”);
int fd;
if((fd=serialOpen(“/dev/ttyAMA0”, 115200))<0)
{
fprintf(stderr, "Unable to open serial device: %s\n", strerror(errno));
return 1;
}
serialPutchar(fd, 'i');
return 0;
}
my includes got chopped off, they were
#include
#include
#include
#include
And again, maybe it’s an escaping thing with the
stdio.h
string.h
errno.h
wiringSerial.h
The printf (“0”); ought to work whether you’re root or not, although add a \n after the 0 to make sure the output is printed immediately.
and if you don’t get any error when opening the device, then you’re fine too. There’s very little that can go wrong here.
Make sure Linux isn’t using the serial port – look for /dev/ttyAMA0 in /boot/cmdline.txt and in /etc/inittab too.
-Gordon
Thanks for the reply, and for the tip about the \n, the debug lines are being printed now and I can see that the step the program is freezing on is the serialOpen.
There is a bit more of a story here – it seems to be that connecting my rxd and txd together is what triggers the problem, I’ll run serialTest and one of two things will happen:
1) It will work as expected – print the sent byte and then print the correct received one
2) print the sent bytes without printing any received ones, sometimes it may start working after a few bytes though
But whichever one of these it does, it will eventually stop printing sent bytes and just print received bytes of -1 continually, the screen will fill instantly with -1’s.
Regarding the cmdline.txt, i’m a linux noob, but I can see a reference to the serial port in there. It looks like it’s setting it to disabled, have I read that right?
dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 console=tty1 $=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait
It’s not disabled.
Edit the line to:
dwc_otg.lpm_enable=0 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait
ie. remove the references to AMA0 and tty1
-Gordon
I also found this at the bottom of my inittab
T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100
comment this like out then:
sudo kill -1 1
or reboot
-Gordon
Sorry for the spam, I should explain one more thing: The freezing I mentioned, it will happen whenever I run the program after I’ve already run it once and seen the -1 problem. So if I see the -1 thing then I know next time I try running it it will freeze and I have to reboot to be able to get anything to work again.
the freezes are probably due to the getty process running. It will fight you for the serial port.
Thanks so much, it’s working 100% now!
Hi Gordon,
First of all, thanks for your wonderful work. I am using this library for a personal project. I have got the RS232 communication working and have control of a LG monitor using a USB to serial adapter. I am wondering if you could help me with RS485 communication. My questions are following
1. Is it possible to do RS485 communication using your library and a USB to serial adapter on a Pi?
2. If it is, what parameters do i have to change to initialize the communication?
Kindly help me when you have a chance.
Sidd
Hi!
I have the following c:
#include
#include
#include
#include
int main ()
{
int fd ;
if ((fd = serialOpen (“/dev/ttyUSB0”, 9600)) < 0)
{
fprintf (stderr, "Unable to open serial device: %s\n", strerror (errno)) ;
return 1 ;
}
// Loop, getting and printing characters
for (;;)
{
printf("–%x", serialGetchar (fd)) ;
fflush (stdout) ;
}
}
except the correct data "–96" i also receive "–ffffffff".
What is going wrong?
Thank you!
There is a 10-second timeout in the serialGetchar () call. Just test for -1, and if -1 then you know its timed out and can just loop for another character.
-Gordon
Thank you for the reply.
After some search i realized that another process was using the port, that’s why the strange data…
Hi Gordon i’m an 18 years old italian student.
I’m not very good in english…sorry…
i’ve a question: this is my first code for the pi and uart .
i don’t understand why the txd pin is always at logic level 1, there isn’t comunication.
can you tel me what i have wrong? there are other settings?(i misure with scope directly to raspberri pi )(in addition i use RTS pin on gpio-r2 4(wiringpi 7))…thanks
my poor code is:
#include
#include
#include
#include
#include
main ()
{
int count=33;
int fd=2;
serialOpen (“/dev/ttyAMA0”, 9600) ;
wiringPiSetup () ;
pinMode (0, OUTPUT) ;
pinMode (1, OUTPUT) ;
pinMode (2, OUTPUT) ;
pinMode (3, OUTPUT) ;
pinMode (4, OUTPUT) ;
pinMode (5, OUTPUT) ;
pinMode (6, OUTPUT) ;
pinMode (7, OUTPUT) ;
digitalWrite (7, HIGH) ;
if (fd < 0)
{
printf ("Unable to open serial device\n") ;
}
else printf ("serial device is open\n");
serialPutchar(fd, '1');
serialClose(fd);
digitalWrite (7, LOW) ;
while(1)
{
digitalWrite (0, HIGH) ; delay (250) ;
digitalWrite (1, HIGH) ; delay (250) ;
digitalWrite (2, HIGH) ; delay (250) ;
digitalWrite (3, HIGH) ; delay (250) ;
digitalWrite (4, HIGH) ; delay (250) ;
digitalWrite (5, HIGH) ; delay (250) ;
digitalWrite (6, HIGH) ; delay (250) ;
delay (250) ;
digitalWrite (0, LOW) ; delay (250) ;
digitalWrite (1, LOW) ; delay (250) ;
digitalWrite (2, LOW) ; delay (250) ;
digitalWrite (3, LOW) ; delay (250) ;
digitalWrite (4, LOW) ; delay (250) ;
digitalWrite (5, LOW) ; delay (250) ;
digitalWrite (6, LOW) ; delay (250) ;
delay (250) ;
while(1){
digitalWrite (7, HIGH) ;
delay(5);
serialPrintf(fd, "this is a test stream\n");
delay(5);
digitalWrite (7, LOW) ;
printf("sent\n");
}
}
}
make sure there isn’t another program using the serial port – the kernel uses it (edit /boot/cmdline.txt) and Raspbian uses it (edit /etc/inittab) by default.
-Gordon
hi Gordon, I’ve done! but nothing is change!
my cmdline.txt is :
dwc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait
and in inittab i comment the line:
#T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100
what do you suggest I do?
thanks
stefano (not good at english:-) )
sorry, i’ve found the mistake!
i don’t know why but the serialOpen……need to change in fd=serialOpen…
can you help me to know the origin of this situation?why i’ve to put “fd=….”?
thank thank thank!!!!
Sorry no idea – This is wordpress comments not a forum, so I’ve sort of lost track..
fd usually stands for file descriptor – it’s just a varaible to hold the handle or reference to the serial port you’ve just opened.
-Gordon
Gordon your libraries are fantastic. Here is what we are using the Pi for. I work for a door and window company so what we need to do is this: i need it to receive files from the server and re-transmit through the serial out to a different machine with baud rate of 57600. Any idea as to how I would be able to do this using your libraries?
the simplest way is to simply use stty -F /dev/ttyAMA0 to set the baud rate then just cat the files to the serial port – cat filename > /dev/ttyAMA0
Or look at the serial example programs to see how to open the device inside a program.
-Gordon
hi… Gordon sir, I am trying to send and receive the data serially by using on board tx and rx pins i,e., 8 and 10. but i am getting error in serialOpen() function.
My code is
int dt;
char p[]={“/dev/ttyAMA0”};
char *device = p;
dt = serialOpen(*device, 9600);
the error is: bad assress
please tell me how give address in device pointer.
Thanks in advace
Spending a day learning more about C is what you really need to do.
In the meantime, you can do this:
dt = serialOpen (“/dev/ttyAMA0”) ;
or
char *p = “/dev/ttyAMA0” ;
dt = serialOpen (p) ; // no star
-Gordon
hi sir, I am working on UART of RPi and I want save received data on rx into file..so what shall i do?…
thanks in advance,..
You need to write a program to open the serial port and open a file, then receive data from the serial port and write it into the file. You can use a variety of programming languages – e.g. BASIC, C, etc.
-Gordon
thanks sir ,
i have done reception of data through uart by using minicom but i cant understand how to write this data on file..
You write a program to read from the serial port then write that data to the file.
You will need to learn how to write computer programs.
-Gordon
hi sir i have written this code to display on (screen) received data on RXD.but I have send 4 on UART by using (xbee) it shows 10 after hit enter.why this is happening…please tell me.
so i have crosscheck is there any problem with xbee but not any it get show data on screen by using minicom..
#include
#include
#include
int main ()
{
int fs,c ;
if ((fs = serialOpen (“/dev/ttyAMA0”, 9600)) < 0)
{
printf ( "unable to open serial device") ;
return 1 ;
}
if (wiringPiSetup () == -1)
{
printf ("Unable to start wiringPi") ;
return 1 ;
}
while(1)
{
if(serialDataAvail(fs) == -1)
{ printf("data is not available") ;
}
else
{ c = serialGetchar(fs);
printf("%d \n",c);
fflush(stdout);
}
delay(3);
}
Your program seems OK – if it’s printing out the number 10, then do be aware that this is probably ascii code 10 which is a line feed code. What are you using on the xbee side to send data?
-Gordon
sir, i am sending “44” from xbee but it gets 10 after hits enter or 32 after press space and enter.
You need to lookup and understand the difference between single characters and numbers. The space character has numeric value 32 – that’s why your program prints out 32 when you press space. The program sending the data needs to use the same format to pass data as the program recieving the data.
-Gordon
Hi Gordon! How would you fix a problem like that:
I’m getting data with following code:
while(serialDataAvail(fd))
{
putchar(serialGetchar(fd));
fflush(stdout);
}
Output:
1125
1134
There are 4 digits presented in one row, but that aren’t allready integer values or?
But how is it possible to store every 4 of these characters in one variable so that I can make calculations?
Thanks
Florian
the answer is yes it’s possible.
You need to learn a bit more about C programming, and to interpret the return value from serialGetchar() – it will be -1 on a time out (no data for 10 seconds).
Essentially you store characters into a buffer (character array) until the terminating character (probably a new line), then you can use the atoi() function on it.
-Gordon
Dear Gordon,
first I’d like to thank you so much for your great libraries!
Your GPIO lib work without any problem so far.
Yesterday I tried to work with your serial lib, with the first attempt I could receive char’s at my PC, only receiving with the RPi won’t work, but this I’ve planed to checkout this morning. After a shut down of the RPi (last evening), I tried to start my app this morning (code unchanged), but unfortunately, when serialOpen is called:
nHandle = serialOpen(“/dev/ttyAMA0”, 9600 );
The function doesn’t return, but the day before it did! I assume, may be I have done any shell cmd on the RPi, which made it work yesterday, but I don’t remember.. I’ve really got no idea?
Calling the regular open() function, it always returns a valid handle, but transmitting of char won’t work, as well!
nHandle = open(“/dev/ttyAMA0”, O_RDWR | O_NOCTTY | O_NDELAY);
May be you have an idea or hint for me?
Regards and thanks in advance!
Ralph
Firsly make sure the Pi is setup for user serial port access – check /boot/cmdline.txt and /etc/inittab (Raspbian) to make sure the OS isn’t using it.
The system open() will work just as well as my helper library, but then you need to do more “stuff” to set the baud rate, non-blocking, etc. You may also need to run your program as root – check the permissions on /dev/ttyAMA0 and run the ‘id’ command to make sure you’re in the ‘dialout’ group and /dev/ttyAMA0 is in the dialout group too.
Other than that, there really shouldn’t be any issues – the serialOpen() function can’t block, so it should always return (check the return value – if < 0 then there is a fault of some kind (same for open()) -Gordon
Dear Gordon,
many thnanks for your reply and your helpful support. After modifying cmdline.txt and inittab, mincom works perfect and your lib as well!
Now using your API (open(), Rx(), Tx()..) within my application everything works as it should, perfect!
Once again thanks a lot!
Regards
Ralph
Hello Gordon,
On my Raspberry with Raspbian, the tcsetattr () method need three arguments. So I complete with TCSANOW :
tcsetattr (fd, TCSANOW, &options) ;
Thanx for all.
How can I read the input to a variable and then write it to a file. I have tried a few ways but it seems to just print strange characters to the file. It prints to terminal fine but I am unsure how to get the input into a variable. The text I am sending from my arduino are two letters long. Let me know if you need any more details about it.
Thanks in advance.
You need to write a program that reads in the characters from the Arduno and re-assembles them into a number from a string. That’s assuming you’re printing them on the Arduino as a string – using printf or Serial.print or something like that.
On the Pi, you can read a string into a char array then use the atoi() function if it’s an ordinary integer.
-Gordon
Sorry about this but I am really new to this. Would you have any examples or places where I could find out stuff about this.
Thanks again.
Serial port handling has been an integral part of Unix for 40 years. There is plenty online to help. There are also my example programs in the examples directory to look at.
-Gordon
I am currently pursuing my under graduation in electronics.My project involves measuring the current generated by a circuit using an IC and to store that values to a data base.Can some one help me how to configure the ethernet in Raspberry Pi so that i can use it to stream the values measured to a data base
Hi Gordon,
Thanks for putting up this excellent library!!
I’m trying to use it on a Raspberry Pi with USB Serial connection (thru an FTDI breakout board).
I have a question:
The WiringSerial’s doc says that the funcion ‘serialGetchar’ blocks for 10 seconds if there is no data.
However, when I checked the source for it (in wiringSerial.c), I don’t see any wait/sleep.
In fact, this is all the code that does the reading:
…
if (read (fd, &x, 1) != 1)
return -1 ;
…
Could you throw some light on this? If it doesn’t do any wait/sleep, does it mean we need to add it on top of this at the app layer?
Thanks
Do be aware that my code is nothing more than wrappers round the standard Linux serial handling code – use my code for simple cases, but for anything more complex, you may have to dig a little deeper – of-course my code can be used as a starting point!
As for the timeout – look in serialOpen() code. It sets the timeout there.
-Gordon
Please ignore my prior question about timeout in read().
I see that you’re setting the timeout value in the fd options.
Thanks!
Dear Gordon,
I’m using my raspberry Pi to configure the registers of an IC. The communication interface I’m using is uart. I used the following code segment:
#include
#include
#include
#include
#include
int main ()
{
int fd ;
int count ;
unsigned int nextTime ;
if ((fd = serialOpen (“/dev/ttyAMA0″, 115200)) %3d\n”, serialGetchar (fd)) ;
fflush (stdout) ;
}
delay(2.6)
while (serialDataAvail (fd))
{
printf (” -> %3d\n”, serialGetchar (fd)) ;
fflush (stdout) ;
}
return 0;
}
I’m not getting my expected outcome. I found the problem was with using the ‘serialPutchar’ function to send a large integer value.
The compiler also warned me about this.
Kindly suggest me with an alternative wiringPi function so that I can send my data through uart without being truncated.
#include
#include
#include
#include
#include
int main ()
{
int fd ;
int count ;
unsigned int nextTime ;
if ((fd = serialOpen (“/dev/ttyAMA0″, 115200)) %3d\n”, serialGetchar (fd)) ;
fflush (stdout) ;
}
delay(2.6)
while (serialDataAvail (fd))
{
printf (” -> %3d\n”, serialGetchar (fd)) ;
fflush (stdout) ;
}
return 0;
}
sorry for the inconvinience sir… this was the actual code I used.
This really is for COMMENTS to the article – it’s not a forum. far better to email me if you want answers to stuff like this. However I think you need to read-up more on serial data communications – serialPutchar() does just that – it sends a single character to the serial device – a LONG integer is 4 or 8 bytes long – you need to use other methods to send those bytes instead of just one byte.
Also the delay(2.6); Please please please use -Wall when compiling your code – it’ll tell you there’s an error there. This will not dealy for 2.6 milliseconds, but 2 miliseconds as the delay() function is expecting an integer.
-Gordon