Multiple Analogue Sensors AND Razor 9DOF IMU

edited November 2013 in Arduino

Hi guys. I am trying to integrate a program that I wrote to represent the value of two strain gauges in a processing sketch, varying the colour of a rectangle according to the amount of strain, and code for the Razor 9DOF IMU. When I try and just represent one of the strain gauges, I have no problem. However, in order to represent the two strain gauges, I have split the values, as can be seen in the code below:

Arduino Code int gauge0; int gauge1;

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  gauge0=analogRead(A0);
  gauge1=analogRead(A1);
  Serial.print(gauge0);
  Serial.print(",");
  Serial.println(gauge1);
  //Serial.print(",");
  delay(10);
}

Processing Code import processing.serial.*;

int gauge0=0;
int gauge1=1;

Serial myPort;

void setup()
{
  size (800, 500);
  println (Serial.list());
  myPort = new Serial (this, "COM21", 9600);
  myPort.bufferUntil('\n');

}

void draw()
{
  pushMatrix();
  translate(300, 260);
  fill(gauge0, (100-gauge0), 0);
  rect(100,100,100,100);
  popMatrix();

  pushMatrix();
  translate(400, 260);
  fill(gauge1, (100-gauge1), 0);
  rect(100, 100, 100, 100);
  popMatrix();
}

void serialEvent(Serial myPort)
{
  String inString = myPort.readStringUntil('\n');

  if (inString!=null)
  {
    inString=trim(inString);
    int [] sensors = int(split(inString, ","));

    if (sensors.length >=2)
    {
      gauge0=sensors[0];
      gauge1=sensors[1];
    }
  }
}

This program works with no problems on its own. However, when I connect the razor IMU to one com port and an arduino loaded with the above code to another com port, and try to integrate it with code for the Razor IMU (taken from https://github.com/ptrbrtz/razor-9dof-ahrs/wiki/Tutorial , the sketch hangs on startup. I tried to integrate values for just one of the sensors with a slightly modified code, and that worked fine. I think the problem when I try and integrate the two is in the function serialEvent, and may come when I try and split the string. However, I have no idea what to do fix this problem. The code that I am using to try and integrate is below:

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

float yaw = 0.0f;
float pitch = 0.0f;
float roll = 0.0f;
float yawOffset = 0.0f;

PFont font;

Serial serial;
Serial strain;

int gauge0=0;
int gauge1=1;
boolean synched = false;

// Global setup
void setup() 
{
  // Setup graphics
  size(640, 480, OPENGL);
  smooth();
  noStroke();
  frameRate(50);

  // Load font
  font = loadFont("Univers-66.vlw");
  textFont(font);

  // Setup serial port I/O
  serial = new Serial(this, "COM18", 57600);
  strain = new Serial(this, "COM21", 9600);
  strain.bufferUntil('\n');
}

void drawBoard() {
  pushMatrix();

  rotateY(-radians(yaw - yawOffset));
  rotateX(-radians(pitch));
  rotateZ(radians(roll)); 

  // Board body
  //fill(brightness, (100-brightness), 0);
  fill (100, 100, 100);
  box(250, 20, 400);

  popMatrix();
}

// Skip incoming serial stream data until token is found
boolean readToken(Serial serial, String token) {
  // Wait until enough bytes are available
  if (serial.available() < token.length())
    return false;

  // Check if incoming bytes match token
  for (int i = 0; i < token.length(); i++) {
    if (serial.read() != token.charAt(i))
      return false;
  }

  return true;
}

void setupRazor() {
  println("Trying to setup and synch Razor...");
  delay(3000);  // 3 seconds should be enough

  // Set Razor output parameters
  serial.write("#ob");  // Turn on binary output
  serial.write("#o1");  // Turn on continuous streaming output
  serial.write("#oe0"); // Disable error message output

  // Synch with Razor
  serial.clear();  // Clear input buffer up to here
  serial.write("#s00");  // Request synch token
}

float readFloat(Serial s) {
  // Convert from little endian (Razor) to big endian (Java) and interpret as float
  return Float.intBitsToFloat(s.read() + (s.read() << 8) + (s.read() << 16) + (s.read() << 24));
}

void draw() {
   // Reset scene
  background(0);
  lights();

  // Sync with Razor 
  if (!synched) {
    textAlign(CENTER);
    fill(255);
    text("Connecting to Razor...", width/2, height/2, -200);

    if (frameCount == 2)
      setupRazor();  // Set ouput params and request synch token
    else if (frameCount > 2)
      synched = readToken(serial, "#SYNCH00\r\n");  // Look for synch token
    return;
  }

  // Read angles from serial port
  while (serial.available() >= 12) {
    yaw = readFloat(serial);
    pitch = readFloat(serial);
    roll = readFloat(serial);
  }

  // Draw board
  pushMatrix();
  translate(width/2, height/2, -350);
  drawBoard();
  popMatrix();

  textFont(font, 20);
  fill(255);
  textAlign(LEFT);

  // Output angles
  pushMatrix();
  translate(10, height - 10);
  textAlign(LEFT);
  text("Yaw: " + ((int) yaw), 0, 0);
  text("Pitch: " + ((int) pitch), 150, 0);
  text("Roll: " + ((int) roll), 300, 0);
  popMatrix();

  pushMatrix();
  translate(300, 260);
  fill(gauge0, (100-gauge0), 0);
  rect(100,100,100,100);
  popMatrix();

  pushMatrix();
  translate(400, 260);
  fill(gauge1, (100-gauge1), 0);
  rect(100, 100, 100, 100);
  popMatrix();

}

void serialEvent(Serial strain)
{
  String inString = strain.readStringUntil('\n');

  if (inString!=null)
  {
    inString=trim(inString);
    int [] sensors = int(split(inString, ","));

    if (sensors.length >=2)
    {
      gauge0=sensors[0];
      gauge1=sensors[1];
    }
  }
}

As a point of reference, the code that I had working with just the one sensor is below too. The arduino code mapped the analog input value, and is represented in the processing value brightness:

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

float yaw = 0.0f;
float pitch = 0.0f;
float roll = 0.0f;
float yawOffset = 0.0f;

PFont font;
Serial serial;
Serial strain;

float brightness=0;
boolean synched = false;

// Global setup
void setup() {
  // Setup graphics
  size(640, 480, OPENGL);
  smooth();
  noStroke();
  frameRate(50);

  // Load font
  font = loadFont("Univers-66.vlw");
  textFont(font);

  // Setup serial port I/O
  serial = new Serial(this, "COM18", 57600);
  strain = new Serial(this, "COM21", 9600);
  strain.bufferUntil('\n');
}

void drawBoard() {
  pushMatrix();

  rotateY(-radians(yaw - yawOffset));
  rotateX(-radians(pitch));
  rotateZ(radians(roll)); 

  // Board body
  fill(brightness, (100-brightness), 0);
  box(250, 20, 400);

  popMatrix();
}

// Skip incoming serial stream data until token is found
boolean readToken(Serial serial, String token) {
  // Wait until enough bytes are available
  if (serial.available() < token.length())
    return false;

  // Check if incoming bytes match token
  for (int i = 0; i < token.length(); i++) {
    if (serial.read() != token.charAt(i))
      return false;
  }

  return true;
}

void setupRazor() {
  println("Trying to setup and synch Razor...");
  delay(3000);  // 3 seconds should be enough

  // Set Razor output parameters
  serial.write("#ob");  // Turn on binary output
  serial.write("#o1");  // Turn on continuous streaming output
  serial.write("#oe0"); // Disable error message output

  // Synch with Razor
  serial.clear();  // Clear input buffer up to here
  serial.write("#s00");  // Request synch token
}

float readFloat(Serial s) {
  // Convert from little endian (Razor) to big endian (Java) and interpret as float
  return Float.intBitsToFloat(s.read() + (s.read() << 8) + (s.read() << 16) + (s.read() << 24));
}

void draw() {
   // Reset scene
  background(0);
  lights();

  // Sync with Razor 
  if (!synched) {
    textAlign(CENTER);
    fill(255);
    text("Connecting to Razor...", width/2, height/2, -200);

    if (frameCount == 2)
      setupRazor();  // Set ouput params and request synch token
    else if (frameCount > 2)
      synched = readToken(serial, "#SYNCH00\r\n");  // Look for synch token
    return;
  }

  // Read angles from serial port
  while (serial.available() >= 12) {
    yaw = readFloat(serial);
    pitch = readFloat(serial);
    roll = readFloat(serial);
  }

  // Draw board
  pushMatrix();
  translate(width/2, height/2, -350);
  drawBoard();
  popMatrix();

  textFont(font, 20);
  fill(255);
  textAlign(LEFT);

  // Output info text
  text("Point FTDI connector towards screen and press 'a' to align", 10, 25);

  // Output angles
  pushMatrix();
  translate(10, height - 10);
  textAlign(LEFT);
  text("Yaw: " + ((int) yaw), 0, 0);
  text("Pitch: " + ((int) pitch), 150, 0);
  text("Roll: " + ((int) roll), 300, 0);
  popMatrix();

  pushMatrix();
  translate(300, 260);
  fill(brightness, (100-brightness), 0);
  rect(100,100,100,100);
  popMatrix();

}

void serialEvent (Serial strain)
{
  brightness = float (strain.readStringUntil('\n')

}

Any help that could be offered in this matter would be greatly appreciated. Thanks, and sorry for the very long post!

Kind Regards G.

Tagged:

Answers

  • See To newcomers in this forum: read attentively these instructions
    Categories
    Moved from Using Processing (that's not about issues with the PDE, the installation or something).

  • OK thanks PhiLho. However, I notice you've moved this topic to the Arduino forum. I don't think this is an issue with the arduino code, but rather with the processing code. Regards G.

  • Perhaps, but I see Arduino code, you mention an Arduino board, the title is all about this, and I suppose this code cannot be run without such device.

    If you think you have a pure Processing issue, I suggest to extract the relevant code to a simple sketch allowing somebody like me, without Arduino nor even a serial device, to run it. Perhaps replace serial events with key events or something.

    Sometime, this simple exercise is enough for the person doing this to see the issue, by isolating the relevant code and better understanding it. :-D

  • edited November 2013

    Ah fair enough I see your point. What leads me to believe this is a processing issue is that the arduino is loaded with only the code for the strain gauges, which works in isolation, and the razor is loaded with only code for the razor, which also works in isolation. However, when I plug these devices into two separate com ports and run the above sketch, the sketch hangs on startup. When I tried using only one strain gauge and slightly modified arduino and processing code, there was no issue. However, when trying the code for two strain gauges with the razor, it is here I have the issue, and I think it must be something to do with the function serial event, where i split a string and allow for the input from two serial ports. However, as I said, this worked fine when tested in isolation, without being combined with the razor code,

    I will give your suggestion a try tomorrow and see if I can extract some testable code for others here to possibly help with. I am currently repairing my laptop and am working from my nexus at the moment, which isn't loaded with the arduino or processing software. Thank you for your suggestion.

    Kind Regards G.

Sign In or Register to comment.