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.
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.
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?
So that means serial port is the SDA and SCL which is located at pin2(SDA) and pin3(SCL) ?
It means no such thing.
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?
But for my arduino uno, it works perfectly fine.
There's that vague reference to "it" again. What the hell is "it"?
What do you mean by one way communication?
It means that you can't write to a keyboard. Or read from a monitor.
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.
FreeIMU_quaternion.pde (570 Bytes)
FreeIMU_cube.pde (6.9 KB)
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.
Sorry for not giving the link asap but here it is varesano.net -. In here fabio is using an arduino uno, however I wanted to use arduino leonardo.
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?
You will need to add
Serail.begin(9600);
// while the serial stream is not open, do nothing:
while (!Serial) ;
In your setup function.
And have you read this?
#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);
}
So why are you ignoring what I said in reply #8?
Okay this is the code now after I implement your reply #8.
But the processing sketch still cant work.
#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 :
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;
}
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.
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.
So print out all the ports that processing can see. Unless your arduino shows up as COM3 it will not connect.
I use this sort of code to make sure that Processing is connected to the correct port no matter where it appears in the list of ports.
Serial myPort;
String adaptor= "/dev/tty.usbmodem1a21"; // change this to your port name
void portConnect(){
int portNumber = 99;
String [] ports;
println(Serial.list()); // print a list of ports available
ports = Serial.list();
for(int j = 0; j< ports.length; j++) { // search for the port we want
if(adaptor.equals(Serial.list()[j])) portNumber = j;
}
if(portNumber == 99) portNumber = 0; // if we haven't found our port connect to the first one
String portName = Serial.list()[portNumber];
println("Connected to "+portName); // print out what we have connected to
myPort = new Serial(this, portName, 57600);
}
Can you incorporate this into your code? Call his function from the setup and remove any port initialisation you have.