DIYstompboxes.com

DIY Stompboxes => Digital & DSP => Topic started by: deadastronaut on December 11, 2018, 08:06:50 AM

Title: ARDUINO TAP TEMPO experiments.
Post by: deadastronaut on December 11, 2018, 08:06:50 AM
hi guys...just dug out my arduino UNO. as i have a tremolo on breadboard
and thought it would be fun to try a tap for it......simple led to ldr setup...

after seeing this guys video on tap tempo. which looks cool

https://www.youtube.com/watch?v=ur_PEUH7sns

however he is using an arduino NG.

and i cant get the code to load on my UNO. (forgive my noobyness) but can his NG code go onto my UNO?

here is his code : it compiles ok, but wont actually load. thanks in advance.. :)

/*
    Tap Tempo
   
    An experiment to detect tempo by tapping a button
   
    Press a button connected to digital pin 12.
    LED on pins 2-12 displays the beat pulse
    LED on pin 13 shows the current button state (dim when button is pressed)
   
    Digital Output <--------/\/ 220 ohm /\/----[LED]----> GND
   
    (Digital 13 is wired up to the LED on the NG board.  If you have an older
     board, drop the standard LED between pin 13 and GND)
     
                     +------> +5 power
                     |
    Digital 12 <-----+----[ switch ]-----/\/ 10k ohm /\/-----> GND

*/

void setup()
{
  pinMode( 12, INPUT );   /* tap button - press it to set the tempo */
 
  pinMode( 13, OUTPUT );  /* button state display - not necessary */
 
  for( int i=2 ; i<12 ; i++ ) {
    pinMode( i, OUTPUT );  /* tempo display light - shows the current tempo */
  }
}


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 12, and only pay attention to the
     HIGH-LOW transition so that we only register when the
     button is first pressed down */
  int tapState = digitalRead( 12 );
  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() + 30;  /* this sets the time when LED 13 goes off */
    /* and reschedule the timer to keep the pace */
    rescheduleTimer();
  }
 
  /* display the button state on LED 2 */
  digitalWrite( 13, tapState );
 
  /* display the tap blink on LED 13 */
  for( int i=2 ; i<12 ; i++ ) {
    if( millis() < indicatorTimeout ) {
      digitalWrite( i, HIGH );
    } else {
      digitalWrite( i, LOW );
    }
  }
}

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);
}
Title: Re: ARDUINO TAP TEMPO experiments.
Post by: anotherjim on December 11, 2018, 10:18:11 AM
There are some older sketches about that won't compile in the latest IDE, but you should get compiler warnings about that.
There probably aren't any good reasons why a sketch that compiles ok will be refused by the programmer because of what's in the program. There are many other possible reasons for it to fail to upload to the board...

Do you have the right board and processor selected in the Tools menu? I don't think you should get a processor item once UNO is selected because that board never had a choice of processor.
Have you got the right USB driver the UNO uses and is the right COM port selected in the tools menu?
Have you tried a simple example sketch to prove your board can be programmed ok?

A trivial thing in that code, and nothing to do with it working or not. I'm not quite sure what the instruction for the input button is in there...
Quote
                     +------> +5 power
                     |
    Digital 12 <-----+----[ switch ]-----/\/ 10k ohm /\/-----> GND
I've a feeling the formatting may be messed up. Probably it's a 10k pull-up to +5v and the button grounds pin12 when you press it? In which case you could lose the 10k and enable the pins internal pull-up by changing...
QuotepinMode( 12, INPUT );   /* tap button - press it to set the tempo */
To...
pinMode( 12, INPUT_PULLUP );   /* tap button - press it to set the tempo */
Then the only connection is to ground when the button is pressed.
Title: Re: ARDUINO TAP TEMPO experiments.
Post by: deadastronaut on December 11, 2018, 10:48:09 AM
hi jim, got the code uploaded now, using a better usb pc socket....

so com port /compiling etc all ok....

not so sure on my connections though, the led was flashing, but being quite random...

and no tap...hmmm...
Title: Re: ARDUINO TAP TEMPO experiments.
Post by: deadastronaut on December 11, 2018, 11:30:00 AM
hi im, yep tried that, when i push button it turns the arduino off...(powers off)

hmmm......

edit:  it works.

i removed the 5v supply. and the 10k. and changed the code according to your tip....

now it responds as it should...cheers man . rob .  8) 8) 8)
Title: Re: ARDUINO TAP TEMPO experiments.
Post by: anotherjim on December 12, 2018, 01:45:41 PM
Cool  8)
Odd the original external 10k pullup resistor caused a holdup. Looks like you're good to go though.
Incidentally, you don't usually have to have the Arduino wired to the application circuit to program it. It's probably a good idea to have nothing but the USB to your computer connected to program it. Normally, the Arduino won't mind things plugged into the I/O pins. But if the digital0 or digital1 pins are used, it can hold up the USB connection needed to program it.
Title: Re: ARDUINO TAP TEMPO experiments.
Post by: deadastronaut on December 12, 2018, 01:55:30 PM
right, gotcha cheers jim....that makes sense, so it gets confused on uploading..

i tried sticking the code onto a nano earlier, just for neatness, but having grief with a dodgy ch403g driver...i'll persevere...

but yeah it works pretty good....very slow to mega fast...

i tapped along with a few drum riffs at different bpm's just to test ...looked pretty much bang on.
nifty... 8)
Title: Re: ARDUINO TAP TEMPO experiments.
Post by: deadastronaut on December 13, 2018, 07:20:20 AM
hi guys, well i managed to get it onto a nano...i had driver issues :icon_rolleyes:. done.

heres what i have, and the updated code for anyone playing along... :)

the square is fun and works really well, but how to make it switch between square and triangle..(pulsing led)?

excuse my noobness with this lark.. ::)

(https://i.postimg.cc/sggw7jQ4/NANOTAPTEMPO.jpg)


/*
    Tap Tempo
   
    An experiment to detect tempo by tapping a button
   
    Press a button connected to digital pin 12.
    LED on pins 2-11 displays the beat pulse
    LED on pin 13 shows the current button state (dim when button is pressed)
   
    Digital Output 2-11 pins <----- 220 ohm ----+[LED]----> GND
   
    (Digital 13 is wired up to the LED on the uno/nano board.  If you have an older
     board, drop the standard LED between pin 13 and GND)
     
    Digital 12 <---------[ switch ]--------> GND

*/

void setup()
{
  pinMode( 12, INPUT_PULLUP );   /*   /* tap button - press it to set the tempo */
 
  pinMode( 13, OUTPUT );  /* button state display - not necessary */
 
  for( int i=2 ; i<12 ; i++ ) {
    pinMode( i, OUTPUT );  /* tempo display light - shows the current tempo */
  }
}


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 12, and only pay attention to the
     HIGH-LOW transition so that we only register when the
     button is first pressed down */
  int tapState = digitalRead( 12 );
  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() + 30;  /* this sets the time when LED 13 goes off */
    /* and reschedule the timer to keep the pace */
    rescheduleTimer();
  }
 
  /* display the button state on LED 2 */
  digitalWrite( 13, tapState );
 
  /* display the tap blink on LED 13 */
  for( int i=2 ; i<12 ; i++ ) {
    if( millis() < indicatorTimeout ) {
      digitalWrite( i, HIGH );
    } else {
      digitalWrite( i, LOW );
    }
  }
}

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);
}
Title: Re: ARDUINO TAP TEMPO experiments.
Post by: anotherjim on December 13, 2018, 03:58:15 PM
So you have pins 2 to 11 pulsing high in turn at the set tempo?
Do you want a 10 stage resistor ladder thing then to make a staircase ramp waveform?
Title: Re: ARDUINO TAP TEMPO experiments.
Post by: deadastronaut on December 13, 2018, 04:01:37 PM
Hi jim. No i just have 1 led...i just showed it can be connected to any or all of those pins..
Title: Re: ARDUINO TAP TEMPO experiments.
Post by: potul on December 14, 2018, 06:19:01 AM
If you want to output something different than a square signal, you will need some sort of DAC.

For arduino, the simplest way is to use PWM in one of the compatible pins, and use the analogWrite() (https://www.arduino.cc/reference/en/language/functions/analog-io/analogwrite/) function.

In arduino nano, the pwm compatible pins are:

QuotePWM: 3, 5, 6, 9, 10, and 11. Provide 8-bit PWM output with the analogWrite() function.
Title: Re: ARDUINO TAP TEMPO experiments.
Post by: potul on December 14, 2018, 06:20:46 AM
Note that you may need some filtering, and that the output is only 8 bits.... You could combine 2 outputs for better resolution, I guess.
Title: Re: ARDUINO TAP TEMPO experiments.
Post by: anotherjim on December 14, 2018, 12:08:03 PM
Yeh, I thought PWM too.
If you have the tempo period as a value, you could divide that by how many "steps" for a staircase ramp wave you want. Use that time to delay between increments of a value that is used for the analogWrite to a PWM output. Reset the value to zero when it reaches a maximum for a saw wave or start decrementing back down toward zero for a triangle. You'll probably have to shave some time off the step delay time period to allow for calculation delays.
Alternatively for simple, scale the tempo value so that its range suits what the analogWrite can take, and treat it the PWM voltage as a control voltage, although it won't be scaled in any exact way to the tempo, just inversely proportional. Faster tempo = lower voltage.
Title: Re: ARDUINO TAP TEMPO experiments.
Post by: deadastronaut on December 14, 2018, 12:29:55 PM
ha ha i'm lost already..... ::)

i was looking at the resistor ladder earlier...hmmmm.

couldn't i just take the arduino out to an opamp lfo with triangle and square
and use the tap part to control the speed of that?....just thinking aloud..  :-\

gets coat... :-\
Title: Re: ARDUINO TAP TEMPO experiments.
Post by: anotherjim on December 14, 2018, 04:05:29 PM
You could use the tempo pulse from the Arduino to clock a counter with a resistor ladder and use that as an LFO. There is a kind of sequencer, used for making evolving sounds, that's actually a step sequencer with pots instead of fixed resistors. There are some designs out there for that using CD4017 counter chips.

The problem with controlling an external LFO is in making the speed of that LFO match in sync with the tempo pulse. Just for kicks, hook up a simple RC low pass on the tempo output to get a poor man's triangle wave. You should find there is no way to have the full voltage swing up and down for a range of tempo. Either the cap charges too soon and you get flat top waves or never reaches the top before it goes back down.  It will only be close to ideal at one tempo rate. That said, with a variable resistor or some different caps in the RC, you might find that works well enough for your application.

The counter/step sequencer approach is sure to be in sync, but the period before it repeats will be some multiple slower than the tempo pulse. So a 4bit counter gives an LFO sequence of 16 steps, but the rate is 16 times slower than the tempo pulse. Ok for a flanger sweep, but maybe not a tremolo?

I don't know for sure how the Arduino LED acts in tempo. Is it like, if you tap 60 per minute, then it flashes 60 times per minute, so it's 1 pulse per quarter note? What most tap tempo devices do under the hood, is derive a pulse time a fraction of the BPM time. They can deliver the tempo control at rates like 48 or 96 PPQN or as fast as the processor allows. PPQN is pulses per quarter note. So if the tempo is 60BPM which is 60 quarter notes per minute, the tempo pulse may actually be up to 96 times faster (but it displays at a more human-readable rate). Then it can use that faster time or multiples of it, to step through a wavetable of a selected wave shape and deliver a reasonable quality LFO output via some kind of DAC that can be fast enough for vibe/trem use if it's called for.

Title: Re: ARDUINO TAP TEMPO experiments.
Post by: deadastronaut on December 14, 2018, 04:19:37 PM
''hook up a simple RC low pass on the tempo output to get a poor man's triangle wave.''

hi jim, yeah i tried that, not good..didnt notice much difference if any...maybe i had wrong values.  ::)

anyway as for the bpm. i was tapping along with drum beats at different bpm's, and yes it does quarter notes

quite nicely ,60bpm, 120bpm, etc....it looks like its bang on going by the led on /off...it can go very slow , to very fast....


i now have 2 nanos on breadboard....one with the tap tempo as above...

and the other nano as a flash led with pot for speed control......

ive been trying to get the flash led with speed control to pulse (fade in / out instead of flash...

theres plenty of sketches out there to 'fade' but none that use the pot as the speed too...still looking/tweaking.

it would be nice to combine all 3,  flash, pulse (fade in/out) , with speed pot....and of course tempo.

then it would be pretty useful..

Title: Re: ARDUINO TAP TEMPO experiments.
Post by: deadastronaut on December 15, 2018, 09:41:02 AM
well ive been looking about, and found a great little gem...

https://github.com/jandelgado/jled/tree/master/examples/multiled

now i have 
1: flashing led : perfect for choppy trem. 8)
2 pulsing led   : perfect for smooth trem. 8)
3 ramp up then off led  : might be interesting ::)
4 ramp down then off led  :might be intersting ::)

all at the same time, in time too...as in the link.

here is code for above.

#include <jled.h>

JLed leds[] = {
    JLed(3).Breathe(2000).Forever(),
    JLed(4).Blink(750, 250).Forever(),
    JLed(5).FadeOff(1000).Forever(),
    JLed(6).FadeOn(1000).Forever(),
    JLed(LED_BUILTIN).Blink(500, 500).Forever()};

void setup() {
}

void loop() {
    for (auto& led : leds) {led.Update();}
    delay(1);
}


how to paste this into the above tap code if possible????....hmmmm...
Title: Re: ARDUINO TAP TEMPO experiments.
Post by: potul on December 17, 2018, 06:45:32 AM
Give this a try:


/*
    Tap Tempo using Jleds
   
*/

#include <jled.h>

int period = 2000;
JLed leds[] = {
    JLed(3).Breathe(period).Forever(),
    JLed(4).Blink(period/4*3, period/4).Forever(),
    JLed(5).FadeOff(period).Forever(),
    JLed(6).FadeOn(period).Forever(),
    JLed(LED_BUILTIN).Blink(period/2, period/2).Forever()};

void setup()
{
  pinMode( 12, INPUT );   /* tap button - press it to set the tempo */
}


int lastTapState = LOW;  /* the last tap button state */
unsigned long currentTimer[2] = { 500, 500 };  /* array of most recent tap counts */

void loop()
{
  /* read the button on pin 12, and only pay attention to the
     HIGH-LOW transition so that we only register when the
     button is first pressed down */
  int tapState = digitalRead( 12 );
  if( tapState == LOW && tapState != lastTapState )
  {
    tap(); /* we got a HIGH-LOW transition, call our tap() function */
  }
  lastTapState = tapState; /* keep track of the state */
 
    // update leds
    for (auto& led : leds) {led.Update();}
    delay(1);
}

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();
 
  // establish new period
  period = ((currentTimer[0] + currentTimer[1])/2);

  // update leds period
  leds[0] = JLed(3).Breathe(period).Forever();
  leds[1] = JLed(4).Blink(period/4*3, period/4).Forever();
  leds[2] = JLed(5).FadeOff(period).Forever();
  leds[3] = JLed(6).FadeOn(period).Forever();
  leds[4] = JLed(LED_BUILTIN).Blink(period/2, period/2).Forever();
}
Title: Re: ARDUINO TAP TEMPO experiments.
Post by: deadastronaut on December 17, 2018, 07:43:27 AM
hi potul, thanks for taking a look, very much appreciated.

i tried it, but its not accepting any taps.....no tap tempo.

the 4 leds react as they should for a while,, then go a bit random...and fast..without tapping.

cheers rob .

Title: Re: ARDUINO TAP TEMPO experiments.
Post by: potul on December 17, 2018, 07:46:08 AM
crazy... I will try to debug it... I did not test it in an actual arduino, just simulated.
Title: Re: ARDUINO TAP TEMPO experiments.
Post by: deadastronaut on December 17, 2018, 07:53:22 AM
cheers man, i was just thinking,

if we use the original tap tempo sketch, and then just add a fading led to a pwm pin

so one is flashing on off/ and the other is fading on/off, it may be easier....just thinking aloud..

cheers rob .

Title: Re: ARDUINO TAP TEMPO experiments.
Post by: potul on December 17, 2018, 08:10:17 AM
Well, this is basically what I did. I took the original sketch, added the LEDs and modified the code to update the period of the Leds.

I reviewed the code and it seems to be ok, and it woks fine in my simulator.

How do you have everything connected?

BTW, I just noticed this:

                     +------> +5 power
                     |
    Digital 12 <-----+----[ switch ]-----/\/ 10k ohm /\/-----> GND


I don't think this is a good way to connect the switch.. I would do it this way:


                     +-----/\/ 10k ohm /\/----> +5 power
                     |
    Digital 12 <-----+----[ switch ]-------> GND
Title: Re: ARDUINO TAP TEMPO experiments.
Post by: deadastronaut on December 17, 2018, 08:20:04 AM
hi, ok i just rigged up the 5v- 10k to pin 12 as you did above...

pin 12... switch.....gnd.

pin3/4/5/6 to 330r's /leds and gnd...

still no tap. hmmmm.....

i'll take out nano, and re upload, then put back on bread.....
Title: Re: ARDUINO TAP TEMPO experiments.
Post by: deadastronaut on December 17, 2018, 08:26:30 AM
yup, that did it.....seems to be working now man.....nice one.

i'm getting a flash between  the 3 taps, which is a bit disconcerting, but yeah it seems to work.

8) 8) 8)

edit.
cool, i just removed leds 5/6 and off the code too....cool, works ok. cheers man,  8)
Title: Re: ARDUINO TAP TEMPO experiments.
Post by: potul on December 17, 2018, 08:31:59 AM
Nice,

what do you mean by getting a flash between 3 taps?
Title: Re: ARDUINO TAP TEMPO experiments.
Post by: deadastronaut on December 17, 2018, 08:34:32 AM
the leds come on between tapping.....

rather than tap/blink....tap/blink........tap/blink.......and its set to tempo...
Title: Re: ARDUINO TAP TEMPO experiments.
Post by: potul on December 17, 2018, 08:53:12 AM
Ok, the way it is coded, the leds are never stopping, so they always flash. When you tap you update the timing, but they don't stop in between taps. And the timing is only updated after you do at least two taps. But only if you tap 3 times it will work properly.
This is because the code doesn't know if you are in the middle of tapping or not. they way it works is that it simply counts time between taps, and always average the last 2 intervals you tapped.

So, if you stop tapping... it countinues counting, and if you tap  once after 2 minutes, it will count as a 2 minutes tap,... so until you tap 3 times you are not cleaning up the "old" taps.

With this what I try to explain is that the way the code works, the LEDs are always blinking at the set time, even during tapping. They are not synched to the actual taps of the switch.

Title: Re: ARDUINO TAP TEMPO experiments.
Post by: deadastronaut on December 17, 2018, 08:57:29 AM
ahh ok gotcha.....i see.

i just tried tapping along to a drum beat at different bpm's.

seemed ok,  however the onboard led was more in time than the pin4 led...(pin4 was just a littl lagging behind going by my eye)

so i just moved the pin 4 led to the pin 13 so its the same as the onboard led...now its bang on by the looks of it.

cool..... 8)
Title: Re: ARDUINO TAP TEMPO experiments.
Post by: deadastronaut on December 17, 2018, 09:04:08 AM
so here is the wiring as i have it. :

5v ---10k---D12

D12----SW---GND

D3---330r--LED---GND (PULSE) fade on off

D13---330r---LED--GND (FLASH) on/off

edit, ooh one last thing, can a pot be added for manual speed too?

i know i'm a pain in the ass :)
Title: Re: ARDUINO TAP TEMPO experiments.
Post by: potul on December 17, 2018, 09:14:33 AM
Quote from: deadastronaut on December 17, 2018, 08:57:29 AM
ahh ok gotcha.....i see.

i just tried tapping along to a drum beat at different bpm's.

seemed ok,  however the onboard led was more in time than the pin4 led...(pin4 was just a littl lagging behind going by my eye)

so i just moved the pin 4 led to the pin 13 so its the same as the onboard led...now its bang on by the looks of it.

cool..... 8)

I see. Well, there are 2 blinking leds in the code, but they are not the same.
onbaord LED is blinking following the tap tempo.
Led 4 is blinking with a 75% duty cycle (it's on 75% of the time, off 25%). I thought this was added by you.... :)

You customize what each LED does here:

  leds[0] = JLed(3).Breathe(period).Forever();
  leds[1] = JLed(4).Blink(period/4*3, period/4).Forever();
  leds[2] = JLed(5).FadeOff(period).Forever();
  leds[3] = JLed(6).FadeOn(period).Forever();
  leds[4] = JLed(LED_BUILTIN).Blink(period/2, period/2).Forever();

The "blink" function has 2 parameters. The first one is the ON time, the second one is the OFF time. if you see, the LED_BUILTIN (onboard) is ON half of the time, and LEd 4 is ON 75% (3/4) of the time.

You can customize this in the code as needed.
Title: Re: ARDUINO TAP TEMPO experiments.
Post by: potul on December 17, 2018, 09:21:31 AM
Regarding the pot, yes, it is possible with some adjustments. Adding and reading a pot is somehow easy, what is tricky is how to combine pot and tap information

How do you want to  handle this? The way I would do is:

-if pot is not moved by a certain threshold, tempo is taken from tapping.
-If pot moves higher than this threshold, it takes control and time is taken from the pot position.
-If you tap, control goes back to tapping and pot gets ignored.

Another option would be that pot always have preference, unless it's set at zero. So you can only tap tempo if the pot is at zero.

What's your idea here?
Title: Re: ARDUINO TAP TEMPO experiments.
Post by: deadastronaut on December 17, 2018, 09:27:41 AM
ahh ok i got it on the values now..i shall tinker wih the d4 values... 8)

as for the pot idea. option 3 sounds pretty cool..

'-If you tap, control goes back to tapping and pot gets ignored.'

will pot take over tempo if moved? if so how does tapping take over again?.
Title: Re: ARDUINO TAP TEMPO experiments.
Post by: potul on December 17, 2018, 09:47:36 AM
Yes, the idea will be that last thing used will take over. So, if you tap, tap takes over. And stays like this until you move the pot.... and so on.
Title: Re: ARDUINO TAP TEMPO experiments.
Post by: potul on December 17, 2018, 10:08:47 AM
Ok, try this one.

Pot should be connected to A0 as a voltage divider between Vcc and GND.

               
Analog 0   <-----+
                         |
                         |
Vcc   <-----/\/ 10k ohm Pot /\/-----> GND


Pot doesn't need to be 10k... but 10k is usually a good value.


/*
    Tap Tempo using Jleds
*/

#include <jled.h>

#define THRESHOLD 20
#define EXP1 A0
#define MAXDELAY 3000

int period = 2000;
JLed leds[] = {
    JLed(3).Breathe(period).Forever(),
    JLed(4).Blink(period/4*3, period/4).Forever(),
    JLed(5).FadeOff(period).Forever(),
    JLed(6).FadeOn(period).Forever(),
    JLed(LED_BUILTIN).Blink(period/2, period/2).Forever()};


int lastVal = 0;
int tempAnalog = 0;
boolean PotControls = true;

void setup()
{
  pinMode( 12, INPUT );   /* tap button - press it to set the tempo */
}

int lastTapState = LOW;  /* the last tap button state */
unsigned long currentTimer[2] = { 500, 500 };  /* array of most recent tap counts */

void loop()
{
  /* read the button on pin 12, and only pay attention to the
     HIGH-LOW transition so that we only register when the
     button is first pressed down */
  int tapState = digitalRead( 12 );
  if( tapState == LOW && tapState != lastTapState )
  {
    tap(); /* we got a HIGH-LOW transition, call our tap() function */
  }
  lastTapState = tapState; /* keep track of the state */
 
    // update leds
    for (auto& led : leds) {led.Update();}
    // check pot value
    poll_pot();
    delay(1);
}

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();
 
  // establish new period
  period = ((currentTimer[0] + currentTimer[1])/2);

  PotControls = false;
 
  // update leds period
  update_leds();
}

void update_leds(){
  leds[0] = JLed(3).Breathe(period).Forever();
  leds[1] = JLed(4).Blink(period/4*3, period/4).Forever();
  leds[2] = JLed(5).FadeOff(period).Forever();
  leds[3] = JLed(6).FadeOn(period).Forever();
  leds[4] = JLed(LED_BUILTIN).Blink(period/2, period/2).Forever();
}

void poll_pot() {
  // Read analog value
  tempAnalog = analogRead(EXP1);
 
  // Convert 10 bit to milliseconds, 3 seconds maximum
  tempAnalog = map(tempAnalog, 0, 1023, 0, MAXDELAY);
  tempAnalog = constrain(tempAnalog, 0, MAXDELAY);
 
  // Check pot value and compare variation with threshold
  if((abs(tempAnalog-lastVal)>THRESHOLD))
  {
    // update period with pot value
    period = tempAnalog;
    //return control to Pot   
    PotControls = true;
    // Store current value to be used laters
    lastVal = tempAnalog;
    // update leds with new timing
    update_leds();
  }
   
  //delay(5); 
}
   


You can customize these values:

#define THRESHOLD 20
#define EXP1 A0
#define MAXDELAY 3000

THRESHOLD = minimum movement of the pot to take control (in ms). You may need to play with this one if you see erratic timing changes.
EXP1 = pin used for the pot
MAXDELAY = maximum delay when pot is at 100% (in ms)
Title: Re: ARDUINO TAP TEMPO experiments.
Post by: potul on December 17, 2018, 10:23:21 AM
An updated version with some corrections and one new feature.

now you can configure MAXTAP in this line:

#define MAXTAP 8000

It defines a timeout between taps. Any tap interval higher than this value will be ignored. This avoid that after some minutes, if you push the tap once, everything is screwed.


/*
    Tap Tempo using Jleds
*/

#include <jled.h>

#define THRESHOLD 20
#define EXP1 A0
#define MAXDELAY 3000
#define MINDELAY 1
#define MAXTAP 8000

int period = 2000;
JLed leds[] = {
    JLed(3).Breathe(period).Forever(),
    JLed(4).Blink(period/4*3, period/4).Forever(),
    JLed(5).FadeOff(period).Forever(),
    JLed(6).FadeOn(period).Forever(),
    JLed(LED_BUILTIN).Blink(period/2, period/2).Forever()};


int lastVal = 0;
int tempAnalog = 0;
boolean PotControls = true;

void setup()
{
  pinMode( 12, INPUT );   /* tap button - press it to set the tempo */
}

int lastTapState = LOW;  /* the last tap button state */
unsigned long currentTimer[2] = { 500, 500 };  /* array of most recent tap counts */

void loop()
{
  /* read the button on pin 12, and only pay attention to the
     HIGH-LOW transition so that we only register when the
     button is first pressed down */
  int tapState = digitalRead( 12 );
  if( tapState == LOW && tapState != lastTapState )
  {
    tap(); /* we got a HIGH-LOW transition, call our tap() function */
  }
  lastTapState = tapState; /* keep track of the state */
 
    // update leds
    for (auto& led : leds) {led.Update();}
    // check pot value
    poll_pot();
    delay(1);
}

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

void tap()
{
  if ((millis()-lastTap)>MAXTAP){
      lastTap = millis();
      return;
    }
  /* we keep two of these around to average together later */
  currentTimer[1] = currentTimer[0];
  currentTimer[0] = millis() - lastTap;
  lastTap = millis();
 
  // establish new period
  period = ((currentTimer[0] + currentTimer[1])/2);

  PotControls = false;
 
  // update leds period
  update_leds();
}

void update_leds(){
  leds[0] = JLed(3).Breathe(period).Forever();
  leds[1] = JLed(4).Blink(period/4*3, period/4).Forever();
  leds[2] = JLed(5).FadeOff(period).Forever();
  leds[3] = JLed(6).FadeOn(period).Forever();
  leds[4] = JLed(LED_BUILTIN).Blink(period/2, period/2).Forever();
}

void poll_pot() {
  // Read analog value
  tempAnalog = analogRead(EXP1);
 
  // Convert 10 bit to milliseconds, 3 seconds maximum
  tempAnalog = map(tempAnalog, 0, 1023, 0, MAXDELAY);
  tempAnalog = constrain(tempAnalog, MINDELAY, MAXDELAY);
 
  // Check pot value and compare variation with threshold
  if((abs(tempAnalog-lastVal)>THRESHOLD))
  {
    // update period with pot value
    period = tempAnalog;
    //return control to Pot   
    PotControls = true;
    // Store current value to be used laters
    lastVal = tempAnalog;
    // update leds with new timing
    update_leds();
  }
   
  //delay(5); 
}
Title: Re: ARDUINO TAP TEMPO experiments.
Post by: deadastronaut on December 17, 2018, 12:02:30 PM
Hi potul , great thanks man, excellent.

the first pot one works fine...

i played with the values of the 4*3 bit, but couldnt get the d4 led to be same as the built in led

timing wise....the leds come on at the same time, but the d4 led goes off a little later...like you said

which values should they be do you think?.
Title: Re: ARDUINO TAP TEMPO experiments.
Post by: potul on December 17, 2018, 03:36:35 PM
the on period and the off period must be a total equal to "period"

so...

leds[1] = JLed(4).Blink(period/2, period/2).Forever();

should work
Title: Re: ARDUINO TAP TEMPO experiments.
Post by: deadastronaut on December 18, 2018, 04:12:51 AM
cheers potul, yep that works in time with pin13 led now....excellent,

i tried removing the code for other unused leds, but it messed the timing up again...so left that in

so heres where we are now.  (sussed pasting code now too)  ::)


/*
    Tap Tempo using Jleds
*/

#include <jled.h>

#define THRESHOLD 20
#define EXP1 A0
#define MAXDELAY 3000

int period = 2000;
JLed leds[] = {
    JLed(3).Breathe(period).Forever(),
    JLed(4).Blink(period/2, period/2).Forever(),
    JLed(5).FadeOff(period).Forever(),
    JLed(6).FadeOn(period).Forever(),
    JLed(LED_BUILTIN).Blink(period/2, period/2).Forever()};


int lastVal = 0;
int tempAnalog = 0;
boolean PotControls = true;

void setup()
{
  pinMode( 12, INPUT );   /* tap button - press it to set the tempo */
}

int lastTapState = LOW;  /* the last tap button state */
unsigned long currentTimer[2] = { 500, 500 };  /* array of most recent tap counts */

void loop()
{
  /* read the button on pin 12, and only pay attention to the
     HIGH-LOW transition so that we only register when the
     button is first pressed down */
  int tapState = digitalRead( 12 );
  if( tapState == LOW && tapState != lastTapState )
  {
    tap(); /* we got a HIGH-LOW transition, call our tap() function */
  }
  lastTapState = tapState; /* keep track of the state */
 
    // update leds
    for (auto& led : leds) {led.Update();}
    // check pot value
    poll_pot();
    delay(1);
}

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();
 
  // establish new period
  period = ((currentTimer[0] + currentTimer[1])/2);

  PotControls = false;
 
  // update leds period
  update_leds();
}

void update_leds(){
  leds[0] = JLed(3).Breathe(period).Forever();
  leds[1] = JLed(4).Blink(period/2, period/2).Forever();
  leds[2] = JLed(5).FadeOff(period).Forever();
  leds[3] = JLed(6).FadeOn(period).Forever();
  leds[4] = JLed(LED_BUILTIN).Blink(period/2, period/2).Forever();
}

void poll_pot() {
  // Read analog value
  tempAnalog = analogRead(EXP1);
 
  // Convert 10 bit to milliseconds, 3 seconds maximum
  tempAnalog = map(tempAnalog, 0, 1023, 0, MAXDELAY);
  tempAnalog = constrain(tempAnalog, 0, MAXDELAY);
 
  // Check pot value and compare variation with threshold
  if((abs(tempAnalog-lastVal)>THRESHOLD))
  {
    // update period with pot value
    period = tempAnalog;
    //return control to Pot   
    PotControls = true;
    // Store current value to be used laters
    lastVal = tempAnalog;
    // update leds with new timing
    update_leds();
  }
   
  //delay(5); 
}
Title: Re: ARDUINO TAP TEMPO experiments.
Post by: potul on December 18, 2018, 04:20:46 AM
Great!

If you want to remove the unused LEDs it can be done easily, but you can't simply delete the lines, some minor adjustments needed because the Leds are part of an array, that must be adapted.

But I can do it in two minutes if you need to. Just tells me wich ones you want to keep.
Title: Re: ARDUINO TAP TEMPO experiments.
Post by: deadastronaut on December 18, 2018, 04:48:37 AM
cheers man, im just using the 2 breathe and the blink leds. .

been having a little issue with the pot , it gets a bit glitchy, here and there...but that may be due to flying wires etc...

heres where i am. connection wise...

(https://i.postimg.cc/K8Z6dCdQ/NANOTAPTEMPO66.jpg)

Title: Re: ARDUINO TAP TEMPO experiments.
Post by: potul on December 18, 2018, 10:23:07 AM
You can play with this:

#define THRESHOLD 20

and see if the glitchyness of the pot improves. Theoretically, if you increase this number it should be more stable, but less smooth.
Title: Re: ARDUINO TAP TEMPO experiments.
Post by: potul on December 18, 2018, 10:26:41 AM
Forgot to mention... when you use the tap tempo to set the time, and afterward you move the pot, there will always be some jump, because the LFO will change the period from the tapped tempo to the position of the pot.

Mat
Title: Re: ARDUINO TAP TEMPO experiments.
Post by: pbrommer on February 28, 2019, 01:28:18 PM
Quote from: potul on December 17, 2018, 08:53:12 AM
Ok, the way it is coded, the leds are never stopping, so they always flash. When you tap you update the timing, but they don't stop in between taps. And the timing is only updated after you do at least two taps. But only if you tap 3 times it will work properly.
This is because the code doesn't know if you are in the middle of tapping or not. they way it works is that it simply counts time between taps, and always average the last 2 intervals you tapped.


Hopefully this isn't bringing up too old of a post, but it has been helpful to read what is going on for myself and an idea I've had for a while.

Since you say the LEDs are always on, is there a way to write the code without the jLEDs to cause the LEDs to write on and off in a cycling sequence at the rate of the taps? I've seen an example from the author of the original code, but it works with bytes and numbers that I can't translate. The link is here: https://github.com/Interlock-Rochester/light-displays/blob/master/Arlene/Arlene.ino (https://github.com/Interlock-Rochester/light-displays/blob/master/Arlene/Arlene.ino). Works better than the previous code and is a bit more complex, but I cannot figure out how to write the code for a tap tempo LED sequencer. Thanks for the help. Maybe this will help.

Patrick
Title: Re: ARDUINO TAP TEMPO experiments.
Post by: potul on March 03, 2019, 03:52:38 PM
Quote from: pbrommer on February 28, 2019, 01:28:18 PM


Since you say the LEDs are always on, is there a way to write the code without the jLEDs to cause the LEDs to write on and off in a cycling sequence at the rate of the taps?


I thought this is what the code does. LEDs flashing at the rate given by the tap tempo
Title: Re: ARDUINO TAP TEMPO experiments.
Post by: pbrommer on March 04, 2019, 09:33:31 AM
It does. I was just hoping to see if there was a way to write the code to turn the LEDs on and off in sequence and cycle through 1-8.

Does that make sense? I can start another thread if needed to break this down.
Title: Re: ARDUINO TAP TEMPO experiments.
Post by: potul on March 04, 2019, 09:40:21 AM
I see... so one LED at a time and scrolling through leds?
Title: Re: ARDUINO TAP TEMPO experiments.
Post by: deadastronaut on March 10, 2019, 12:41:19 PM
hi guys, back on this again,  i gave up on the pot with tap, it was a bit too glitchy...

so i am back to 1 blink led, and 1 fade led setup..

tap is working all fine as it should. i was just wondering how to have ''unlimited time'' between taps.

so i can go ultra uber slow fade (for a filter sweep using lfo led) ....or is there a limit to this?.

heres where i am as a reference.


/*
    Tap Tempo using Jleds
   
*/

#include <jled.h>

int period = 2000;
JLed leds[] = {
    JLed(3).Breathe(period).Forever(),
    JLed(4).Blink(period/4*3, period/4).Forever(),

    JLed(LED_BUILTIN).Blink(period/2, period/2).Forever()};

void setup()
{
  pinMode( 12, INPUT );   /* tap button - press it to set the tempo */
}


int lastTapState = LOW;  /* the last tap button state */
unsigned long currentTimer[2] = { 500, 500 };  /* array of most recent tap counts */

void loop()
{
  /* read the button on pin 12, and only pay attention to the
     HIGH-LOW transition so that we only register when the
     button is first pressed down */
  int tapState = digitalRead( 12 );
  if( tapState == LOW && tapState != lastTapState )
  {
    tap(); /* we got a HIGH-LOW transition, call our tap() function */
  }
  lastTapState = tapState; /* keep track of the state */
 
    // update leds
    for (auto& led : leds) {led.Update();}
    delay(1);
}

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();
 
  // establish new period
  period = ((currentTimer[0] + currentTimer[1])/2);

  // update leds period
  leds[0] = JLed(3).Breathe(period).Forever();
  leds[1] = JLed(4).Blink(period/4*3, period/4).Forever();

  leds[4] = JLed(LED_BUILTIN).Blink(period/2, period/2).Forever();
}
Title: Re: ARDUINO TAP TEMPO experiments.
Post by: slacker on March 10, 2019, 02:32:29 PM
There's nothing in that code that times out if you don't make a second tap a certain amount of time after the first one, so It looks like the maximum time between taps is set by the fact that "period" is held as an int (integer). The biggest number this can hold is 32767, the tap time is in milli seconds so this gives a maximum time of about 32 seconds.
If you want even longer times you could try changing
int period = 2000;

to

long period = 2000;

"period" could then be up to about 2 billion milli seconds or roughly 24 days :) This will probably break the JLed code though.
Title: Re: ARDUINO TAP TEMPO experiments.
Post by: deadastronaut on March 10, 2019, 03:21:36 PM
24 days should be long enough ha ha..... ;D

cheers ian, good to see ya back. thanks man .  8) 8) 8)