Random sound generator with water

Hi, I made this instrument for an art school in mexico city (la esmeralda) it works by sensing light with phototransistors and converting them to midi wich is the read and played by LMMS

Simply fantastic!

Very nicely done! The hardware is clean, and simple. I LOVE it!

Could you share your code with us? I'd be very interested to see what's on the software side of it! :slight_smile:

hey Thanks!! of course! here is the code, must have ttymidi libraries, then run ttymidi after upload to arduino and then connect as midi cotroller to lmms or other program.

#include <ardumidi.h>

const int sensorPin = 0; // pin that the sensor is attached to
const int ledPin = 9; // pin that the LED is attached to

// variables:
int x = 6;
int sensorValue = 0; // the sensor value
int sensorMin = 1023; // minimum sensor value
int sensorMax = 0; // maximum sensor value

// These constants won't change:
const int analogPin = 0; // pin that the sensor is attached to

const int sensorPin1 = 1; // pin that the sensor is attached to
const int ledPin1 = 10; // pin that the LED is attached to

// variables:
int sensorValue1 = 0; // the sensor value
int sensorMin1 = 1023; // minimum sensor value
int sensorMax1 = 0; // maximum sensor value

// These constants won't change:
const int analogPin1 = 1; // pin that the sensor is attached to

const int sensorPin2 = 2; // pin that the sensor is attached to
const int ledPin2 = 11; // pin that the LED is attached to

// variables:
int sensorValue2 = 0; // the sensor value
int sensorMin2 = 1023; // minimum sensor value
int sensorMax2 = 0; // maximum sensor value

// These constants won't change:
const int analogPin2 = 2; // pin that the sensor is attached to

const int sensorPin3 = 3; // pin that the sensor is attached to
const int ledPin3 = 6; // pin that the LED is attached to

// variables:
int sensorValue3 = 0; // the sensor value
int sensorMin3 = 1023; // minimum sensor value
int sensorMax3 = 0; // maximum sensor value

// These constants won't change:
const int analogPin3 = 3; // pin that the sensor is attached to

const int sensorPin4 = 4; // pin that the sensor is attached to
const int ledPin4 = 5; // pin that the LED is attached to

// variables:
int sensorValue4 = 0; // the sensor value
int sensorMin4 = 1023; // minimum sensor value
int sensorMax4 = 0; // maximum sensor value

// These constants won't change:
const int analogPin4 = 4; // pin that the sensor is attached to

const int sensorPin5 = 5; // pin that the sensor is attached to
const int ledPin5 = 3; // pin that the LED is attached to

// variables:
int sensorValue5 = 0; // the sensor value
int sensorMin5 = 1023; // minimum sensor value
int sensorMax5 = 0; // maximum sensor value

// These constants won't change:
const int analogPin5 = 5; // pin that the sensor is attached to

const int numReadings = 100;

int readings[numReadings]; // the readings from the analog input
int index = 0; // the index of the current reading
int total = 0; // the running total
int average = 0; // the average

void setup() {

// turn on LED to signal the start of the calibration period:
pinMode(13, OUTPUT);
digitalWrite(13, HIGH);

// calibrate during the first five seconds
while (millis() < 5000) {
sensorValue = analogRead(sensorPin);
sensorValue1 = analogRead(sensorPin1);
sensorValue2 = analogRead(sensorPin2);
sensorValue3 = analogRead(sensorPin3);
sensorValue4 = analogRead(sensorPin4);
sensorValue5 = analogRead(sensorPin5);

// record the maximum sensor value
if (sensorValue > sensorMax) {
sensorMax = sensorValue;
}

// record the minimum sensor value
if (sensorValue < sensorMin) {
sensorMin = sensorValue;
}

if (sensorValue1 > sensorMax1) {
sensorMax1 = sensorValue1;
}

// record the minimum sensor value
if (sensorValue1 < sensorMin1) {
sensorMin1 = sensorValue1;
}

if (sensorValue2 > sensorMax2) {
sensorMax2 = sensorValue2;
}

// record the minimum sensor value
if (sensorValue2 < sensorMin2) {
sensorMin2 = sensorValue2;
}

if (sensorValue3 > sensorMax3) {
sensorMax3 = sensorValue3;
}

// record the minimum sensor value
if (sensorValue3 < sensorMin3) {
sensorMin3 = sensorValue3;
}

if (sensorValue4 > sensorMax4) {
sensorMax4 = sensorValue4;
}

// record the minimum sensor value
if (sensorValue4 < sensorMin4) {
sensorMin4 = sensorValue4;
}

if (sensorValue5 > sensorMax5) {
sensorMax5 = sensorValue5;
}

// record the minimum sensor value
if (sensorValue5 < sensorMin5) {
sensorMin5 = sensorValue5;
}

}

// signal the end of the calibration period
digitalWrite(13, LOW);

// initialize the LED pin as an output:
pinMode(ledPin, OUTPUT);
pinMode(ledPin1, OUTPUT);
pinMode(ledPin2, OUTPUT);
pinMode(ledPin3, OUTPUT);
pinMode(ledPin4, OUTPUT);
pinMode(ledPin5, OUTPUT);

// initialize serial communications:
Serial.begin(115200);

for (int thisReading = 0; thisReading < numReadings; thisReading++)
readings[thisReading] = 0;

}

void loop() {

// read the sensor:
sensorValue = analogRead(sensorPin);
sensorValue1 = analogRead(sensorPin1);
sensorValue2 = analogRead(sensorPin2);
sensorValue3 = analogRead(sensorPin3);
sensorValue4 = analogRead(sensorPin4);
sensorValue5 = analogRead(sensorPin5);

// apply the calibration to the sensor reading
sensorValue = map(sensorValue, sensorMin, sensorMax, 0, 255);
sensorValue1 = map(sensorValue1, sensorMin1, sensorMax1, 0, 255);
sensorValue2 = map(sensorValue2, sensorMin2, sensorMax2, 0, 255);
sensorValue3 = map(sensorValue3, sensorMin3, sensorMax3, 0, 255);
sensorValue4 = map(sensorValue4, sensorMin4, sensorMax4, 0, 255);
sensorValue5 = map(sensorValue5, sensorMin5, sensorMax5, 0, 255);

// in case the sensor value is outside the range seen during calibration
sensorValue = constrain(sensorValue, 0, 255);
sensorValue1 = constrain(sensorValue1, 0, 255);
sensorValue2 = constrain(sensorValue2, 0, 255);
sensorValue3 = constrain(sensorValue3, 0, 255);
sensorValue4 = constrain(sensorValue4, 0, 255);
sensorValue5 = constrain(sensorValue5, 0, 255);

// fade the LED using the calibrated value:
analogWrite(ledPin, sensorValue);
analogWrite(ledPin1, sensorValue1);
analogWrite(ledPin2, sensorValue2);
analogWrite(ledPin3, sensorValue3);
analogWrite(ledPin4, sensorValue4);
analogWrite(ledPin5, sensorValue5);

// read the value of the potentiometer:
int analogValue = analogRead(analogPin);
int analogValue1 = analogRead(analogPin1);
int analogValue2 = analogRead(analogPin2);
int analogValue3 = analogRead(analogPin3);
int analogValue4 = analogRead(analogPin4);
int analogValue5 = analogRead(analogPin5);

// if the analog value is high enough, turn on the LED:
if (analogValue-x > sensorMin ) {

midi_note_on(0, 60, 120);

}
else
{
//int time = 0;
//while( time < 9000 ){

midi_note_off(0, 60, 120);
// time++;
// }

}

if (analogValue1-x > sensorMin1) {

midi_note_on(0, 65, 120);
}
else {

midi_note_off(0, 65, 120);
}

if (analogValue2-x > sensorMin2) {

midi_note_on(0, 69, 120);
}
else {

midi_note_off(0, 69, 120);
}

if (analogValue3-x > sensorMin3) {

midi_note_on(0, 74, 120);
}
else {

midi_note_off(0, 74, 120);
}

if (analogValue4-x > sensorMin4) {

midi_note_on(0, 80, 120);
}
else {

midi_note_off(0, 80, 120);
}

if (analogValue5-x > sensorMin5) {

midi_note_on(0, 85, 120);
}
else {

midi_note_off(0, 85, 120);
}

total= total - readings[index];
// read from the sensor:
readings[index] = sensorValue;
// add the reading to the total:
total= total + readings[index];
// advance to the next position in the array:
index = index + 1;

// if we're at the end of the array...
if (index >= numReadings)
// ...wrap around to the beginning:
index = 0;

// calculate the average:
average = total / numReadings;

}

// Available commands:
//
// Start/stop playing a certain note:
// midi_note_on(byte channel, byte key, byte velocity);
// midi_note_off(byte channel, byte key, byte velocity);
//
// Change pressure of specific keys:
// midi_key_pressure(byte channel, byte key, byte value);
//
// Change controller value (used for knobs, etc):
// midi_controller_change(byte channel, byte controller, byte value);
//
// Change "program" (change the instrument):
// midi_program_change(byte channel, byte program);
//
// Change key pressure of entire channels:
// midi_channel_pressure(byte channel, byte value);
//
// Change pitch-bend wheel:
// midi_pitch_bend(byte channel, int value);
//
// Send a comment:
// midi_comment(char* str);
//
// Send a series of bytes (to be interpreted by another program):
// midi_printbytes(char* bytes, int len);
//
// Parameters:
// channel an integer from 0 to 15
// pitch-bend value an integer from 0 to 16383
// all other values an integer from 0 to 127
//

Basic, but beautiful to see and listen to - awesome!

:slight_smile:

Muy buen projecto. mis felicitaciones :slight_smile:

Gracias!

Very nice!

I wonder if I poked one finger in could the waves be read to show where I'd touched? It would be slow but it could be a 'touch screen' :slight_smile:

yea, you can do that by placing sensors in a row and a column at the edge, so when you poked a finger a wave in a form of a circle will form, and can easily detect the center like this:
in this case the first sensors to sense change in light where c4, the using procesing could display the center

Grande, Grande !! I would do that in a fountain. And the Arduino could control the fountain so people wouuld be able to interact with it. Great invention, now fishes can make music !