Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple serial values from arduino to processing?

I have a small problem.

I am passing information from an arduino attached 3 axis accelerometer + 3 axis magnetometer + compass heading. These are scaled to midi ranges (0-127).

ARDUINO: This is passed in a serial print with a format like 76a45b120c23d12e23f34g

  Serial.print(shiftAx);
  Serial.print("a");
  Serial.print(shiftAy);
  Serial.print("b");
  Serial.print(shiftAz);
  Serial.print("c");
  Serial.print(shiftMx);
  Serial.print("d");
  Serial.print(shiftMy);
  Serial.print("e");
  Serial.print(shiftMz);
  Serial.print("f");
  Serial.print(shiftHead);
  Serial.print("g");

I can see this works using my serial monitor. (however I am unsure as to print it as println at "g" or not.)

PROCESSING 2:

I buffer until g in my void setup()

port = new Serial(this, "/dev/tty.usbmodem411", 9600);
port.bufferUntil('g'); 

i have the function

    void serialEvent (Serial port)
{

  data = port.readStringUntil('g');

  AxVal = data.substring(0, data.indexOf('a'));

  AyVal = data.substring(data.indexOf("a") + 1, data.indexOf("b"));  

  AzVal = data.substring(data.indexOf("b") + 1, data.indexOf("c"));

  MxVal = data.substring(data.indexOf("c") + 1, data.indexOf("d"));

  MyVal = data.substring(data.indexOf("d") + 1, data.indexOf("e"));

  MzVal = data.substring(data.indexOf("e") + 1, data.indexOf("f"));

  HeadVal = data.substring(data.indexOf("f") + 1, data.indexOf("g"));

}

THE PROBLEM So this doesn't work. No text displayed. (its just a simple fill(), text())

I don't see why. Is the problem my protocol (if I can call it that), how I'm unpacking the string? Or some other problem.

I am very confused.

I can get it to work with just two values as in this tutorial

notes: The arduino main loop is on delay(100); arduino is at 9600 baud rate

I shall attach the whole sketches if needed to help me, which I shall extend my thanks beforehand.

CODE:

PROCESSING

import themidibus.*; //Import the library
import javax.sound.midi.MidiMessage; //Import the MidiMessage classes http://java.sun.com/j2se/1.5.0/docs/api/javax/sound/midi/MidiMessage.html
import javax.sound.midi.SysexMessage;
import javax.sound.midi.ShortMessage;
import processing.serial.*;

MidiBus myBus; // The MidiBus

Serial port;

String AxVal = " ", AyVal = " ", AzVal = " ";
String MxVal = " ", MyVal = " ", MzVal = " ";
String HeadVal = " ";
String AxString="Ax",AyString = "Ay",AzString = "Az";
String MxString="Mx",MyString = "My",MzString = "Mz";
String HeadString="Heading";
String data = " ";
PFont font;


int status_byte = 0xB0; //  send control change
  int channel_byte = 0; // On channel 0 
  int first_byte; // cc number;
  int second_byte; // value

void setup()
{
  size(1000,500);
  port = new Serial(this, "/dev/tty.usbmodem411", 9600);
  port.bufferUntil('g'); 
  font = loadFont("NanumBrush-48.vlw");
  textFont(font, 48);

    MidiBus.list(); // List all available Midi devices on STDOUT. This will show each device's index and name.
  myBus = new MidiBus(this, 1, 0); // Create a new MidiBus object

}

void draw()
{
  background(0,0,0);

  //first_byte = 1;
  //second_byte = int(AxVal); // But with less velocity
  //myBus.sendMessage(status_byte, channel_byte, first_byte, second_byte);
  fill(46, 209, 2);
  text(AxVal, 60, 75);
  text(AxString, 60, 125);

  //first_byte = 2;
  //second_byte = int(AyVal); // But with less velocity
  //myBus.sendMessage(status_byte, channel_byte, first_byte, second_byte);
  fill(0, 160, 153);
  text(AyVal, 120, 75);
  text(AyString,120,125);



 // first_byte = 3;
  //second_byte = int(AzVal); // But with less velocity
  //myBus.sendMessage(status_byte, channel_byte, first_byte, second_byte);
  fill(0, 160, 153);
  text(AzVal, 180, 75);
  text(AzString,180,125);

  /*
  first_byte = 4;
  second_byte = int(MxVal); // But with less velocity
  myBus.sendMessage(status_byte, channel_byte, first_byte, second_byte);
  fill(0, 160, 153);
  text(MxVal, 240, 75);
  text(MxString,240,125);

  first_byte = 5;
  second_byte = int(MyVal); // But with less velocity
  myBus.sendMessage(status_byte, channel_byte, first_byte, second_byte);
  fill(0, 160, 153);
  text(MyVal, 300, 75);
  text(MyString,300,125);

  first_byte = 6;
  second_byte = int(MzVal); // But with less velocity
  myBus.sendMessage(status_byte, channel_byte, first_byte, second_byte);
  fill(0, 160, 153);
  text(MzVal, 360, 75);
  text(MzString,360,125);

  first_byte = 7;
  second_byte = int(HeadVal); // But with less velocity
  myBus.sendMessage(status_byte, channel_byte, first_byte, second_byte);
  fill(0, 160, 153);
  text(HeadVal, 420, 75);
  text(HeadString,420,125);

  */

}

void serialEvent (Serial port)
{

  data = port.readStringUntil('g');
  data = data.substring(0, data.length() - 1);

  AxVal = data.substring(0, data.indexOf('a'));


  AyVal = data.substring(data.indexOf("a") + 1, data.indexOf("b"));


  AzVal = data.substring(data.indexOf("b") + 1, data.length());

 /* 
  index = data.indexOf("c")+1;
  MxVal = data.substring(index, data.indexOf("d"));

  index = data.indexOf("d")+1;
  MyVal = data.substring(index, data.indexOf("e"));

  index = data.indexOf("e")+1;
  MzVal = data.substring(index, data.indexOf("f"));

  index = data.indexOf("f")+1;
  HeadVal = data.substring(index, data.indexOf("g"));
  */

}
/*
void serialEvent (Serial port)
{

  data = port.readStringUntil('g');

  AxVal = data.substring(0, data.indexOf('a'));

  AyVal = data.substring(data.indexOf("a") + 1, data.indexOf("b"));  

  AzVal = data.substring(data.indexOf("b") + 1, data.indexOf("c"));

  MxVal = data.substring(data.indexOf("c") + 1, data.indexOf("d"));

  MyVal = data.substring(data.indexOf("d") + 1, data.indexOf("e"));

  MzVal = data.substring(data.indexOf("e") + 1, data.indexOf("f"));

  HeadVal = data.substring(data.indexOf("f") + 1, data.indexOf("g"));

}

ARDUINO:

// Add lastvalue check

#include <Wire.h>
#include <LSM303DLH.h>

LSM303DLH glove;

 //set max min magnetometer
        int maxMx = +353, maxMy = +527, maxMz = 426;
    int minMx = -700, minMy = -477, minMz = -561;

        int maxA = 2019;
    int minAx = -1043, minAy = -2048, minAz = -2048;

        int shiftMx,shiftMy,shiftMz;
        int shiftAx,shiftAy,shiftAz;    
        float shiftHeadTemp;
        int shiftHead;  



void setup()
{
 Wire.begin();
    glove.enableDefault();
   Serial.begin(9600);
}

void loop()
{



 glove.read();


    shiftMx = ((glove.m.x - minMx) / (maxMx - minMx)) * 127;
    shiftMy = ((glove.m.y - minMy) / (maxMy - minMy)) * 127;
    shiftMz = ((glove.m.z - minMz) / (maxMz - minMz)) * 127;

    shiftAx = ((glove.a.x - minAx) / (maxA - minAx)) * 127;
    shiftAy = ((glove.a.y - minAy) / (maxA - minAy)) * 127;
    shiftAz = ((glove.a.z - minAz) / (maxA - minAz)) * 127;

    shiftHeadTemp = (glove.heading((LSM303DLH::vector){0,-1,0}));

    shiftHead =  (shiftHeadTemp/360)*127; 

    if (shiftMx < 0){shiftMx=0;}
    if (shiftMx >127){shiftMx=127;}
    if (shiftMy < 0){shiftMy=0;}
    if (shiftMy >127){shiftMy=127;}
    if (shiftMz < 0){shiftMz=0;}
    if (shiftMz >127){shiftMz=127;}

    if (shiftAx < 0){shiftAx=0;}
    if (shiftAx >127){shiftAx=127;}
    if (shiftAy < 0){shiftAy=0;}
    if (shiftAy >127){shiftAy=127;}
    if (shiftAz < 0){shiftAz=0;}
    if (shiftAz >127){shiftAz=127;}

    if (shiftHead < 0){shiftHead=0;}
    if (shiftHead >127){shiftHead=127;}




  Serial.print(shiftAx);
  Serial.print("a");
  Serial.print(shiftAy);
  Serial.print("b");
  Serial.print(shiftAz);
  Serial.print("c");
  Serial.print(shiftMx);
  Serial.print("d");
  Serial.print(shiftMy);
  Serial.print("e");
  Serial.print(shiftMz);
  Serial.print("f");
  Serial.print(shiftHead);
  Serial.println("g");



  delay(100);


}
like image 761
ash Avatar asked Aug 11 '13 13:08

ash


People also ask

How does Arduino send data to serial monitor?

How? Using serial inputs is not much more complex than serial output. To send characters over serial from your computer to the Arduino just open the serial monitor and type something in the field next to the Send button. Press the Send button or the Enter key on your keyboard to send.

Why do we use serial begin 9600?

begin(9600)'. This starts serial communication, so that the Arduino can send out commands through the USB connection. The value 9600 is called the 'baud rate' of the connection. This is how fast the data is to be sent.

Is Arduino serial asynchronous?

As of Arduino IDE 1.0, serial transmission is asynchronous. If there is enough empty space in the transmit buffer, Serial. write() will return before any characters are transmitted over serial.


1 Answers

I can't test your code right now but here are some ideas.

You could send JSON from your Arduino to processing. Here is the example I'm using in one of my own project but you could easily adapt it to suit your needs:

void sendJson(){
    String json;

    json = "{\"accel\":{\"x\":";
    json = json + getXYZ(0);
    json = json + ",\"y\":";
    json = json + getXYZ(1);
    json = json + ",\"z\":";
    json = json + getXYZ(2);
    json = json + "},\"gyro\":{\"yaw\":";
    json = json + getYPR(0);
    json = json + ",\"pitch\":";
    json = json + getYPR(1);
    json = json + ",\"roll\":";
    json = json + getYPR(2);
    json = json + "}}";

    Serial.println(json);
}

The good thing about JSON is that it is easily "parsable" with processing using the getType() function. No more readUntil, it all goes like this: (note that in void setup() you need to change port.bufferUntil('g'); to port.bufferUntil('\n'); because in the Arduino, json is sent with Serial.println();)

void serialEvent (Serial port){
        String json = port.readString();

        shiftAx = getInt("shiftAx");
        shiftAy = getInt("shiftAy"); // and so on...
}

You will have to change your code a little but it will be a lot more maintainable in the long run, say if you add more sensors. You'll just need to change the json in arduino and simply get the value in processing.

Another thing: you could use the constrain function to constrain your value between 0 and 127.

value = constrain(value, 0, 127);

Hope it helps!

like image 170
ladislas Avatar answered Sep 21 '22 16:09

ladislas