Raspberry Pi <-> Arduino Uno using i2c crashes after a while


hi all,

i have been trying make raspberry pi communicate arduino uno via i2c in order make kind of "rf card" pi.

the idea communicate distant arduino (with 434mhz rf emitter/receptors). tried make pi communicate arduino directly via rf not able cope real time (at least default kernel, far know) had trouble making work reliably "home made" radio protocol.

virtualwire works fine between 2 arduinos, hence idea put arduino in between, serving i2c rf extension pi.

my problem i2c works time, after while arduino disappears i2c bus (as seen pi perspective @ least, doesn't appear i2cdetect command anymore) , have reset arduino rejoin bus.
i started simple "ping" application in pi sends string arduino, arduino copies buffer , sends when pi requests it. plan make bidirectional communication other arduino put random "latency" before data ready (to simulate acknoledge via radio).
here code arduino slave device

code: [select]

#include <wire.h>

volatile boolean inputavailable = false;
volatile boolean outputready = false;
volatile char buffer[32];
char buf[32];
long randomwait;
long heartbeat;
void setup()
{
 wire.begin(4);                // join i2c bus address #4
 wire.onreceive(receiveevent); // register event
 wire.onrequest(requestevent); // register event
 serial.begin(9600);           // start serial output
 randomseed(analogread(0));
 heartbeat = millis();
}

void loop()
{
 long target;
 if (inputavailable){
   randomwait = random(200,2500);
   target = millis()+randomwait; // random latency
   while (millis() < target); // active waiting
   inputavailable = false;
   outputready = true;
 }
 if (millis()>= heartbeat){
   serial.println("still alive");
   heartbeat = millis()+5000;
 }
}

void receiveevent(int howmany)
{
 if (!outputready && !inputavailable){
   int = 0;
   while(0 < wire.available() && < 32)
   {
     char c = wire.read();
     buffer[i++] = c;
   }
   inputavailable = true;
 }
 else{
   // inconsistant state, dump
   while (0 < wire.available()){
     wire.read();
   }
 }
}

void requestevent()
{
 if (outputready){
       memcpy((void*)buf, (void*)buffer, strlen((const char*)buffer));
     wire.write((const uint8_t*)buf, strlen(buf));
    outputready = false;
 }
}


and code pi (master) :

code: [select]
#include <stdio.h>
#include <stdlib.h>
#include <linux/i2c-dev.h>
#include <fcntl.h>
#include <string.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <time.h>

int devicehandle;

int main (int argc, char** argv)
{
 int readbytes;
 int i;
 int errcode = 0;
 // initialize buffer
 char str[32] = "hello";
 char buffer[32]; // reponse
 memset (buffer, 0, 32);
 time_t temps;
 
 if (argc > 1){
   sprintf(str,argv[1]);
 }
 
 // open device on /dev/i2c-1
 devicehandle = open("/dev/i2c-1", o_rdwr);

 if (devicehandle < 0){
   printf("problem devicehandle...\n");
 }
 
 // connection arduino i2c slave
 int devicei2caddress = 0x04;
 int res = ioctl(devicehandle, i2c_slave, devicei2caddress);
 
 if (res < 0){
     printf("problem ioctl\n");
 }
 
  int writtenbytes;
   
 printf("send %s\n", str);
 writtenbytes = write(devicehandle, str, strlen(str));
 if (writtenbytes < 1){
   printf("error!\n");
 }
 usleep(20000);
 char finished = 0;
 printf("polling i2c\n");
 time_t start, current, totaltime, prevtime;
 time (&start);
 do{
   int answer = read(devicehandle, buffer, strlen(str));
   time (&current);
   totaltime = difftime(current, start);
   
   if(answer != strlen(str) || buffer[0] == 0x00){
     if (prevtime < totaltime) // write dot every second
printf(".");
   }else{
printf ("\nreceived: %s\n---------------\n",buffer);
finished = 1;
   }
   prevtime = totaltime;
 }
 while(!finished && totaltime < 5);
 if (!finished){
   fprintf(stderr,"time out!\n");
   errcode = 1;
 }
 
 // close connection , exit
 close(devicehandle);
 return errcode;
}


the code works ok time. test :
$ while [ $? -eq 0 ];do ./a.out anticonstitutionnellement;done

after while (few dozains of seconds few minutes) output :

send anticonstitutionnellement
polling i2c
...
received: anticonstitutionnellement
---------------
send anticonstitutionnellement
polling i2c
..
received: anticonstitutionnellement
---------------
send anticonstitutionnellement
error!
polling i2c

received: ?????????????????????????
---------------
send anticonstitutionnellement
error!
polling i2c
time out!

the arduino keeps writing "still alive" on serial monitor it's not crashed...

i have level shifter between pi , arduino, worked "well" without.
i don't have osciloscope , don't know if problem timing issue, clock stretching lock or other problem.

does have clue on ? i'm out of ideas...

code: [select]
    while (millis() < target); // active waiting
what's active this? how advantage on delay()?

code: [select]
        memcpy((void*)buf, (void*)buffer, strlen((const char*)buffer));
why? there no need copy data 1 buffer another.


Arduino Forum > Using Arduino > Networking, Protocols, and Devices (Moderator: fabioc84) > Raspberry Pi <-> Arduino Uno using i2c crashes after a while


arduino

Comments

Popular posts from this blog

Convierte tu Raspberry en un NAS. Firmware fvdw-sl 15.3 - Raspberry Pi Forums

Rasperry Wifi LAN Controller - Raspberry Pi Forums

Unlock car with bluetooth and car key