PTNewbie
Posts: 5
Joined: Thu Jun 27, 2019 3:11 pm

I2C communication from Arduino to Processing 3 in RPI

Mon Jul 22, 2019 3:11 pm

Hello,

I'm doing a project in which I have an Arduino UNO adquiring data from an experimental setup and then it sends the data via I2C to the RPI where the data will be analyzed in Processing 3. I'm still a beginner in Processing 3 and I have some issues in Processing 3 more precisely in the data I'm receiving from Arduino via I2C. What I intend to have is the Processing 3 acquiring the data from the Arduino after receiving a string from the Arduino that says "done" or "ready" but the code in Processing 3 is acquiring the data before receiving the ready/done string from Arduino. Another problem I have is an error that happens frequently that says "The device did not respond. Check the cabling and whether you are using the correct address. RuntimeException: Remote I/O error" and this error appears after the Processing 3 adquire some data from Arduino and I didn't touch any wire connecting the two devices or did I change the address of the Arduino.
Can anyone help me solve these issues?

PTNewbie
Posts: 5
Joined: Thu Jun 27, 2019 3:11 pm

Re: I2C communication from Arduino to Processing 3 in RPI

Thu Aug 08, 2019 11:37 am

For anyone you can help this is the code I'm using in Processing 3, it may have something missing since I have tried different approaches to the problem.

Code: Select all

PrintWriter output;
import processing.io.*;
I2C i2c;
String transfer; 
int time;
int size = 1000, i = 0, tamanho = 200;
int value, begin=0, end = 0, jcount=0;
int sumsize = 0;
float[] sum = new float[100];
float[] voltage = new float[size];
float[] dadostempo = new float[size];

int d = day(), h =hour(), mi=minute(),seco=second();
int m = month();
int y= year();
String s = "dados"+String.valueOf(d)+String.valueOf(m)+String.valueOf(y)+"-"+String.valueOf(h)+String.valueOf(mi)+String.valueOf(seco)+".txt";

void setup(){
  println("Available I2C Interface: ");
  printArray(I2C.list());
  i2c = new I2C(I2C.list()[0]);
  //m0 = millis();
  output = createWriter(s);
  println("File open, when you want to end the program press y");
}

void draw() {
  delay(1000);

    i2c.beginTransmission(0x08);
    i2c.write(0x08);
    byte[] in = i2c.read(5);
    time = unbinary(binary(in[1])+binary(in[0]));
    value = unbinary(binary(in[3]) + binary(in[2]));
    jcount = unbinary(binary(in[4]));
    i2c.endTransmission();
    voltage[i] = value*5./1023;
    dadostempo[i] = float(tempo/1000);
    println(value, "\t", voltage[i], "\t", jcount, "\t", i);
    if (i ==tamanho-1){
     for (int j=0; j< tamanho; j++){
       output.println(dadostempo[j] + "\t" + voltage[j]); 
       println("Value of voltage is ", voltage[j]);
       if(j<tamanho-3){
         if (voltage[j] < voltage[j+1] && voltage[j+1] <= voltage[j+2] && voltage[j+2] <= voltage[j+3]){
           
           inicio=j;
           for (int k = inicio; k< tamanho-3;k++){
             if( voltage[k] >= voltage[k+1] && voltage[k+1] >= voltage[k+2] && (voltage[k+2] <= voltage[k+3] || voltage[k+3] <= 20)){
               fim = k;
               for(int l= inicio; l<fim;l++){
                 sum[sumsize] += voltage[l];
               }
               println("Value of sum is ", sum[sumsize]);
               output.println("\t\t Value of sum is " + sum[sumsize]);
               j = fim;
               k = tamanho;
               sumsize++;
             }
           }
         }
       }
     }
     output.flush();
     println("Do you want to close file?(y or n)");
     i=-1;
    }
    i+=1;
    
}

void keyPressed(){
  if(key=='y'){
    output.close();
    //i2c.endTransmission();
    noLoop();
  }
  
}
And the code I'm using in Arduino is

Code: Select all

#include <Wire.h>
const int analogINpin = A0;
const int tamanho = 200;
int measures[tamanho];
byte lowbyte[tamanho];
byte highbyte[tamanho];
int time0,time1,dt;
byte lowdt;
byte highdt;
int i=0, j=0;
float voltage;
char str[5] = "Ready";
void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  pinMode(analogINpin,INPUT);
  Wire.begin(8);
  Wire.onRequest(requestEvent); // register event
}

void loop() {
  // put your main code here, to run repeatedly:
  time0 = micros();
  for (i=0; i<tamanho; i++){
    measures[i]= analogRead(analogINpin);
  }
  time1=micros();
  dt= time1-time0;
  lowdt = dt;
  highdt = dt >> 8;
  for (i=0; i<tamanho; i++){
    lowbyte[i] = measures[i];
    highbyte[i] = measures[i] >> 8;
    Serial.println(measures[i]);
  }
//  str[5] = "done";
//  Wire.write(str); // respond with message of 5 bytes
//  str[5] = "notno";
////  Serial.print("Time ");
////  Serial.println( dt);
  
  delay(1000);
}

void requestEvent() {
  
    Wire.write(lowdt);
    Wire.write(highdt);
    Wire.write(lowbyte[j]);
    Wire.write(highbyte[j]);
    Wire.write(j);
    j+=1;
    if(j==tamanho){j=0;}
}
What I wanted the code in processing to do was to wait until it receives the value of str from arduino saying done which would allow arduino to fill the measures array and then sending that data to Processing 3. What I noticed is that Processing starts acquiring the data before receiving the str "done".

User avatar
scruss
Posts: 2360
Joined: Sat Jun 09, 2012 12:25 pm
Location: Toronto, ON
Contact: Website

Re: I2C communication from Arduino to Processing 3 in RPI

Thu Aug 08, 2019 12:18 pm

Your processing code never checks for 'done' (does it even open the serial device to do it?) and the Arduino code has the 'done' printing bit commented out.
‘Remember the Golden Rule of Selling: “Do not resort to violence.”’ — McGlashan.

PTNewbie
Posts: 5
Joined: Thu Jun 27, 2019 3:11 pm

Re: I2C communication from Arduino to Processing 3 in RPI

Fri Aug 09, 2019 11:48 am

As I said before I copied the code, in the last post, the code I copied was one of the variants I tried. The version that as the search for done is the following code, but I still have the same problem, the Processing starts to search for the word before the Arduino changes the value of the string to done and then I'm stuck in the loop of receiving Ready in Processing and can't get out of the loop. :/

Code: Select all

PrintWriter output;
import processing.io.*;
I2C i2c;

String transfer; 
int time;
int size = 1000, i = 0, sizearray = 200;
int value, begin=0, end = 0, jcount=0;
int sumsize = 0;
float[] sum = new float[100];
float[] voltage = new float[size];
float[] datatime = new float[size];

void setup(){
  println("Available I2C Interface: ");
  printArray(I2C.list());
  i2c = new I2C(I2C.list()[0]);
  //m0 = millis();
  
}

void draw() {
  //m = millis();
  
  i2c.beginTransmission(0x08);
  i2c.write(0x33);
  byte[] stready = i2c.read(4);
  i2c.endTransmission();
  transfer = trim(new String(stready));
  println(transfer);
  if (transfer.equals("done")){
    test.beginTransmission(0x08);
    test.write(0x08);
    byte[] in = test.read(4);
    time = unbinary(binary(in[1])+binary(in[0]));
    value = unbinary(binary(in[3]) + binary(in[2]));
    test.endTransmission();
    voltage[i] = val*5./1023;
    datatime[i] = float(time/1000);
    println(time, "\t", value, "\t", voltage[i]);
    if (i ==size){
     for (int j=0; j< sizearray; j++){
       output.println(datatime[j] + "\t" + voltage[j]); 
       println("Value of voltage is ", voltage[j]);
       if(j<tamanho-3){
         if (voltage[j] < voltage[j+1] && voltage[j+1] <= voltage[j+2] && voltage[j+2] <= voltage[j+3]){
           
           start=j;
           for (int k = start; k< sizearray-3;k++){
             if( voltage[k] >= voltage[k+1] && voltage[k+1] >= voltage[k+2] && (voltage[k+2] <= voltage[k+3] || voltage[k+3] <= 20)){
               end = k;
               for(int l= start; l<end;l++){
                 sum[sumsize] += voltage[l];
               }
               println("Value of sum is ", sum[sumsize]);
               output.println("\t\t Value of sum is " + sum[sumsize]);
               j = fim;
               k = tamanho;
               sumsize++;
             }
           }
         }
       }
     }
     output.flush();
     println("Do you want to close file?(y or n)");
     i=-1;
    }
    i+=1;
    
  }
  counter += 1;
  println("Number of cycle ", counter, "\t Time of this cycle: ", dt, "\t Time since start of program: ", dtt);
}
This is the code for the Arduino. The idea in this version of the code for Arduino is that it starts the acquisition after receiving a byte with the int 51 and the idea in the loop is to change the variable str to done after it has finished the acquisition which is represented by the delay(1000) in this version of the code.

Code: Select all

#include <Wire.h>

char str[4] = "set1";
int counter =0;
int time=22000;
int value = 1000;
byte lowbyte = value;
byte highbyte = value >> 8;
byte lowdt = dt;
byte highdt = dt >> 8;
void setup() {
  Serial.begin(9600);
  Wire.begin(8);                // join i2c bus with address #8
  //Wire.onRequest(requestEvent); // register event
  Wire.onReceive(receivevent);

}

void loop() {
  delay(1000); //it should change the value of time and value in this part, but for the example it works with a fix value
  str[4] = "done";
   Wire.onRequest(requestEvent);
  str[4] = "sdat";
  counter++;
}

// function that executes whenever data is requested by master
// this function is registered as an event, see setup()
void requestEvent() {
  Wire.write(str);
  if(str == "done")
  {
     Wire.write(lowdt);
     Wire.write(highdt);
     Wire.write(lowbyte);
     Wire.write(highbyte);
     Wire.write(counter); 
     counter++;
  }
 
}

void receivevent() {
  
    int rec = Wire.read();
    Serial.println(rec);
    if(rec == 51){
      loop();
    }
}

Return to “Java”