🚀 Introduzione
Vuoi realizzare una manopola del volume simile a quella di una radio o di un amplificatore? 🎛️🔊
In questo progetto utilizzerai un encoder rotativo per aumentare o diminuire il volume di un buzzer, visualizzando il livello impostato su un display OLED.
Premendo la manopola potrai inoltre attivare o disattivare rapidamente l’audio tramite una funzione mute.
👉 Il progetto introduce il controllo di un’uscita sonora attraverso un’interfaccia semplice, compatta e intuitiva.
Vuoi realizzare una manopola del volume simile a quella di una radio o di un amplificatore? 🎛️🔊
In questo progetto utilizzerai un encoder rotativo per aumentare o diminuire il volume di un buzzer, visualizzando il livello impostato su un display OLED.
Premendo la manopola potrai inoltre attivare o disattivare rapidamente l’audio tramite una funzione mute.
👉 Il progetto introduce il controllo di un’uscita sonora attraverso un’interfaccia semplice, compatta e intuitiva.
🎯 Cosa realizzerai
Con Arduino creerai un sistema che:
Con Arduino creerai un sistema che:
- 🎛️ legge la rotazione di un encoder;
- ➕ aumenta il volume;
- ➖ diminuisce il volume;
- 🔇 attiva e disattiva la modalità mute;
- 🔊 riproduce un tono attraverso un buzzer;
- 📟 mostra il volume su display OLED;
- 📊 visualizza una barra grafica;
- 💾 conserva il livello precedente durante il mute;
- ⏱️ gestisce encoder e pulsante senza bloccare Arduino;
- 🚫 limita il volume tra 0% e 100%.
🧰 Materiale necessario
- 1x Arduino UNO;
- 1x encoder rotativo KY-040 o compatibile;
- 1x display OLED 0,96 pollici I2C SSD1306;
- 1x buzzer passivo;
- 1x resistenza da 100 Ω;
- cavetti jumper;
- breadboard;
- cavo USB.
🛒 Non hai ancora i componenti?
Molti dei progetti presenti su progettiarduino.com utilizzano componenti elettronici di base come LED, resistenze, sensori e breadboard.
Se stai iniziando con Arduino, il modo più semplice è utilizzare un kit completo per principianti, che include quasi tutti i componenti necessari per realizzare molti dei progetti presenti sul sito.
👉 Kit Arduino consigliato:
ℹ️ Link di affiliazione Amazon: in qualità di Affiliato Amazon ricevo un guadagno dagli acquisti idonei, senza alcun costo aggiuntivo per te.
https://amzn.to/4b3dxjW
📘 Vuoi imparare Arduino passo dopo passo?
Se vuoi approfondire e realizzare progetti più completi, puoi dare un'occhiata anche ai miei libri dedicati ad Arduino.
All'interno troverai spiegazioni semplici, schemi chiari e molti progetti pratici pensati per chi parte da zero.
👉 Scopri i miei libri su Arduino:
ℹ️ Link di affiliazione Amazon: in qualità di Affiliato Amazon ricevo un guadagno dagli acquisti idonei, senza alcun costo aggiuntivo per te.
https://amzn.to/4rfzjXE
Molti dei progetti presenti su progettiarduino.com utilizzano componenti elettronici di base come LED, resistenze, sensori e breadboard.
Se stai iniziando con Arduino, il modo più semplice è utilizzare un kit completo per principianti, che include quasi tutti i componenti necessari per realizzare molti dei progetti presenti sul sito.
👉 Kit Arduino consigliato:
ℹ️ Link di affiliazione Amazon: in qualità di Affiliato Amazon ricevo un guadagno dagli acquisti idonei, senza alcun costo aggiuntivo per te.
https://amzn.to/4b3dxjW
📘 Vuoi imparare Arduino passo dopo passo?
Se vuoi approfondire e realizzare progetti più completi, puoi dare un'occhiata anche ai miei libri dedicati ad Arduino.
All'interno troverai spiegazioni semplici, schemi chiari e molti progetti pratici pensati per chi parte da zero.
👉 Scopri i miei libri su Arduino:
ℹ️ Link di affiliazione Amazon: in qualità di Affiliato Amazon ricevo un guadagno dagli acquisti idonei, senza alcun costo aggiuntivo per te.
https://amzn.to/4rfzjXE
📚 Librerie necessarie
Per utilizzare il display OLED devi installare:
Per la gestione dell’encoder e del buzzer non sono necessarie librerie aggiuntive.
Per utilizzare il display OLED devi installare:
- Adafruit SSD1306;
- Adafruit GFX Library.
Per la gestione dell’encoder e del buzzer non sono necessarie librerie aggiuntive.
🔌 Schema di collegamento
Display OLED SSD1306
Encoder rotativo KY-040
Buzzer passivo
Display OLED SSD1306
- VCC → 5V;
- GND → GND;
- SDA → A4;
- SCL → A5.
Encoder rotativo KY-040
- + → 5V;
- GND → GND;
- CLK → pin digitale 2;
- DT → pin digitale 3;
- SW → pin digitale 4.
Buzzer passivo
- terminale positivo → resistenza da 100 Ω;
- resistenza → pin digitale 9;
- terminale negativo → GND.
💻 Codice Arduino
Il programma controlla il volume attraverso l’encoder.
Ogni scatto modifica il livello di 5 punti percentuali.
Il volume può assumere valori compresi tra:
Premendo la manopola viene attivata la modalità mute.
Premendola nuovamente, il volume torna al valore precedente.
Il programma controlla il volume attraverso l’encoder.
Ogni scatto modifica il livello di 5 punti percentuali.
Il volume può assumere valori compresi tra:
- 0%;
- 100%.
Premendo la manopola viene attivata la modalità mute.
Premendola nuovamente, il volume torna al valore precedente.
/*
============================================================
Progetto 134 - Controllo volume con encoder e buzzer
Regola il livello audio e gestisce la funzione mute
============================================================
*/
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
// Dimensioni e indirizzo del display OLED
#define LARGHEZZA_DISPLAY 128
#define ALTEZZA_DISPLAY 64
#define RESET_OLED -1
#define INDIRIZZO_OLED 0x3C
// Collegamenti dell'encoder rotativo
#define PIN_CLK 2
#define PIN_DT 3
#define PIN_SW 4
// Pin collegato al buzzer passivo
#define PIN_BUZZER 9
// Frequenza del tono generato
const unsigned int FREQUENZA_TONO = 1000;
// Incremento applicato a ogni scatto
const byte PASSO_VOLUME = 5;
// Tempi utilizzati per ridurre
// rimbalzi e letture multiple
const unsigned long TEMPO_DEBOUNCE_PULSANTE = 180;
const unsigned long TEMPO_MINIMO_ROTAZIONE = 3;
// Oggetto utilizzato per controllare il display OLED
Adafruit_SSD1306 display(
LARGHEZZA_DISPLAY,
ALTEZZA_DISPLAY,
&Wire,
RESET_OLED
);
// Volume corrente espresso in percentuale
byte volume = 50;
// Memorizza il volume prima dell'attivazione del mute
byte volumePrecedente = 50;
// Indica se il sistema è in modalità mute
bool muteAttivo = false;
// Stato precedente del segnale CLK
int statoPrecedenteClk = HIGH;
// Variabili temporali dell'interfaccia
unsigned long ultimaRotazione = 0;
unsigned long ultimaPressione = 0;
// Variabili utilizzate per generare il segnale audio
unsigned long ultimoCambioSegnale = 0;
bool uscitaBuzzerAlta = false;
// Indica quando il display deve essere aggiornato
bool aggiornamentoDisplayRichiesto = true;
void setup() {
// I pin dell'encoder utilizzano
// le resistenze interne di Arduino
pinMode(PIN_CLK, INPUT_PULLUP);
pinMode(PIN_DT, INPUT_PULLUP);
pinMode(PIN_SW, INPUT_PULLUP);
// Configura il buzzer come uscita
pinMode(PIN_BUZZER, OUTPUT);
digitalWrite(PIN_BUZZER, LOW);
// Memorizza lo stato iniziale del segnale CLK
statoPrecedenteClk = digitalRead(PIN_CLK);
// Inizializza il display OLED
if (!display.begin(
SSD1306_SWITCHCAPVCC,
INDIRIZZO_OLED
)) {
// Se il display non viene rilevato,
// il programma rimane bloccato
while (true) {
}
}
display.clearDisplay();
display.setTextColor(SSD1306_WHITE);
display.setTextWrap(false);
mostraAvvio();
mostraInterfaccia();
aggiornamentoDisplayRichiesto = false;
}
void loop() {
// Controlla continuamente la rotazione
gestisciEncoder();
// Controlla il pulsante integrato
gestisciPulsante();
// Genera il segnale del buzzer
// senza utilizzare delay()
aggiornaBuzzer();
// Ridisegna il display soltanto
// quando cambia il volume o lo stato mute
if (aggiornamentoDisplayRichiesto) {
mostraInterfaccia();
aggiornamentoDisplayRichiesto = false;
}
}
void gestisciEncoder() {
// Legge lo stato attuale del segnale CLK
int statoAttualeClk = digitalRead(PIN_CLK);
// Rileva il fronte di discesa del segnale
if (statoPrecedenteClk == HIGH &&
statoAttualeClk == LOW &&
millis() - ultimaRotazione >=
TEMPO_MINIMO_ROTAZIONE) {
ultimaRotazione = millis();
// Se il sistema era in mute,
// la rotazione riattiva automaticamente l'audio
if (muteAttivo) {
muteAttivo = false;
volume = volumePrecedente;
}
// Confronta DT con CLK per determinare
// la direzione della rotazione
if (digitalRead(PIN_DT) != statoAttualeClk) {
aumentaVolume();
} else {
diminuisciVolume();
}
aggiornamentoDisplayRichiesto = true;
}
// Salva lo stato per il controllo successivo
statoPrecedenteClk = statoAttualeClk;
}
void gestisciPulsante() {
// Con INPUT_PULLUP il pulsante premuto
// viene letto come livello LOW
if (digitalRead(PIN_SW) == LOW &&
millis() - ultimaPressione >=
TEMPO_DEBOUNCE_PULSANTE) {
ultimaPressione = millis();
cambiaMute();
aggiornamentoDisplayRichiesto = true;
}
}
void aumentaVolume() {
// Aumenta il volume del passo impostato
int nuovoVolume = volume + PASSO_VOLUME;
// Impedisce di superare il 100%
volume = constrain(
nuovoVolume,
0,
100
);
// Memorizza l'ultimo volume valido
volumePrecedente = volume;
}
void diminuisciVolume() {
// Diminuisce il volume del passo impostato
int nuovoVolume = volume - PASSO_VOLUME;
// Impedisce di scendere sotto lo 0%
volume = constrain(
nuovoVolume,
0,
100
);
// Memorizza l'ultimo volume valido
volumePrecedente = volume;
}
void cambiaMute() {
// Se il mute è già attivo,
// ripristina il livello precedente
if (muteAttivo) {
muteAttivo = false;
volume = volumePrecedente;
return;
}
// Prima di silenziare il buzzer,
// conserva l'ultimo volume maggiore di zero
if (volume > 0) {
volumePrecedente = volume;
}
muteAttivo = true;
}
void aggiornaBuzzer() {
// Spegne completamente il buzzer
// quando il mute è attivo o il volume è zero
if (muteAttivo || volume == 0) {
digitalWrite(PIN_BUZZER, LOW);
uscitaBuzzerAlta = false;
return;
}
// Calcola la durata di mezzo periodo
// necessaria per generare la frequenza impostata
unsigned long mezzoPeriodo =
500000UL / FREQUENZA_TONO;
unsigned long momentoAttuale = micros();
// Cambia lo stato del segnale
// quando è trascorso mezzo periodo
if (momentoAttuale - ultimoCambioSegnale >=
mezzoPeriodo) {
ultimoCambioSegnale = momentoAttuale;
uscitaBuzzerAlta = !uscitaBuzzerAlta;
// Il volume viene simulato applicando
// il segnale solo per una parte dei cicli
if (uscitaBuzzerAlta &&
faseVolumeAttiva()) {
digitalWrite(PIN_BUZZER, HIGH);
} else {
digitalWrite(PIN_BUZZER, LOW);
}
}
}
bool faseVolumeAttiva() {
// Divide il segnale audio in 20 livelli.
// Un volume del 50% attiva circa metà dei cicli.
static byte fase = 0;
fase++;
if (fase >= 20) {
fase = 0;
}
byte livelliAttivi = map(
volume,
0,
100,
0,
20
);
return fase < livelliAttivi;
}
void mostraInterfaccia() {
// Pulisce completamente il display
display.clearDisplay();
display.setTextColor(SSD1306_WHITE);
display.setTextSize(1);
// Titolo della schermata
display.setCursor(0, 0);
display.print("CONTROLLO VOLUME");
display.drawLine(
0,
10,
127,
10,
SSD1306_WHITE
);
// Mostra il livello oppure lo stato mute
if (muteAttivo) {
display.setTextSize(2);
display.setCursor(38, 18);
display.print("MUTE");
} else {
display.setTextSize(2);
display.setCursor(42, 18);
display.print(volume);
display.print("%");
}
// Disegna il bordo della barra grafica
display.drawRect(
8,
39,
112,
11,
SSD1306_WHITE
);
// Calcola la larghezza proporzionale al volume
int larghezzaBarra = map(
muteAttivo ? 0 : volume,
0,
100,
0,
108
);
// Riempie la barra con il livello corrente
display.fillRect(
10,
41,
larghezzaBarra,
7,
SSD1306_WHITE
);
// Mostra le istruzioni principali
display.setTextSize(1);
display.setCursor(0, 55);
display.print("Ruota: volume");
display.setCursor(78, 55);
display.print("Premi: mute");
// Invia al display tutti gli elementi disegnati
display.display();
}
void mostraAvvio() {
display.clearDisplay();
display.setTextSize(1);
display.setCursor(17, 15);
display.print("Controllo volume");
display.setCursor(16, 31);
display.print("Encoder e buzzer");
display.setCursor(28, 47);
display.print("Progetto 134");
display.display();
delay(1800);
}
============================================================
Progetto 134 - Controllo volume con encoder e buzzer
Regola il livello audio e gestisce la funzione mute
============================================================
*/
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
// Dimensioni e indirizzo del display OLED
#define LARGHEZZA_DISPLAY 128
#define ALTEZZA_DISPLAY 64
#define RESET_OLED -1
#define INDIRIZZO_OLED 0x3C
// Collegamenti dell'encoder rotativo
#define PIN_CLK 2
#define PIN_DT 3
#define PIN_SW 4
// Pin collegato al buzzer passivo
#define PIN_BUZZER 9
// Frequenza del tono generato
const unsigned int FREQUENZA_TONO = 1000;
// Incremento applicato a ogni scatto
const byte PASSO_VOLUME = 5;
// Tempi utilizzati per ridurre
// rimbalzi e letture multiple
const unsigned long TEMPO_DEBOUNCE_PULSANTE = 180;
const unsigned long TEMPO_MINIMO_ROTAZIONE = 3;
// Oggetto utilizzato per controllare il display OLED
Adafruit_SSD1306 display(
LARGHEZZA_DISPLAY,
ALTEZZA_DISPLAY,
&Wire,
RESET_OLED
);
// Volume corrente espresso in percentuale
byte volume = 50;
// Memorizza il volume prima dell'attivazione del mute
byte volumePrecedente = 50;
// Indica se il sistema è in modalità mute
bool muteAttivo = false;
// Stato precedente del segnale CLK
int statoPrecedenteClk = HIGH;
// Variabili temporali dell'interfaccia
unsigned long ultimaRotazione = 0;
unsigned long ultimaPressione = 0;
// Variabili utilizzate per generare il segnale audio
unsigned long ultimoCambioSegnale = 0;
bool uscitaBuzzerAlta = false;
// Indica quando il display deve essere aggiornato
bool aggiornamentoDisplayRichiesto = true;
void setup() {
// I pin dell'encoder utilizzano
// le resistenze interne di Arduino
pinMode(PIN_CLK, INPUT_PULLUP);
pinMode(PIN_DT, INPUT_PULLUP);
pinMode(PIN_SW, INPUT_PULLUP);
// Configura il buzzer come uscita
pinMode(PIN_BUZZER, OUTPUT);
digitalWrite(PIN_BUZZER, LOW);
// Memorizza lo stato iniziale del segnale CLK
statoPrecedenteClk = digitalRead(PIN_CLK);
// Inizializza il display OLED
if (!display.begin(
SSD1306_SWITCHCAPVCC,
INDIRIZZO_OLED
)) {
// Se il display non viene rilevato,
// il programma rimane bloccato
while (true) {
}
}
display.clearDisplay();
display.setTextColor(SSD1306_WHITE);
display.setTextWrap(false);
mostraAvvio();
mostraInterfaccia();
aggiornamentoDisplayRichiesto = false;
}
void loop() {
// Controlla continuamente la rotazione
gestisciEncoder();
// Controlla il pulsante integrato
gestisciPulsante();
// Genera il segnale del buzzer
// senza utilizzare delay()
aggiornaBuzzer();
// Ridisegna il display soltanto
// quando cambia il volume o lo stato mute
if (aggiornamentoDisplayRichiesto) {
mostraInterfaccia();
aggiornamentoDisplayRichiesto = false;
}
}
void gestisciEncoder() {
// Legge lo stato attuale del segnale CLK
int statoAttualeClk = digitalRead(PIN_CLK);
// Rileva il fronte di discesa del segnale
if (statoPrecedenteClk == HIGH &&
statoAttualeClk == LOW &&
millis() - ultimaRotazione >=
TEMPO_MINIMO_ROTAZIONE) {
ultimaRotazione = millis();
// Se il sistema era in mute,
// la rotazione riattiva automaticamente l'audio
if (muteAttivo) {
muteAttivo = false;
volume = volumePrecedente;
}
// Confronta DT con CLK per determinare
// la direzione della rotazione
if (digitalRead(PIN_DT) != statoAttualeClk) {
aumentaVolume();
} else {
diminuisciVolume();
}
aggiornamentoDisplayRichiesto = true;
}
// Salva lo stato per il controllo successivo
statoPrecedenteClk = statoAttualeClk;
}
void gestisciPulsante() {
// Con INPUT_PULLUP il pulsante premuto
// viene letto come livello LOW
if (digitalRead(PIN_SW) == LOW &&
millis() - ultimaPressione >=
TEMPO_DEBOUNCE_PULSANTE) {
ultimaPressione = millis();
cambiaMute();
aggiornamentoDisplayRichiesto = true;
}
}
void aumentaVolume() {
// Aumenta il volume del passo impostato
int nuovoVolume = volume + PASSO_VOLUME;
// Impedisce di superare il 100%
volume = constrain(
nuovoVolume,
0,
100
);
// Memorizza l'ultimo volume valido
volumePrecedente = volume;
}
void diminuisciVolume() {
// Diminuisce il volume del passo impostato
int nuovoVolume = volume - PASSO_VOLUME;
// Impedisce di scendere sotto lo 0%
volume = constrain(
nuovoVolume,
0,
100
);
// Memorizza l'ultimo volume valido
volumePrecedente = volume;
}
void cambiaMute() {
// Se il mute è già attivo,
// ripristina il livello precedente
if (muteAttivo) {
muteAttivo = false;
volume = volumePrecedente;
return;
}
// Prima di silenziare il buzzer,
// conserva l'ultimo volume maggiore di zero
if (volume > 0) {
volumePrecedente = volume;
}
muteAttivo = true;
}
void aggiornaBuzzer() {
// Spegne completamente il buzzer
// quando il mute è attivo o il volume è zero
if (muteAttivo || volume == 0) {
digitalWrite(PIN_BUZZER, LOW);
uscitaBuzzerAlta = false;
return;
}
// Calcola la durata di mezzo periodo
// necessaria per generare la frequenza impostata
unsigned long mezzoPeriodo =
500000UL / FREQUENZA_TONO;
unsigned long momentoAttuale = micros();
// Cambia lo stato del segnale
// quando è trascorso mezzo periodo
if (momentoAttuale - ultimoCambioSegnale >=
mezzoPeriodo) {
ultimoCambioSegnale = momentoAttuale;
uscitaBuzzerAlta = !uscitaBuzzerAlta;
// Il volume viene simulato applicando
// il segnale solo per una parte dei cicli
if (uscitaBuzzerAlta &&
faseVolumeAttiva()) {
digitalWrite(PIN_BUZZER, HIGH);
} else {
digitalWrite(PIN_BUZZER, LOW);
}
}
}
bool faseVolumeAttiva() {
// Divide il segnale audio in 20 livelli.
// Un volume del 50% attiva circa metà dei cicli.
static byte fase = 0;
fase++;
if (fase >= 20) {
fase = 0;
}
byte livelliAttivi = map(
volume,
0,
100,
0,
20
);
return fase < livelliAttivi;
}
void mostraInterfaccia() {
// Pulisce completamente il display
display.clearDisplay();
display.setTextColor(SSD1306_WHITE);
display.setTextSize(1);
// Titolo della schermata
display.setCursor(0, 0);
display.print("CONTROLLO VOLUME");
display.drawLine(
0,
10,
127,
10,
SSD1306_WHITE
);
// Mostra il livello oppure lo stato mute
if (muteAttivo) {
display.setTextSize(2);
display.setCursor(38, 18);
display.print("MUTE");
} else {
display.setTextSize(2);
display.setCursor(42, 18);
display.print(volume);
display.print("%");
}
// Disegna il bordo della barra grafica
display.drawRect(
8,
39,
112,
11,
SSD1306_WHITE
);
// Calcola la larghezza proporzionale al volume
int larghezzaBarra = map(
muteAttivo ? 0 : volume,
0,
100,
0,
108
);
// Riempie la barra con il livello corrente
display.fillRect(
10,
41,
larghezzaBarra,
7,
SSD1306_WHITE
);
// Mostra le istruzioni principali
display.setTextSize(1);
display.setCursor(0, 55);
display.print("Ruota: volume");
display.setCursor(78, 55);
display.print("Premi: mute");
// Invia al display tutti gli elementi disegnati
display.display();
}
void mostraAvvio() {
display.clearDisplay();
display.setTextSize(1);
display.setCursor(17, 15);
display.print("Controllo volume");
display.setCursor(16, 31);
display.print("Encoder e buzzer");
display.setCursor(28, 47);
display.print("Progetto 134");
display.display();
delay(1800);
}
⚙️ Come funziona
Il buzzer passivo riproduce un tono con frequenza fissa.
Il volume viene simulato modificando il duty cycle del segnale PWM applicato al buzzer.
Arduino converte il valore percentuale in un livello compreso tra 0 e 255:
int valorePwm = map(volume, 0, 100, 0, 255);
Un valore basso produce un segnale meno intenso.
Un valore alto produce un segnale più marcato.
👉 La regolazione effettiva può variare in base al buzzer utilizzato.
Il buzzer passivo riproduce un tono con frequenza fissa.
Il volume viene simulato modificando il duty cycle del segnale PWM applicato al buzzer.
Arduino converte il valore percentuale in un livello compreso tra 0 e 255:
int valorePwm = map(volume, 0, 100, 0, 255);
Un valore basso produce un segnale meno intenso.
Un valore alto produce un segnale più marcato.
👉 La regolazione effettiva può variare in base al buzzer utilizzato.
🔇 Modalità mute
Premendo il pulsante integrato nell’encoder, Arduino attiva la modalità mute.
Durante il mute:
Premendo nuovamente il pulsante, il suono viene ripristinato allo stesso livello precedente.
Premendo il pulsante integrato nell’encoder, Arduino attiva la modalità mute.
Durante il mute:
- il buzzer viene spento;
- il display mostra la scritta MUTE;
- il valore del volume rimane memorizzato.
Premendo nuovamente il pulsante, il suono viene ripristinato allo stesso livello precedente.
📊 Barra grafica del volume
Il display OLED mostra:
Con il volume al 100%, la barra risulta completamente piena.
Il display OLED mostra:
- percentuale del volume;
- barra grafica;
- stato attivo o mute;
- indicazioni per la manopola.
Con il volume al 100%, la barra risulta completamente piena.
🧠 Perché è un progetto importante
Con questo progetto impari a:
👉 Queste tecniche possono essere riutilizzate in radio, amplificatori, timer sonori e pannelli di controllo.
Con questo progetto impari a:
- utilizzare un encoder rotativo;
- controllare un parametro percentuale;
- creare una funzione mute;
- pilotare un buzzer passivo;
- generare un segnale audio;
- utilizzare micros() senza bloccare Arduino;
- visualizzare una barra grafica;
- convertire valori con map();
- limitare i valori tramite constrain();
- costruire un’interfaccia simile a una manopola del volume.
👉 Queste tecniche possono essere riutilizzate in radio, amplificatori, timer sonori e pannelli di controllo.
🔄 Varianti possibili
Vuoi migliorare il progetto?
Vuoi migliorare il progetto?
- 🎵 aggiungi più frequenze selezionabili;
- 💾 salva il volume nella EEPROM;
- 🔘 riconosci una pressione lunga;
- 🔊 collega un piccolo altoparlante;
- ⚡ utilizza un transistor per pilotare il carico;
- 🎚️ aggiungi bassi, medi e alti;
- 📋 crea un menu audio completo;
- 🌈 aggiungi LED che seguono il volume;
- 📟 utilizza un display OLED più grande;
- 🎶 riproduci una melodia;
- 🔇 aggiungi un’icona grafica per il mute;
- 📶 controlla il volume tramite Bluetooth.