News:

SMF for DIYStompboxes.com!

Main Menu

Atmel-based tap temp for DD-7

Started by stirfoo, March 23, 2013, 01:09:19 PM

Previous topic - Next topic

stirfoo

Since I'm too poor to finish my looper right now I thought I'd look at some of the TODO's I've created.

One is a programmable tap tempo.

Has anyone written a simple uC-based tap tempo, preferably on an Atmel (Arduino) chip and have the code to share? All I would need is to record the interval of the last two taps in milliseconds, store that with the preset, then send two pulses out when a preset is loaded. The interval could be stored in an unsigned 16 bit integer giving me 65+ seconds. Way more than I'll ever need with the Boss DD-7.

A couple of things that concern me are:

* Latency
My current switch debounce routine takes approx 30ms. It's based on the "Handling Multiple Inputs" section found here: http://www.ganssle.com/debouncing-pt2.htm. It works marvelously but I haven't tried to reduce the number of samples (6) or the sample interval (5ms). I need to get the whole thing in a stomp-able enclosure before I start tweaking values. As coded, I'm thinking that's going to limit my tap interval to >= 60ms (approximately, of course).

Am I going to need a different routine to read just the tap tempo switch?

* Physically shorting the tap out jack
My looper has two amp control outputs. One stereo, one mono. I use a couple of DPDT relays to short tip/sleeve and/or tip/ring. I was thinking about making the mono jack double as a tap tempo out.

How do other folks send the pulses to the external device?

artifus

#1
http://umlautllama.com/projects/arduino/s/TapTempo.pde
http://umlautllama.com/projects/arduino/s/TapTempo_WithPressAndHold.pde

*edit* same code for msp430 value line chip:

/*  Based on tap tempo code found here: http://umlautllama.com/projects/arduino/s/TapTempo.pde

   Ported to msp430g2231 launchpad rev1.4 with energia september 2012

   Use pinMode(5, INPUT_PULLUP) for rev1.5  */





void setup()

{

 pinMode( 5, INPUT );            /* tap button -  - press three times to set the tempo */

 pinMode( 14, OUTPUT );          /* button state display led - low on button push */

 pinMode( 2, OUTPUT );           /* tempo display led - shows the current tempo */

 pinMode( 3, OUTPUT );           /* tempo display led inverted - led to gnd from pin 3 */

}



int lastTapState = LOW;                         /* the last tap button state */

unsigned long currentTimer[2] = { 500, 500 };   /* array of most recent tap counts */

unsigned long timeoutTime = 0;                  /* this is when the timer will trigger next */

unsigned long indicatorTimeout;                 /* for our fancy "blink" tempo indicator */



void loop()

{

 /* read the button on pin 5, and only pay attention to the

  HIGH-LOW transition so that we only register when the

  button is first pressed down */

 int tapState = digitalRead( 5 );

 if( tapState == LOW && tapState != lastTapState )

 {

   tap();                         /* we got a HIGH-LOW transition, call our tap() function */

 }

 lastTapState = tapState;         /* keep track of the state */



 /* check for timer timeout */



 if( millis() >= timeoutTime )

 {

   /* timeout happened.  clock tick! */

   indicatorTimeout = millis() + ((currentTimer[0] + currentTimer[1])/2)/2;  /* this sets the time when LED 14 goes off */

   

   /* and reschedule the timer to keep the pace */

   rescheduleTimer();

 }



 /* display the button state on LED 2 */

 digitalWrite( 14, tapState );



 /* display the tempo on LED 1 and inverse on pin 3 */

 if( millis() < indicatorTimeout ) {

   digitalWrite( 2, HIGH );

   digitalWrite( 3, LOW );

 }

 else {

   digitalWrite( 2, LOW );

   digitalWrite( 3, HIGH );

 }



}



unsigned long lastTap = 0; /* when the last tap happened */

void tap()

{

 /* we keep two of these around to average together later */

 currentTimer[1] = currentTimer[0];

 currentTimer[0] = millis() - lastTap;

 lastTap = millis();

 timeoutTime = 0; /* force the trigger to happen immediately - sync and blink! */

}



void rescheduleTimer()

{

 /* set the timer to go off again when the time reaches the

  timeout.  The timeout is all of the "currentTimer" values averaged

  together, then added onto the current time.  When that time has been

  reached, the next tick will happen...

  */

 timeoutTime = millis() + ((currentTimer[0] + currentTimer[1])/2);

}