Bonjour,
J'ai pour projet de monter un relais temporisé au BPM battement par minute.
Sur mon pédalier, plusieurs pédales utilisent le TAP TEMPO comme le delay et tremolo seulement il faut être sur de frapper le bon tempo avant que le morceau commence et cela sur deux pédales.
Je souhaite remplacer ce footswitch par des relais donneront trois impulsions et cela au tempo que l'on aura choisi grace à un écran.
Bon la partie ecran, encodeur c'est ok pour moi, mais c'est surtout la partie mathématique sur laquelle je colle.
Exemple
Grâce à l'encodeur je monte à 120bpm, j'appuie sur un bouton pour valider et donc l'idée serait de faire une impulsion de 100ms une pause de 400ms; une impulsion de 100ms une pause de 400ms et encore une impulsion de 100ms pour un écart entre chaque "coup de caisse claire" de 500ms et donc 120bpm.
Auriez vous des tutos pour appréhender ce type de programme car jusque là je faisais surtout des machines à état.
si c'est le cas, comme une minute c'est 60,000 ms, la durée totale de la pause est donc de ∆t = durée totale - durée de l'impulsion = (60000 / bpm) - 100
comme la pause ne peut pas être négative ça veut dire que
(60000 / bpm) >= 100 soit bpm <= 60000 / 100 = 600
ensuite c'est juste une mini machine à état qui alterne 100ms avec le relai ON et ∆t avec le relai OFF
sans le bouton de validation (modification en temps réel du BPM) ça pourrait donner cela
#include <Encoder.h> // https://www.pjrc.com/teensy/td_libs_Encoder.html
#include <Wire.h>
#include <hd44780.h> // main hd44780 header
#include <hd44780ioClass/hd44780_I2Cexp.h> // i2c expander i/o class header
hd44780_I2Cexp lcd(0x27); // declare lcd object at address 0x27 (use i2c address zero to auto locate address)
const byte relaiPin = 9; // le relai
const byte buzPin = 10; // un buzzer pour le fun
const byte encoderCLKPin = 2; // encoder encoder CLK
const byte encoderDTPin = 3; // encoder encoder DT
const byte tickShift = 2; // nombre de décalages à faire sur la valeur (puissance de 2) ici 2**2 => 4 ticks pour 1 valeur
const long minBPM = 0;
const unsigned long dureeImpulsion = 100; // ms
const long maxBPM = 60000ul / dureeImpulsion; // pour que la pause soit toujours positive
long currentBPM = 60;
unsigned long chrono;
Encoder encoder(encoderDTPin, encoderCLKPin);
bool encoderChanged() {
long newPosition = encoder.read() >> tickShift;
if (newPosition != currentBPM) {
if (newPosition < minBPM) {
currentBPM = minBPM;
encoder.write(currentBPM << tickShift);
}
else if (newPosition > maxBPM) {
currentBPM = maxBPM;
encoder.write(currentBPM << tickShift);
}
else currentBPM = newPosition;
return true;
}
return false;
}
void tickEncoder() {
lcd.setCursor(4, 0);
lcd.print(" ");
lcd.setCursor(4, 0);
lcd.print(currentBPM);
}
void configuration() {
pinMode(relaiPin, OUTPUT);
pinMode(buzPin, OUTPUT);
Serial.begin(115200);
encoder.write(currentBPM << tickShift);
int status = lcd.begin(16, 2);
if (status != 0) hd44780::fatalError(status); // does not return
lcd.print("BPM:");
lcd.print(currentBPM);
chrono = millis();
Serial.println("Pret!");
}
void interface() {
if (encoderChanged()) tickEncoder();
}
void animation() {
static bool enImpulsion = false;
if (currentBPM != 0) {
if (enImpulsion) {
if (millis() - chrono >= dureeImpulsion) {
digitalWrite(relaiPin, LOW);
enImpulsion = false;
chrono = millis();
}
} else {
unsigned long dureePause = (60000ul / currentBPM) - dureeImpulsion;
if (millis() - chrono >= dureePause) {
digitalWrite(relaiPin, HIGH);
tone(buzPin, 2000, dureeImpulsion);
enImpulsion = true;
chrono = millis();
}
}
}
}
void setup() {
configuration();
}
void loop() {
interface();
animation();
}