Welcome
Username or Email:

Password:


Missing Code




[ ]
[ ]
Online
  • Guests: 59
  • Members: 0
  • Newest Member: omjtest
  • Most ever online: 396
    Guests: 396, Members: 0 on 12 Jan : 12:51
Members Birthdays:
All today's birthdays', congrats!
Munkey (31)
CokeCanNinja (30)


Next birthdays
11/25 Chris (39)
11/25 JamesH (17)
11/25 Oakley (21)
Contact
If you need assistance, please send an email to forum at 4hv dot org. To ensure your email is not marked as spam, please include the phrase "4hv help" in the subject line. You can also find assistance via IRC, at irc.shadowworld.net, room #hvcomm.
Support 4hv.org!
Donate:
4hv.org is hosted on a dedicated server. Unfortunately, this server costs and we rely on the help of site members to keep 4hv.org running. Please consider donating. We will place your name on the thanks list and you'll be helping to keep 4hv.org alive and free for everyone. Members whose names appear in red bold have donated recently. Green bold denotes those who have recently donated to keep the server carbon neutral.


Special Thanks To:
  • Aaron Holmes
  • Aaron Wheeler
  • Adam Horden
  • Alan Scrimgeour
  • Andre
  • Andrew Haynes
  • Anonymous000
  • asabase
  • Austin Weil
  • barney
  • Barry
  • Bert Hickman
  • Bill Kukowski
  • Blitzorn
  • Brandon Paradelas
  • Bruce Bowling
  • BubeeMike
  • Byong Park
  • Cesiumsponge
  • Chris F.
  • Chris Hooper
  • Corey Worthington
  • Derek Woodroffe
  • Dalus
  • Dan Strother
  • Daniel Davis
  • Daniel Uhrenholt
  • datasheetarchive
  • Dave Billington
  • Dave Marshall
  • David F.
  • Dennis Rogers
  • drelectrix
  • Dr. John Gudenas
  • Dr. Spark
  • E.TexasTesla
  • eastvoltresearch
  • Eirik Taylor
  • Erik Dyakov
  • Erlend^SE
  • Finn Hammer
  • Firebug24k
  • GalliumMan
  • Gary Peterson
  • George Slade
  • GhostNull
  • Gordon Mcknight
  • Graham Armitage
  • Grant
  • GreySoul
  • Henry H
  • IamSmooth
  • In memory of Leo Powning
  • Jacob Cash
  • James Howells
  • James Pawson
  • Jeff Greenfield
  • Jeff Thomas
  • Jesse Frost
  • Jim Mitchell
  • jlr134
  • Joe Mastroianni
  • John Forcina
  • John Oberg
  • John Willcutt
  • Jon Newcomb
  • klugesmith
  • Leslie Wright
  • Lutz Hoffman
  • Mads Barnkob
  • Martin King
  • Mats Karlsson
  • Matt Gibson
  • Matthew Guidry
  • mbd
  • Michael D'Angelo
  • Mikkel
  • mileswaldron
  • mister_rf
  • Neil Foster
  • Nick de Smith
  • Nick Soroka
  • nicklenorp
  • Nik
  • Norman Stanley
  • Patrick Coleman
  • Paul Brodie
  • Paul Jordan
  • Paul Montgomery
  • Ped
  • Peter Krogen
  • Peter Terren
  • PhilGood
  • Richard Feldman
  • Robert Bush
  • Royce Bailey
  • Scott Fusare
  • Scott Newman
  • smiffy
  • Stella
  • Steven Busic
  • Steve Conner
  • Steve Jones
  • Steve Ward
  • Sulaiman
  • Thomas Coyle
  • Thomas A. Wallace
  • Thomas W
  • Timo
  • Torch
  • Ulf Jonsson
  • vasil
  • Vaxian
  • vladi mazzilli
  • wastehl
  • Weston
  • William Kim
  • William N.
  • William Stehl
  • Wesley Venis
The aforementioned have contributed financially to the continuing triumph of 4hv.org. They are deserving of my most heartfelt thanks.
Forums
4hv.org :: Forums :: Projects
« Previous topic | Next topic »   

Free Plans for an Arduino-Based DRSSTC MIDI Interrupter

Move Thread LAN_403
Daniel Kramnik
Sat Jun 30 2012, 04:46AM Print
Daniel Kramnik Registered Member #3885 Joined: Sun May 15 2011, 12:47AM
Location: Newton, Massachusetts, United States
Posts: 94
Hi all!

I've decided to post some plans for a dead-simple DRSSTC MIDI interrupter based on an Arduino and a handful of fairly basic off-the-shelf components. These plans should make it very easy for anyone to add audio modulation to their solid state coil.

MIDI parsing is done using the Arduino MIDI library, and notes are generated using 16-bit Timer1 in CTC mode - the output compare interrupt generates an output pulse with a duration retrieved from a lookup table to ensure that the output of the coil is roughly the same at every frequency. This lookup table is coil-specific and therefore experimentally determined.

I'm working on adding polyphony by using software counters with 8-bit Timer0 and Timer2 to extend them to 16 bits. Hopefully, this should be out in another few days or so (but no promises).

I've attached the Arduino sketch file, along with a tested Eagle CAD schematic and board layout for a standalone interrupter. The total parts cost is roughly $15, I will be releasing a Digikey bill of materials shortly.

Enjoy!

(If you have any comments about my code, or if you have ideas for features I should incorporate, feel free to suggest them here)

I am planning on selling a few of these boards, etched, drilled, assembled, programmed, and tested, on eBay (target price ~$40, shipped) to see if there is interest. Once these boards have been sold, I may send out a PCB fab order so that I can offer them as kits for even less money. The idea here is to make a basic, inexpensive, and easy to understand DRSSTC interrupter that anyone can add to their coil.

I've also included modified schematic and board files for Bwang's 1Tesla DRSSTC that are compatible with this interrupter. Note that the interrupter is an Eagle 5 file while the modified 1Tesla is an Eagle 6 file.

Here's a video of something very similar to this interrupter playing back music from a computer:


It also does polyphony, although I am unable to release the code for this at the moment:
Back to top
Daniel Kramnik
Sat Jun 30 2012, 04:55AM
Daniel Kramnik Registered Member #3885 Joined: Sun May 15 2011, 12:47AM
Location: Newton, Massachusetts, United States
Posts: 94
I've tried again to upload the file - can an admin please delete the previous posts? It seems there's no way for me to try uploading a new file other than to post a reply, and there doesn't seem to be a way for me to delete my own replies if the upload fails...

In case you'd like to take a look at the code without unzipping the file, here it is:
/*
* Monophonic MIDI-Based DRSSTC Interrupter
* Daniel Kramnik, June 29, 2012
* Hardware:
*  - Optical transmitter connected to Port D.2 (Arduino Digital Pin 2) through 100 ohm resistor
*  - MIDI input connected to RXD (Arduino RX Pin) through 4N25 optocoupler circuit to isolate micro and prevent ground loops
*/

// MIDI class import - Note: this is not a standard Arduino library, it needs to be downloaded and added to your libraries folder
#include <MIDI.h>

// Function prototypes
void setupTimers     (void);
void setupInterrupts (void);
void HandleNoteOn    (byte, byte, byte);
int  findOnTime      (int);

// Global constants
#define PW_TABLE_MULTIPLIER  1.5

// Global primitives
volatile int on_time, current_pitch = 0;

void setup() {
  // Setup optical transmitter on Port D.2 (Digital Pin 2)
  DDRD  |=  (1 << 2);
  PORTD &= ~(1 << 2);    // Start the pin LOW (Note: you should *never* use digitalWrite to set this pin, as that function takes several microseconds
  
  setupTimers();
  setupInterrupts();
  
  // Initiate MIDI communications, listen to all channels
  MIDI.begin(MIDI_CHANNEL_OMNI);    
  
  // Setup MIDI callback functions (add more callback functions here to handle other MIDI events)
  MIDI.setHandleNoteOn(HandleNoteOn);    // Put only the name of the function
}

// Functions for setting up timer and interrupt reigsters
void setupTimers() {
  /*
    Timer1 is used to time the period of a note, with 0.5uS per tick
    When Timer1 reaches the compare value, an interrupt is triggered that generates the output pulse
  */
  
  // Set up 16-bit Timer1 (0.5uS per tick, hardware pins disconnected - interrupt starts disabled)
  TCCR1A = 0x00;                        // CTC mode, hardware pins disconnected
  TCCR1B = (1 << CS11) | (1 << WGM12);  // CTC mode, set prescaler to divide by 8 for 1 / 2MHz or 0.5uS per tick (clkio = 16MHz)
}

void setupInterrupts() {
  sei();    // Enable global interrupts to be safe, nothing else to do here
}

// Main program loop polls for MIDI events
void loop() {
  MIDI.read();
}

// MIDI callback functions
void HandleNoteOn(byte channel, byte pitch, byte velocity) {
  if (channel == 1) {
    if (velocity == 0) {  // Note off
      if (pitch == current_pitch) {
        TIMSK1 &= ~(1 << OCIE1A);    // Disable Timer1's overflow interrupt to halt the output
      }
    }
    else {  // Note on
        TIMSK1 &= ~(1 << OCIE1A);    // Disable Timer1's overflow interrupt to halt the output
        
        current_pitch = pitch;  // Store the pitch that will be played
        
        int frequency = (int) (220.0 * pow(pow(2.0, 1.0/12.0), pitch - 57) + 0.5);  // Decypher the pitch number
        int period = 1000000 / frequency;                                           // Perform period and calculation
        on_time = findOnTime(frequency);                                            // Get a value from the pulsewidth lookup table
        
        OCR1A   = 2 * period;     // Set the compare value
        TCNT1   = 0;              // Reset Timer1
        TIMSK1 |= (1 << OCIE1A);  // Enable the compare interrupt (start playing the note)
    }
  }
  else {
    // Ignore the command if it wasn't on channel 1 - this part may depend on the particular MIDI instrument you use, so modify the code here if you encounter a problem!
  }
}

// Pulsewidth lookup table
int findOnTime(int frequency_input) {
  int on_time = 17;
  if (frequency_input < 1000) {on_time = 17;}
  if (frequency_input < 900)  {on_time = 18;}  
  if (frequency_input < 800)  {on_time = 20;}
  if (frequency_input < 700)  {on_time = 20;}
  if (frequency_input < 600)  {on_time = 23;}
  if (frequency_input < 500)  {on_time = 27;}
  if (frequency_input < 400)  {on_time = 30;}  
  if (frequency_input < 300)  {on_time = 35;}
  if (frequency_input < 200)  {on_time = 40;}
  if (frequency_input < 100)  {on_time = 45;}       
  on_time *= PW_TABLE_MULTIPLIER;
  return on_time;
}

// Interrupt vectors
// Timer1 Compare Interrupt - signals when it's time to start a bang
ISR (TIMER1_COMPA_vect) {
  PORTD |= (1 << 2);           // Set the optical transmit pin high
  delayMicroseconds(on_time);  // Wait
  PORTD &= ~(1 << 2);          // Set the optical transmit pin low
}


]arduino_interrupter_and_1tesla.zip[/file]
Back to top
HB
Sat Jun 30 2012, 07:36PM
HB Registered Member #4146 Joined: Tue Oct 18 2011, 02:01AM
Location: Wisconsin, U.S.A
Posts: 56
Nice work. I've also been working on a midi Arduino however i have very little programming knowledge. It can play poly using up to 3 seperate timers with outputs of each tied together but i ran into issues doing it that way. Sadly i went back to not combining the channels and can play alternating notes using more than 1 Tesla coil which will sound great once i build a few more coils. Anyhow i am looking forward to your Poly sketch to see how its all done up. Keep up the good work and its nice to see your willing to share.

edit: You can also use Link2 along with midi yoke to stream the midi to the Arduino with usb rather than use extra components if you wanna play midi directly from a pc. Its worked very well for me
Back to top
Killa-X
Sun Jul 01 2012, 05:45AM
Killa-X Registered Member #1643 Joined: Mon Aug 18 2008, 06:10PM
Location:
Posts: 1039
Nice, I myself for awhile had one going, just tones though, no midi...using a LCD screen and encoders...will look into trying this for fun, hope to see more!

I'd be more interested in the polyphonic though, mono is boring and I already do that off a basic op-amp and FL-Studios :( hehe
Back to top
Paul_J.
Sun Jul 01 2012, 03:41PM
Paul_J. Registered Member #5436 Joined: Sun Jun 24 2012, 01:44AM
Location:
Posts: 39
Hello,

I would be interested in a kit.

Thanks,

Paul
Back to top
E.TexasTesla
Sun Aug 12 2012, 11:41PM
E.TexasTesla Registered Member #4362 Joined: Sat Jan 21 2012, 03:44AM
Location: Texas
Posts: 98
Thanks for the code, it works great.
One question, my coil produces very weak sparks while playing keyboard.
I would like to increase duration to get a few more cycles and more spark.

Im new to arduino and im not sure where to make a change.
on timedelay?
Back to top
Daniel Kramnik
Sun Aug 12 2012, 11:45PM
Daniel Kramnik Registered Member #3885 Joined: Sun May 15 2011, 12:47AM
Location: Newton, Massachusetts, United States
Posts: 94
Nice job! (Got a video?)

You'll need to increase the values in the lookup table function - int findOnTime(int frequency_input)

Alternately, you could just increase the value of PW_TABLE_MULTIPLIER in the #defines from 1.5.
Back to top

Moderator(s): Chris Russell, Noelle, Alex, Tesladownunder, Dave Marshall, Dave Billington, Bjørn, Steve Conner, Wolfram, Kizmo, Mads Barnkob

Go to:

Powered by e107 Forum System
 
Legal Information
This site is powered by e107, which is released under the GNU GPL License. All work on this site, except where otherwise noted, is licensed under a Creative Commons Attribution-ShareAlike 2.5 License. By submitting any information to this site, you agree that anything submitted will be so licensed. Please read our Disclaimer and Policies page for information on your rights and responsibilities regarding this site.