Go Down

Topic: Arduino Leonardo interface with Processing (Read 2637 times) previous topic - next topic

daisygrm

Hi, I am currently working on a project that involves arduino leonardo and needs to interface with processing software.
Upon reading other posts by other members I found out that their question is still unresolved. SO may I know is processing compatible with arduino leonardo? If yes, how do I go about doing it? I hope I could get a reply.

Grumpy_Mike

It is the same as any other arduino just use the serial port.
The leonardo can be made to look like a keyboard to a computer but that is only one way communication and not what you need when communicating with Processing.

daisygrm

So that means serial port is the SDA and SCL which is located at pin2(SDA) and pin3(SCL) ? Cause I have tried it using serial monitor and I could get the values however when I tried it on the processing, it doesnt work. But for my arduino uno, it works perfectly fine. What do you mean by one way communication?

PaulS

Quote
So that means serial port is the SDA and SCL which is located at pin2(SDA) and pin3(SCL) ?

It means no such thing.

Quote
Cause I have tried it using serial monitor and I could get the values however when I tried it on the processing, it doesnt work.

It, it, it. What is it? What have you tried? What are you using the Serial Monitor for? The Serial Monitor can not talk to Processing. What are you trying on Processing?

Quote
But for my arduino uno, it works perfectly fine.

There's that vague reference to "it" again. What the hell is "it"?

Quote
What do you mean by one way communication?

It means that you can't write to a keyboard. Or read from a monitor.

daisygrm

I am using a code from the FREEIMU library which is the FreeImu Quartenion  which is supposed  to give orientation values of my IMU connected to my arduino board. I want to interface the FreeIMU quartenion with the FREEIMU cube in processing. However, when I am using arduino UNO, the program can work but when I am using Arduino Leonardo it cant work. Attached was the files I am trying to work with.

Grumpy_Mike

Quote
I am using a code from the FREEIMU library which is the FreeImu Quartenion  which is supposed  to give orientation values of my IMU connected to my arduino board. I want to interface the FreeIMU quartenion with the FREEIMU cube in processing.

I have no idea what any of that means. If you are running code from a library and have hardware to interface to, then give us a break and provide some links.

daisygrm

Sorry for not giving the link asap but here it is http://www.varesano.net/blog/fabio/initial-tests-freeimu-v04-and-mpu6050. In here fabio is using an arduino uno, however I wanted to use arduino leonardo.

Grumpy_Mike

You haven't got the hang of asking questions have you.

You have code that works on the Uno but not on the leonardo, so what we need to see is this code.
A link to it would be good.
The link you posted had a FreeIMU_cube zip file but it contained no Arduino code only processing code.
So what code are you running on the Arduino?

Grumpy_Mike

You will need to add
Code: [Select]

Serail.begin(9600);
   // while the serial stream is not open, do nothing:
   while (!Serial) ;

In your setup function.

And have you read this?
http://arduino.cc/en/Guide/ArduinoLeonardo#toc2

daisygrm

Code: [Select]

#include <ADXL345.h>
#include <bma180.h>
#include <HMC58X3.h>
#include <ITG3200.h>
#include <MS561101BA.h>
#include <I2Cdev.h>
#include <MPU60X0.h>
#include <EEPROM.h>

//#define DEBUG
#include "DebugUtils.h"
#include "CommunicationUtils.h"
#include "FreeIMU.h"
#include <Wire.h>
#include <SPI.h>


float q[4];

// Set the FreeIMU object
FreeIMU my3IMU = FreeIMU();

void setup() {
  Serial.begin(115200);
  Wire.begin();
 
  delay(5);
  my3IMU.init();
  delay(5);
}


void loop() {
  my3IMU.getQ(q);
  serialPrintFloatArr(q, 4);
  Serial.println("");
  delay(20);
}

Grumpy_Mike

So why are you ignoring what I said in reply #8?

daisygrm

#11
Apr 26, 2013, 03:57 am Last Edit: Apr 26, 2013, 04:00 am by daisygrm Reason: 1
Okay this is the code now after I implement your reply #8.
But the processing sketch still cant work.
Code: [Select]
#include <ADXL345.h>
#include <bma180.h>
#include <HMC58X3.h>
#include <ITG3200.h>
#include <MS561101BA.h>
#include <I2Cdev.h>
#include <MPU60X0.h>
#include <EEPROM.h>

//#define DEBUG
#include "DebugUtils.h"
#include "CommunicationUtils.h"
#include "FreeIMU.h"
#include <Wire.h>
#include <SPI.h>


float q[4];

// Set the FreeIMU object
FreeIMU my3IMU = FreeIMU();

void setup() {
 Serial.begin(115200);
 while(!Serial);
 Wire.begin();
 
 delay(5);
 my3IMU.init();
 delay(5);
}


void loop() {
 my3IMU.getQ(q);
 serialPrintFloatArr(q, 4);
 Serial.println("");
 delay(20);
}
]


This is the code at my processsing sketch :
Code: [Select]

import processing.serial.*;
import processing.opengl.*;

Serial myPort;  // Create object from Serial class

final String serialPort = "COM3"; // replace this with your serial port. On windows you will need something like "COM1".

float [] q = new float [5];
float [] hq = null;
float [] Euler = new float [3]; // psi, theta, phi
float [] d= new float[12];
float [] g= new float[4];//gravity
float [] a= new float[11];//accelerometer data
float [] v= new float [11];//velocity
float [] distance = new float [12];
int seconds;
float b;
int t=0;//counter

int lf = 10; // 10 is '\n' in ASCII
byte[] inBuffer = new byte[22]; // this is the number of chars on each line from the Arduino (including /r/n)

PFont font;
final int VIEW_SIZE_X = 1000, VIEW_SIZE_Y =600;
final int burst = 32;
int count = 0;

void myDelay(int time) {
  try {
    Thread.sleep(time);
  }
  catch (InterruptedException e) {
  }
}

void setup()
{
  size(VIEW_SIZE_X, VIEW_SIZE_Y, OPENGL);
  myPort = new Serial(this, serialPort, 115200);

  // The font must be located in the sketch's "data" directory to load successfully
  font = loadFont("CourierNew36.vlw");

  println("Waiting IMU..");

  myPort.clear();

  while (myPort.available () == 0) {
    myPort.write("v");
    myDelay(1000);
  }
  println(myPort.readStringUntil('\n'));
  myPort.write("q" + char(burst));
  myPort.bufferUntil('\n');
}


float decodeFloat(String inString) {
  byte [] inData = new byte[4];

  if (inString.length() == 8) {
    inData[0] = (byte) unhex(inString.substring(0, 2));
    inData[1] = (byte) unhex(inString.substring(2, 4));
    inData[2] = (byte) unhex(inString.substring(4, 6));
    inData[3] = (byte) unhex(inString.substring(6, 8));
  }

  int intbits = (inData[3] << 24) | ((inData[2] & 0xff) << 16) | ((inData[1] & 0xff) << 8) | (inData[0] & 0xff);
  return Float.intBitsToFloat(intbits);
}

void serialEvent(Serial p) {
  if (p.available() >= 18) {
    String inputString = p.readStringUntil('\n');
    //print(inputString);
    if (inputString != null && inputString.length() > 0) {
      String [] inputStringArr = split(inputString, ",");
      if (inputStringArr.length >= 5) { // q1,q2,q3,q4,\r\n so we have 5 elements
        q[0] = decodeFloat(inputStringArr[0]);
        q[1] = decodeFloat(inputStringArr[1]);
        q[2] = decodeFloat(inputStringArr[2]);
        q[3] = decodeFloat(inputStringArr[3]);
      }
    }
    count = count + 5;
    if (burst == count) { // ask more data when burst completed
      p.write("q" + char(burst));
      count = 0;
    }
  }
}



void buildBoxShape() {
  //box(40, 10, 60);
  stroke(#ffffff, 255);
  strokeWeight(10);
  beginShape(QUADS);


  //x- (to the drawing area)
  fill(#00ff00);
  vertex(-20, -10, 30);
  vertex(20, -10, 30);
  vertex(20, 10, 30);
  vertex(-20, 10, 30);


  //x+
  fill(#0000ff);
  vertex(-20, -10, -30);
  vertex(20, -10, -30);
  vertex(20, 10, -30);
  vertex(-20, 10, -30);

  //y+
  fill(#ff0000);
  vertex(-20, -10, -30);
  vertex(-20, -10, 30);
  vertex(-20, 10, 30);
  vertex(-20, 10, -30);

  //y-
  fill(#ffff00);
  vertex(20, -10, -30);
  vertex(20, -10, 30);
  vertex(20, 10, 30);
  vertex(20, 10, -30);

  //Z+
  fill(#ff00ff);
  vertex(-20, -10, -30);
  vertex(20, -10, -30);
  vertex(20, -10, 30);
  vertex(-20, -10, 30);

  //Z-
  fill(#00ffff);
  vertex(-20, 10, -30);
  vertex(20, 10, -30);
  vertex(20, 10, 30);
  vertex(-20, 10, 30);

  endShape();
}


void drawCube() { 
  pushMatrix();
  translate(VIEW_SIZE_X/2, VIEW_SIZE_Y/2 + 50, 0);
  scale(5, 5, 5);

  // a demonstration of the following is at
  // http://www.varesano.net/blog/fabio/ahrs-sensor-fusion-orientation-filter-3d-graphical-rotating-cube
  rotateZ(-Euler[2]);
  rotateX(-Euler[1]);
  rotateY(-Euler[0]);

  buildBoxShape();

  popMatrix();
}


void draw() {
  background(#000000);
  fill(#FFFFFF);

  if (hq != null) { // use home quaternion
    quaternionToEuler(quatProd(hq, q), Euler);
    text("Disable home position by pressing \"n\"", 20, VIEW_SIZE_Y - 30);
  }
  else {
    quaternionToEuler(q, Euler);
    text("Point FreeIMU's X axis to your monitor then press \"h\"", 20, VIEW_SIZE_Y - 30);
  }

  textFont(font, 22);
  textAlign(LEFT, TOP);
  text("RawAcc DATA:\n" + q[0] + "\n" + q[1] + "\n" + q[2] + "\n" + q[3], 20, 20);
  text("GYRO DATA:\nYaw (psi)  : " + degrees(Euler[0]) + "\nPitch (theta): " + degrees(Euler[1]) + "\nRoll (phi)  : " + degrees(Euler[2]), 200, 20);
if (key == 's')
{
  t=t+1;
  seconds = t/60;
  if (seconds == 0)
  {
    a[0] = q[2];
    v[0] = 0;
    d[0] = 0;
  }
    if (seconds == 1)
  {
    a[1] = q[2];
    v[1] = a[0];
    d[1] = 0.5 * a[0];
  }
    if (seconds == 2)
  {
    a[2] = q[2];
    v[2] = v[1] + a[1];
    d[2] = d[1] + v[1] + 0.5 * a[1];
  }
    if (seconds == 3)
  {
    a[3] = q[2];
    v[3] = v[2] + a[2];
    d[3] = d[2] + v[2] + 0.5 * a[2];
  }
    if (seconds == 4)
  {
    a[4] = q[2];
    v[4] = v[3] + a[3];
    d[4] = d[3] + v[3] + 0.5 * a[3];
  }
    if (seconds == 5)
  {
    a[5] = q[2];
    v[5] = a[4] + v[4];
    d[5] = v[4] + d[4] + 0.5* a[4];
  }
    if (seconds == 6)
  {
    a[6] = q[2];
    v[6] = a[5] + a[5] ;
    d[6] = v[5] + d[5] + 0.5 * a[5];
  }
    if (seconds == 7)
  {
    a[7] = q[2];
    v[7] = a[6] + v[6];
    d[7] = v[6] + d[6] + 0.5 * a[6];
  }
    if (seconds == 8)
  {
    a[8] = q[2];
    v[8] = a[7] + v[7];
    d[8] = v[7] + d[7] + 0.5 * 8;
  }
    if (seconds == 9)
  {
    a[9] = q[2];
    v[9] = a[8] + v[8];
    d[9] = v[8] + d[8] + 0.5 * a[8];
  }
      if (seconds == 10)
  {
    a[10] = q[2];
    v[10] = a[9] + v[9];
    d[10] = v[9] + d[9] + 0.5 * a[9];
  }

}
if ( key=='d')
{
  t=0;
  seconds = 0;
  a[10] = 0;
  v[10] = 0;
  d[10] = 0;
}
  text("Time:\n" +"\n" + seconds,700, 200);
  text("AccMap:\n" + "\n" + a[10] , 700,300);
  text("Velocity:\n"+ v[10] + "\n" + "Distance:" + d[10], 700,  450);
  drawCube();
  //myPort.write("q" + 1);
}


void keyPressed() {
  if (key == 'h') {
    println("pressed h");

    // set hq the home quaternion as the quatnion conjugate coming from the sensor fusion
    hq = quatConjugate(q);
  }
  else if (key == 'n') {
    println("pressed n");
    hq = null;
  }

}
// See Sebastian O.H. Madwick report
// "An efficient orientation filter for inertial and intertial/magnetic sensor arrays" Chapter 2 Quaternion representation

void quaternionToEuler(float [] q, float [] euler) {
  euler[0] = atan2(2 * q[1] * q[2] - 2 * q[0] * q[3], 2 * q[0]*q[0] + 2 * q[1] * q[1] - 1); // psi
  euler[1] = -asin(2 * q[1] * q[3] + 2 * q[0] * q[2]); // theta
  euler[2] = atan2(2 * q[2] * q[3] - 2 * q[0] * q[1], 2 * q[0] * q[0] + 2 * q[3] * q[3] - 1); // phi
}

float [] quatProd(float [] a, float [] b) {
  float [] q = new float[4];

  q[0] = a[0] * b[0] - a[1] * b[1] - a[2] * b[2] - a[3] * b[3];
  q[1] = a[0] * b[1] + a[1] * b[0] + a[2] * b[3] - a[3] * b[2];
  q[2] = a[0] * b[2] - a[1] * b[3] + a[2] * b[0] + a[3] * b[1];
  q[3] = a[0] * b[3] + a[1] * b[2] - a[2] * b[1] + a[3] * b[0];

  return q;
}

// returns a quaternion from an axis angle representation
float [] quatAxisAngle(float [] axis, float angle) {
  float [] q = new float[4];

  float halfAngle = angle / 2.0;
  float sinHalfAngle = sin(halfAngle);
  q[0] = cos(halfAngle);
  q[1] = -axis[0] * sinHalfAngle;
  q[2] = -axis[1] * sinHalfAngle;
  q[3] = -axis[2] * sinHalfAngle;

  return q;
}

// return the quaternion conjugate of quat
float [] quatConjugate(float [] quat) {
  float [] conj = new float[4];

  conj[0] = quat[0];
  conj[1] = -quat[1];
  conj[2] = -quat[2];
  conj[3] = -quat[3];

  return conj;
}




Grumpy_Mike

Quote
But the processing sketch still cant work.

You have to say how. It does note work.
Is it not seeing the arduino?
Does the arduino show up in the list of com ports when you print it out?
Print out what serial port to attach to in order to make sure it is the correct one.

daisygrm

It doesnt work meaning it can initialise the processing sketch but it is stuck at the "WAITING IMU" . I believe its not seeing the arduino.

Grumpy_Mike

So print out all the ports that processing can see. Unless your arduino shows up as COM3 it will not connect.

Go Up