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
and code pi (master) :
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...
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 (¤t);
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...
Arduino Forum > Using Arduino > Networking, Protocols, and Devices (Moderator: fabioc84) > Raspberry Pi <-> Arduino Uno using i2c crashes after a while
arduino
Comments
Post a Comment