ARDUINO TAP TEMPO experiments.

Started by deadastronaut, December 11, 2018, 08:06:50 AM

Previous topic - Next topic

potul

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

deadastronaut

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.....
https://www.youtube.com/user/100roberthenry
https://deadastronaut.wixsite.com/effects

chasm reverb/tremshifter/faze filter/abductor II delay/timestream reverb/dreamtime delay/skinwalker hi gain dist/black triangle OD/ nano drums/space patrol fuzz//

deadastronaut

#22
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)
https://www.youtube.com/user/100roberthenry
https://deadastronaut.wixsite.com/effects

chasm reverb/tremshifter/faze filter/abductor II delay/timestream reverb/dreamtime delay/skinwalker hi gain dist/black triangle OD/ nano drums/space patrol fuzz//

potul

Nice,

what do you mean by getting a flash between 3 taps?

deadastronaut

the leds come on between tapping.....

rather than tap/blink....tap/blink........tap/blink.......and its set to tempo...
https://www.youtube.com/user/100roberthenry
https://deadastronaut.wixsite.com/effects

chasm reverb/tremshifter/faze filter/abductor II delay/timestream reverb/dreamtime delay/skinwalker hi gain dist/black triangle OD/ nano drums/space patrol fuzz//

potul

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.


deadastronaut

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)
https://www.youtube.com/user/100roberthenry
https://deadastronaut.wixsite.com/effects

chasm reverb/tremshifter/faze filter/abductor II delay/timestream reverb/dreamtime delay/skinwalker hi gain dist/black triangle OD/ nano drums/space patrol fuzz//

deadastronaut

#27
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 :)
https://www.youtube.com/user/100roberthenry
https://deadastronaut.wixsite.com/effects

chasm reverb/tremshifter/faze filter/abductor II delay/timestream reverb/dreamtime delay/skinwalker hi gain dist/black triangle OD/ nano drums/space patrol fuzz//

potul

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.

potul

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?

deadastronaut

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?.
https://www.youtube.com/user/100roberthenry
https://deadastronaut.wixsite.com/effects

chasm reverb/tremshifter/faze filter/abductor II delay/timestream reverb/dreamtime delay/skinwalker hi gain dist/black triangle OD/ nano drums/space patrol fuzz//

potul

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.

potul

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)

potul

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); 
}

deadastronaut

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?.
https://www.youtube.com/user/100roberthenry
https://deadastronaut.wixsite.com/effects

chasm reverb/tremshifter/faze filter/abductor II delay/timestream reverb/dreamtime delay/skinwalker hi gain dist/black triangle OD/ nano drums/space patrol fuzz//

potul

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

deadastronaut

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); 
}
https://www.youtube.com/user/100roberthenry
https://deadastronaut.wixsite.com/effects

chasm reverb/tremshifter/faze filter/abductor II delay/timestream reverb/dreamtime delay/skinwalker hi gain dist/black triangle OD/ nano drums/space patrol fuzz//

potul

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.

deadastronaut

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://www.youtube.com/user/100roberthenry
https://deadastronaut.wixsite.com/effects

chasm reverb/tremshifter/faze filter/abductor II delay/timestream reverb/dreamtime delay/skinwalker hi gain dist/black triangle OD/ nano drums/space patrol fuzz//

potul

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.