Arduino and MIDI

Thread Starter

DerStrom8

Joined Feb 20, 2011
2,390
Hi again,

I've decided I'm only going to worry about playing 3 tones at the same time, instead of 6. 6 is an awful lot for a Tesla coil, but 3 will allow for some of the most common chords.

The difficult part is ensuring the mixed output doesn't exceed the 1mS limit, not just the individual tones. I made this mistake before. This will probably get quite tricky.
 

THE_RB

Joined Feb 11, 2008
5,438
Very interesting project!

I think reducing it to 3 voice polyphony is a good idea. And using the tesla coil to voice the notes will really limit the range of frequencies down to 2 or 3 octaves I'm thinking.

How is the note generated? It looks like you are planning to modulate the tesla coil carrier at the note frequency, with <1mS ON period?

I always thought when people made music with those spark coild they generate the note as single spark events at the note frequency? So a note of 440Hz would be 440 actual spark "cracks" per second? That gives a clearly defined note frequency.
 

Thread Starter

DerStrom8

Joined Feb 20, 2011
2,390
Very interesting project!

I think reducing it to 3 voice polyphony is a good idea. And using the tesla coil to voice the notes will really limit the range of frequencies down to 2 or 3 octaves I'm thinking.

How is the note generated? It looks like you are planning to modulate the tesla coil carrier at the note frequency, with <1mS ON period?

I always thought when people made music with those spark coild they generate the note as single spark events at the note frequency? So a note of 440Hz would be 440 actual spark "cracks" per second? That gives a clearly defined note frequency.
My Tesla coil operates around 217kHz, which is (obviously) outside the range of human hearing. The sparks are actually very high voltage, high frequency alternating current. By switching the entire coil on and off (using the interrupter) at, say, 440 times per second, the output sounds like it's playing an A4 note.

I would like to keep the frequency the same but reduce the on-time to prevent the IGBTs from over-heating. The tone should sound roughly the same, since it has the same frequency, but the on-time will be shorter. That's the hope, anyway :p

Regards,
Matt
 

THE_RB

Joined Feb 11, 2008
5,438
Thanks for explaining I get it now. :)

So a really short burst of 217kHz makes a lot of HF audio frequencies and sounds like a "crack", whcih is what I have seen in videos etc.

I would be tempted to use a ON period which is very small, so it is half the period of your highest note for instance. Then the same ON period can be used for all notes, like if it was from a monostable etc.

I worry that if you use different lengths of ON period for different freq notes (like a 50:50 duty) then notes will have different perceived volumes. Have you done tests using a 555 timer or similar where you can adjust the freq and duty and listen to the result?
 

Thread Starter

DerStrom8

Joined Feb 20, 2011
2,390
Thanks for explaining I get it now. :)

So a really short burst of 217kHz makes a lot of HF audio frequencies and sounds like a "crack", whcih is what I have seen in videos etc.

I would be tempted to use a ON period which is very small, so it is half the period of your highest note for instance. Then the same ON period can be used for all notes, like if it was from a monostable etc.

I worry that if you use different lengths of ON period for different freq notes (like a 50:50 duty) then notes will have different perceived volumes. Have you done tests using a 555 timer or similar where you can adjust the freq and duty and listen to the result?
You are correct, for the most part--a single burst of 217kHz heats up the air around it and makes a small "bang" (think thunder). Creating 440 of these "bangs" per second makes it sound like the TC is playing an A.

As for the volume issue, that is another thing I was going to bring up. That's actually why I was hoping to have a variable on-time (depending on the note), but the max it can be is 1mS. I have experimented with PWM using a 555 timer and a 393 comparator, which allows for independent frequency and duty cycle adjustment. I know exactly what you are referring to when you mention the volume.

I'm thinking that if I keep the duty cycle (of every note) at 3-5% it should work. Just to show the math:

C1 is 33 Hz, and probably the lowest note I'd ever need. The period of the note, therefore, is 0.0303 seconds, or 30.3mS. In order to keep the on-time close to 1mS, then the duty cycle would have to be around 3%. I could probably go up to 5% because technically the absolute maximum on-time allowed by my IGBTs would be 2mS, but I wanted to keep a very safe margin, which is why I've planned on 1mS.

Of course any higher notes will have a higher frequency, and thus a shorter on-time anyway. So I think 3-5% might be my ideal.

Regards,
Matt
 

THE_RB

Joined Feb 11, 2008
5,438
The ear can do some funny things. I played a lot with sampling and repeated sounds/percussive sounds etc when i used to do home studio recording.

With a repetitive sound the ear will get a perceived volume based on the peak sound, especially at lowish frequencies. So 100Hz with a 0.5mS ON period will sound as loud as 300Hz with the same 0.5mS ON period.

At higher frequencies you may need to reduce the 0.5mS ON period so it doesn't sound louder than the low frequencies but it might not be as much volume difference as you would expect.

I would hook up a 555 or some simple arduino code to make a couple of different notes and see how it sounds on the tesla coil. Then you will know what you are up for in the proper coding. :)
 

Thread Starter

DerStrom8

Joined Feb 20, 2011
2,390
The ear can do some funny things. I played a lot with sampling and repeated sounds/percussive sounds etc when i used to do home studio recording.

With a repetitive sound the ear will get a perceived volume based on the peak sound, especially at lowish frequencies. So 100Hz with a 0.5mS ON period will sound as loud as 300Hz with the same 0.5mS ON period.

At higher frequencies you may need to reduce the 0.5mS ON period so it doesn't sound louder than the low frequencies but it might not be as much volume difference as you would expect.

I would hook up a 555 or some simple arduino code to make a couple of different notes and see how it sounds on the tesla coil. Then you will know what you are up for in the proper coding. :)
Actually, that was my point--by choosing a specific duty cycle, the on-time should be directly proportional to the note period, so the volume should *sound* roughly the same, am I correct? I realize if I chose a non-varying on-time of, say, 0.5mS for all notes, the volume would appear to change. But keeping the on-time proportional should prevent that, I would think.

The Tesla coil has not been completed yet, so I cannot use it for testing. I am still working on the design and am currently working on the interrupter, which is what this (very enlightening :D) conversation is about. I do plan to start off with a simple 555 timer interrupter and won't be implementing the MIDI until later, so that will give me some time to experiment a bit.

I realized recently that I'll have to feed the signal into a flip-flop to prevent the interrupter from switching the IGBTs off when they have 100+A going through them. That puts a lot of stress on the transistors and is a very good way to destroy them. I don't think this will affect the sound too much, as the next zero-crossing point of the primary current won't be more than 4.6μS away at any given point in time.
 

THE_RB

Joined Feb 11, 2008
5,438
Actually, that was my point--by choosing a specific duty cycle, the on-time should be directly proportional to the note period, so the volume should *sound* roughly the same, am I correct?
...
Generally that's not true. When the sound is made by a repeated "crack" the ear bases the perceived volume on the intensity of the crack. Especially at lower frequencies. So you need a fixed volume per crack (fixed ON period).

It's only at higher notes that you might need to vary the ON period.

It's going to be hard to guess at what freq and how much, so testing will be the thing.

Maybe the first code you need is one that will generate a single note at a time, but have easily adjustable freq and duty. And the ability to test two notes (one after the other alternating) so you can judge the volume? (And so you can adjust the freq and duty of each note independently.) That would let you test the effect once the coil is operating.

I think it's a really cool project, and if you do it right you might even be able to adjust the volume of the different voices in the polyphony. That would give an even more impressive effect playing back a MIDI file than the other setups I have seen in videos.
:)
 

Thread Starter

DerStrom8

Joined Feb 20, 2011
2,390
Generally that's not true. When the sound is made by a repeated "crack" the ear bases the perceived volume on the intensity of the crack. Especially at lower frequencies. So you need a fixed volume per crack (fixed ON period).

It's only at higher notes that you might need to vary the ON period.

It's going to be hard to guess at what freq and how much, so testing will be the thing.

Maybe the first code you need is one that will generate a single note at a time, but have easily adjustable freq and duty. And the ability to test two notes (one after the other alternating) so you can judge the volume? (And so you can adjust the freq and duty of each note independently.) That would let you test the effect once the coil is operating.

I think it's a really cool project, and if you do it right you might even be able to adjust the volume of the different voices in the polyphony. That would give an even more impressive effect playing back a MIDI file than the other setups I have seen in videos.
:)
Ah, I see what you mean. I was thinking you were saying the exact opposite :D

In that case, what would be the chances of using a 555 timer one-shot to keep the on-time (roughly) the same? I'm not sure how accurate 555 timers are--I would think not very--but I thought I'd ask just in case. I'm thinking an on-time of around 250uS would be sufficient to get me up to 2kHz (I could probably go a bit less for higher frequencies).

There will definitely be a lot of testing, for sure!

Thanks,
Matt
 
Last edited:

THE_RB

Joined Feb 11, 2008
5,438
You can easily make a 555 astable with a fixed, short ON period, and a longer variable OFF period to set the note.

The easiest way is to make the 555 output active low, so it is ON when the output is 0v. Since you are driving an opto that should be fine, it just depends how you wire the 555 to the opto.
 

Thread Starter

DerStrom8

Joined Feb 20, 2011
2,390
Okay. I was thinking of simply using a 2.2uF capacitor and a 100 ohm resistor in the standard one-shot circuit to give me an on-time of roughly 250uS. not sure how I'd do the triggering, though, because I'd want to make sure it turns off even if the trigger input is still high from the previous pulse. I want to say it doesn't do that normally, but I could be wrong. Interesting idea though, about making it active-low. Definitely some more things to think about!
 

Thread Starter

DerStrom8

Joined Feb 20, 2011
2,390
Here's the design I was thinking of. If I am not mistaken, this should prevent re-triggering until the trigger signal has gone low and then high again. It should give me an on-time that's limited to 250uS, and should work as long as the interrupter output (connected to the trigger transistor) supplies a 2kHz signal or lower.

on-time_limiter.png
 
Last edited:

THE_RB

Joined Feb 11, 2008
5,438
I'm not sure that circuit will oscillate.

I would use a standard astable circuit;



With a small R2 (R2 sets the LO period to 250uS) and a larger R1 which is a pot (R1 sets the HI period, hence sets the note).

If you use two pots for both resistors you can also experiment with adjusting the LO period, which makes the tesla burst. :)

If you are concerned about triggering, just control pin4 (reset pin) with your trigger signal to turn the note on/off.
 

Thread Starter

DerStrom8

Joined Feb 20, 2011
2,390
Sorry, I guess I should have been clearer. The above circuit would be connected to the output of my actual interrupter. It is not intended to oscillate. Its sole purpose would be for limiting the on-time of any pulse from the interrupter. This way, I could use the tone library in Arduino (for example) and the external circuitry would take care of the on-time limiting.
 

THE_RB

Joined Feb 11, 2008
5,438
Ahh, OK I get you now. Sorry about that! :)

We have different approaches I think. If I was using a microcontroller I would just control the ON period with the micro so there would be no 555 needed.

It didn't occur to me that you would use a micro AND a 555 monostable.
 

Thread Starter

DerStrom8

Joined Feb 20, 2011
2,390
Ahh, OK I get you now. Sorry about that! :)

We have different approaches I think. If I was using a microcontroller I would just control the ON period with the micro so there would be no 555 needed.

It didn't occur to me that you would use a micro AND a 555 monostable.
Yes, the 555 timer was an afterthought, as I thought it would simplify things a bit with the code. I'm still having a little trouble understanding how to apply the timer idea to supply a tone at the right frequency and duty cycle.
 

THE_RB

Joined Feb 11, 2008
5,438
Sorry I'm not an Arduino user and don't know the AVR chip architecture well either, so I can't help you with exact source code.

I modified the code I made before to set the pin HI at the actual note frequency (not toggling at twice the note freq like before).

Then the HI duty is determined by a new variable; note_duty
which makes the note HI for exactly 10 interrupts. That's very close to 0.5 mS.

Rich (BB code):
unsigned long bres;       // now using 32bit accumulators
unsigned long note1freq;  // and 32bit note frequencies
unsigned char note1_duty;

// this code is in main(), and sets the note to play
note1freq = 7040;         // assign note A2 to note1


// code below is in the interrupt
if(note1on==1)            // this flag turns sound on/off
{
  bres1 += note1freq;    
  if(bres1 >= 1250000)     // using 19531.25Hz * 64
  {
    bres1 -= 1250000;
    note1_duty = 10;
  }
}
if(note1_duty)
{
  note1_duty--;
  PORTB.F1 = 1;      // note HI
}
else PORTB.F1 = 0;   // note LO again
That code should be convertable to Aduinoese assuming you can make the timer interrupt at 19531.25 Hz as discussed (10MHz xtal / 512).

Then by setting the note_duty to a value other than 10, you can set different note HI periods. This is independent of the note frequency, which is set by note1freq.
:)
 

Thread Starter

DerStrom8

Joined Feb 20, 2011
2,390
Sorry I'm not an Arduino user and don't know the AVR chip architecture well either, so I can't help you with exact source code.

I modified the code I made before to set the pin HI at the actual note frequency (not toggling at twice the note freq like before).

Then the HI duty is determined by a new variable; note_duty
which makes the note HI for exactly 10 interrupts. That's very close to 0.5 mS.

Rich (BB code):
unsigned long bres;       // now using 32bit accumulators
unsigned long note1freq;  // and 32bit note frequencies
unsigned char note1_duty;

// this code is in main(), and sets the note to play
note1freq = 7040;         // assign note A2 to note1


// code below is in the interrupt
if(note1on==1)            // this flag turns sound on/off
{
  bres1 += note1freq;    
  if(bres1 >= 1250000)     // using 19531.25Hz * 64
  {
    bres1 -= 1250000;
    note1_duty = 10;
  }
}
if(note1_duty)
{
  note1_duty--;
  PORTB.F1 = 1;      // note HI
}
else PORTB.F1 = 0;   // note LO again
That code should be convertable to Aduinoese assuming you can make the timer interrupt at 19531.25 Hz as discussed (10MHz xtal / 512).

Then by setting the note_duty to a value other than 10, you can set different note HI periods. This is independent of the note frequency, which is set by note1freq.
:)
Ahh, I see what you're doing now. I should be able to adapt this quite easily. The Arduino runs at 16MHz so I may have to recalculate some of the values, but that shouldn't be too difficult.

I'll definitely take a closer look at this tomorrow. Thanks a lot for all your help. Timers are new to me when it comes to microcontrollers (at least the Arduino--I've used them on the MSP430 but that's about it). I appreciate it!

Best wishes,
Matt
 

Thread Starter

DerStrom8

Joined Feb 20, 2011
2,390
I believe the arduino will make this very easy. Here's the documentation on Timer1:

http://www.pjrc.com/teensy/td_libs_TimerOne.html

As you can see, you initialize the timer with the number of microseconds you want it to count before finishing. Unfortunately I won't be able to set it precisely for 51.2uS because the initialize() function requires an integer, so it would truncate it to 51uS, which means we'd be off by around 76.6 Hz. I'm thinking I'll just use the 16MHz clock frequency, which would give us a timer interrupt frequency of (16MHz / 512) = 31.25 kHz. Not quite sure if this will affect any of the other numbers or not. How much is based on the 19531.25 Hz?

Also, just checking, note_duty is actually just the on-time, correct? In which case, I should probably rename it to avoid confusion. The duty cycle will change depending on the frequency. What we want is to keep the on-time constant.

Regards,
Matt
 

THE_RB

Joined Feb 11, 2008
5,438
Using the arduino compiler libraries for timers will not give the precision frequencies that my code will do using a timer interrupt.

Those libraries wont be free running, so there will be overhead after each timed period.

It may be usable with their interrupt functions provided there is no attached latency especially variable latency.

Do you have a freq counter? If so you could write a quick test in code setting the timer to 50uS and using the timer interrupt toggle an output pin. Toggling at 50uS is 100uS period = 10 kHz output freq from the pin. Then the frequency counter will tell you if it is 10000 Hz or there is latency.

DerStrom8 said:
...
I'm thinking I'll just use the 16MHz clock frequency, which would give us a timer interrupt frequency of (16MHz / 512) = 31.25 kHz. Not quite sure if this will affect any of the other numbers or not. How much is based on the 19531.25 Hz?
...
That sounds much better! If you can just set an interrupt to occur after every 512 instructions there will be no variable latency. Then my code will work fine and you will get very precise frequencies.

Just change this section of code to work with 31.25 kHz interrupt freq;
Rich (BB code):
  if(bres1 >= 2000000)     // using 31.25 kHz * 64
  {
    bres1 -= 2000000;
    note1_duty = 10;
  }
Then all the notes will be exact again.

Regarding the note ON period and variable name you are correct, I just rushed that code example. :) A better name would be note1_onperiod or something like that.

It's your baby so just change var names to whatever suits your code and your preferences.
 
Top