j'aimerais réaliser une sorte de boîte à musique connectée à mon ordinateur, c'est-à-dire une boîte avec manivelle qui lorsqu'on la tourne cela déclenche la musique et si l'on s'arrête, la musique s'arrête aussi.
J'ai réussi à trouver un tutoriel qui permet de réaliser un bouton de commande avec un encodeur rotatif permettant de contrôler la fonction pause/play avec mon arduino Leonardo.
Là je sais que si le arduino détecte un mouvement, ça me fait juste du pause/play sans arrêt (c'est évident vu que c'est une boucle) et c'est pas vraiment mon but haha.
J'aimerais bien que lorsque l'arduino détecte un mouvement (valeur qui change sur me moniteur), il appuie une seule fois sur play, tant que les valeurs changent, rien ne se passe mais par contre, lorsque l'on arrête de tourner l'encodeur rotatif, on met sur pause (lorsque les valeurs qui s'affichent sur mon moniteur ne changent plus au bout de deux.)
Si vous aviez une petite piste pour m'aider ce serait génial Merci !!
il faut détecter le premier mouvement, noter l'heure (avec millis()) et envoyer la commande PLAY.
ensuite il faut surveiller
les mouvements, à chaque mouvement vous mettez à jour l'heure du dernier mouvement.
si la différence de temps entre le dernier mouvement et l'heure courante est trop grande (par exemple vous n'avez pas tourné la manivelle depuis 1seconde) alors envoyer STOP
une petite "machine à état" en terme de structuration du code permet de faire cela simplement (cf mon tuto éventuellement)
un exemple de code avec une autre librairie pour encodeur rotatif plus simple d'emploi
#include <Encoder.h> // https://www.pjrc.com/teensy/td_libs_Encoder.html
Encoder encodeurRotatif(2, 3); // attaché sur pins 2 (Encodeur DT) et 3 (Encodeur CLK)
#include <simpleBouton.h> // http://forum.arduino.cc/index.php?topic=375232.0 la librairie de @bricoleau
simpleBouton boutonEncodeur(4);//Cablage : pin 4 --- Encodeur SW
long positionEnCours;
unsigned long dernierTick = 0;
const unsigned long delaiMax = 500;
enum : byte {REPOS, TOURNE} etat = REPOS;
void etatInitial()
{
encodeurRotatif.write(0); // valeur initiale du compteur
positionEnCours = 0L;
etat = REPOS;
}
void setup()
{
Serial.begin(115200);
etatInitial();
}
void loop()
{
// la librairie envoie 2 ticks par cran sur mon encodeur
// je divise donc par 2 (décale à droite d'un bit) pour avoir le bon compte.
// certains encodeurs envoient 4 ticks donc faudrait faire >> 2 dans ce cas,
// d'autres qu'un seul tick, auquel cas il faut virer carrément le >> 1
long nouvellePosition = encodeurRotatif.read() >> 1;
switch (etat) {
case REPOS:
if (nouvellePosition > positionEnCours) { // on a commencé à tourner côté croissant
Serial.println(nouvellePosition);
Serial.println(F("PLAY"));
etat = TOURNE;
dernierTick = millis();
positionEnCours = nouvellePosition;
}
break;
case TOURNE:
if (nouvellePosition > positionEnCours) { // on continue à tourner
Serial.println(nouvellePosition);
dernierTick = millis();
positionEnCours = nouvellePosition;
}
if (millis() - dernierTick >= delaiMax) { // ça fait trop longtemps qu'on n'a pas tourné
Serial.println(F("STOP"));
etatInitial();
}
break;
}
if (boutonEncodeur) Serial.println(F("appui bouton"));
}
j'ai aussi mis du code pour détecter si on appuie sur le bouton de l'encodeur rotatif - au cas où vous voudriez faire que chose de plus; si pas besoin vous pouvez bien sûr enlever
#include <simpleBouton.h> // http://forum.arduino.cc/index.php?topic=375232.0 la librairie de @bricoleau
simpleBouton boutonEncodeur(4);//Cablage : pin 4 --- Encodeur SW
ainsi que le test en fin de loop()
if (boutonEncodeur) Serial.println(F("appui bouton"));
Merci pour votre aide!! Je ne connaissais pas la fonction millis, ça va beaucoup me servir pour mes futurs projets
J'ai incorporé la bibliothèque que j'avais trouvé pour les fonctions pause/play et ça a marché un certain temps...
J'ai beau retéléverser le code ça ne fonctionne pas, par contre si je téléverse un autre code utilisant l'encodeur ça fonctionne... J'ai l'impression que lorsque je téléverse mon code, ma carte se déconnecte automatiquement...
#include <Encoder.h> // https://www.pjrc.com/teensy/td_libs_Encoder.html
Encoder encodeurRotatif(2, 3); // attaché sur pins 2 (Encodeur DT) et 3 (Encodeur CLK)
#include <HID-Project.h>
long positionEnCours;
unsigned long dernierTick = 0;
const unsigned long delaiMax = 500;
enum : byte {REPOS, TOURNE} etat = REPOS;
void etatInitial()
{
encodeurRotatif.write(0); // valeur initiale du compteur
positionEnCours = 0L;
etat = REPOS;
}
void setup()
{
Serial.begin(115200);
etatInitial();
}
void loop()
{
// la librairie envoie 2 ticks par cran sur mon encodeur
// je divise donc par 2 (décale à droite d'un bit) pour avoir le bon compte.
// certains encodeurs envoient 4 ticks donc faudrait faire >> 2 dans ce cas,
// d'autres qu'un seul tick, auquel cas il faut virer carrément le >> 1
long nouvellePosition = encodeurRotatif.read() >> 1;
switch (etat) {
case REPOS:
if (nouvellePosition > positionEnCours) { // on a commencé à tourner côté croissant
Serial.println(nouvellePosition);
Consumer.write(MEDIA_PLAY_PAUSE);
etat = TOURNE;
dernierTick = millis();
positionEnCours = nouvellePosition;
}
break;
case TOURNE:
if (nouvellePosition > positionEnCours) { // on continue à tourner
Serial.println(nouvellePosition);
dernierTick = millis();
positionEnCours = nouvellePosition;
}
if (millis() - dernierTick >= delaiMax) { // ça fait trop longtemps qu'on n'a pas tourné
Consumer.write(MEDIA_PLAY_PAUSE);
etatInitial();
}
break;
}
// if (boutonEncodeur) Serial.println(F("appui bouton"));
}
Voilà le code,
effectivement il est utilisé en émulation de clavier
J'ai essayé mais le problème doit vraiment venir de ma carte puisqu'elle se déconnecte même si je téléverse un sketch vierge...
Je vois sur mon gestionnaire des pilotes dès que je téléverse le pilote disparaît et ré-apparaît dans la foulée, ce qui empêche le téléversement et si j'appuie sur le bouton reset il se produit la même chose
"elle se déconnecte " --> que voulez vous dire par là?
si vous n'ouvrez pas de connexion Serial, la liaison USB n'est pas établie. C'est donc normal
je ne connais pas votre librairie "HID-Project.h".. assurez vous qu'elle soit de bonne qualité et que vous l'utilisez correctement
Vous avez essayé bêtement avec la librairie Keyboard standard? (ça n'envoie pas toutes les combinaisons de touches donc faudra peut être hacker un peu)
Je veux dire par là que la connexion usb entre mon ordi et la carte est interrompu pile au moment du téléversement
Cette librairie est issue d'un tutoriel prusa 3D
J'ai essayé avec la librairie standard mais effectivement comme la fonction pause/play n'est pas présente et que mes connaissances sont assez limitées, je me suis du coup tournée vers des librairies toutes faites...
Alors effectivement j'ai reset la carte et je peux recommencer à téléverser
Par contre le code ne fonctionne toujours pas, j'ai essayé avec la librairie standard, je remet le code peut être que c'est moi qui m'y prend mal...
#include <Encoder.h> // https://www.pjrc.com/teensy/td_libs_Encoder.html
Encoder encodeurRotatif(2, 3); // attaché sur pins 2 (Encodeur DT) et 3 (Encodeur CLK)
#include <Keyboard.h>
long positionEnCours;
unsigned long dernierTick = 0;
const unsigned long delaiMax = 500;
enum : byte {REPOS, TOURNE} etat = REPOS;
void etatInitial()
{
encodeurRotatif.write(0); // valeur initiale du compteur
positionEnCours = 0L;
etat = REPOS;
}
void setup()
{
Serial.begin(115200);
while (!Serial);
etatInitial();
}
void loop()
{
// la librairie envoie 2 ticks par cran sur mon encodeur
// je divise donc par 2 (décale à droite d'un bit) pour avoir le bon compte.
// certains encodeurs envoient 4 ticks donc faudrait faire >> 2 dans ce cas,
// d'autres qu'un seul tick, auquel cas il faut virer carrément le >> 1
long nouvellePosition = encodeurRotatif.read() >> 1;
switch (etat) {
case REPOS:
if (nouvellePosition > positionEnCours) { // on a commencé à tourner côté croissant
Keyboard.press(' ');
delay(50);
Keyboard.release(' ');
etat = TOURNE;
dernierTick = millis();
positionEnCours = nouvellePosition;
}
break;
case TOURNE:
if (nouvellePosition > positionEnCours) { // on continue à tourner
// Serial.println(nouvellePosition);
dernierTick = millis();
positionEnCours = nouvellePosition;
}
if (millis() - dernierTick >= delaiMax) { // ça fait trop longtemps qu'on n'a pas tourné
Keyboard.press(' ');
delay(50);
Keyboard.release(' ');
etatInitial();
}
break;
}
// if (boutonEncodeur) Serial.println(F("appui bouton"));
}
#include <Encoder.h> // https://www.pjrc.com/teensy/td_libs_Encoder.html
Encoder encodeurRotatif(2, 3); // attaché sur pins 2 (Encodeur DT) et 3 (Encodeur CLK)
#include <Keyboard.h>
long positionEnCours;
unsigned long dernierTick = 0;
const unsigned long delaiMax = 500;
enum : byte {REPOS, TOURNE} etat = REPOS;
void etatInitial()
{
encodeurRotatif.write(0); // valeur initiale du compteur
positionEnCours = 0L;
etat = REPOS;
}
void setup()
{
Keyboard.begin();
etatInitial();
}
void loop()
{
// la librairie envoie 2 ticks par cran sur mon encodeur
// je divise donc par 2 (décale à droite d'un bit) pour avoir le bon compte.
// certains encodeurs envoient 4 ticks donc faudrait faire >> 2 dans ce cas,
// d'autres qu'un seul tick, auquel cas il faut virer carrément le >> 1
long nouvellePosition = encodeurRotatif.read() >> 1;
switch (etat) {
case REPOS:
if (nouvellePosition > positionEnCours) { // on a commencé à tourner côté croissant
Keyboard.press(' ');
delay(50);
Keyboard.releaseAll();
etat = TOURNE;
dernierTick = millis();
positionEnCours = nouvellePosition;
}
break;
case TOURNE:
if (nouvellePosition > positionEnCours) { // on continue à tourner
dernierTick = millis();
positionEnCours = nouvellePosition;
}
if (millis() - dernierTick >= delaiMax) { // ça fait trop longtemps qu'on n'a pas tourné
Keyboard.press(' ');
delay(50);
Keyboard.releaseAll();
etatInitial();
}
break;
}
}
il faut virer tout l'usage de Serial et penser à faire le Keyboard.begin();
(tapé ici donc pas testé)