Show Posts
Pages: [1]
1  Using Arduino / Audio / MIDI note-off logic for player piano - new technique? on: March 29, 2011, 02:23:27 pm
I ran into some difficulty getting notes to stop and learned a lot in the last few days. Using my Yamaha PSR-292 as a test source, I not only found that it never sends note-off codes but also never sends note-on-zero-velocity (nozv) codes either. These nozv codes are used in "status streaming" to reduce redundant status codes in the MIDI stream and stop notes already started with non-zero velocity. Also my kbd was sending a steady stream of high (>F7) codes that did nothing for me. Having seen a commercial decoder operate properly, I was convinced that there had to be another way for the Yamaha to stop notes. I ruled out all codes other than the note-on 144 (and other channels) and the high hex (>F7) by lighting the LED if any were seen. The only possible way left was to toggle notes on and off with pairs of note-on codes. This could get upside down but not likely if other flaws are carefully avoided. I implemented it in code, keeping other techniques as well, and matched the performance of the commercial decoder perfectly!

Code follows:
// MIDIplayerpiano v1.0 code by Chris Clement 3/29/2011 - chris(at)chrisclement(dot)com
// Drawn from Midi In Basic  0.2 // kuki 8.2007 but greatly modified.
// As MIDI evolved, quicker methods were developed to turn notes off. With solenoids,
// it is essential not to cook them so reliable, redundant note-off methods are needed.
// Testing with a PSR-292, the original did not perform as well as a commercial decoder.
// In addition to note-off code which my kbd doesn't seem to use, I added "status streaming" logic.
// But, even the note-on-velocity-zero codes were not forthcoming so I made a subsequent note-on
// stop a prior note-on if the note was on. This is sort of a toggle button action that seems to do
// what I want. It is possible but unlikely to get "upside down". Make sure source doesn't
// send a note-on-velocity-zero code first. Power cycle the Atmel chips to clear.
// Additional insurance against stuck notes is present as "all notes off" code, power reset, and
// a crude periodic notesoff() call. I will use 8 Atmel chips for the piano each starting
// at A0 thru A7 (cval = 9, 21, 33, 45, 57, 69, 81, 93).
// This code may be used noncommercially with credit.

byte incomingByte=0;
byte note=0;
byte velocity=0;
int cval=60;   // select the octave starting note (originally C4).
int action=2;  // state machine 0=note off ; 1=note on ; 2= nada ; 3=all notes off
int hilo;int cnt1=0;int cnt2=0;
int digitalWrit2[16];//array to model status of pins

void setup() {
//       c  c# d  d# e  f  f# g g# a  a# b      
// 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15

  pinMode(2,OUTPUT);  pinMode(3,OUTPUT);  pinMode(4,OUTPUT);  pinMode(5,OUTPUT);
  pinMode(6,OUTPUT);  pinMode(7,OUTPUT);  pinMode(8,OUTPUT);  pinMode(9,OUTPUT);
  pinMode(10,OUTPUT);  pinMode(11,OUTPUT);  pinMode(12,OUTPUT);  pinMode(13,OUTPUT);

void loop () {
L10: // Although I abhor "goto", this is not proper COBOL.
  if (Serial.available() > 0) {
    incomingByte =;
    cnt1++;if (cnt1 > 100){cnt1 = 0;cnt2++;}//not to worry about INT sizes and types
    if (cnt2 > 1){cnt2 = 0;notesoff();}

    //digitalWrite(13, HIGH);digitalWrite(13, LOW);
    // If we have a status byte, decide how to handle exclusively.
    if  (incomingByte  > 247){goto L10;}//PSR-292 puts out a steady stream of > F7 codes
    if  (incomingByte  > 127){action=2;note=0;velocity=0;}
    //Listening on all channels
    if ((incomingByte  > 143)&&(incomingByte  < 160)){action=1;incomingByte =;}//note on
    if ((incomingByte  > 127)&&(incomingByte  < 144)){action=0;incomingByte =;}//note off
    if ((incomingByte  > 175)&&(incomingByte  < 192)){action=3;incomingByte =;}//all notes off
    if ((incomingByte  > 127)&&(action==2)){goto L10;}
    //handle 1st databyte (and second if note-on)
    if ((action==1)&&(note==0)){note=incomingByte;}
    if ((action==1)&&(note!=0)){incomingByte =;velocity=incomingByte;
         if (digitalWrit2[note-cval+2]==HIGH){hilo=LOW;}
         if(note>=cval && note<cval+12){
              digitalWrite(note-cval+2, hilo);
              digitalWrit2[note-cval+2]= hilo;
    if ((action==0)&&(note==0)){note=incomingByte;}
    if ((action==0)&&(note!=0)){incomingByte =;velocity=incomingByte;
         hilo=LOW ;//if(velocity<10){hilo=LOW;}
         if(note>=cval && note<cval+12){
              digitalWrite(note-cval+2, hilo);
              digitalWrit2[note-cval+2]= hilo;

    if ((action==3)&&(incomingByte==123)){notesoff();

void blinker(){
  digitalWrite(13, HIGH);
  digitalWrite(13, LOW);

void notesoff(){
  digitalWrite(2, LOW);  digitalWrite(3, LOW);  digitalWrite(4, LOW);  digitalWrite(5, LOW);
  digitalWrite(6, LOW);  digitalWrite(7, LOW);  digitalWrite(8, LOW);  digitalWrite(9, LOW);
  digitalWrite(10, LOW);  digitalWrite(11, LOW);  digitalWrite(12, LOW);  digitalWrite(13, LOW);
  for (int i=0; i <= 15; i++){digitalWrit2[i]=LOW;}//not to worry about ends of array


2  Forum 2005-2010 (read only) / Troubleshooting / Re: Arduino Software not launching on: August 20, 2008, 08:41:34 pm
I ran the run.bat file on the original vista machine and the IDE came up! Sorry I missed the note about it in the troubleshooting page and earlier post. Now I am dealing with the following protocol error:

avrdude: stk500_getsync(): not in sync: resp=0x00
avrdude: stk500_disable(): protocol error, expect=0x14, resp=0x51

From what I can see in the forums, I need to experiment with different USB ports, etc.
3  Forum 2005-2010 (read only) / Troubleshooting / Re: Arduino Software not launching on: August 20, 2008, 09:20:58 am
I got the same result (fail to run) on a 2nd HP/Vista machine.
4  Forum 2005-2010 (read only) / Troubleshooting / Re: Arduino Software not launching on: August 19, 2008, 09:23:40 pm
I did just now. I ran earlier versions 0010 and 0009 as well. This is really a hard crash. Here are screen dumps of the error:
5  Forum 2005-2010 (read only) / Troubleshooting / Re: Arduino Software not launching on: August 19, 2008, 05:20:06 pm
I am getting a different error. When I click up the arduino.exe, a popup appears saying "arduino.exe has stopped working" and vague references to a "problem" and will notify if a solution is available.

I have a HP Pavilion with AMD Sempron CPU and Vista Home Deluxe.
6  Forum 2005-2010 (read only) / Troubleshooting / Re: :-S arduino lilypad blues :: not in sync on: January 22, 2011, 12:45:12 am
I also have this "sync" problem with a Lilypad and USB link purchased in 2008. I gave up after a while and moved on to Rabbit. My interest was rekindled recently when someone confirmed that a Windows pc could be used (after all). I now have a Windows 7 64-bit box but the error persists, even with the latest IDE (22). I saw the discussion in this thread about possible reversal of rx and tx between the devices and thought that would explain my lack of success after trying almost everything else. But, even after reversing the two middle pins, I get the same "sync/protocol" errors posted above. There was no conducting foam or shorting since I know about that. I had put everything away carefully before trying again.

Leah, can you suggest anything else?
7  Forum 2005-2010 (read only) / Frequently-Asked Questions / Re: Super easy questions [getting started] on: August 20, 2008, 09:25:37 am
What pc are you using? I am having a lot of difficulty with Windows Vista (and XP but Vista is more important right now).
8  Forum 2005-2010 (read only) / Frequently-Asked Questions / Re: HHO gas on: August 20, 2008, 08:41:24 am
Also, they only work with bottled water that costs more than gas anyway!!
9  Forum 2005-2010 (read only) / Frequently-Asked Questions / Re: Vista Home Deluxe on: August 19, 2008, 05:38:07 pm
I removed and disabled a number of USB and COM/LPT drivers in Device Manager and got past this problem. Thanks for your replies.
10  Forum 2005-2010 (read only) / Frequently-Asked Questions / Re: Vista Home Deluxe on: August 18, 2008, 11:35:14 pm
No. There doesn't seem to be any ".exe" files other than the uninstall FTDIUNIN.EXE. The pc doesnt' recognize the hardware when I plug it in. When I did the 1st time, it did invoke the wizard but quickly found something and said it was "successfully" installed. It might have been another driver for a USB-to-serial adapter. I since disabled that driver and ran the uninstall (above) for this. Now, when I plug it in, nothing happens at all.
11  Forum 2005-2010 (read only) / Frequently-Asked Questions / Vista Home Deluxe on: August 18, 2008, 06:23:09 pm
I d/l the Arduino 0011 files and tried unsuccessfully to get the Windows driver installed on Vista Home Deluxe. It doesn't see any "new hardware" and I can't click/run the driver install directly, either. What to do?
Pages: [1]