I'm really new to Raspberry Pi and Arduino programming (+ I2C). Recently I start working on a project where I have to connect an Arduino and a Raspberry Pi to send and receive data from each other.

I'm using Wire.h to handle I2C from the Arduino end. Hence it has Wire.onReceive() and Wire.onRequest() methods, I can specify two methods to act as trigger methods. But I've having a trouble in implementing such kind of methods.

I need to implement a method (on Raspberry Pi), which will be invoked only when the Arduino sends some data (some kind of an interrupt). I need this to be written in C/C++, since I already have some other functions (using OpenCV) implemented.

Any ideas or suggestions to achieve this task ?


Do not use I2C.

The standard Raspberry Pi Linux I2C driver can only act as a master device. It can not deal with unsolicited I2C messages.

Use the serial link instead. On the Pi end that is /dev/ttyAMA0. The Pi's gpios are 3.3V so use a voltage divider on the Arduino TX/Pi RX line if you are using a 5V Arduino.

  • Thanks for the comment. I'm currently using the Raspberry pi to do the processing, which acts as the master. But the problem is, if I'm using serial comm at Raspberry end, I have to keep listening to the port to see if it receives any data. And also, I have to change the code of Arduino to do the same. Wouldn't it be expensive? Oct 8 '14 at 13:49
  • Your choice. I2C will not work. Serial will. Serial data is buffered at the Pi end. Poll for serial data regularly.
    – joan
    Oct 8 '14 at 13:54

I agree with Joan's comments. The serial has a large buffer (about 200 bytes I think), so you can poll it infrequently. About once per second has minimal impact on processor.

You may be interested in a function serialGets I wrote for the Pi.

The available libraries have serial read, but there is no equivalent of gets to read a line of data.

#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include <termios.h>
#include <wiringPi.h>
#include <wiringSerial.h>

#define MAXLINE 20

int serialOpenB (const char *device, const int baud, const int n)
    struct termios options ;
    int fd = serialOpen(device, baud);
    // Get and modify current options:
    tcgetattr (fd, &options) ;

    options.c_lflag |= ICANON;  // set canonical mode (line by line)
    options.c_iflag |= IGNCR;   // ignore CR on input
    options.c_cc [VMIN] = n-1;  // return if n-1 bytes received
    options.c_cc [VTIME] = 0;   // no timeout

    tcsetattr (fd, TCSANOW | TCSAFLUSH, &options) ;

    usleep (10000) ;    // 10mS

    return fd ;

/* Get a newline-terminated string of finite length.

char * serialGets (char *buf, const int n, const int fd)
    int m;
    m = read (fd, buf, n);
    if (m != n) {
      *(buf+m) = '\0';
    return 0 ;
    return (buf) ;

int main ()
  char line[MAXLINE] ;

// Always initialise wiringPi. Use wiringPiSys() if you don't need
//  (or want) to run as root

  wiringPiSetupSys () ;
  int fd = serialOpenB("/dev/ttyAMA0", 9600, MAXLINE);
 for(;;) {
    serialGets(line, MAXLINE, fd);

    time_t ctm = time(NULL);    // log time
    struct tm *ltime = localtime (&ctm);
    char tbuf[20];
    strftime (tbuf, 20, "%F %T", ltime);

  return 0 ;

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.