Synth Not Starting Up

Thread Starter

IWorkInPixels

Joined Sep 25, 2015
55
Ok, so I can now tell for sure that the atmega is dropping the note offs, and not the soundgin.

I will post my version of the code to github as soon as I get home... I had to modify it to even compile under arduino 1.6, as it depends on an old version of the midi library and an old version of the IDE.
 

Thread Starter

IWorkInPixels

Joined Sep 25, 2015
55
Ok, here's the software as it's running on my synth right now... I have various amounts of blinking going on depending on what note the atmega thinks it is receiving... it doesn't do any amount of blinking for note offs, so the midi library isn't understanding my note off commands. It blinks 3 times every time a note on is sent, meaning it has reached the if branch that stores the old note in a variable, then sends the new note the the soundgin.

You can clearly see the note offs come in if you probe the output of the optocoupler, so they're being sent, but the note handler never sees them.

https://github.com/iworkinpixels/NaV-Firmware
 
Last edited:

Thread Starter

IWorkInPixels

Joined Sep 25, 2015
55
Ok, at this point I'm convinced this thing has a demon in it.

All note offs are dropped, and I have zero idea why, as you can clearly see them at the output of the opto, and the code seems legit. It's just reading a velocity of >=1 when it should be reading 0 for some reason. Putting the MIDI.read() inside of a noInterrupts() block causes the menu to die.

If anybody's interested, I'll pay handsomely for help getting this thing working by Wednesday... I'm 3 weeks out from when I had hoped to have it running, and I really need to have it done by then.
 
Last edited:

Alec_t

Joined Sep 17, 2013
14,335
I'm no programmer, so can you confirm lines 31-43 of your MyHandleNoteOn routine do what you want? It looks to me as though when velocity =0, newNote (with the same pitch value as currentNote) gets triggered by lines 38-42?
CodeSnip.PNG
 

Thread Starter

IWorkInPixels

Joined Sep 25, 2015
55
No, 38 - 42 is for if you play a note before releasing the previous note... it will store the previous note so it can be retriggered after you release the new note. And since all note offs are dropped, that's the branch that always runs (except the first note).
 

Thread Starter

IWorkInPixels

Joined Sep 25, 2015
55
HA! Ok, so I finally went to check out the MIDI spec, and it turns out there *is* a note off (0x80), so every single tutorial ever that I've seen was for some old version of the Arduino MIDI library that said that note offs were just note ons with 0 velocity. That is incorrect.

So, I updated the code to use a proper note-off callback function, and it's no longer dropping note offs!

However, if you play it with the keyboard, you have to hit the key at just the right time for the MIDI library to see the key press, if you hit it while it's off in the menu loop or while it's off sending commands to the soundgin it won't play the note/note off.

So, this will require more work, but at least that's one more mystery solved!
 
Last edited:

Alec_t

Joined Sep 17, 2013
14,335
Good. You're getting there! Can you give the key-scan routine priority so that it interrupts the other routines?
 

Thread Starter

IWorkInPixels

Joined Sep 25, 2015
55
Not without making a whole new board, which may be what I have to do... there are only two pins on the arduino that support interrupts. Digital pins 2 and 3, neither of which are currently what I am listening for notes on.
 

kubeek

Joined Sep 20, 2005
5,795
But you need to listen to uart interrupts instead. Give those highest priority or make them such that they cant be interrupted. Second priority would be communication with soundgine, and the rest needs to be done in the main loop when there is enough time.
 

Thread Starter

IWorkInPixels

Joined Sep 25, 2015
55
Yup, currently looking into whether that's possible. I know you can't register an interrupt handler for TX/RX, but apparently you can hack the Serial library if you want. Yuck. :(
 

kubeek

Joined Sep 20, 2005
5,795
Well, maybe it is time to leave arduino skethces and start doing the real deal. I never actually worked with arduino IDE, but I think it is fairly limited, while going to C and atmel studio will get everything that is possible with the chip.
 

Thread Starter

IWorkInPixels

Joined Sep 25, 2015
55
Yup, that's the next step, whether I get this working in Arduino or not. I'd like to create an open source drop in atmega replacement for the soundgin, so I can start selling OSHW kits of these things.
 
Yup, currently looking into whether that's possible. I know you can't register an interrupt handler for TX/RX, but apparently you can hack the Serial library if you want. Yuck. :(
Even if you have a polled-only serial library, it does (should!?) buffer one character. So if you can make a timer service handler that runs faster than the minimum MIDI message interval, you could always snatch off any note from the serial library and put it in a buffer for the "main loop" to process at its leisure.

[edit]

Oops, I guess as long as the serial library doesn't "block" on a read request or if you can check whether a byte is ready without getting "blocked".
 

Thread Starter

IWorkInPixels

Joined Sep 25, 2015
55
Ok, so learned a little bit more about it, software interrupts are possible in Arduino with the Timer1 library, so I tried that, and things got worse. So I reverted to earlier code, here's an example of how bad it is with just the stock code plus my changes so it'll compile (the LED is supposed to turn on when I press a key and turn off if there are no more keys pressed):


Commenting out everything that actually sends data to the soundgin still leaves the LED slow and buggy, so it's our MIDI connection that's the problem. I had the LCD start dumping the currentNote and newNote values to the screen, and holy hell yeah it is! The old and new numbers will turn out to be the same a lot of the time, and they'll often become numbers that are out of range for a data byte, like 183! Once it's in that state, it's hard to clear out cause you'd have to create whatever voodoo led to it becoming 183 in the first place.

So, to debug that I built an identical midi input circuit on a breadboard, and hooked up the keyboard on the input end and an arduino mega on the output end, so I could watch the serial monitor and see what was up.

I can now verify that my keyboard does use the note-off is zero velocity note-on method, and it does not use the running-status to save bytes.

Here's an example of the output:

Code:
90 30 4A -  ON C3
90 31 30 -  ON C#3
90 30 00 - OFF C3
90 32 47 -  ON D3
90 31 00 - OFF C#3
90 33 1A -  ON D#3
90 32 00 - OFF D3
90 34 31 -  ON E3
90 33 00 - OFF D#3
 
Last edited:

Thread Starter

IWorkInPixels

Joined Sep 25, 2015
55
Also, just out of curiosity I timed the note-on and note-off handlers, and got the following:

We are inside the note-off handler for 2-3 milliseconds every time, and inside the note-on handler for 15-16 milliseconds every time!!!

So there's the problem right there... we miss all kinds of stuff while we're off in la-la land trying to decide what to send to the soundgin at 9600 baud.
 

kubeek

Joined Sep 20, 2005
5,795
You should look up how to do an interrupt when the uart transmit buffer is empty. Then Prepare all the data you want to be sent and its lenght, then enable that interrupt and start sending.
The interrupt should take the current byte, put it in the send buffer of the uart and decerement the number of bytes to send. When that goes to zero disable the empty buffer interrupt.
 

Thread Starter

IWorkInPixels

Joined Sep 25, 2015
55
Ok, so if I understand you right, I'm *not* gonna use the MIDI library with callbacks at all, but instead going to use a UART callback to run something every time the RX pin starts up with a new message, and that something will fill up a buffer full of stuff I'm gonna send over the soft serial to the soundgin, but the difference is it will wait until things calm down on the RX pin before it starts sending to the soundgin?
 

kubeek

Joined Sep 20, 2005
5,795
Oh I missed that the atmega has only one uart, then this most likely wouldnt work.
I cannot find what soundgin.write does, so it is kinda tough to give any directions. You would generally want to use a timer to generate the 9600 software uart instead of delays.
 
Ok, so if I understand you right, I'm *not* gonna use the MIDI library with callbacks at all, but instead going to use a UART callback to run something every time the RX pin starts up with a new message, and that something will fill up a buffer full of stuff I'm gonna send over the soft serial to the soundgin, but the difference is it will wait until things calm down on the RX pin before it starts sending to the soundgin?
You really don't want to interrupt on something happening on the Rx pin, but rather use the interrupt generated by the UART when a byte is fully received and in the Rx holding register (while it's potentially shifting in another Rx byte from the input).

[Unless it's a software serial UART emulator. then you'd be interrupting on the Rx pin to drive the software UART emulator. I've coded these before. They're OK.]
 
Top