Panneau de modération ]

[Commande] Tap Tempo pour synchroniser 6 pédales (en cours)

Une idée ? Creuser un schéma qui vous intéresse ? Besoin d'affiner votre projet avant de le concrétiser ? Parlons en ensemble !

[Commande] Tap Tempo pour synchroniser 6 pédales (en cours)

Messagepar Spike7 le 15 Avr 2018 16:20

Salut

Depuis que j’ai acheté le kit Tap Tempo Tremolo y'a quelques mois, je me suis lancé dans la fabrication d’une pédale Tap Tempo pour synchroniser mes 6 pédales de modulation :
Rocktek Chr01 , Ibanez PH5 , Behringer DD400 , TT Tremolo , UglyFace , Zoom G1

Pour commencer, le schéma :
Image

Ensuite, découpe du code en 3 codes :

1 > Tap In Switch + Led + Optocoupleur
------> Ce Code, y fonctionne (mais y'a peut être mieux ?)

CODE perso :
Code: Tout sélectionner
/*    Tap Tempo with Press And Hold - Schéma + Code OK

    Reste à voir :
    > Test Optos + Led
    > Test Led + Transo + Optos ???   (vérif conso sortie)
    > Ajouter afficheur LCD Tap Bpm + Encodeur/Sw (menu)
 ---------------------------------------   
    Press a Tap button connected to digital D11.
    LED on digital D12 displays the beat pulse. */
     
//                  +-----/\/ 10k ohm /\/------> +5 PWR
//                  |
//    In  D11 <-----+----[ switch ]--+--> GND
//                  +-----[c 10n ]---+   
//
//    Out D12 <-----[LED]----/\/ 220 ohm /\/---> +5 PWR
// 
//   Uno                   ATmega328p                   
//                           |    |   
//                           |    |   
//        In Tap D11        ?|    |?        D12 Out Tap
//                           |    |
//                           
//    The behavior of this program is as follows:
//      - the user will tap out a tempo on the switch (3 taps required)
//      - the leds will blink to this tempo.
//      - if presses and holds the Tap button for 1 seconds : STOP.


void setup()
{
  pinMode( 11, INPUT );   /* tap button - press it to set the tempo */
  pinMode( 12, OUTPUT );  /* button state display - not required */
 
  /*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 *LOW* Test HIGH Ok à voir!!! */
unsigned long currentTimer[2] = { 0 };  /* array of most recent tap counts *{ 500,500 }*/
unsigned long timeoutTime = 0;  /* this is when the timer will trigger next */
unsigned long downTime = 0;     /* for our delayed press reset */

unsigned long indicatorTimeout; /* for our fancy "blink" tempo indicator */
boolean pressTimeout = false;

void loop()
{
  /* transition detection:
     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( 11 );
  if( tapState == LOW && tapState != lastTapState ) /* button up->down */
  {
    tap(); /* we got a HIGH-LOW transition, call our tap() function */
    downTime = millis();
    pressTimeout = false;
  }

  /* press-and-hold detection */ 
  if( tapState == LOW ) /* button is down... */
  {
    /* if we have not triggered before, and the down time is more than 2 seconds... */
    /* 2000 = 2000ms = 2 seconds */
    if( !pressTimeout && ((millis() - downTime ) > 1000 ))
    {
      /* lets hard code a 1/10 delay...
         you can use this to trigger other things as well */
      currentTimer[0] = currentTimer[1] = 0; /* make sure they get averaged to be equal *=100* */
      rescheduleTimer(); /* start the timer */
      pressTimeout = true; /* make sure we don't get called again during this press */
    }
  }
 
  lastTapState = tapState; /* keep track of the last state, for transition detection */
 
  /* check for timer timeout */
  if( millis() >= timeoutTime )
  {
    /* timeout happens */
    indicatorTimeout = millis() + 60;  /* this sets the time when the LED goes off */
    /* and reschedule the timer to keep the pace */
    rescheduleTimer();
  }
 
  /* display the button state on LED 1 */
  digitalWrite( 12, tapState );
 
  /* display the tap blink on all other LEDs */
  /*for( int i=2 ; i<12 ; i++ )*/ {
    if( millis() < indicatorTimeout ) {
      digitalWrite( 12, HIGH );
    } else {
      digitalWrite( 12, 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; /* current = duration since last tap */
  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);   /* 2 */
}

Lien du CODE d'origine :
http://umlautllama.com/projects/arduino/s/TapTempo_WithPressAndHold.pde
Lien Vidéo :
https://www.youtube.com/watch?v=ur_PEUH7sns

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2 > Tap In Switch + Led + LCD (affichage BPM)
------> Ce Code par contre, j’ai beau bidouiller, ça affiche plein de trucs bizarres mais pas les BPM !

CODE perso :
Code: Tout sélectionner
/*    Tap Tempo w/ Press And Hold - Uno / ATmega328p - !!! SCHEMA + CODE OK !!!

    Reste à voir :
    > Test Optos + Led
    > Test Led + Transo + Optos ???   (vérif conso sortie)
    > 20*4 LCD : > Tap Bpm   -> EN COURS <- (Ex: @ Cardiac Monitoring + Metronome lcd hp)
                 > Encodeur menu (on/off Outs)
 -----------------------------------------------------------
    Press a Tap button connected to digital D7.
    LED on digital D13 displays the beat pulse. */
     
//                      +-----/\/ 10k ohm /\/----------> +5 PWR
//                      |
//    In  D7  <---------+----[ switch ]--+-------------> GND
//                      +-----[c 10n ]---+   
//
//    Out D13 <--------[LED]----/\/ 220 ohm /\/----+---> +5 PWR
//                                                 |
//    Out D ? <-------[OPTO]----/\/ 330 ohm /\/----+
// 
//   Uno                   ATmega328p                   
//                           |    |   
//                           |    |   
//        In Tap D7         ?|    |?        D13 Out Tap
//                           |    |
//                           
//    The behavior of this program is as follows:
//      - the user will tap out a tempo on the switch (3 taps required)
//      - the leds will blink to this tempo.
//      - if presses and holds the Tap button for 1 seconds : STOP.
// --------------------------------------------------------------------------------------------
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);  // Pins

//  VARIABLES

int beats = 0;
int BPM = 0;
long BeatTime = 0;
unsigned long tdelay;   // @ Metro lcd hp
//__________________________________

void setup()    //-----------------------------------------------------------------------//
{
//Serial.begin(9600);   // Moniteur série pour test
//Serial.print("Bpm");
lcd.begin(16, 2);
lcd.print("Bpm ");
//lcd.write(1);         // Besoin de cette ligne ???  Définir à quoi correspond "(1)"
lcd.setCursor(0,1);
lcd.print(" 0 ");     // Valeur de départ
//tdelay = 60000/BPM;   // @ Metro lcd hp
//_________________________________

  pinMode( 7, INPUT );   /* tap button - press it to set the tempo */
  pinMode( 13, OUTPUT );  /* button state display - not required */
 
}

int lastTapState = LOW;  /* the last tap button state *LOW* Test HIGH Ok à VOIR!!! */
unsigned long currentTimer[2] = { 0 };  /* array of most recent tap counts *{ 500,500 }*/
unsigned long timeoutTime = 0;  /* this is when the timer will trigger next */
unsigned long downTime = 0;     /* for our delayed press reset */

unsigned long indicatorTimeout; /* for our fancy "blink" tempo indicator */
boolean pressTimeout = false;

void loop()    //------------------------------------------------------------------------//
{
  /* transition detection:
     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( 7 );
  if( tapState == LOW && tapState != lastTapState ) /* button up->down */
  {
    tap(); /* we got a HIGH-LOW transition, call our tap() function */
    downTime = millis();
    pressTimeout = false;
  }

  /* press-and-hold detection */ 
  if( tapState == LOW ) /* button is down... */
  {
    /* if we have not triggered before, and the down time is more than 2 seconds... */
    /* 2000 = 2000ms = 2 seconds */
    if( !pressTimeout && ((millis() - downTime ) > 1000 ))
    {
      /* lets hard code a 1/10 delay...
         you can use this to trigger other things as well */
      currentTimer[0] = currentTimer[1] = 0; /* make sure they get averaged to be equal *=100* */
      rescheduleTimer(); /* start the timer */
      pressTimeout = true; /* make sure we don't get called again during this press */
    }
  }
 
  lastTapState = tapState; /* keep track of the last state, for transition detection */
 
  /* check for timer timeout */
  if( millis() >= timeoutTime )
  {
    /* timeout happens */
    indicatorTimeout = millis() + 100;    // *+ 60* -> +100 ??  time when the LED goes off
    /* and reschedule the timer to keep the pace */
    rescheduleTimer();
  }
 
  /* display the button state on LED */
  digitalWrite( 13, tapState );

  /* display the tap blink on all other LEDs */
  /*for( int i=2 ; i<12 ; i++ )*/ {
    if( millis() < indicatorTimeout ) {
      digitalWrite( 13, HIGH );
    } else {
      digitalWrite( 13, LOW );
    }
   
//------------------------------------
 // @ https://redd.it/7nrcmb           
 //beats++;      // detected beat
 BPM = BeatTime-millis();   // BPM = 60000 / (BeatTime-millis());
 BeatTime = millis();   // BeatTime = millis();

 //tdelay = 60000/BPM;   // @ Metro lcd hp
 
// Récup état digitalWrite( 13 ) et calculer : Nb de x Led en High / Tps
BPM = timeoutTime / 60000;   // 60000/indicatorTimeout -> Nbres décroissants
lcd.clear();
//lcd.print("BPM: " + String(BPM));   // @ Metro lcd hp // Défilement mode "drapeau"
lcd.print("Bpm ");
lcd.setCursor(0,1);
lcd.print (BPM);                // Affichage : 0
//lcd.write (BPM);                // Affichage : caractère
lcd.print (timeoutTime);        // Affichage : défilement tps (ms)
//lcd.write (timeoutTime);        // Affichage : défilement caractères à la vitesse Led
//lcd.print (indicatorTimeout);   // Affichage : défilement tps (ms)
//lcd.write(indicatorTimeout);      // Affichage : défilement caractères à la vitesse Led
//lcd.print (tapState);           // Affichage : 0 - 1 (état Sw)
//________________________________________
  }
}

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; /* current = duration since last tap */
  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);   /* /2 */
}


Liens inspiration :
https://create.arduino.cc/projecthub/us ... m&offset=0

http://fritzing.org/projects/arduino-metronome
CODE inspiration :
Code: Tout sélectionner
// http://fritzing.org/projects/arduino-metronome
//   Sw - Lcd + HP + Led
#include <LiquidCrystal.h>
#include "pitches.h"


//PINS
const int SPEAKER_PIN = 8;
const int LED_PIN = 13;
const int BUTTON_PIN = 7;
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

const long debounceDelay = 50;
const boolean ACCENT = true;

int BPM = 100;

unsigned long last;
unsigned long tdelay;
int signiture = 4;

long lastDebounceTime = 0;
int buttonState;
int lastButtonState = LOW;

const int taps_len = 24;
unsigned long taps[taps_len];
int next_tap = 0;
int total_taps = 0;

int noteDuration;
int beat;

void setup() {    //-------------------------------------------------------------//
  Serial.begin(9600);
 
  pinMode(LED_PIN, OUTPUT);
  pinMode(SPEAKER_PIN, OUTPUT);
  pinMode(BUTTON_PIN, INPUT);
 
  lcd.begin(16, 2);
 
  beat = 0;
  //calculate seconds per beat
  tdelay = 60000/BPM;
  last = millis();
 
  // to calculate the note duration, take one second
  // divided by the note type.
  //e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
  noteDuration = 1000 / 16;
}

void loop() {    //-------------------------------------------------------------//
  int elapsed = millis() - last;
 
  int reading = digitalRead(BUTTON_PIN);
 
  if (reading != lastButtonState) {
    // reset the debouncing timer
    lastDebounceTime = millis();
  }

  if ((millis() - lastDebounceTime) > debounceDelay) {
    // whatever the reading is at, it's been there for longer
    // than the debounce delay, so take it as the actual current state:

    // if the button state has changed:
    if (reading != buttonState) {
      buttonState = reading;

      // only toggle the LED if the new button state is HIGH
      if (buttonState == HIGH) {
        lcd.setCursor(15, 0);
        lcd.write(-1);
        taps[next_tap] = millis();
        Serial.println(String(next_tap) + ": " + String(taps[next_tap]));
        //lcd.setCursor(0, 1);
        //lcd.print(taps[next_tap]);
       
        BPM = bpms();
        Serial.println("BPM: " + String(BPM));
       
        next_tap = ++next_tap % taps_len;
        total_taps++;
      } else {
        lcd.setCursor(15, 0);
        lcd.print(" ");
      }
    }
  }
  lastButtonState = reading;
 
  if(total_taps < signiture || BPM == 0) {
    return;
  }
 
  if(elapsed > noteDuration) {
    digitalWrite(LED_PIN, LOW);
  }
 
  tdelay = 60000/BPM;
 
  if(elapsed < tdelay) {
    return;
  }
 
 
  lcd.clear();
  lcd.print("BPM: " + String(BPM));
 
  int play_note = NOTE_C4;
 
 
  beat = beat % signiture;
  lcd.setCursor(0, 1);
  lcd.print(String(beat+1));
 
  if(ACCENT && beat == 0) {
    play_note = NOTE_C6;
  }

  tone(SPEAKER_PIN, play_note, noteDuration);
  digitalWrite(LED_PIN, HIGH);

 
  last = millis();
  beat++;
}

int bpms() {
  if(total_taps < signiture) {
    return 0;
  }
 
  unsigned long total = 0;
  for(int i=1; i<=signiture; i++) {
    int tap = next_tap - i;
   
    if(tap < 0) {
      tap = taps_len + tap;
    }
   
    if(i>1) {
      Serial.print(String(tap+1%taps_len) + ": " + String(taps[tap+1%taps_len]) + " - ");
      Serial.print(String(tap) + ": " + String(taps[tap]));
     
      total += (taps[tap+1%taps_len] - taps[tap]);
    }
    Serial.println(total);
  }
 
  return 60000/(total / (signiture - 1));
}


-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
3 > Encodeur + LCD + Leds (sélection pédale + validation du Tap)
------> Ce Code avance mais c’est pas encore ça !

Image

CODE perso :
Code: Tout sélectionner
//Programa : Menu com encoder e LCD 20x4      + I²C
//Autor : Arduino e Cia
// https://www.arduinoecia.com.br/2015/08/como-usar-encoder-rotativo-ky-040-arduino.html  ( Code origine )
    // https://simple-circuit.com/arduino-ds3231-real-time-clock-alarm-temperature/       ( Code modif )
 
//Carrega biblioteca LCD e encoder
#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
#include <RotaryEncoder.h>

#define I2C_ADDR    0x3F  // (0x3F :20*4 || 0x27 :16*2 ) Define I2C Address where the PCF8574A is
#define BACKLIGHT_PIN     3
#define En_pin  2
#define Rw_pin  1
#define Rs_pin  0
#define D4_pin  4
#define D5_pin  5
#define D6_pin  6
#define D7_pin  7

LiquidCrystal_I2C  lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);
//Pinos de ligacao do encoder
RotaryEncoder encoder(A2, A3);

//int contador = 1;
//int contador_anterior = 1;
int valor = 0;


byte Bloco_Cheio[8]  = {0b11111, 0b11111, 0b11111, 0b11111,
                        0b11111, 0b11111, 0b11111, 0b11111
                       };
byte Um_invertido[8] = {0b11011, 0b10011, 0b11011, 0b11011,
                        0b11011, 0b11011, 0b10001, 0b11111
                       };
byte Dois_invertido[8] = {0b10001, 0b01110, 0b11110, 0b11101,
                          0b11011, 0b10111, 0b00000, 0b11111
                         };
byte Tres_invertido[8] =  {0b00000, 0b11101, 0b11011, 0b11101,
                           0b11110, 0b01110, 0b10001, 0b11111
                          };
byte Quatro_invertido[8] = {0b11101, 0b11001, 0b10101, 0b01101,
                            0b00000, 0b11101, 0b11101, 0b11111
                           };
byte Cinco_invertido[8] = {0b00000, 0b01111, 0b00001, 0b11110,
                           0b11110, 0b01110, 0b10001, 0b11111
                          };
byte Seis_invertido[8] = {0b11001, 0b10111, 0b01111, 0b00001,
                          0b01110, 0b01110, 0b10001, 0b11111
                         };

static int pos = 1;
int newPos = 0;
int selecionado = 0;


void setup()      /////////////////////////////   SETUP   /////////////////////////////////////
{
//----- Modif LED ------------------------------
  pinMode(13, OUTPUT);
  //byte etat;        // etat sortie
//-----------------------------------------------
  Serial.begin(9600);
  //Inicializa o botao do encoder no pino 8
  pinMode(8, INPUT);
  //Define o LCD com 20 colunas e 4 linhas
  lcd.begin(20, 4);

  // Switch on the backlight
  lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);    // I²C
  lcd.setBacklight(HIGH);                         // I²C
  lcd.home ();                   // go home       // I²C
 
  //Cria os caracteres customizados
  lcd.createChar(0, Bloco_Cheio);
  lcd.createChar(1, Um_invertido);
  lcd.createChar(2, Dois_invertido);
  lcd.createChar(3, Tres_invertido);
  lcd.createChar(4, Quatro_invertido);
  lcd.createChar(5, Cinco_invertido);
  lcd.createChar(6, Seis_invertido);

  //Informacoes iniciais
  lcd.setCursor(0, 0);
  lcd.print("  1  2  3  4  5  6");
  lcd.setCursor(1, 2);
  lcd.print("Valor atual: 0");
  lcd.setCursor(1, 3);
  lcd.print("Selecionado: -");
//----- Modif -------------------------------
  lcd.setCursor(0, 1);
  lcd.print("  .  .  .  .  .  .");
//------------------------------------
}

void loop()      /////////////////////////////   LOOP   ///////////////////////////////////////
{
  //Verifica se o botao do encoder foi pressionado
  valor = digitalRead(8);
  Serial.println(valor);
  if (valor != 1)
  {
    Serial.println("Botao pressionado");
    lcd.setCursor(14, 3);
    selecionado = newPos;
    lcd.print(selecionado);
    //while (digitalRead(8) == 1)
    //  delay(10);
  }

  //Le as informacoes do encoder
  encoder.tick();
  newPos = encoder.getPosition();
  if (pos != newPos)
  {
    //Limite maximo menu
    if (newPos > 6)
    {
      encoder.setPosition(6);
      newPos = 6;
    }
    //Limite minimo menu
    if (newPos < 1)
    {
      encoder.setPosition(1);
      newPos = 1;
    }
    Serial.print("Posicao: ");
    Serial.println(newPos);

   
    //Atualiza o menu no display
    destaque_selecionado(newPos);
    pos = newPos;
  }
//----- Modif (Bug) -----------------------------------------

}

void destaque_selecionado(int conta)      ////////////////////   D _ S   //////////////////////
{
  //Define posicao inicial
  int posicao = (conta * 3) - 1;
  //Apaga selecao anterior
  if (conta > pos)
  {
    lcd.setCursor(posicao - 4, 0);
    lcd.print(" ");
    lcd.print(conta - 1);
    lcd.print(" ");
  }
  //Apaga selecao posterior
  if (conta < pos)
  {
    lcd.setCursor(posicao + 2, 0);
    lcd.print(" ");
    lcd.print(conta + 1);
    lcd.print(" ");
  }

  //Imprime blocos cheios
  lcd.setCursor(posicao - 1, 0);
  lcd.write((uint8_t)0);
  lcd.write((uint8_t)0);
  lcd.write((uint8_t)0);

  //imprime valor
  lcd.setCursor(posicao, 0);
  lcd.write((uint8_t)(conta));

  //Imprime Opcao atual
  lcd.setCursor(14, 2);
  lcd.print(conta);
 
//----- Modif LED -----------------------------------------
/*//if (posicao == 5)       // Posit° x=5 == n°2

//while (encoder.getPosition());
//if (newPos == 1)  {
//----------------------------------------------
if (valor != 1)  {                // Posit° 1 + Appuyer + Tourner = Led ON
lcd.setCursor(selecionado, 1);
//    selecionado = newPos;     
//    lcd.print(selecionado);
lcd.print(" On ");
digitalWrite(13, HIGH);  }
else             
{lcd.print(" Off");
digitalWrite(13, LOW);   }      */
     

}                                    //----- FIN -----//


Lien du CODE d'origine :
https://www.arduinoecia.com.br/2015/08/ ... duino.html

Liens inspiration :
https://simple-circuit.com/arduino-ds32 ... mperature/
https://openclassrooms.com/courses/perf ... -ecran-lcd
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Je fais donc appel à vos talents de programmation, histoire d’avoir au moins quelques pistes à potasser :euh:
(Actuellement, je potasse le 3e code)

J’ai fouiné sur le forum, sur Arduino.cc et d’autres sites pour trouver des codes ressemblant à ce que je voudrai.

J’ai un niveau quasi débutant dans la programmation sur Arduino. J'ai étudié le blog d’Eskimon.
J’ai quand même fait quelques bidouilles de programmes !

Si y’a besoin de plus d’infos, hésitez pas !

Merci :wink:
Spike
Avatar de l’utilisateur
Spike7
Etamé jusqu'à  l'os
 
Messages: 128
Enregistré le: 02 Mar 2014 12:39
Localisation: 85 - Pas loin des Sables d'Olonne

Retourner vers CONCEPTION

 


  • Articles en relation
    Réponses
    Vus
    Dernier message

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 0 invités