Questo breve tutorial ti mostra come accendere o spegnere il LED Flash dell’ESP32-CAM, con e senza deep-sleep. Imparerai anche come controllare la luminosità del LED e cosa tenere a mente quando usi il LED insieme all’interfaccia della scheda SD.
Parti necessarie
Ti servirà un ESP32-CAM per provare gli esempi di codice. Puoi procurarti un ESP32-CAM con uno Shield USB-TTL per la programmazione o un adattatore FTDI USB-TTL. Consiglio l’adattatore FTDI USB-TTL, perché è più comodo per programmare, ma ho elencato entrambe le opzioni qui sotto.
Se vuoi usare il lettore di schede SD ti servirà una scheda SD non più grande di 16 GB. Comunque, non ti servirà per questo tutorial.

ESP32-CAM con Shield USB-TTL

Adattatore FTDI USB-TTL

MicroSD Card 16GB
Makerguides is a participant in affiliate advertising programs designed to provide a means for sites to earn advertising fees by linking to Amazon, AliExpress, Elecrow, and other sites. As an Affiliate we may earn from qualifying purchases.
Far lampeggiare il LED Flash
Se non usi la scheda SD o la modalità deep-sleep dell’ESP32-CAM, controllare il LED flash è semplice. Il LED flash è collegato al GPIO 4 e il solito Blink code funziona perfettamente.
void setup() {
pinMode(GPIO_NUM_4, OUTPUT);
}
void loop() {
digitalWrite(GPIO_NUM_4, HIGH);
delay(1000);
digitalWrite(GPIO_NUM_4, LOW);
delay(1000);
}
Se selezioni la scheda AI Thinker ESP32-CAM come board, la costante GPIO_NUM_4 per il GPIO 4 è definita.

Nella funzione setup possiamo quindi usare GPIO_NUM_4 per impostare il GPIO 4 in modalità output. Nella funzione loop abbiamo il solito Blink code che accende il LED per un secondo e lo spegne per un altro secondo.
Se non sai come caricare il codice sull’ESP32-CAM dai un’occhiata al tutorial Programming the ESP32-CAM.
Controllare la luminosità del LED Flash
Il GPIO 4 supporta anche il PWM (Pulse Width Modulation), il che significa che puoi controllare la luminosità del LED flash. L’esempio seguente aumenta la luminosità b da 0 (spento) al massimo (255) in un ciclo:
void setup() {
pinMode(GPIO_NUM_4, OUTPUT);
}
void loop() {
for (int b = 0; b < 256; b++) {
analogWrite(GPIO_NUM_4, b);
delay(10);
}
}
Far lampeggiare il LED Flash con deep-sleep
Le cose si complicano quando vuoi far lampeggiare il LED in combinazione con il deep-sleep. Per esempio, vuoi mettere l’ESP32-CAM in sleep, risvegliarlo quando un oggetto si muove, accendere il LED flash, scattare una foto, spegnere il LED e tornare a dormire.
Il problema è che lo stato di output dei pin GPIO si perde normalmente quando l’ESP32 entra in deep-sleep. I pin GPIO rimangono flottanti, senza un valore definito. Puoi evitare questo chiamando la funzione rtc_gpio_hold_en(pin) per un pin specifico o la funzione rtc_gpio_force_hold_en_all() per congelare tutti i pin nel loro stato attuale.
Tuttavia, quando l’ESP32 si risveglia dal deep-sleep, devi disabilitare questo holding dei pin, altrimenti non puoi impostare lo stato dei pin. Per disabilitare il holding puoi chiamare le funzioni rtc_gpio_hold_dis(pin) o rtc_gpio_force_hold_dis_all().
Il seguente esempio di codice mostra come usare queste funzioni per spegnere il LED per un secondo mentre l’ESP32 è sveglio, e poi accendere il LED mentre l’ESP32 dorme per un secondo:
#include "driver/rtc_io.h"
void setup() {
rtc_gpio_hold_dis(GPIO_NUM_4);
pinMode(GPIO_NUM_4, OUTPUT);
digitalWrite(GPIO_NUM_4, LOW);
delay(1000);
digitalWrite(GPIO_NUM_4, HIGH);
rtc_gpio_hold_en(GPIO_NUM_4);
esp_sleep_enable_timer_wakeup(1 * 1000 * 1000);
esp_deep_sleep_start();
}
void loop() {}
Discutiamone un po’ più nel dettaglio.
Per prima cosa importiamo il file driver/rtc_io.h, necessario per le funzioni rtc_gpio_hold_xxx.
Nella funzione setup, iniziamo chiamando rtc_gpio_hold_dis(GPIO_NUM_4). Questo disabilita qualsiasi hold sul pin GPIO 4. Senza questo non potremmo cambiare lo stato del pin 4 più avanti.
Alla riga successiva chiamiamo pinMode(GPIO_NUM_4, OUTPUT) per impostare il pin GPIO 4 in modalità output. Poi possiamo impostare il pin 4 su LOW (spegnendo il LED) chiamando digitalWrite(GPIO_NUM_4, LOW).
Dopo un ritardo di un secondo impostiamo il pin 4 su HIGH e qui diventa interessante. Vogliamo entrare in deep-sleep ma perderemmo lo stato del pin 4. Perciò dobbiamo chiamare rtc_gpio_hold_en(GPIO_NUM_4) per mantenere lo stato HIGH attuale del pin 4.
Infine impostiamo il timer di deep sleep a un secondo (esp_sleep_enable_timer_wakeup) ed entriamo in deep-sleep tramite esp_deep_sleep_start().
Quando l’ESP32 si risveglia dopo un secondo, ricomincia dall’inizio della funzione setup. La funzione loop non viene mai chiamata.
LED Flash e interfaccia scheda SD
Controllare il LED flash è particolarmente complicato quando vuoi usare anche la scheda SD. Questo perché la linea dati HS2_DATA1 dell’interfaccia scheda SD è condivisa con il LED flash. Il diagramma seguente mostra il circuito di controllo del LED flash.

Si vede che l’alimentazione del LED_FLASH è commutata tramite il transistor Q1, che a sua volta è controllato da una linea di segnale chiamata HS2_DATA1. Se guardi ora lo schema di collegamento del connettore della scheda SD vedrai anche la linea HS2_DATA1 (ultimo filo), usata per trasferire dati alla scheda SD:

Questa è la ragione per cui il LED dell’ESP32-CAM lampeggia brevemente quando scrivi sulla scheda SD.
Poiché il LED e la scheda SD usano entrambi HS2_DATA1, devi assicurarti di non mantenere attivo GPIO 4 né fare nulla con il LED/GPIO 4 mentre scrivi o leggi dalla scheda SD.
L’esempio di codice seguente mostra come accendere il LED, scattare una foto, salvarla sulla scheda SD, spegnere il LED e poi dormire per 5 secondi prima della prossima iterazione.
#include "FS.h"
#include "SD_MMC.h"
#include "driver/rtc_io.h"
#include "esp32cam.h"
const auto RES = esp32cam::Resolution::find(800, 600);
RTC_DATA_ATTR uint16_t counter = 0;
void takeAndSavePic() {
static char path[64];
auto frame = esp32cam::capture();
if (frame) {
sprintf(path, "/img%d.jpg", counter++);
File file = SD_MMC.open(path, FILE_WRITE);
frame->writeTo(file);
file.close();
Serial.printf("Wrote: %s\n", path);
delay(10);
}
}
void initCamera() {
using namespace esp32cam;
Config cfg;
cfg.setPins(pins::AiThinker);
cfg.setResolution(RES);
cfg.setJpeg(80);
Camera.begin(cfg);
}
void setup() {
Serial.begin(115200);
rtc_gpio_hold_dis(GPIO_NUM_4);
SD_MMC.begin();
initCamera();
pinMode(GPIO_NUM_4, OUTPUT);
digitalWrite(GPIO_NUM_4, HIGH);
takeAndSavePic();
digitalWrite(GPIO_NUM_4, LOW);
rtc_gpio_hold_en(GPIO_NUM_4);
esp_sleep_enable_timer_wakeup(5 * 1000 * 1000);
esp_deep_sleep_start();
}
void loop() { }
Per questo codice ti servirà la libreria esp32cam, che semplifica la gestione della fotocamera. Puoi installarla tramite il Library Manager nell’IDE Arduino. Cerca semplicemente “esp32cam”:

Non entrerò nei dettagli di come funziona il codice della fotocamera, ma mi concentrerò sull’interazione tra scattare una foto, salvarla sulla scheda SD, controllare il LED flash e usare il deep-sleep. Tutto questo avviene nella funzione setup.
Come vedi, la prima cosa è chiamare rtc_gpio_hold_dis(GPIO_NUM_4) per disabilitare qualsiasi hold su GPIO 4. Altrimenti non potremmo controllare il flash né usare la scheda SD.
Poi inizializziamo l’interfaccia della scheda SD tramite SD_MMC.begin() e inizializziamo anche la fotocamera tramite initCamera().
Quindi accendiamo il LED flash chiamando digitalWrite(GPIO_NUM_4, HIGH), scattiamo una foto, la salviamo sulla scheda SD e poi spegniamo di nuovo il LED.
Prima di entrare in deep-sleep, devi chiamare rtc_gpio_hold_en(GPIO_NUM_4) per assicurarti che GPIO 4 mantenga il suo stato (LOW) durante il deep-sleep e che il LED flash rimanga spento.
Dopodiché impostiamo il timer per il deep-sleep a 5 secondi e avviamo la modalità deep-sleep. L’ESP32 si risveglierà automaticamente dopo 5 secondi e il ciclo si ripeterà.
Spegnere il Flash durante la scrittura sulla scheda SD
Come detto prima, il LED flash e la scheda SD condividono la stessa linea di segnale chiamata HS2_DATA1, quindi il LED lampeggia brevemente quando scrivi sulla scheda SD. Puoi evitare questo abilitando la modalità 1-bit per il SD Card interface:
SD_MMC.begin("/sdcard", true);
Il secondo argomento mode1bit==true imposta la modalità 1-bit. In questa modalità la linea HS2_DATA1 (GPIO 4) non viene usata e il LED non lampeggia durante la scrittura sulla scheda SD. Anche se la velocità di scrittura sarà più lenta, ora puoi controllare liberamente GPIO 4, visto che viene usato solo dal LED.
Puoi provare questo con il seguente codice di test. Spegne il LED e scrive un file 10 volte:
#include "FS.h"
#include "SD_MMC.h"
void setup() {
Serial.begin(115200);
pinMode(GPIO_NUM_4, OUTPUT);
digitalWrite(GPIO_NUM_4, LOW);
//SD_MMC.begin(); // LED will switch on
SD_MMC.begin("/sdcard", true); // LED remains off
for (int i = 0; i < 10; i++) {
delay(1000);
File file = SD_MMC.open("/test.txt", FILE_WRITE);
file.println("TEST");
file.close();
Serial.println("File written");
}
}
void loop() { }
Con SD_MMC.begin(), il LED si accenderà (nonostante sia impostato spento) appena il codice inizia a scrivere i file. Con SD_MMC.begin("/sdcard", true) invece, il LED resta spento e rimane spento.
Conclusioni
In questo tutorial hai imparato a controllare il LED flash dell’ESP32-CAM in vari scenari, soprattutto in combinazione con deep-sleep e supporto scheda SD.
Vale la pena ricordare che dovresti evitare di tenere acceso il LED flash per lunghi periodi. Lo schema elettrico mostra che non c’è un resistore di limitazione della corrente per il LED, il che significa che può facilmente surriscaldarsi e bruciarsi.
Se ti servono informazioni più fondamentali sull’ESP32-CAM dai un’occhiata al tutorial Programming the ESP32-CAM. Se vuoi applicare quanto imparato qui per costruire una fotocamera attivata dal movimento, vedi il tutorial Motion Activated ESP32-CAM. Infine, se vuoi usare l’ESP32-CAM per il riconoscimento oggetti, il tutorial Object Detection with ESP32-CAM and YOLO ti sarà utile.
Se hai domande, sentiti libero di lasciarle nella sezione commenti.
Buon divertimento con il tinkering ; )

