I want to make an instrument, like a piano, which is played automatically by rain drops in P5 sketch. People can enjoy the rain and the rhythm by humming songs, and rain drops will change their directions according to the voice input.

Singing in the rain” is the name of my project. The poster of this movie strikes a chord with me:


This is the sketch of my idea:


Step 1. Play Test



I got two main feedbacks:

The first one is that there is no need to change the rain from light to heavy manually. If it changes automatically according to the tone or volume of users’ voice, the interaction would be more interesting and easier.

The second one is that when people is humming, they will hear their own voice, meanwhile, the sound of the piano is another input for people’s ears. People may feel difficult to focus on the two sounds together.

So, according to these feedbacks, the interaction between users and the instrument should be modified.


Step2.  Serial communication between Arduino and P5

Step3. Control the delay of on time of LEDs.

Because delay() will stop everything for a while, but the serial can’t stop. So I have to use millis() instead delay().


How and Why to avoid delay()

Using millis() for timing

Arduino: Millis() Cookbook

I also found this interesting solution: Binary counter

Finally, this program gave me an important inspiration:Use Arduino millis() with buttons to delay events. Because water drops work like buttons.

Step4. Play Midi Notes in P5.js



Mini Note Numbers

The codes:

const int ledPins[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11,12,13};
bool ledState[] = {false,false,false,false,false,false,false,false,false,false,false,false} ;
bool ledReady[] = {false,false,false,false,false,false,false,false,false,false,false,false} ;
unsigned long buttonPushedMillis; // when button was released
unsigned long ledTurnedOnAt; // when led was turned on
unsigned long turnOffDelay = 500; // turn off LED after this time

void setup() {
for (int i = 0; i < 12; i++) {
pinMode(ledPins[i], OUTPUT);
digitalWrite(ledPins[i], LOW);

void loop() {
for (int i = 0; i < 12; i++) {
if (Serial.available() > 0) {
int inByte = Serial.read();
ledReady[inByte] = true;
unsigned long currentMillis = millis();

if (ledReady[i]) {
buttonPushedMillis = currentMillis;
digitalWrite(ledPins[i], HIGH);
ledState[i] = true;
ledTurnedOnAt = currentMillis;
ledReady[i]= false;

if (ledState[i]) {
if ((unsigned long)(currentMillis - ledTurnedOnAt) >= turnOffDelay) {
ledState[i] = false;
digitalWrite(ledPins[i], LOW);

Step5. Sound input analyze.



The project is still under construction.

My next steps will be:

1.Add the interaction part in P5.js:  people can enjoy the rain and the rhythm by humming songs, and rain drops will change their directions according to the voice input and accompanied users on the piano.

2.Do the fabrication: laser cut the acrylic boards to make a keyboard of the piano and connect them to solenoids in order to move up and down.