Pages: [1]   Go Down
Author Topic: ping ))) code help  (Read 757 times)
0 Members and 1 Guest are viewing this topic.
UK
Offline Offline
Full Member
***
Karma: 0
Posts: 115
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

hi

I have recently aquired a Ping ))) ultrasonic sensor for an upcoming project for which I need the data being recieved by the sensor to be output as a midi cc value to control a vj software (it is to build a crystal ball which a magician will use to tell the future - by bringing his hand towards it and hence increasing the opacity / volume of the video clip). The sensor works great and when I tested it with the code provided in the playground i get very stable results. I have been trying to implement the code found on the brilliant little_scale blog:
http://little-scale.blogspot.com/2008/04/ping-sans-max.html

however when i input the code into arduino:

Code:
/* New Variables */
int delay_time = 40; // delay for this amount each write cycle.
byte MIDI_channel = 1;
byte cc_number = 127;

byte printing_byte = 0;
int baud_rate = 31250;

/* Ultrasound Sensor
 *------------------
 *
 * Reads values (00014-01199) from an ultrasound sensor (3m sensor)
 * and writes the values to the serialport.
 *
 * http://www.xlab.se | http://www.0j0.org
 * copyleft 2005 Mackie for XLAB | DojoDave for DojoCorp
 *
 */
 
 // CODE EDITED BY SEBASTIAN TOMCZAK 23 APRIL 2008

int ultraSoundSignal = 7; // Ultrasound signal pin
int val = 0;
int ultrasoundValue = 0;
int timecount = 0; // Echo counter
int ledPin = 13; // LED connected to digital pin 13

void setup() {
  beginSerial(baud_rate);
  pinMode(ledPin, OUTPUT);            // Sets the digital pin as output
  MIDI_channel = MIDI_channel - 1;
}

void loop() {
  timecount = 0;
  val = 0;
  pinMode(ultraSoundSignal, OUTPUT); // Switch signalpin to output

  /* Send low-high-low pulse to activate the trigger pulse of the sensor
   * -------------------------------------------------------------------
   */

  digitalWrite(ultraSoundSignal, LOW); // Send low pulse
  delayMicroseconds(2); // Wait for 2 microseconds
  digitalWrite(ultraSoundSignal, HIGH); // Send high pulse
  delayMicroseconds(5); // Wait for 5 microseconds
  digitalWrite(ultraSoundSignal, LOW); // Holdoff

  /* Listening for echo pulse
   * -------------------------------------------------------------------
   */

  pinMode(ultraSoundSignal, INPUT); // Switch signalpin to input
  val = digitalRead(ultraSoundSignal); // Append signal value to val
  while(val == LOW) { // Loop until pin reads a high value
    val = digitalRead(ultraSoundSignal);
  }

  while(val == HIGH) { // Loop until pin reads a high value
    val = digitalRead(ultraSoundSignal);
    timecount = timecount +1;            // Count echo pulse time
  }

  /* Writing out values to the serial port
   * -------------------------------------------------------------------
   */

  ultrasoundValue = timecount; // Append echo pulse time to ultrasoundValue

  /* BEGIN EDITED CODE */

  ultrasoundValue = ultrasoundValue - 14;
  ultrasoundValue = ultrasoundValue / 5;

  if(ultrasoundValue > 127) {
    printing_byte = 127;
  }
  
  else {
  
  printing_byte = ultrasoundValue;
  }
  
  printByte(B10110000 + MIDI_channel);
  printByte(cc_number);
  printByte(printing_byte);
  
  
  
  
  
  /* END EDITED CODE */



  /* Lite up LED if any value is passed by the echo pulse
   * -------------------------------------------------------------------
   */

  if(timecount > 0){
    digitalWrite(ledPin, HIGH);
  }

  /* Delay of program
   * -------------------------------------------------------------------
   */

  delay(delay_time);
}


I get the following error message:

In function 'void loop()':
error: 'printByte' was not declared in this scope


I am not too sure as to how to address this issue?
has anyone had any success outputting data being received by the ping sensor as midi cc values to a software?
any help would be greatly appreciated

Logged

London
Offline Offline
Faraday Member
**
Karma: 8
Posts: 6240
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

That looks like it used an old version of serial code. Not tested, but try this:
Code:
/* New Variables */
int delay_time = 40; // delay for this amount each write cycle.
byte MIDI_channel = 1;
byte cc_number = 127;

byte printing_byte = 0;
int baud_rate = 31250;

/* Ultrasound Sensor
 *------------------
 *
 * Reads values (00014-01199) from an ultrasound sensor (3m sensor)
 * and writes the values to the serialport.
 *
 * http://www.xlab.se | http://www.0j0.org
 * copyleft 2005 Mackie for XLAB | DojoDave for DojoCorp
 *
 */

 // CODE EDITED BY SEBASTIAN TOMCZAK 23 APRIL 2008

int ultraSoundSignal = 7; // Ultrasound signal pin
int val = 0;
int ultrasoundValue = 0;
int timecount = 0; // Echo counter
int ledPin = 13; // LED connected to digital pin 13

void setup() {
  Serial.begin(baud_rate);
  pinMode(ledPin, OUTPUT);            // Sets the digital pin as output
  MIDI_channel = MIDI_channel - 1;
}

void loop() {
  timecount = 0;
  val = 0;
  pinMode(ultraSoundSignal, OUTPUT); // Switch signalpin to output

  /* Send low-high-low pulse to activate the trigger pulse of the sensor
   * -------------------------------------------------------------------
   */

  digitalWrite(ultraSoundSignal, LOW); // Send low pulse
  delayMicroseconds(2); // Wait for 2 microseconds
  digitalWrite(ultraSoundSignal, HIGH); // Send high pulse
  delayMicroseconds(5); // Wait for 5 microseconds
  digitalWrite(ultraSoundSignal, LOW); // Holdoff

  /* Listening for echo pulse
   * -------------------------------------------------------------------
   */

  pinMode(ultraSoundSignal, INPUT); // Switch signalpin to input
  val = digitalRead(ultraSoundSignal); // Append signal value to val
  while(val == LOW) { // Loop until pin reads a high value
    val = digitalRead(ultraSoundSignal);
  }

  while(val == HIGH) { // Loop until pin reads a high value
    val = digitalRead(ultraSoundSignal);
    timecount = timecount +1;            // Count echo pulse time
  }

  /* Writing out values to the serial port
   * -------------------------------------------------------------------
   */

  ultrasoundValue = timecount; // Append echo pulse time to ultrasoundValue

  /* BEGIN EDITED CODE */

  ultrasoundValue = ultrasoundValue - 14;
  ultrasoundValue = ultrasoundValue / 5;

  if(ultrasoundValue > 127) {
    printing_byte = 127;
  }
  
  else {
  
  printing_byte = ultrasoundValue;
  }
  
  Serial.print(B10110000 + MIDI_channel,BYTE);
  Serial.print(cc_number,BYTE);
  Serial.print(printing_byte,BYTE);
  
  
  /* END EDITED CODE */

  /* Lite up LED if any value is passed by the echo pulse
   * -------------------------------------------------------------------
   */

  if(timecount > 0){
    digitalWrite(ledPin, HIGH);
  }

  /* Delay of program
   * -------------------------------------------------------------------
   */

  delay(delay_time);
}
« Last Edit: May 29, 2009, 12:29:03 pm by mem » Logged

UK
Offline Offline
Full Member
***
Karma: 0
Posts: 115
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

thanks for that - it works perfectly now. The ping))) sensor is very responsive! really looking forward to working with it. Is there a way to reverse the output from it? What I mean is currently the sensor with the above code outputs a constant midi cc value, which goes from 127 - 0, so the closer i bring my hand to the sensor the lower the number - what I want to do is make it work in reverse so the closer I bring my hand to the sensor the higher the number. I have found a software solution (MidiPipe OS X) which allows you to run all sorts of midi filters including an inverse one, but was hoping to do it internally on the arduino board itself.

So at the moment the Ping ))) sensor outputs continuous midi data which I can now use to control ableton / modul8 etc. and that is the sound and video side of the project resolved. However - I want a series of lights to be triggered when the sensor reads that the hand is close to it, i.e. when it reads that the hand is 10cm away (midi value around smiley-cool that it can trigger a sequence of on/off on pins 2-10 and then reset itself. The idea is that if the viewer brings his hand too close to the crystal ball a whole host of lights and fans will turn on and off in a fairly manic sequence to give the impression that the viewer has gone too far.
« Last Edit: June 01, 2009, 07:05:46 am by kazimier » Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 239
Posts: 24371
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
so the closer i bring my hand to the sensor the lower the number - what I want to do is make it work in reverse so the closer I bring my hand to the sensor the higher the number

There's a handy function the Arduino provides for this very application, called "subtract".   smiley-wink
« Last Edit: June 01, 2009, 06:45:48 am by AWOL » Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

London
Offline Offline
Faraday Member
**
Karma: 8
Posts: 6240
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You could also use the map function: http://www.arduino.cc/en/Reference/Map

This would also provide the capability to change the range of notes for a given range of distance.
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 3
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

hey, i have been following this thread, and have been trying about myself. but one ting doesnt work,..

i am trying to do this with vdmx and if i have the ard. enviroment running and uploaded the code vdmx doesnt find a incoming singnal.

are you running this trough a other programme before reading it in your video software?
Logged

UK
Offline Offline
Full Member
***
Karma: 0
Posts: 115
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

hey - yeah, I am using a programme called MidiPipe http://www.macupdate.com/info.php/id/10541, although this is only necessary if there is some form of midi filtering needed. If its coming out of the ping sensor correctly then it should come up on vdmx. To make sure your computer is receiving MIDI data (correctly) I use a little app called MidiMonitorhttp://www.snoize.com/MIDIMonitor/ which shows what data is coming in on what channel etc. once you establish that there is something coming in correctly the next place to check is the IAC midi driver (applications/utility/audio midi setup) is turned on and online.  
Logged

UK
Offline Offline
Full Member
***
Karma: 0
Posts: 115
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

mem: the map function seems like the perfect solution but I have been trying to implement it with little success:

Code:
/* New Variables */
int delay_time = 40; // delay for this amount each write cycle.
byte MIDI_channel = 1;
byte cc_number = 127;

byte printing_byte = 0;
int baud_rate = 31250;

/* Ultrasound Sensor
 *------------------
 *
 * Reads values (00014-01199) from an ultrasound sensor (3m sensor)
 * and writes the values to the serialport.
 *
 * http://www.xlab.se | http://www.0j0.org
 * copyleft 2005 Mackie for XLAB | DojoDave for DojoCorp
 *
 */

 // CODE EDITED BY SEBASTIAN TOMCZAK 23 APRIL 2008

int ultraSoundSignal = 11; // Ultrasound signal pin
int val = 0;
int ultrasoundValue = 0;
int timecount = 0;
int brightness = 0;// Echo counter
int ledPin = 13;
int redPin = 2;
int bluePin = 3;
int yellowPin = 4;
int whitePin = 10;// LED connected to digital pin 13

void setup() {
  Serial.begin(baud_rate);
  pinMode(ledPin, OUTPUT);
  pinMode(redPin, OUTPUT);
  pinMode(bluePin, OUTPUT);
  pinMode(yellowPin, OUTPUT);
  pinMode(whitePin, OUTPUT);            // Sets the digital pin as output
  MIDI_channel = MIDI_channel - 1;
}

void loop() {
  timecount = 0;
  val = 0;
  pinMode(ultraSoundSignal, OUTPUT); // Switch signalpin to output

  /* Send low-high-low pulse to activate the trigger pulse of the sensor
   * -------------------------------------------------------------------
   */

  digitalWrite(ultraSoundSignal, LOW); // Send low pulse
  delayMicroseconds(2); // Wait for 2 microseconds
  digitalWrite(ultraSoundSignal, HIGH); // Send high pulse
  delayMicroseconds(5); // Wait for 5 microseconds
  digitalWrite(ultraSoundSignal, LOW); // Holdoff

  /* Listening for echo pulse
   * -------------------------------------------------------------------
   */

  pinMode(ultraSoundSignal, INPUT); // Switch signalpin to input
  val = digitalRead(ultraSoundSignal); // Append signal value to val
  while(val == LOW) { // Loop until pin reads a high value
    val = digitalRead(ultraSoundSignal);
  }

  while(val == HIGH) { // Loop until pin reads a high value
    val = digitalRead(ultraSoundSignal);
    timecount = timecount +1;            // Count echo pulse time
  }

  /* Writing out values to the serial port
   * -------------------------------------------------------------------
   */

  ultrasoundValue = timecount;
ultrasoundValue = map(ultrasoundValue, 0, 127, 127, 0);

 // Append echo pulse time to ultrasoundValue
  if((ultrasoundValue >= 110) && (ultrasoundValue < 127)){
    digitalWrite(redPin, HIGH);
    delay(100);
    digitalWrite(redPin, LOW);
    digitalWrite(bluePin, HIGH);
    delay(100);
    digitalWrite(bluePin, LOW);
    digitalWrite(redPin, HIGH);
    delay(100);
    digitalWrite(redPin, LOW);
    digitalWrite(bluePin, HIGH);
    delay(100);
    digitalWrite(bluePin, LOW);
  
  }
 
 else{
  digitalWrite(redPin, LOW);
  digitalWrite(bluePin, LOW);  
 }



  /* BEGIN EDITED CODE */

  ultrasoundValue = ultrasoundValue - 14;
  ultrasoundValue = ultrasoundValue / 5;
  brightness = ultrasoundValue;
  analogWrite(whitePin, brightness);
  if(ultrasoundValue > 127) {
    printing_byte = 127;
    
  
  }
  
  else {
  
  printing_byte = ultrasoundValue ;
  }
  
  Serial.print(B10110000 + MIDI_channel,BYTE);
  Serial.print(cc_number,BYTE);
  Serial.print(printing_byte,BYTE);
  

  /* END EDITED CODE */

  /* Lite up LED if any value is passed by the echo pulse
   * -------------------------------------------------------------------
   */

  if(timecount > 0){
    digitalWrite(ledPin, HIGH);
  }

  /* Delay of program
   * -------------------------------------------------------------------
   */

  delay(delay_time);
}

All I want is for the MIDI data to be inversed, so instead of going from 0 to 127 it went the opposite way.

On a slightly side note - I have now attached a length of LED's that get brighter when the person comes closer to the sensor, however the fade is a bit jerky (i.e. not like a smooth fade) - is that because the midi data is 0 - 127 and the LED wants to have the brightness controlled from 0 to 255? or is it just bound to be a bit jerky.
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 239
Posts: 24371
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
All I want is for the MIDI data to be inversed, so instead of going from 0 to 127 it went the opposite way

As I said earlier...if you've got a value in, say "midiData" that runs from 0...127, then

inverseMidiData = 127 - midiData;


That's the handy "subtract" operation.


If the LED fade is a bit jerky, you could try a simple rolling average over, say eight samples.
« Last Edit: June 05, 2009, 02:32:35 am by AWOL » Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

0
Offline Offline
Newbie
*
Karma: 0
Posts: 7
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I would like to use this sensor and part of this code to simply start and control volume from an MP3 track. I was going to buy the wav shield kit from adafruit to do it. Could anyone tell me how to modify the code to do that? (I'm pretty new to all of this)
Logged

Pages: [1]   Go Up
Jump to: