You are here

DIY Airpiano

Customising, building or repairing your own gear? Need help with acoustic treatment or soundproofing? Ask away…

DIY Airpiano

Postby BJG145 » Wed Aug 05, 2020 5:54 pm

Back around 2010, Omer Yosher came up with the Airpiano.

Image

The original website is long gone, though you can still view it on WayBack. It was adopted by a Scottish musician called Jo Hamilton, who made a pretty cool video with it.

Image

https://youtu.be/DTp5MFgzqZk?t=126

Guardian write-up:

https://www.theguardian.com/music/2011/ ... -air-piano

They were sold in small numbers and then discontinued.

It's based on an Arduino and a set of eight IR sensors. There aren't many instruments around that use IR to trigger notes...the Naonext Crystall Ball (sic) can do it, but it only has five of them, which is a bit limiting. There's also a couple of DIY versions like the Flightdeck, which is conceptually quite close, with eight IR modules.

So inspired by those, I've decided to have a go. I ruthlessly reclaimed the Arduino with its Sparkfun MIDI shield from my last project (byebye Eletrunk), picked up a Sharp GP2Y0A21YK0F on eBay, and I've been messing around with that today.

Image

So far so good...after spending a couple of hours trying to remember how to do some basic coding and sorting out bugs like using "=" instead of "==" I was able to get it to trigger a couple of different MIDI notes for different levels...

https://youtu.be/WVkta4_Yaq8

The original Airpiano seems to have been configured to play a scale, with three octaves for different heights.

Encouraged by this, I just ordered another half dozen sensors, and I think I'll need to upgrade to an Arduino Mega to handle the extra inputs.

My enthusiasm for electronics, programming and woodworking vastly outweighs my skills though sadly, so I'll probably be back asking for help for the next stage. (Need to sort out a decent case next.)
User avatar
BJG145
Jedi Poster
Posts: 4532
Joined: Sat Aug 06, 2005 12:00 am

Re: DIY Airpiano

Postby Eddy Deegan » Wed Aug 05, 2020 6:10 pm

A very impressive first homebrew iteration of the concept! :clap:
User avatar
Eddy Deegan
Moderator
Posts: 4725
Joined: Wed Sep 01, 2004 12:00 am
Location: Brighton & Hove, UK
Some of my works
The 2nd SOS Forum Album project
 

Re: DIY Airpiano

Postby BJG145 » Wed Aug 05, 2020 7:10 pm

Thanks Eddy!

Programming has always interested me, but I'm pretty basic, and I know there's some people on the forum who are handy at it, so, I'll just explain what I've got so far in case anyone wants some bedtime reading. ;)

I started by splicing together a couple of demos...one which reads and displays IR values (which seemed to go from about 3 to 30), and another to output MIDI notes, and so far I've got this.

/*
* getDistance
*
* Example of using SharpIR library to calculate the distance beetween the sensor and an obstacle
*
* Created by Giuseppe Masino, 15 June 2016
*
* -----------------------------------------------------------------------------------
*
* Things that you need:
* - Arduino
* - A Sharp IR Sensor
*
*
* The circuit:
* - Arduino 5V -> Sensor's pin 1 (Vcc)
* - Arduino GND -> Sensor's pin 2 (GND)
* - Arduino pin A0 -> Sensor's pin 3 (Output)
*
*
* See the Sharp sensor datasheet for the pin reference, the pin configuration is the same for all models.
*/

//import the library in the sketch
#include <SharpIR.h>
#include <MIDI.h>

//Create a new instance of the library
//Call the sensor "sensor"
//The model of the sensor is "GP2YA41SK0F"
//The sensor output pin is attached to the pin A0
SharpIR sensor( SharpIR::GP2Y0A41SK0F, A0 );

MIDI_CREATE_DEFAULT_INSTANCE();
int noteon = 0;
int olddist = 0;

void setup()
{
MIDI.begin(4); // Launch MIDI and listen to channel 4

}

void loop()
{
int distance = sensor.getDistance(); //Calculate the distance in centimeters and store the value in a variable

if ((distance >= 5) and (distance <= 6) and (noteon == 0))
{
MIDI.sendNoteOn(50, 127, 1); // Send a Note (pitch 50, velo 127 on channel 1)
noteon = 1;
olddist = 1;
}
if ((distance >= 9) and (distance <= 10) and (noteon == 0))
{
MIDI.sendNoteOn(60, 127, 1); // Send a Note (pitch 60, velo 127 on channel 1)
noteon = 1;
olddist = 2;
}
if (((distance < 4) or (distance > 7)) and (noteon == 1) and (olddist == 1))
{
noteon = 0;
olddist = 0;
MIDI.sendNoteOff(50, 127, 1);
}
if (((distance < 8) or (distance > 11)) and (noteon == 1) and (olddist == 2))
{
noteon = 0;
olddist = 0;
MIDI.sendNoteOff(60, 127, 1);
}
delay(10); // Wait
}

I had this idea of a variable "noteon" which remembers whether there's currently a note playing or not, and a variable "olddist" which is like a range; 1 for the low note, 2 for the high note, 0 for neither.

(To reproduce what I think is one of the modes of an Airpiano, I imagine multiplying the whole thing by 8 for an octave of sensors, and have a distance range divided into three height areas for three octaves. I picked that up from the demo here.)

With these DIY Arduino/MIDI instruments, there's always some "debounce" to get jittery sensors turning out a clean range, a clean note-on note-off. (Some commercial instruments are still quite bad at this.) So in the above, I trigger the lower note within a certain limited range of sensor values (5 or 6) but kill it with a wider range (below 4 or above 7). The idea was to stop fluctuations on the margin.

I'm aware it's pretty bad, and this is just a quick 1st draft, so I'm happy to hear any ideas about a better logic! I haven't thought about polyphony yet.
User avatar
BJG145
Jedi Poster
Posts: 4532
Joined: Sat Aug 06, 2005 12:00 am

Re: DIY Airpiano

Postby Folderol » Wed Aug 05, 2020 7:13 pm

I like it. I think the humble Arduino is grossly underestimated.
I can see you're using you're using an analog input (A0) and guess your just dividing the received value down for the octave steps. The mega would indeed readily give you an entire 12 notes (it actually has 16 analog inputs, so you could use some for volume, pitchbend etc.

Edit. I see I'm late :lol:

P.S
I always use a time based debounce. Accept the first change on a channel immediately, but then don't accept any changes within 50mS. Rinse and repeat.
User avatar
Folderol
Jedi Poster
Posts: 11356
Joined: Sat Nov 15, 2008 1:00 am
Location: The Mudway Towns, UK
Yes. I am that Linux nut.
Onwards and... err... sideways!

Re: DIY Airpiano

Postby BJG145 » Wed Aug 05, 2020 7:22 pm

Folderol wrote:I always use a time based debounce. Accept the first change on a channel immediately, but then don't accept any changes within 50mS. Rinse and repeat.

Right, yes. Time-based debounce sounds like a good idea...
User avatar
BJG145
Jedi Poster
Posts: 4532
Joined: Sat Aug 06, 2005 12:00 am

Re: DIY Airpiano

Postby Eddy Deegan » Wed Aug 05, 2020 9:15 pm

I've never done Arduino programming, but a quick search indicates that the language does support switch statements and array indexing.

At the moment you have the checks for distance ranges combined with the actions:

Code: Select all
if ((distance >= 5) and (distance <= 6) and (noteon == 0))
{
MIDI.sendNoteOn(50, 127, 1); // Send a Note (pitch 50, velo 127 on channel 1)
noteon = 1;
olddist = 1;
}
if ((distance >= 9) and (distance <= 10) and (noteon == 0))
{
MIDI.sendNoteOn(60, 127, 1); // Send a Note (pitch 60, velo 127 on channel 1)
noteon = 1;
olddist = 2;
}
if (((distance < 4) or (distance > 7)) and (noteon == 1) and (olddist == 1))
{
noteon = 0;
olddist = 0;
MIDI.sendNoteOff(50, 127, 1);
}


I would be inclined to do the range checking separately, put the result into an enumerated result value and then evaluate it in a switch statement. The specific ranges in your example code look slightly non-intuitive to me but I expect they are there for a reason.

In C (and I suspect the Arduino language) I would handle the distance like this:

Code: Select all

void loop()
{
   // Stuff ...

   int distance_range = normalise_distance(sensor.getDistance());

   switch  (distance_range) {

   case 1:
        // Insert logic here for when the actual distance is 0-2
        break;

   case 2:
        // Insert logic here for when the actual distance is 3-5
        break;

    case 3:
        // ... and so on
        break;

   // ... and so on
   }
}

// Example only: Translate actual distances into a range identifier
// In the below example, distances from 0-2 map to range 1,
// distances from 3-5 map to range 2,
// distances from 6-9 map to range 3,
// distances from 10-14 map to range 4,
// distances from 15-17 map to range 5,
// everything greater defaults to range 6
int normalise_distance(int actual_distance)
{
    int distance_map[] = 1,1,1,2,2,2,3,3,3,3,4,4,4,4,4,5,5,5,6,6,6;
    int max_mapped_distance = sizeof(distance_map) - 1;

    if (actual_distance > max_mapped_distance) {
        return 7;  // Or whatever...
    } else {
        return distance_map[actual_distance];
    }
}


There's nothing majorly spectacular I'm adding there but it might help you start to organise the logic in a slightly more manageable way. One advantage is that if you want to process a distance value differently then you can simply change the values in the distance_map array and not have to edit a bunch of 'if' statements with the new range checks.

If that makes sense?

You could also go further and extend normalise_distance() to return different values for the same range depending on if noteon is 0 or 1 which would save a bunch more 'if' statements in the calling code.
User avatar
Eddy Deegan
Moderator
Posts: 4725
Joined: Wed Sep 01, 2004 12:00 am
Location: Brighton & Hove, UK
Some of my works
The 2nd SOS Forum Album project
 

Re: DIY Airpiano

Postby Martin Walker » Wed Aug 05, 2020 9:27 pm

Fascinating stuff BJG145!

And well done for getting octave switching on your very first session.

However, I gained an extra thrill out of discovering Jo Hamilton whose video demonstrating the prototype was truly haunting, so thanks for that too.


Martin
User avatar
Martin Walker
Moderator
Posts: 16241
Joined: Wed Jan 13, 2010 9:44 am
Location: Cornwall, UK

Re: DIY Airpiano

Postby BJG145 » Wed Aug 05, 2020 9:36 pm

Martin Walker wrote:I gained an extra thrill out of discovering Jo Hamilton

...yeah, she's quite cool...

Thanks for the programming tips Eddy, I'll study that. I wasn't fishing honest... ;)
User avatar
BJG145
Jedi Poster
Posts: 4532
Joined: Sat Aug 06, 2005 12:00 am

Re: DIY Airpiano

Postby James Perrett » Wed Aug 05, 2020 9:51 pm

Rather than upgrading the processor to gain more inputs, it may be worth just adding an analogue input shield like the one at

https://www.vellemanformakers.com/produ ... uino-ka12/
User avatar
James Perrett
Moderator
Posts: 9679
Joined: Mon Sep 10, 2001 12:00 am
Location: The wilds of Hampshire
JRP Music - Audio Mastering and Restoration. JRP Music Facebook Page

Re: DIY Airpiano

Postby BJG145 » Wed Aug 05, 2020 10:04 pm

James Perrett wrote:Rather than upgrading the processor to gain more inputs, it may be worth just adding an analogue input shield

Thanks James, interesting...I'd been wondering about going for one of these, which is cheaper (16 analogue inputs on the Mega compared to 6 on the Uno, which should be plenty); not sure how these "compatible" boards compare to originals, or how likely it is to work with the same Sparkfun MIDI shield and code, but can't go too far wrong for a tenner...(?)
User avatar
BJG145
Jedi Poster
Posts: 4532
Joined: Sat Aug 06, 2005 12:00 am

Re: DIY Airpiano

Postby Folderol » Wed Aug 05, 2020 10:37 pm

BJG145 wrote:
James Perrett wrote:Rather than upgrading the processor to gain more inputs, it may be worth just adding an analogue input shield

Thanks James, interesting...I'd been wondering about going for one of these, which is cheaper (16 analogue inputs on the Mega compared to 6 on the Uno, which should be plenty); not sure how these "compatible" boards compare to originals, or how likely it is to work with the same Sparkfun MIDI shield and code, but can't go too far wrong for a tenner...(?)
Most Arduino clones are quite reliable (they use the same chips and board layout).
The Mega should behave identically with the Sparkfun board.
However... the mega also has 3 additional serial ports, all of which are trivially easy to set up as MIDI out ports (and not quite so easily as MIDI in ones).
The only thing you have to watch out for is that you don't try to send MIDI messages too fast, or they are liable to overfill the buffer and get corrupted. Simply put a 1mS delay after each complete command.
User avatar
Folderol
Jedi Poster
Posts: 11356
Joined: Sat Nov 15, 2008 1:00 am
Location: The Mudway Towns, UK
Yes. I am that Linux nut.
Onwards and... err... sideways!

Re: DIY Airpiano

Postby BJG145 » Thu Aug 06, 2020 10:31 pm

Cheers Folderol, think I'll give that one a try then.

Second attempt...

https://youtu.be/fDRFHEF2UK4

...not much different here, just added a third zone and tried to make it more musical. The readings become increasingly jittery with distance, so I'll definitely have to work on the debounce. Anyways I'll wait for the rest of my flock of sensors to turn up now...
User avatar
BJG145
Jedi Poster
Posts: 4532
Joined: Sat Aug 06, 2005 12:00 am

Re: DIY Airpiano

Postby Arpangel » Sun Aug 09, 2020 9:03 am

My god, this could be what I’m looking for in my Spice Up A Laptop Performance thread.
User avatar
Arpangel
Jedi Poster
Posts: 4998
Joined: Sat Jul 12, 2003 12:00 am

Re: DIY Airpiano

Postby BJG145 » Sun Aug 09, 2020 10:03 am

OK well I wasn't really accepting pre-orders but if you like you can put down a £500 deposit. It's a lot cheaper than this one. ;)
User avatar
BJG145
Jedi Poster
Posts: 4532
Joined: Sat Aug 06, 2005 12:00 am

Re: DIY Airpiano

Postby Arpangel » Sun Aug 09, 2020 10:57 am

BJG145 wrote:OK well I wasn't really accepting pre-orders but if you like you can put down a £500 deposit. It's a lot cheaper than this one. ;)

So what’s the spec?

:think:
User avatar
Arpangel
Jedi Poster
Posts: 4998
Joined: Sat Jul 12, 2003 12:00 am

Next