MUFF WIGGLER Forum Index
 FAQ & Terms of UseFAQ & Terms Of Use   Wiggler RadioMW Radio   Muff Wiggler TwitterTwitter   Support the site @ PatreonPatreon 
 SearchSearch   RegisterSign up   Log inLog in 
WIGGLING 'LITE' IN GUEST MODE

tap tempo timer on b
MUFF WIGGLER Forum Index -> nw2s  
Author tap tempo timer on b
spacenoodle
I'm wondering how to make my tap tempo controlled timer work with interrupts. I'm tapping a button on the PS3 controller attached to the b here:

Code:
void controller_button_L3()//tap tempo
{
  bool l3 = ps3->getButtonPress(L3);
  static bool tapping;
  static unsigned long tapTime[4];
  static int tapAverage;
 
  if (l3 && !tapping)
  {   
    tapTime[0] = millis();
    tapTime[1] = tapTime[2];
    tapTime[2] = tapTime[0] - tapTime[3];
    tapTime[3] = tapTime[0];
    tapAverage = ((tapTime[1] + tapTime[2]) * 0.5);
       
    if(tapTime[2] > 3000)//if more than 3 seconds has elapsed, ignore the previous tap.
    {
        //do nothing
    }
    else if(tapTime[1] > 3000)//get a delta between the first and second tap. Nothing to average yet.
    {
      tempo = 60000/tapTime[2];
    }
    else//average tap time
    {
      tempo = 60000/tapAverage;
    }
   
    millisPerPulse = (1 / tempo) * 2500.0; //pulse length in milliseconds (scaled with tempo) : (1/tempo) * (1/ppqn) * 60000
    digitalWrite(DUE_OUT_D06, 1);
    tapping = true;
  } 
  else if (!l3)
  {
    digitalWrite(DUE_OUT_D06, 0);
    tapping = false;
  }
}


And here's the inefficient part, a timer that checks millis() to increment:
Code:
void masterClock()
{
  currentMillis = millis();

  if (currentMillis - lastMillis > millisPerPulse)
  {
    lastMillis = currentMillis;

    if (transport == SEQ_START)
    {
      if (pulse < 97) //24 ppqn, 96 ppm
      {
        pulse++;
      }
      else
      {
        pulse = 0;
      }

      slave1Sync(pulse);
      slave2Sync(pulse);
    }
  }
}


Do you have any recommendations how I could fix this to work without constantly rechecking millis()? I haven't used interrupts before and most of the examples I've found for the Due are checking states on pins. I looked into using the clock library you've provided for the b but was unsuccessful incorporating it into my sketch in this way.
spacenoodle
This timer library seems like a good fit. The documentation is very helpful. Just a little rewrite and I'll see if she likes it!

https://github.com/ivanseidel/DueTimer

EDIT: Working. Although more precise timing tests are in order. w00t
scottwilson
Cool - There wasn't a Due timer library before... the timer code on the ARM is a but more complicated than the AVR. I need to do the same to get a real slave clock running!

s
magneticstripper
any time frame on the slave clock? will there be a Json version?
scottwilson
Yes, it's actually what I'm working on now... along with a clock divider kinda like the "limit" portion of the pendulum/ratchet.

s
magneticstripper
You are a King amongst men Scott!
scottwilson
Tap tempo clock getting close... Just working through some timing bugs. Also, the ratchet divider! (Includes JSON definitions)

Should finish today for anyone looking for it.
spacenoodle
In testing out several tap tempo applications, I definitely prefer ones that don't slew the rate between taps. If I can get to the new tempo with two taps, it feels nice and responsive. I'm wondering what your approach is as there are so many ways to do it.
scottwilson
My original design had a 4 tap averaging, but the new one is simpler. Two taps gets you a new tempo.

You can slave to another clock by simply patching into the digital input or you can tap a couple of times till the tempo is where you want it and then it'll freewheel at that tempo. 4 seconds is the pause between taps for it to consider that you're starting anew.

s
spacenoodle
Nice. I'm hoping to add a little logic to prevent tempo weirdness possible to occur before the listening timeout has elapsed. For example, if it's still listening, and there is a long pause followed by two taps close together, ignore the second to last tap in favor of the most recent two. At least, I think it will be beneficial in my design.
magneticstripper
Scott, how is the slave clock turning out?
scottwilson
C++ version is checked in... I haven't done the JSON parser for it yet, but should be done by the end of the weekend.

(Also adding USB Midi support this weekend)

s
magneticstripper
That is a lot of connective tissue! Good job!
scottwilson
Testing the JSON version of this today before I say it's done... but I also added another similar clock that is a passthru clock.

So the way a tap tempo clock works, as the tempo goes up and down, devices in the sketch can get out of sync... This is because when you go from, say a 60BPM to 100BPM tempo, the device that was clocked to 60BPM won't start looking for another tick until the next tick at 60BPM... if it's ticking away at quarter notes, that will be the next quarter note.

To defeat this, I added another toggle that will force a reset() (a clock tick) on all devices when a tap tempo comes in. This will keep them in sync, effectively resetting them all to "start" on the next beat.

Note that this is definitely geared towards a tap tempo rather than a continuous clock. You can't send a swing clock to the tap tempo and expect the devices to begin swinging.

For that, I created a passthru clock. This will take a trigger input and on every pulse, send a pulse to the devices slaved to that clock. This _will_ allow you to swing... but it won't freewheel. When the clock stops, the devices stop.

Two different approaches for what one might call a "slave" clock. One tap tempo and the other a passthrough.

I'll have some samples up with the tested code.

s
scottwilson
So passthruclock and tap tempo clocks are checked in. Working in JSON.

Here's a sample - a tap tempo clock divider:

Code:

{
   "program" :    

   {
      "name" :          "Tap Divider",
         
      "clock" :

      {
         "type" : "TapTempoClock",
         "tapInput" : 1,
         "resetInput" : 2,
         "beats" : 16         
      },

      "devices" : [
         
         {
            "type" : "Trigger",
            "division" : "whole",
            "triggerOutput" : 1
         },

         {
            "type" : "Trigger",
            "division" : "half",
            "triggerOutput" : 2
         },

         {
            "type" : "Trigger",
            "division" : "quarter",
            "triggerOutput" : 3
         },

         {
            "type" : "Trigger",
            "division" : "quarter triplet",
            "triggerOutput" : 4
         },

         {
            "type" : "Trigger",
            "division" : "dotted eighth",
            "triggerOutput" : 5
         },

         {
            "type" : "Trigger",
            "division" : "eighth",
            "triggerOutput" : 6
         },

         {
            "type" : "Trigger",
            "division" : "eighth triplet",
            "triggerOutput" : 7
         },

         {
            "type" : "Trigger",
            "division" : "sixteenth",
            "triggerOutput" : 8
         }      
      ]
   }
}


And here's a passthru clock with a 1:1 tap to Turing Machine trigger:

Code:

{
   "program" :    

   {
      "name" :          "Alanesque",

      "clock" :
      
      {
           "type" : "PassthruClock",
           "tapInput" : 1,
           "beats" : 16           
      },
      

      "devices" : [         
         
         {
            "type" : "RandomLoopingShiftRegister",
            "size" : 32,
            "division" : "sixteenth",
            "controlInput" : 2,
            "analogOutput" : 15,
            "delayedOutput" : 16,
            "delay" : 12,
            "triggerOutput1" : 5,
            "triggerOutput2" : 6,
            "triggerOutput3" : 7,
            "triggerOutput4" : 8,
            "triggerOutput5" : 9,
            "triggerOutput6" : 10,
            "triggerOutput7" : 11,
            "triggerOutput8" : 12,
            "logicalAND1" : 13,
            "logicalAND2" : 14,
            "logicalAND3" : 15,
            "logicalAND4" : 16
         }
      ]
   }
}
MUFF WIGGLER Forum Index -> nw2s  
Page 1 of 1
Powered by phpBB © phpBB Group