MIDI synth - noise on serial reception?

So I have a MIDI synth I'm working on, and it's all working nicely, except for one thing.

When the arduino receives any type of MIDI message (and I would assume any serial message in general), I get a small click on the audio output I have set up. It's really not manageable, since doing things like turning a pitchbend wheel causes an audible buzz.
here's a little soundclip of the synth while I turn the mod and pitchbend wheel on my keyboard:
http://soundcloud.com/beefinator-2/arduino-synth-weirdness
About halfway through, I turn up the gain so the buzzing is more audible. But the first half, that's at the same recording gain as when I play a couple notes, so you can see how relatively loud it is compared to the actual notes.

I'm using an MCP4822 DAC, but that's irrelevant, because I had this same issue a while ago when I used filtered PWM to generate an analog output.

I have in the program an interrupt routine that runs at 22KHz to update the DAC.

I would guess that the clicking has something to do with the serial reception interrupt, but I don't see how it would affect anything. My routine is not reentrant, so it can't be that the serial interrupt is firing midway through my interrupt. The DAC is completely updated by the time my routine is done, and the chip has an internal buffer, so the problem can't be the Serial interrupt slightly delaying my interrupt.

I looked through the Serial source code, the MIDI library code, and the atmega328 datasheet to try to figure out what's going on, but I couldn't find any solutions. From what I understand, the SPI and USART are independent on the chip, so that's not an issue.

I dunno.

The sketch is attached; any ideas on something I'm missing?

super_synth_3p0_midi.ino (14.9 KB)

I would guess that the clicking has something to do with the serial reception interrupt

My guess is that it is the serial ISR that is delaying the output sample ISR and causing the click.

Yes, I mentioned that in my post. But I don't see how that could be the issue.

As I said above, the DAC has an internal buffer, so even if it is delayed, it should just remain at the same value for a tiny bit longer. I don't believe that should cause any audible click, at least not nearly as loud as the one in the audio clip.

One more thought: the loudness of the clicking changes depending on whether the Arduino is powered via USB or the DC jack. So I think the problem could be the output very briefly going into a floating state, and then the clicking is just a short burst of noise. That would change depending on how the circuit is grounded, etc.

But still, that doesn't make sense. The only way the DAC chip will go into a floating state is if bit 4 of the high byte sent to the DAC is cleared. Which, within my interrupt routine, I don't think it can be, since the high byte is always or'd with 0x70, or 0b01110000.

So I'm still puzzled.

Bear with me if some of these things don't help ...

struct oscStruct  {
  volatile unsigned int increment;       //determines frequency.  see setFrequency().
  volatile unsigned int counter;         //keeps track of the phase.  the high byte gets us a sawtooth
  volatile byte dutyCycle;               //duty cycle of square wave.  but also holds config bits:
  //bits 0 and 1 of dutyCycle determine the waveform.
  //Notice that bit 1 decides triangle or not.  So if bit 1 is 1, bit 0 doesn't matter.
  //Bit 1:    0=saw or square,    1=triangle   |||||    Bit 0:    0=square     1=sawtooth 
  volatile byte volume;                  //256 volume levels
};

oscStruct oscillators[8];                //8 oscillators

I would make the structure volatile, not sure if what you have will work perfectly:

struct oscStruct  {
  unsigned int increment;       //determines frequency.  see setFrequency().
  unsigned int counter;         //keeps track of the phase.  the high byte gets us a sawtooth
  byte dutyCycle;               //duty cycle of square wave.  but also holds config bits:
  //bits 0 and 1 of dutyCycle determine the waveform.
  //Notice that bit 1 decides triangle or not.  So if bit 1 is 1, bit 0 doesn't matter.
  //Bit 1:    0=saw or square,    1=triangle   |||||    Bit 0:    0=square     1=sawtooth 
  byte volume;                  //256 volume levels
};

volatile oscStruct oscillators[8];                //8 oscillators

What's all the assembler for? The natively-generated SPI is pretty fast. Example here:

I output to a VGA screen which requires very precise timing. No assembler in it.

The SPI in assembler is just because I already was using assembler.

I was already using assembler because it was the most efficient way to do the oscillator calculations. With 8 oscillators, I want it to be as fast as possible. I got down to around 33 clock cycles for all the necessary code for one oscillator. Each oscillator is individually configurable to be a triangle wave, sawtooth wave, or square wave (with ~64 different pulse widths), with an 8-bit volume envelope. I think that's pretty good for 33 clock cycles! :slight_smile:

I put both SPI transmits in between oscillator calculations so no extra time is used up transmitting. And having the SPI also in assembly makes things faster; otherwise, 2 inline assembler functions would be needed, which would mean twice the pushing/popping of registers used.

sciguy:
I would guess that the clicking has something to do with the serial reception interrupt, but I don't see how it would affect anything.

If you disconnect the serial input does the problem go away?

yeah, like nick said if you disconnect the serial input does the problem go away? if it's not the software then it's most probably the grounding. Audio and digital don't like sharing grounds. Also pcb layout is very critical for these types of applications. Try to separate the audio ground and digital ground and connect the together in only one spot as close to the power supply. Also decouple every chip with at least a 0.1uF cap. If all else fails think about using opto couplers to decouple the serial bus and/or a transformer on the audio output for galvanic isolation. there is a reason that midi outputs use opto couplers as standard.

greetings,

Thomas

Yep, now I think it's a grounding issue.

I'm using the Sparkfun MIDI breakout, and I realized it still makes the noise when the Rx pin is disconnected via the switch.

But that breakout does have an optoisolated input, so shouldn't it be fine?
It appears to be isolated, based on the schematic: http://www.sparkfun.com/datasheets/BreakoutBoards/BOB-09598-MIDI_Breakout-v11.pdf

Other info on my circuit: the DAC's on a breadboard, connected to the Arduino just via 5v, gnd, clock, MOSI, and the slave select pin. It is already decoupled. The output of the DAC goes thru a 100uF cap to block DC, to the tip of the jack I'm using. The sleeve of the jack is to the ground row on the breadboard, which is to the Arduino ground.

The grounding issue must be with the MIDI connection; it's fine as long as there's no MIDI input. I even tried connecting a battery pack between the pins of the connector (obviously with the midi cable disconnected) and I get noise.
But it's theoretically isolated, so I don't know.

But that breakout does have an optoisolated input, so shouldn't it be fine?

MIDI inputs are always opto isolated, it is part of the spec.

The grounding issue must be with the MIDI connection;

No it is as you point out optically isolated so there can't be a grounding problem.

it's fine as long as there's no MIDI input.

Ring any bells?

I even tried connecting a battery pack between the pins of the connector (obviously with the midi cable disconnected) and I get noise.

When you do that you send a junk byte into the serial input.

I still think it's something related to grounding somehow.

If I remove the MIDI code and put in a Serial.begin(), then send stuff from the serial monitor in the IDE, no noise.

GRRRR... I can unplug the arduino entirely except for the MIDI cable and the audio output cable. And I still get the noise, but quieter. Something must be wrong with the breakout?

I plugged the cable into the aux in on my laptop and recorded the noise into Audacity. (don't have a proper oscilloscope... :stuck_out_tongue: )

Here are 2 of the clicks in the buzzing, normalized and with the space between them cut out (they're normally further apart)

could these be the MIDI messages bleeding through to the output somehow? not sure how that would happen.

Grumpy_Mike:
MIDI inputs are always opto isolated, it is part of the spec.

The data pins are opto-isolated. There is a third pin (ground) which is supposed to be connected at one end but not the other. Maybe noise is bleeding into that?

There is a third pin (ground) which is supposed to be connected at one end but not the other.

Yes but it is supposed to be connected at the MIDI out end not the MIDI in end. There should be no connection to that on the receiver as it kind of defeats the point of having opto isolation.

I mention it because perhaps it is in this case.

Nope. I checked the schematic, and checked the actual board too, and no connection.

sciguy:
GRRRR... I can unplug the arduino entirely except for the MIDI cable and the audio output cable. And I still get the noise, but quieter. Something must be wrong with the breakout?

With the MIDI cable disconnected is there any noise?

If it is connected but you don't connect the wire to the Rx pin of the board is there noise?

If you remove the serial reading (and the begin call) of the sketch is there noise?

If the MIDI device is powered down is there noise?

The noise is lots of short clicks, like in the screenshot of the waveform, one click I would assume for each MIDI message sent. Turning the mod or pitchbend wheels sends a ton of messages, so the clicks turn into a buzz. But there are also clicks at note on's and note off's. So yes, no noise without a MIDI cable connected, but that's irrelevant, since the noise only happens when a MIDI message is sent.

I have the breakout board mounted as a shield, so I can't physically disconnect a wire. But there is a switch that disconnects Rx, so the MIDI circuit doesn't interfere with programming the board. And yes, the clicking/buzzing still happens with that switch disconnecting Rx.

Yep. Assuming the DAC is already in active mode, i.e. not floating, I can upload the bare bones sketch with the empty setup and loop, and I still get the clicking/buzzing noise. So absolutely an electrical issue.

Again, no, but not relevant, since the clicking only occurs when a message is sent.

I'm still puzzled... I tried measuring the resistance between the MIDI connector pins and various points on the board, but nothing unusual. It seems to be isolated.

I think I would like to see a photo. The midi messages effectively are pulses at around 31250 KHz, so with a couple of 1 or 0 bits in a row you effectively have a square wave at 15625 Hz which would be audible, certainly.

You probably need to take steps to ensure that this digital "noise" (data, really) does not make it into your amp. So, shielded cable maybe. More decoupling caps on the DAC. If there is an amp, move it further away. Something like that.

Hi all,

I have a similar issue with one of my projects. I'm using an Arduino to send midi messages to a Roland TD6v sound module, essentially forming a basic step sequencer. In "free-running" mode (i.e. when the Arduino sketch provides its own timing/delays between steps, and no midi receive is used), the Arduino sends all of the right midi messages to the TD6v, and it sounds as expected. In "ext-sync" mode however (I.e. when the Arduino receives tick, start, and stop information from the TD6v), I get the same sort of audio "buzz" that you do at the start of each note.

I should also add that the sound module's midi buffer fills up (which it should not!) a few seconds after playing, like the individual notes are triggered many times. If I simplify the pattern to one hit per cycle, then I get the buzz but the midi buffer does not fill up. I'm pretty sure that there's no way that the midi messages themselves could loop between the devices ("note chase" and midi "soft thru" are turned off on the TD6v), so I'm assuming that there is some sort of grounding issue or something else that I'm unaware of. Perhaps there is some sort of power fluctuation, so the message appears to have been transmitted many times (pardon me if this sounds ridiculous… this is my first Arduino and midi project!).

I'm using the midi interface specified here (thanks to the author/designer!): http://www.stephenhobley.com/blog/2011/03/14/the-last-darned-midi-interface-ill-ever-build/

My next test will be to plug into a PC running some sort of midi message monitor so I can see what's happening on that front.

Any thoughts on this?

Thanks in advance to all.

So here's the circuit:

One thing I tried: I replaced the 220? resistor labeled R2 in the sparkfun schematic with a 1K? resistor.

That value seems to be the correct value according to the optoisolator datasheet, not the MIDI hardware spec. The noise is quieter with the larger resistor, but still audible. I also tried a 10K, but not much of a noticeable difference from the 1K.

And jman, here's a good midi monitor if you don't already have one: snoize: MIDI Monitor