Go Down

Topic: ping ))) code help (Read 948 times) previous topic - next topic

kazimier

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: [Select]
/* 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


mem

#1
May 29, 2009, 07:28 pm Last Edit: May 29, 2009, 07:29 pm by mem Reason: 1
That looks like it used an old version of serial code. Not tested, but try this:
Code: [Select]
/* 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);
}

kazimier

#2
Jun 01, 2009, 01:40 pm Last Edit: Jun 01, 2009, 02:05 pm by kazimier Reason: 1
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 8) 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.

AWOL

#3
Jun 01, 2009, 01:42 pm Last Edit: Jun 01, 2009, 01:45 pm by AWOL Reason: 1
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".   ;)
"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.

mem

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.

gutrun

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?

kazimier

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.  

kazimier

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

Code: [Select]
/* 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.

AWOL

#8
Jun 04, 2009, 11:06 pm Last Edit: Jun 05, 2009, 09:32 am by AWOL Reason: 1
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.
"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.

Rocky78910

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)

Go Up