Ce dont nous avons besoin
Quantité | Composant |
---|---|
1 | Nano v3 atmega328 ou alor Boîte de microcontrôleur avec ATMEGA328P |
4 | Bouton |
1 | Anneau LED 5V RGB WS2812B 12-Bit 37mm |
1 | Module d'alarme de vibreur piézo passif KY-006 |
plusieurs | 65pcs Jumper Wire Cable |
1 | Breadboard ou alors MB 102 Breadboard Kit |
Schéma du circuit
Tout d'abord, nous connectons tous les composants comme indiqué dans le schéma suivant :
Microcontrôleur | Buzzer |
D2 | (S)ignal |
GND | - |
RGB Anneau LED | |
D3 | IN |
+ 5V | VCC |
GND | GND |
Bouton 1-4 | |
D4, D5, D6, D7 | Pin 1 chacun |
GND | Pin 2 chacun |
Comme boutons-poussoirs, vous pouvez choisir n'importe quel composant pour ponter le contact entre GND et l'entrée numérique respective.
Nous utiliserons les résistances pull-up internes, ce qui est donc possible. Nous devons juste nous assurer plus tard que les entrées sont actives et basses.
J'ai utilisé un module buzzer passif. La différence avec le buzzer actif est qu'il n'y a pas de signal carré à générer. Bernd Albrecht a expliqué en détail l'utilisation de ces modules dans son blog "Nous vous apprenons les tons de la flûte".
Présentation
Mon objectif est de pouvoir appuyer sur quatre boutons différents et que chacun d'eux affiche une couleur différente sur l'anneau de LED. Je veux aussi que le module buzzer émette un son correspondant. J'ai d'abord connecté l'anneau de LED et installé la bibliothèque appropriée appelée "Adafruit Neopixel". Il apporte l'exemple du sketch "buttoncycler", que nous pouvons bien utiliser comme base. Au lieu de l'anneau RVB, vous pouvez également utiliser quatre modules RVB SMD. Ensuite, la bibliothèque est omise, mais les broches RVB doivent être connectées individuellement. Cela signifie que 4 x 3 broches seraient nécessaires. Les boutons sont chacun connectés à l'une des quatre broches numériques supplémentaires et à GND. Avec cela, nous aurions le matériel complet.
Pour le buzzer, nous pouvons installer la bibliothèque "Tone". Il est donc très facile d'obtenir des tonalités du module. Nous pouvons utiliser ici le sketch d'exemple "ToneTest".
Le code source
A partir des exemples de croquis, j'ai écrit un programme qui interroge les quatre boutons l'un après l'autre. Si l'on appuie sur l'un d'entre eux, la LED correspondante s'allume pendant 5 secondes et un son est émis brièvement.
Pour tester le fonctionnement des composants dès le début du programme, j'ai ajouté une animation de démarrage qui allume les LED dans les couleurs du joueur et fait sonner le buzzer.
/* MultiplayerGameshowBuzzer
* fuer vier Spieler mit Farben und Toenen
* fuer AZ-Delivery.de
*
* Funktion:
* Spieler können je einen Taster betaetigen
* Spielerfarbe leuchtet auf und Buzzer-Sound erklingt
*
* Verwendete Hardware:
* - ATmega328p Mikrocontroller
* - Passives Buzzer Module
* - Neopixelring mit 12 RGB LEDs
* - 4 Taster
*
* Verwendete Bibliotheken:
* - Adafruit_NeoPixel.h
* - Tone.h
*
* Beispielquelle aus der Adafruit_NeoPixel.h: buttoncycler
*
***************************************************
* @filename : buttoncycler.ino
* @brief : neopixel demo
* @author : Adafruit
*
* Copyright (C) Adafruit
****************************************************
*
* Pinout:
*
* Neopixel Ring | Mikrocontroller
* ------------------------------------
* VCC | 5V oder 3.3V
* GND | GND
* IN | D2
*
*
* Beispielquelle aus der Tone.h: ToneTest
***************************************************
* @filename : ToneTest.ino
* @brief : Tone demo
* @author :
*
* https://code.google.com/archive/p/rogue-code/wikis/ToneLibraryDocumentation.wiki
***************************************************
*
* Pinout:
*
* Active Buzzer Module | Mikrocontroller
* ------------------------------------------------
* GND | GND
* IN | D2
*
*
*/
// Digital IO pin connected to the NeoPixels.
// Number of NeoPixels
/***************************
* NEOPIXEL
*/
// Declare our NeoPixel strip object:
Adafruit_NeoPixel strip(PIXEL_COUNT, PIXEL_PIN, NEO_GRB + NEO_KHZ800);
// Argument 1 = Number of pixels in NeoPixel strip
// Argument 2 = Arduino pin number (most are valid)
// Argument 3 = Pixel type flags, add together as needed:
// NEO_KHZ800 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
// NEO_KHZ400 400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
// NEO_GRB Pixels are wired for GRB bitstream (most NeoPixel products)
// NEO_RGB Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
// NEO_RGBW Pixels are wired for RGBW bitstream (NeoPixel RGBW products)
int LED_number[MAX_BUTTONS] = {7, 10, 1, 4}; // Neopixel-Nummer der Spieler
uint32_t color[MAX_BUTTONS] = { strip.Color(255, 0, 0), // Spielerfarben
strip.Color(0, 255, 0),
strip.Color(0, 0, 255),
strip.Color(255, 0, 255)};
/***************************
* BUTTONS
*/
int BUTTON_PIN[MAX_BUTTONS] = {4, 5, 6, 7}; // Button Pin Nummern
boolean oldState[MAX_BUTTONS] = {HIGH, HIGH, HIGH, HIGH};
boolean newState[MAX_BUTTONS] = {HIGH, HIGH, HIGH, HIGH};
int button_count = 0;
/***************************
* TONES
*/
int notes[] = { NOTE_C3,
NOTE_C4,
NOTE_D4,
NOTE_E4,
NOTE_F4};
Tone buzzer;
void loop() {
newState[button_count] = digitalRead(BUTTON_PIN[button_count]);
if((newState[button_count] == LOW) && (oldState[button_count] == HIGH)) {
// Short delay to debounce button.
delay(20);
// Check if button is still low after debounce.
newState[button_count] = digitalRead(BUTTON_PIN[button_count]);
if(newState[button_count] == LOW) { // Yes, still low
strip.setPixelColor(LED_number[button_count], color[button_count]);
strip.show();
buzzer.play(notes[0], 500);
delay(5000);
strip.setPixelColor(LED_number[button_count], strip.Color( 0, 0, 0));
strip.show();
}
}
// Set the last-read button state to the old state.
oldState[button_count] = newState[button_count];
button_count++;
if (button_count > MAX_BUTTONS-1) {
button_count = 0;
}
}
void startAnimation() {
int i = 0;
int colorCount = 0;
int delayTime = 35;
// Farbkreise mit Spielerfarben
while (colorCount < MAX_BUTTONS) {
buzzer.play(notes[colorCount+1], 200);
for (i = 0; i < PIXEL_COUNT; i++) {
strip.setPixelColor(i, color[colorCount]);
strip.show();
delay(delayTime);
}
colorCount++;
}
colorCount = 0;
// Alle Pixel aus
for (i = 0; i < PIXEL_COUNT; i++) {
strip.setPixelColor(i, strip.Color( 0, 0, 0));
strip.show();
delay(delayTime);
}
// Spieler-Pixel
for (i = 0; i < MAX_BUTTONS; i++) {
strip.setPixelColor(LED_number[i], color[i]);
strip.show();
buzzer.play(notes[i+1], 200);
delay(500);
}
delay(1000);
for (i = 0; i < PIXEL_COUNT; i++) {
strip.setPixelColor(i, strip.Color( 0, 0, 0));
strip.show();
}
}
Pour faire défiler les boutons et les LEDs du programme plus rapidement et avec moins de code source, j'ai utilisé des tableaux. La ligne suivante contient le numéro de la LED dans l'anneau de LED RVB :
int LED_number[MAX_BUTTONS] = {7, 10, 1, 4};
La LED avec le numéro 0 est avec moi à 5 heures, donc juste en bas. Cela est dû au fait que j'ai soudé une bande de broches, avec laquelle je pouvais brancher l'anneau sur la carte enfichable.
Les couleurs des joueurs sont définies avec la ligne suivante :
uint32_t color[MAX_BUTTONS] = { strip.Color(255, 0, 0), // Spielerfarben
strip.Color(0, 255, 0),
strip.Color(0, 0, 255),
strip.Color(255, 0, 255)};
La fonction Color() de la bibliothèque Neopixel crée une valeur de 32 bits. J'ai regroupé ici quatre valeurs.
Les broches des boutons et leurs états sont écrits dans les tableaux comme suit :
int BUTTON_PIN[MAX_BUTTONS] = {4, 5, 6, 7}; // Button Pin Nummern
boolean oldState[MAX_BUTTONS] = {HIGH, HIGH, HIGH, HIGH};
boolean newState[MAX_BUTTONS] = {HIGH, HIGH, HIGH, HIGH};
Avec le tableau, il est maintenant possible d'interroger les quatre broches l'une après l'autre avec digitalRead() en utilisant une boucle. Les tableaux oldState[] et newState[] sont nécessaires pour vérifier si un bouton a été enfoncé et relâché. Sinon, nous devions maintenir le bouton enfoncé et ainsi déclencher le buzzer plusieurs fois. Théoriquement, nous n'aurions pas à le faire, puisque j'ai inséré une pause lorsqu'on appuie sur un bouton.
Les tonalités du buzzer peuvent également être écrites dans un tableau. J'ai défini C3 comme la tonalité qui retentit lorsqu'on appuie sur un bouton. Les autres tonalités sont uniquement destinées à l'animation de démarrage.
Dans le setup(), les résistances pullup des broches d'entrée doivent être activées :
void setup() {
pinMode(BUTTON_PIN[0], INPUT_PULLUP);
pinMode(BUTTON_PIN[1], INPUT_PULLUP);
pinMode(BUTTON_PIN[2], INPUT_PULLUP);
pinMode(BUTTON_PIN[3], INPUT_PULLUP);
buzzer.begin(BUZZER_PIN);
strip.begin();
strip.show();
startAnimation();
}
Pour cela, ils sont initialisés avec INPUT_PULLUP. Le buzzer a besoin de la fonction begin(), tout comme l'anneau de LED RVB. La fonction show() éteint les LEDs ici. Il est toujours nécessaire d'afficher la couleur définie sur la LED souhaitée. Les valeurs sont d'abord chargées en mémoire, puis affichées sur les LED.
Je lance l'animation de démarrage ici après l'initialisation. Avec deux boucles, les pixels sont parcourus et affichés avec les couleurs spécifiées précédemment. Ensuite, elles sont éteintes et les diodes du lecteur sont rallumées l'une après l'autre. Le buzzer retentit alors.
Ici, nous voyons déjà l'avantage des tableaux. Avec les boucles, vous pouvez itérer sur eux très facilement.
La fonction loop() est également devenue relativement courte en conséquence. Comme le microcontrôleur fonctionne de toute façon en boucle sans fin, nous n'avons pas besoin de créer une boucle supplémentaire. Nous interrogeons les broches des boutons et comptons l'indice du tableau à chaque passage. Lorsque vous appuyez sur l'un des boutons, la requête conditionnelle se déclenche et le voyant approprié s'allume. Les broches des boutons, les numéros des LED et les couleurs des lecteurs utilisent le même index dans leurs tableaux. Cela vous permet d'accéder aux valeurs de tous les tableaux avec un seul compteur. Cela permet de raccourcir considérablement le code source.
Conclusion
Vous avez vu comment nous pouvons connecter un bouton poussoir, un buzzer et un anneau de LED RVB à un microcontrôleur ATmega328 et construire un buzzer de jeu à quatre joueurs. J'espère que vous pourrez l'utiliser pour pimenter un peu votre soirée jeu. Amusez-vous bien avec le bricolage.Andreas Wolter
pour AZ-Deliver Blog
3 commentaires
Andreas Wolter
@Buttgereit: Danke für den Hinweis. Wurde korrigiert.
@Klaus: Ja das lässt sich soweit erweiter, wie es digitale Eingänge für die Taster gibt.
Ich werde in Kürze ein Update dazu schreiben und den Quellcode verlinken.
Buttgereit
Fritzing -Verdrahtung und Verbindungstabelle stimmen nicht überein:D2 an Buzzer S-Kontakt, D3 an LED Ring In
Klaus
Hallo
super Projekt – kann man das auch auf 8 Spieler erweitern ?
Danke