sharix
Posts: 200
Joined: Thu Feb 16, 2012 11:29 am
Location: Slovenia

Read serial port

Thu Aug 09, 2012 10:48 pm

Hello, I found this method for reading the serial port on stackoverflow, but I don't know how to use it:
http://stackoverflow.com/questions/7035 ... gh-cpu-use

Can someone make it work? I need this for reading the data output of arduino, I think it will be useful to other users too.

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

Re: Read serial port

Fri Aug 10, 2012 6:31 am

That is a really bad example in that answer. It's not even a valid piece of C code, just a few lines of code that need to be wrapped up in a function, and the port needs to be opened and configured as well.

1st question to you sharix: How much C programming experience do you have ?

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

sharix
Posts: 200
Joined: Thu Feb 16, 2012 11:29 am
Location: Slovenia

Re: Read serial port

Fri Aug 10, 2012 9:23 am

None

here's what I've come up with, but it still doesn't work and I'm sure there are errors and things missing.

Code: Select all

#include <sys/poll.h>
#include <sys/unistd.h>
#include <stdio.h>

#define	SERIAL_DEV "/dev/ttyUSB0"
#define SPEED 9600

void read_port()
{
	int serial_fd = 0;
	struct pollfd fds[1];
	fds[0].fd = serial_fd;
	fds[0].events = POLLIN ;
	int pollrc = poll( fds, 1, 1000);
	if (pollrc < 0)
	{
		perror("poll");
	}
	else if( pollrc > 0)
	{
		if( fds[0].revents & POLLIN )
		{
			char buff[1024];
			ssize_t rc = read(serial_fd, buff, sizeof(buff) );
			if (rc > 0)
			{
				/* You've got rc characters. do something with buff */
				printf("%d\n", buff);
			}
			else
			{
				printf("0\n");
			}
		}
	}
}

int main()
{
	int i = 0;
	while (1)
	if (1)
	{
		printf("%d : buff = \n", i);
		read_port();
		i++;
		sleep(1);
	}
	else
	{
		sleep(1);
	}
	return 0;
}

sharix
Posts: 200
Joined: Thu Feb 16, 2012 11:29 am
Location: Slovenia

Re: Read serial port

Sun Aug 12, 2012 10:13 am

Maybe this should be transferred to the C/C++ section?

andymo
Posts: 4
Joined: Tue Jul 31, 2012 10:10 am

Re: Read serial port

Thu Aug 16, 2012 8:25 am

sharix wrote:Hello, I found this method for reading the serial port on stackoverflow, but I don't know how to use it:
http://stackoverflow.com/questions/7035 ... gh-cpu-use

Can someone make it work? I need this for reading the data output of arduino, I think it will be useful to other users too.
Please don't get mad since this is not exactly on topic (as per your question), but as an amateur programmer (like yourself) I've found the python pyserial to be extremely easy alternative for a beginner.

1) Install Python
2) Spend an afternoon learning python via http://learnpythonthehardway.org/ (free html section) you will pick up everything you need to know from this.
3) download http://pyserial.sourceforge.net/
4) write the programme.
5) Profit??

sharix
Posts: 200
Joined: Thu Feb 16, 2012 11:29 am
Location: Slovenia

Re: Read serial port

Thu Aug 16, 2012 10:26 am

Don't worry I don't get mad easily ;)
I've already started learning python for my projects, so I will definitely try to do this with pyserial.
I prefer languages that don't require compiling, I do everything in bash, python, and mathematica. However I thought that for a task like this it's better to use a more optimised language.

User avatar
panik
Posts: 369
Joined: Fri Sep 23, 2011 12:29 pm
Location: Netherlands

Re: Read serial port

Thu Aug 16, 2012 3:47 pm

Just in case anyone was hoping to find a working C example in this topic after a search, this code has been a great starting point for me in the past: http://www.teuniz.net/RS-232/
If you're using the UART gpio pins on the raspberry pi, make sure to add '/dev/ttyAMA0' to the list of comports, or change an existing one (rs232.c, line 47). For arduino (or other ftdi-like solutions), there's already a '/dev/ttyUSB0' in the list on position 16.
Then in your main.c, it's basically something like:

Code: Select all

#include "rs232.h"

#define COMPORT			16 		// this is '/dev/ttyUSB0' (for arduino) or choose wherever you added '/dev/ttyAMA0' (for raspberry pi UART pins) to the list
#define BAUDRATE		9600	// or whatever baudrate you want
#define RECEIVE_CHARS	8		// or whatever size of buffer you want to receive
#define SEND_CHARS		4		// or whatever size of buffer you want to send

int main (int argc, char **argv) {
	unsigned char receive_buffer[RECEIVE_CHARS];
	unsigned char send_byte = 42;
	unsigned char send_buffer[SEND_CHARS] = {'a','b','c','d'};

	OpenComport(COMPORT, BAUDRATE);
	while(1) {
		// change send_byte and/or send_buffer with what you want to send. Then:
		SendByte(COMPORT, send_byte); // or:
		SendBuf(COMPORT, send_buffer, SEND_CHARS);
		
		// and/or:
		PollComport(COMPORT, receive_buffer, RECEIVE_CHARS);

		// do something with received data in buffer
		// maybe sleep for a while
	}
	CloseComport(COMPORT);
	
	return 0;
}
I haven't tested this code with an actual microprocessor/arduino, but it should get anyone started. I had something similar working before. At least it compiles:

Code: Select all

gcc main.c rs232.c -o my_app

sharix
Posts: 200
Joined: Thu Feb 16, 2012 11:29 am
Location: Slovenia

Re: Read serial port

Thu Aug 16, 2012 4:18 pm

Thank you very much, I'm gonna test it in a couple of days when I get home and report results.

User avatar
panik
Posts: 369
Joined: Fri Sep 23, 2011 12:29 pm
Location: Netherlands

Re: Read serial port

Sat Aug 18, 2012 10:29 pm

Tried it. The code from the main page (http://www.teuniz.net/RS-232/) probably does exactly what you want.
If you change the variable 'cport_nr' to 16 (from the current 0) it'll read and echo received bytes from /dev/ttyUSB0 on 9600 baud.

To have anything communicate with the UART pins (/dev/ttyAMA0) on the Raspberry Pi:
  • - remove 'console=ttyAMA0,115200 kgdboc=ttyAMA0,115200' from /boot/cmdline.txt (back it up first)
    - comment out the last line in /etc/inittab (that is, put a '#' in front of the line "T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100")
Also, reboot. Also, you don't need to do this if you use the arduino in the Raspberry Pi's USB port.

I had the application on the Raspberry Pi receive data from my laptop with an FTDI USB-Serial cable in the laptop's USB port on 115200 baud. Worked great. I only changed the 'bdrate' in main() to 115200, left 'cport_nr' being 0, and changed '/dev/ttyS0' to 'dev/ttyAMA0' in rs232.c on line 47.

Code: Select all

pi@raspberrypi ~/code/rs232 $ ls
gpl.txt  main.c  rs232.c  rs232.h
pi@raspberrypi ~/code/rs232 $ gcc main.c rs232.c -Wall -o2 -o test
pi@raspberrypi ~/code/rs232 $ sudo ./test 
received 1 bytes: h
received 1 bytes: e
received 1 bytes: l
received 1 bytes: l
received 1 bytes: o
received 1 bytes:  
received 1 bytes: w
received 1 bytes: o
received 1 bytes: r
received 1 bytes: l
received 1 bytes: d
received 1 bytes: !
received 1 bytes: .
received 1 bytes: .
^Cpi@raspberrypi ~/code/rs232 $ 
Good luck with what it is you're doing!

Return to “General programming discussion”