Communicating with the Penguino AVR over UART

Penguino Code

The Penguino AVR can communicate using serial UART over the USB connection to a computer.

The Penguino software library lets you set up UART communication to act as if it were standard I/O in a console C program. The following example using the Penguino library shows a simple program that uses UART:

   1 
   2 #include <stdio.h>
   3 
   4 #include "penguino/uart/uart.h"
   5 #include "penguino/uart/uart-stdio.h"
   6 #include "penguino/time.h"
   7 
   8 #define UART_BAUD_RATE 115200
   9 
  10 int main( void ) {
  11         char name[80];
  12         int age = 0;
  13         
  14         // initalise UART
  15         uart_init( UART_BAUD_RATE );
  16         
  17         // enable UART as stdio
  18         uart_stdio_init( );
  19         
  20         // enable echo on the UART stdin so the user can see what they are typing
  21         uart_stdio_echo( true );
  22         
  23         while ( 1 ) {
  24                 printf( "\r\n\r\nHello there, I'm a Penguino AVR!\r\n\r\n" );
  25                 
  26                 printf( "What's your name? " );
  27                 scanf( "%s", name ); // N.B. this is a format vulnerability in C! example only
  28                 
  29                 printf( "\r\n\r\n" );
  30                 
  31                 printf( "Why hello, %s! How old are you? ", name );
  32                 scanf( "%d", &age );
  33                 
  34                 printf( "\r\n\r\n" );
  35                 
  36                 printf( "Thanks, %s, for telling me you're %d years old!\r\n\r\n", name, age );
  37                 
  38                 // snooze
  39                 delay_ms( 300 );
  40         }
  41 
  42         return 0;
  43 }

Things to Note:

Computer-Side

Terminal Applications

This serial communication can be displayed in a terminal on the computer using:

Device Name

The Penguino AVR appears as the following device names (after installing the required drivers):

PySerial

To communicate with the Penguino AVR over UART in python, a python serial package is available called PySerial.

A PySerial program to communicate with the Penguino AVR may look like:

   1 
   2 import serial
   3 
   4 serialConnection = serial.Serial( '/dev/cu.penguino-uart', 115200, timeout=1 )
   5 
   6 while ( True ):
   7         line = serialConnection.readline( )
   8         print( line )
   9         serialConnection.write( "received line" )
  10 
  11 serialConnection.close( )

C Program

A C program on a POSIX or similar (linux/unix/OSX) machine to communicate with the Penguino AVR over UART may look like:

   1 
   2 #include <stdio.h>   /* Standard input/output definitions */
   3 #include <string.h>  /* String function definitions */
   4 #include <unistd.h>  /* UNIX standard function definitions */
   5 #include <fcntl.h>   /* File control definitions */
   6 #include <errno.h>   /* Error number definitions */
   7 #include <termios.h> /* POSIX terminal control definitions */
   8 
   9 #define FD_ERROR (-1)
  10 #define BUF_SIZE 1024
  11 
  12 int open_port( char *device, int baudConstant ) {
  13         int fd = FD_ERROR;
  14         
  15         fd = open( device, O_RDWR | O_NOCTTY | O_NDELAY );
  16         
  17         if ( fd == FD_ERROR ) {
  18                 perror( "Unable to open device" );
  19         } else {
  20                 fcntl( fd, F_SETFL, 0 );
  21         }
  22         
  23         
  24         // set the baud rate
  25         struct termios options;
  26         
  27         tcgetattr( fd, &options );
  28         
  29         cfsetispeed( &options, baudConstant );
  30         cfsetospeed( &options, baudConstant );
  31         
  32         options.c_cflag |= (CLOCAL | CREAD);
  33         
  34         tcsetattr( fd, TCSANOW, &options );
  35 
  36         return fd;
  37 }
  38 
  39 void set_port_nonblocking( int fd ) {
  40         fcntl( fd, F_SETFL, FNDELAY );
  41 }
  42 
  43 void set_port_blocking( int fd ) {
  44         fcntl( fd, F_SETFL, 0 );
  45 }
  46 
  47 int main( int argc, char *argv[] ) {
  48         
  49         // replace the device name with the appropriate name for your system
  50         int serial = open_port( "/dev/cu.penguino-uart", B115200 );
  51         set_port_nonblocking( serial );
  52         
  53         char receive_buffer[BUF_SIZE];
  54         char send_buffer[BUF_SIZE] = "received line";
  55         char line[BUF_SIZE] = "";
  56         char *lineCursor = line;
  57         
  58         while ( 1 ) {
  59                 
  60                 // read bytes from the UART link into 'buffer'
  61                 int bytesRead = read( serial, receive_buffer, BUF_SIZE );
  62                 
  63                 if ( bytesRead  > 0 ) {
  64                         // bytes were received!
  65                         
  66                         
  67                         // go through each byte, and print out lines
  68                         int i;
  69                         for ( i = 0; i < bytesRead; ++i ) {
  70                                 
  71                                 if ( receive_buffer[i] == '\r' || receive_buffer[i] == '\n' ) {
  72                                         // one of the new line characters was found
  73                                         
  74                                         // we only care about one of them, ignore the other
  75                                         if ( receive_buffer[i] == '\n' ) {
  76                                                 
  77                                                 // terminate the line string
  78                                                 *lineCursor = '\0';
  79                                                 // reset the character pointer 
  80                                                 // to the start of the line
  81                                                 lineCursor = line;
  82                                                 
  83                                                 // print this line
  84                                                 printf( "%s\n", line );
  85                                                 
  86                                                 // reply that we've read a line
  87                                                 write( serial, send_buffer, BUF_SIZE );
  88                                         }
  89                                         
  90                                 } else {
  91                                         // not a new line character, add it to the line buffer
  92                                         *lineCursor = receive_buffer[i];
  93                                         ++lineCursor;
  94                                 }
  95                         }
  96                 }
  97         }
  98         
  99         return 0;
 100 }

Documentation/PenguinoAVR/UART Communication (last edited 2010-01-10 11:02:53 by DavidCollien)