Go Down

Topic: [RISOLTO] ESP32-CAM + Arduino Uno (e rilevazione movimento) (Read 1 time) previous topic - next topic

Federico66

Complimenti!
Alle spiegazioni. Credevo che l'ESP32 accedesse alla SD in SPI ma da quello che scrivi (e se avessi letto quello che hai letto tu) avrei dedotto che l'accesso usa SDIO, un protocollo più veloce che è praticamente uno standard nei dispositivi che usano le SD, SPI lo usano solo le MCU con poche linee di I/O, Arduino appunto.
Non mi ricordo se il LED sia attivabile dall'interfaccia web di esempio.
Grazie!

In realtà si può scegliere la modalità di accesso alla SD, e nel caso delle ESP32-CAM, lui libera i pin non necessari.
Devo dire che sto imparando molto sulla ESP32, avendo iniziato con questo particolare modulo.

Nell'interfaccia web di esempio non è possibile gestire il LED e la capture non viene salvata, (solo visualizzata), ma bastano (+o-) poche modifiche al server http, per inserirle.

Credo d'aver risolto anche problema hardware (vari reset e avvii problematici) mettendo in comune i GND della ESP e di Arduino. Pensavo non fosse necessario visto che uso un convertitore logico di livello (vcc e gnd dai due moduli), ma evidentemente non è cosi, visto che ha risolto!


Federico

Federico66

#31
Aug 23, 2019, 06:58 pm Last Edit: Aug 23, 2019, 07:55 pm by Federico66
Eccomi di nuovo qua, stavolta per chiudere :)

Per riepilogare posso dire che trovo questo ESP32-Cam molto "simpatico", ma è stata una vera fatica riuscire a connetterlo (serialmente) ad Arduino!

Dopo svariati tentativi, la soluzione che ho adottato è stata:
- configurare la SD in "1-line mode" in modo da liberare i pin 12 e 13
- "bruciare" gli eFuse XPD_SDIO_TIEH, XPD_SDIO_FORCE, e XPD_SDIO_REG in modo da "liberare" il pin 12, utilizzato anche in fase di boot per selezionare la tensione di uscita di un regolatore interno che alimenta il chip flash (VDD_SDIO).
Per i dettagli rimando qui.

Nota: al contrario di quello che avevo detto, non è possibile utilizzare il pin 16, in quanto utilizzato dalla PSRAM, con effetti "sgradevoli" se utilizzato per la trasmissione seriale.

Quindi i pin utili, in definitiva, sono il 12 e 13.

Naturalmente mi sono fatto prendere la mano, e ho aggiunto un supporto pan/tilt e due servo collegati ad Arduino e pilotati da un Joystick :)

Questo lo schema

e questo il risultato

e questa la pagina semplificata per lo streaming



Materiale utilizzato:
- Arduino Nano
- ESP32-CAM
- CP2102 USB 2.0/UART TTL
- Convertitore di livello logico
- Supporto Pan/Tilt con due Servo SG90
- Joystick

Codice
In allegato i files lato ESP32-Cam (basato su esempio CamServer) ed il file per Arduino.
Naturalmente è solo un progetto di studio, quindi da prendere cosi com'è ;)

Funzionalità lato ESP32
- configurazione da file su SD: wifi (elenco reti conosciute), ntp e server remoto per upload immagini
- decifratura password (xor+base64)
- streaming su pagina web con possibilità di cattura immagine (sd o upload) e accensione flash led (pagina originale rinominata index2)
- salvataggio foto su SD card o invio (http post) su server remoto con Autenticazione base
- generazione nome file con data ora, se disponibile, altrimenti numerazione progressiva assoluta (EEPROM)

Esempio del file di configurazione (config.txt)
Code: [Select]

WIFI|Ufficio|SSID1|PWD1(xor+base64)
WIFI|Casa|SSID2|PWD2(xor+base64)
WIFI|Wind|SSID3|PWD3(xor+base64)
NTP|pool.ntp.org|1|1
POSTURL|http://xxx.xxx.xxx.xxx:pppp/Upload|USER|PWD



Funzionalità lato Arduino
- possibilità (via seriale) di scattare foto e salvarle su sd o upload su server remoto, e tutto quello che si vuole chiedere a ESP (data ora, IP, etc)
- gestione del Joystick per ruotare la video camera sui due assi e scattare foto con il pulsante

Mi pare sia tutto.
Spero d'aver fatto cosa gradita, e se qualcuno vuole giocarci, spero mi faccia notare errori ed eventuali miglioramenti.

Federico

UPDATE
Naturalmente prima di bruciare gli efuse, pensateci!!!

UPDATE 2
Prossimo obiettivo, gestire i servo dalla pagina di streaming ;)

zoomx


Federico66

+1!
Grazie.
Sto verificando la possibilità di rilevare il movimento (no pir) , ma il processing delle immagini in C/C++ mi risulta complicato... per il momento ;)

Federico

Federico66

#34
Sep 03, 2019, 04:38 pm Last Edit: Sep 03, 2019, 04:39 pm by Federico66
Sto verificando la possibilità di rilevare il movimento (no pir) , ma il processing delle immagini in C/C++ mi risulta complicato... per il momento ;)
Scusate se mi autoquoto, ma sono molto soddisfatto e devo assolutamente condividere :)

Primi test molto positivi:




Ho scritto un libreria per l'image processing e utilizzando l'algoritmo del confronto dei frame con un "background" di riferimento riesco a rilevare ed evidenziare le aree differenti.
Naturalmente non potendo utilizzare librerie esistenti, lavoro direttamente con le immagini in formato rgb888(24bit) e grey8 (8bit).
Sia chiaro, per l'image processing, ho cercato in rete, e per fortuna ho trovato quasi tutto quello che mi serviva direttamente in C/C++.

Vi ricordo, che non è Arduino, ma ESP32, quindi si ha a disposizione la PSRAM da 4mb.

Se non è OT, appena ho qualcosa di presentabile, avrei piacere di condividere per avere vs suggerimenti su come ottimizzare.


Grazie
Federico

gpb01

Complimenti, bel lavoro !!! :)

Guglielmo
Search is Your friend ... or I am Your enemy !

Federico66

Complimenti, bel lavoro !!! :)
Grazie :)

Devo ancora verificare se regge nel tempo, ma io sono già contento cosi!

Federico

zoomx

+10!

Sebbene ci sia adesso la Teensy4 a 20$ ma a 600MHz ha meno memoria, 1M

Questa scheda con ESP32 e la PSRAM rimane ancora molto competitiva e aperta a nuovi sviluppi.


Se ci fossero sensori economici ma privi del filtro di bayer......

Federico66

#38
Sep 06, 2019, 06:48 pm Last Edit: Sep 06, 2019, 06:52 pm by Federico66
Come promesso in allegato la mia versione stabile di CameraWebServer distribuito con ESP32.
Le funzionalità aggiunte le trovate elencate nel post #31, qui mi soffermo solo sulla libreria moveDetect.

Premessa, non ho inventato nulla, o solo applicato degli algoritmi conosciuti e mi sono aiutato molto con vari articoli (seri ::) ) trovati in rete.

In pratica la libreria permette di rilevare il movimento confrontando ogni frame con una immagine (iniziale) di riferimento.
Il confronto (byte per byte) avviene tra le immagini in formato grayscale alle quali è stato applicato un filtro di sfocatura (Gaussian blur).
Sull'immagine risultante dal confronto, vengono applicati ulteriori filtri (Threshold, Dilate) ed infine utilizzando l'algoritmo Moore's neighbor tracing algorithm vengono rilevati tutti i contorni (poligoni chiusi).
Per ognuno dei poligoni viene calcolata l'area, e se maggiore di un determinato valore costante, viene considerato "estraneo" alla scena. A questo punto, viene disegnato sul frame il rettangolo che lo contiene.

Per capirci (immagini ottenute con la stessa libreria, ma utilizzando VSC++):



ed il risultato è questo (scusate la qualità, è una gif :) ):




Chiaramente non aspettatevi fluidità, ma sembra funzionare bene.

Tutta la procedura è gestita nell'handler http che effettua lo streaming video, e più o meno fa questo:
(molto sinteticamente)
Code: [Select]

//Inizializza la classe con una area minima da rilevare
//che è data da 1.4% della area totale del frame (w*h)
MoveDetector mov(0.014);
 
while (true) {
  //Archivia il frame
  fb = esp_camera_fb_get();
  
  //Se non esiste l'immagine di riferimento o è passato enne tempo da quando è stata rilevata l'ultima volta
  //Converte il frame in rgb888 e lo archivia come immagine di riferimento
  fmt2rgb888(fb->buf, fb->len, fb->format, image_matrix->item));
  mov.setBackground(image_matrix->item, fb->width, fb->height));
    
  //Se esiste l'immagine di riferimento
  //Verifica se nel frame corrente esistono area da evidenziare
  fmt2rgb888(fb->buf, fb->len, fb->format, image_matrix->item));
  MoveDetector::contoursInfo_t *contoursInfo = mov.moveDetect(image_matrix->item, fb->width, fb->height);

  //Se esistono (contoursInfo->boxesCount > 0)
  //Le riporta sul frame originale
  draw_move_boxes(image_matrix, contoursInfo);

}



Vista la mia poca esperienza con il C++, se qualcuno ha voglia di dare un'occhiata alla libreria (che allego anche separatamente), sarei felice di ricevere commenti su come ottimizzare il codice per renderlo più performante, o semplicemente come migliorare la scrittura.


Per quanto riguarda la pagina web per lo streaming, naturalmente è stata modificata aggiungendo le nuove funzionalità:




Piccola nota sul formato delle immagini:
RGB888: array di bytes, dove ogni pixel e dato da 3 bytes (canali RGB) consecutivi, quindi per accedere al pixel img[r][c] bisogna usare img[c*width+r]; naturalmente la dimensione dell'array è width*height*3.
Gray8: array di bytes, dove ogni byte corrisponde ad un pixel.


Vi ricordo che questo per me è solo un progetto studio, per fare "decentemente" un rilevatore di movimento utilizzando video camere, esistono altri prodotti :)

Grazie
Federico





Federico66

Piccolo aggiornamento poi basta!

Ho aggiunto la possibilità di gestire i due servo (pan-tilt) collegati ad Arduino, direttamente dallo streaming web di ESP32-Cam, tramite mouse o touch (simulazione joystick).

http://xxx.xxx.xxx.xxx/index2



Federico

PS
Esp32_CamWebServer_v1.1.zip: programma per ESP32-Cam
Esp32_SoftwareSerialTest.ino: programma per Arduino

zoomx


Federico66

Ma no!!!!
Oramai per me ESP32-Cam non ha più segreti :D... o quasi

Proprio ieri un amico video maker, mi ha buttato li un'idea... montarla su un rover (Arduino) e scattare foto ogni n metri per realizzare hyperlapse :)

Ci ho pensato un po'.. e ho detto...



Federico


PS
Scusa Guglielmo :)

gpb01

Scusa Guglielmo :)
Figurati ... :D

Piuttosto, visto che l'hai usata parecchio, come siamo messi con il "pattren recognition"?   Ovvero, montata davanti ad un sistema GPS, di quelli che in un angolo mostrano il limite di velocità con l'icona del cartello stradale, si riesce a fare il riconoscimeto del cartello indicato (... e quindi del limite di velocità) ? :)

Grazie,

Guglielmo
Search is Your friend ... or I am Your enemy !

Federico66

Piuttosto, visto che l'hai usata parecchio, come siamo messi con il "pattern recognition"?
ma sai che era un'altra di quelle cose che volevo provare, riconoscere oggetti ... fermi :)

Naturalmente non sono esperto in questo capo (image processing), quindi prendi quello che dico con le dovute pinze :)

Io credo che il problema stia solo nei tempi di elaborazione delle immagini. Sia il giochino che ho realizzato, sia il face-recognition, già presente, lavorano "decentemente" con immagini 320x240 (76800 bytes in bn, 230400 in rgb), se provi ad andare oltre si pianta tutto, credo sia improponibile lavorare con matrici più grandi su un ESP32!
Potrei provare a riconoscere oggetti fermi, ma riconoscere oggetti in movimento (n km/h) non credo sia cosa fattibile!!

Per nulla mi vieta di provare a fare streaming dall'auto a diverse velocità, almeno per capire come va, naturalmente con un programma specifico, e non complesso come questo :)


Federico

PS
Con Raspberry sarebbe molto più semplice, visto che ci si può installare OpenCV (ad esempio)!






gpb01

... no, no, aspetta, ho scritto che dovrei riconoscere l'icona che appare sullo schermo del GPS (uno di quelli che le ha memorizzate all'interno in funzione delle località) ... parleremo di 1.5cm x 1.5cm ... l'icona di un segnale stradale con il limite di velocità ...

... riconoscere quale icona è visualizzata ;)

Guglielmo
Search is Your friend ... or I am Your enemy !

Go Up