How do I read multiple bluetooth serial reads using capacitive touch sensors in Processing?

I am working on a project that uses two lilypad arduino to read capacitive touch sensors. Right now I have hooked up two bluetooth silver mates, one to each arduino, to send serial reads to my laptop. The arduino serial monitor spits out information as:

  smoothed = smooth(total1, .95, smoothed);   

  Serial.print(elapsedTime);
  Serial.print(" ms      ");
  Serial.print(total1);
  Serial.print("     ");
  Serial.println(smoothed);

Now I'm trying to get Processing to read the middle section (total1) so that it turns off/on a simple sketch. Right now I'm modifying the example "SerialMultiple". I had a classmate help me a bit by trying to show me how to split the incoming information, but I'm still at a loss as to how else to modify this sketch to work. I'm new to both arduino and processing. Any advice or references would be very helpful.

I'm looking to have both bluetooth devices turn on an ellipses (turn it white) based on if the total1 > 40. Otherwise it will stay off (be black). Right now the capacitive touch usually has a reading of around 15 when it is off (it fluctuates a bit), and reads above 40 when I press my finger onto it.

This is what I have for the sketch:


/**
 * Many Serial Ports
 * 
 * Read data from the multiple Serial Ports
 */


import processing.serial.*;

Serial[] myPorts = new Serial[2];  // Create a list of objects from Serial class
int[] dataIn = new int[2];         // a list to hold data from the serial ports
int index = 0;

void setup()  {
  size(400, 300);
  // print a list of the serial ports:
  printArray(Serial.list());
  // On my machine, the first and third ports in the list
  // were the serial ports that my microcontrollers were 
  // attached to.
  // Open whatever ports ares the ones you're using.

// get the ports' names:
  String portOne = Serial.list()[8];
 // String portTwo = Serial.list()[9];
  // open the ports:
  myPorts[0] = new Serial(this, portOne, 9600);
//  myPorts[1] = new Serial(this, portTwo, 9600);
}


void draw() {
  // clear the screen:
  background(0);
  // use the latest byte from port 0 for the first circle
  fill(dataIn[0]);
  ellipse(width/3, height/2, 40, 40);
    // use the latest byte from port 1 for the second circle
   fill(dataIn[1]);
  ellipse(2*width/3, height/2, 40, 40);
}

/** 
  * When SerialEvent is generated, it'll also give you
  * the port that generated it.  Check that against a list
  * of the ports you know you opened to find out where
  * the data came from
*/
void serialEvent(Serial thisPort) {
  String buffer1 = myPorts[0].readStringUntil('\n');


  String [] value = split(buffer1, " ");
  //String stringTrim = trim();
  println(value);
 // String buffer2 = myPorts[1].readStringUntil('\n');

 /* if (buffer1 != null) {
    index = buffer1.indexOf(" ");
    if (index > 0) {

      String stringtotal1 = buffer1.substring(index+1, buffer1.length());
      String trimtotal1 = trim(stringtotal1);

      int total1 = int(trimtotal1);
      println(total1);
    }
  }*/
}

  // variable to hold the number of the port:
  /*int portNumber = -1;

  // iterate over the list of ports opened, and match the 
  // one that generated this event:
  for (int p = 0; p < myPorts.length; p++) {
    if (thisPort == myPorts[p]) {
      portNumber = p;
    }
  }
  // read a byte from the port:
  int inByte = thisPort.read();
  // put it in the list that holds the latest data from each port:
  dataIn[portNumber] = inByte;
  // tell us who sent what:
  println("Got " + inByte + " from serial port " + portNumber);*/

/*
The following Wiring/Arduino code runs on both microcontrollers that
were used to send data to this sketch:

void setup()
{
  // start serial port at 9600 bps:
  Serial.begin(9600);
}

void loop() {
  // read analog input, divide by 4 to make the range 0-255:
  int analogValue = analogRead(0)/4; 
  Serial.write(analogValue);
  // pause for 10 milliseconds:
  delay(10);                 
}


*/

Sorry it is kind of messy right now, but I was trying to leave the original file there as well. Please let me know if any other information would be helpful.

-W

Answers

  • Answer ✓

    Start simple by getting 1 serial port to work then graduate to 2.

    To make life easy modify the Lilypad Arduino sketch to transmit only the "total1" value that is of interest. Make sure you transmit it as a single byte and not as a string.

    Run the original SerialMultiple sketch and if you have configured your Bluetooth serial port correctly in the sketch you should see the correct println() data in the debug console.

  • Thanks for the advice. I commented out everything but the total1 serial print in the arduino sketch. Then I put an if statement into the processing sketch to only respond to the DataIn if it was over x amount. (I also cleaned up the sketch by starting over the with the serial multiple example sketch) I set this up first using my USB cable as the serial. Now I should be able to simply switch which serial port I'm using and switch to the bluetooth. Only when I switch to the bluetooth it gives me an error message.

    "Error opening serial port /dev/tty.Bluetooth-RNI-SPP: Port busy"

    and highlights in the sketch:

    "myPorts[0] = new Serial(this, portOne, 9600);"

    There shouldn't be a reason that it is busy and I have tried various combinations of restarting the sketches, exiting out of the programs, and only running one or both at a time. I should also maybe state that I have a Macbook and am running Mavericks on it. I've noticed that it has in some ways limited how my computer acknowledges bluetooth, and was rather counter intuitive to work with in the arduino program in general. Usually in the arduino program when it states it is "busy" it means it is trying to connect, and once it does the error will stay at the bottom, but the serial monitor will work. I have only noticed the bluetooth being able to connect while the serial monitor has been open. Is it possible that there is a correlation between these actions, and that I might need the serial monitor to be open in order for the bluetooth to read? This seems rather unlikely in my mind, but then again, I'm not really well versed in how bluetooth works.

    -W

  • Nvm, I got the bluetooth figured out so that it connects with the sketch. However the serial read is very erratic. With the USB cable I am able to set a threshold in my sketch that a reading of total1 > 40 sets off a response. However with the bluetooth the readings stay in a range of 40-50 with or without me touching the capacitive touch sensor. Meanwhile the LEDS I have hooked up to it still function as normal (they are set through the arduino to still turn off/on with a reading of 40+. I am not quite sure of how my arduino sketch works, but I'm guessing there is some sort of smoothing filter that allows for the readings to be more accurate. How might I be able to add something like that to the processing sketch?

    -----Arduino Sketch-----

    include <CapTouch.h>

    /* CapTouch - an example for the CapTouch class * from the v.04 - Capacitive Sensing Library for 'duino / Wiring * by Paul Badger 2-3-2012 * paul@moderndevice.com http://opensource.org/licenses/mit-license.php * * This capacitive sensing method requires two microcontroller pins (send pin, receive pin) * with a high value resistor between them (1M is a starting point) * a small capacitor (20-40 pf) from the receive pin (the sensor is connected to this pin) * to ground will result in more stable readings. Sensor is any wire or conductive foil * on the receive pin. * * Also demonstrates a simple smoothing filter which is not required in any way * by the sketch */

    // CapTouch(sendPin, receivePin) - recieve pin is the sensor to touch CapTouch touch_2_4 = CapTouch(2,4); int ledPin1 = 13;

    float smoothed;

    void setup()
    {

    Serial.begin(9600); Serial.println("start");

    }

    void loop()
    {

    long start = millis(); // scheme to time performance, delete at will long total1 = touch_2_4.readTouch(15); // read the sensor long elapsedTime = millis() - start; // scheme to time performance, delete at will

    if (total1 < 40) { digitalWrite(ledPin1, HIGH); delay(100);

    } else { digitalWrite(ledPin1, HIGH); delay(50); digitalWrite(ledPin1, LOW); delay(50); digitalWrite(ledPin1, HIGH); delay(50); digitalWrite(ledPin1, LOW); delay(50); digitalWrite(ledPin1, HIGH); delay(50); digitalWrite(ledPin1, LOW); delay(50); }

    // simple lowpass filter to take out some of the jitter // change parameter (0 is min, .99 is max) or eliminate to suit // you need a different "smoothed" variable for each sensor is using more than one smoothed = smooth(total1, .95, smoothed);

    // Serial.print(elapsedTime); // Serial.print(" ms "); Serial.println(total1); // Serial.print(" "); // Serial.println(smoothed); // print sensor output 1

    delay(5);
    }

    // simple lowpass filter // requires recycling the output in the "smoothedVal" param float smooth(float data, float filterVal, float smoothedVal){

    if (filterVal > 1){ // check to make sure param's are within range filterVal = .99; } else if (filterVal <= 0){ filterVal = 0; }

    smoothedVal = (data * (1 - filterVal)) + (smoothedVal * filterVal);

    return smoothedVal; }

    -----End Sketch-----

    -----Processing Sketch-----

    /** * Many Serial Ports * * Read data from the multiple Serial Ports */

    import processing.serial.*;

    Serial[] myPorts = new Serial[2]; // Create a list of objects from Serial class int[] dataIn = new int[2]; // a list to hold data from the serial ports

    void setup() { size(400, 300); // print a list of the serial ports: printArray(Serial.list()); // On my machine, the first and third ports in the list // were the serial ports that my microcontrollers were // attached to. // Open whatever ports ares the ones you're using.

    // get the ports' names: String portOne = Serial.list()[11]; // String portTwo = Serial.list()[2]; // open the ports: myPorts[0] = new Serial(this, portOne, 9600); // myPorts[1] = new Serial(this, portTwo, 9600); }

    void draw() { // clear the screen: background(0); // use the latest byte from port 0 for the first circle if (dataIn[0] > 50){ fill(dataIn[0]); ellipse(width/3, height/2, 40, 40); } // use the latest byte from port 1 for the second circle // fill(dataIn[1]); // ellipse(2*width/3, height/2, 40, 40); }

    /** * When SerialEvent is generated, it'll also give you * the port that generated it. Check that against a list * of the ports you know you opened to find out where * the data came from */ void serialEvent(Serial thisPort) { // variable to hold the number of the port: int portNumber = -1;

    // iterate over the list of ports opened, and match the // one that generated this event: for (int p = 0; p < myPorts.length; p++) { if (thisPort == myPorts[p]) { portNumber = p; } } // read a byte from the port: int inByte = thisPort.read(); // put it in the list that holds the latest data from each port: dataIn[portNumber] = inByte; // tell us who sent what: println("Got " + inByte + " from serial port " + portNumber); }

    /* The following Wiring/Arduino code runs on both microcontrollers that were used to send data to this sketch:

    void setup() { // start serial port at 9600 bps: Serial.begin(9600); }

    void loop() { // read analog input, divide by 4 to make the range 0-255: int analogValue = analogRead(0)/4; Serial.write(analogValue); // pause for 10 milliseconds: delay(10);
    }

    */

    -----End Sketch-----

  • Answer ✓

    Work on sending a known value from the Arduino to the Processing sketch and make sure that works reliably over Bluetooth. You have to have confidence that values can be sent reliably over Bluetooth before monkeying with the capacitive touch portion of the code.

    Have the Arduino send some known fixed number over and over with some delay in between. You should be able to reliably read that in with a barebones Processing sketch. Use println() to debug what you are receiving. If that works, have the Arduino send a known pattern over and over like the numbers 1, 2, 3, 4 repeated and make sure you can receive it reliably in the Processing sketch.

    Also, read this message below to format the code you post to this forum so it is more readable:

    http://forum.processing.org/two/discussion/14/to-newcomers-in-this-forum-read-attentively-these-instructions#Item_20

Sign In or Register to comment.