ARDUINO E VOCE

Buongiorno a tutti. Mi sto cimentando a gestire la voce con arduino o suoi derivati (ESP8266), ma ho riscontrato che ne Arduino UNO ne esp8266 ce la fanno a eseguire un loop in meno di 125 micro sec che mi servirebbero per avere 8000 campioni al secondo.
Cosa strana è che i primi cicli li compie in 15 microsec(ottimo) e poi dal 33-34esimo in poi salta a 434; tutto con solo 3 istruzioni così riportato sotto:

void loop() {

   time1 = micros();
   Serial.println(time1-lastRead);
   lastRead = time1;
   

}

Cosa entra in gioco al 33-34 ciclo? mi potreste dare una mano a risolvere oppure a aggiungere magari qualche hardware specializzato per rimediare a quest lentezza?
Grazie a tutti.

Buongiorno,
essendo il tuo primo post nella sezione Italiana del forum, nel rispetto del regolamento di detta sezione (… punto 13, primo capoverso), ti chiedo cortesemente di presentarti IN QUESTO THREAD (spiegando bene quali conoscenze hai di elettronica e di programmazione ... possibilmente evitando di scrivere solo una riga di saluto) e di leggere con MOLTA attenzione il su citato REGOLAMENTO ... Grazie. :slight_smile:

Guglielmo

Dopo che Ti sei presentato facci vedere il Tuo sketch.
Ciao UWe

Buongiorno a tutti. Poiché avevo trovato il login esistente pensavo avessi già fatto il post di benvenuto forse come dite bene l'avrò fatto in inglese. Mi scuso e mi presento.
Sono un ing pensionato che si diletta da qualche anno con arduino e in special modo con gli ESP8266 e mi sono arredato casa di questi oggettini.

Poiché ci si spinge sempre più avanti nei progetti, ed essendo qui in buona compagnia, credo che frequenterò il forum in maniera assidua diversamente che nel passato visto anche la semplicità di quello che facevo.

Quello che sto facendo relativamente alla mie esperienze di telecomunicazioni è il campionamento della voce di un mic a 8000volte al sec quindi un campione ogni 125usec.
Solo che il buon esp8266 il loop lo esegue in maniera un po' particolare per non dire strana. Infatti se eseguite lo sketch qui di seguito ve ne renderete conto. I primi cicli sono di 15usec i successivi di 430. Che significa questo? dove sbaglio?

Sketch:

unsigned long lastRead = micros();
unsigned long time1;

void setup() {
Serial.begin(115200);
delay(10);
lastRead = micros();
}


void loop() {

  time1 = micros();
  Serial.println(time1-lastRead);
  lastRead = time1;
  

}

>magpa: ti ricordo che in conformità al regolamento, punto 7, devi editare i tui post (quindi NON scrivendo un nuovo post, ma utilizzando il bottone More -> Modify che si trova in basso a destra del tuo post) e racchiudere il codice all'interno dei tag CODE (... sono quelli che in edit inserisce il bottone con icona fatta così: </>, tutto a sinistra).

In pratica, tutto il tuo codice dovrà trovarsi racchiuso tra due tag: [code] _il _tuo_ codice_ [/code] così da non venire interpretato e non dare adito alla formazione di caratteri indesiderati o cattiva formattazione del testo. Grazie. :slight_smile:

Guglielmo

... dopo di che ... NON puoi inserire una Serial.print() nel loop() in cui misuri il tempo ... Serial.print() ti altera tutti i tempi a causa dei buffers e del suo funzionamento.

Acquisisci il tempo iniziale, fai un'operazione, acquisisci l tempo finale e DOPO stampi la differenza tra fine ed inizio, NON con in mezzo una Serial.print() !!!

Non solo, se devi raggiungere certe velocità, ho idea che dovrai scordarti il "framework wiring" (ovvero le funzioni che ti mette a disposizione l'ambiente Arduino) e dovrai programmare accedendo direttamente hai registri.

Guglielmo

Grazie gpb01 togliendo la print e mettendola dopo aver fatto un centinaio di loop il tempo per ciclo scende drasticamente a 5-6 usec e tutti uguali.

L'ultima tua considerazione mi turba. Ossia mi stai dicendo che invece di utilizzare le istruzioni dell'IDE di arduino potrei intervenire direttamente sui registri come se si stesse programmando in Assembler o linguaggio macchina? Questo si che mi mette di buon umore. Dove posso trovare doc ed esempi di questa programmazione?

Grazie infinite per il tuo impagabile aiuto; l'avevo detto di essere in buona compagnia, anzi ottima.
Ciao

Non so se sto facendo la mossa giusta. Spero di eseguire quello che suggerisci ossia modificare l'ultimo mio post e quindi poi Save. Giusto? Così è OK per te?

... le indicazioni te le do, ma tu fai cortesemente quanto ti ho chiesto al post #5 :wink:
Grazie,

Guglielmo

Esempio di come manipolare direttamente i registri delle "PORT" della MCU di Arduino ... QUI ... dovrebbe chiarirti le idee di come si usano direttamente porte e registri attraverso l'IDE.

Per altri approfondimenti ... QUESTO è il posto giusto dove cercare (... non è legato all'ambiente Arduino, ma più alle MCU Atmel), mentre QUI ... cose interessati in ambiente Arduino :wink:

Guglielmo

Sì ma lui sta lavorando su un ESP8266 se non ho capito male...

SukkoPera:
Sì ma lui sta lavorando su un ESP8266 se non ho capito male...

Mah, lui dice ...

magpa:
... Mi sto cimentando a gestire la voce con arduino o suoi derivati (ESP8266), ma ho riscontrato che ne Arduino UNO ne esp8266 ce la fanno a eseguire un loop in meno di 125 micro sec che mi servirebbero per avere 8000 campioni al secondo....

... quindi credo che ESP8266 fosse un ripiego sperando in una maggiore velocità ... ::slight_smile:

Guglielmo

Io invece ho un dubbio di tipo diverso ... da "ex" tecnico audio part-time (molto "ex", parliamo dell'alba dei campionatori, quasi :P), eravamo abituati a campionare le frequenze ad almeno 5 volte la massima frequenza utile ... dato che la voce in media va da 300Hz a 3KHz (salvo casi particolari), al minimo si campionava a 15KHz, di solito, e solo per applicazioni "non-hifi" (per l'HI-FI o applicazioni estreme si arrivava anche a campionare a 50KHz) ... con 8KHz di campionamento, se lo devi usare in ambito audio, al massimo ci campioni in modo decente 1600Hz, e potresti avere qualche disturbo di tipo "chopping" dato dal fatto che anche gli 8KHz a cui campioni rientrano nella frequenza udibile ... sicuro che ti bastano ?

Diciamo che le prove le sto facendo campionando al livello telefonico quindi con una frequenza di max 4Khz e quindi un campionamento almeno il doppio quindi 8000 campioni al sec. Un campione catturato ogni 125usec.
Ed è questo intervallo che vorrei ottenere dall'ESP8266 e penso che con gli accorgimenti di gpb01 credo ci si arrivi. Sto ancora provando.
Grazie dell'interessamento.

Spero a breve di darvi notizie positive.
Ciao a tutti

magpa:
... penso che con gli accorgimenti di gpb01 credo ci si arrivi. Sto ancora provando.

Occhio perché le guide che ti ho dato sono per ATmega328P NON per ESP8266 ... che ha nomi di PORT e registri completamenti diversi ed anche le modalità di accesso diretto.

Perché non usare una Arduino MKRxxxx che monta un CORTEX-M0 la cui documentazione, per la programmazione "bare-metal" è ampiamente disponibile ?

Guglielmo

P.S.: Sto ancora aspettando che sistemi il codice come ti ho già chiesto più volte ...

Beh non ho mai provato ad acquisire audio da Arduino, ma stando a quanto ho letto credo che per acquisire una voce a livello telefonico (max 4kHz quindi campionare a 8kHz, ma bastano anche 4kHz) credo sia alla portata di Arduino UNO (se penso che facevo una cosa analoga con un povero ZX Spectrum che acquisiva ad 1 bit col suo Z80 a 8MHz...). Quindi intanto ti direi di vedere se QUI trovi indicazioni utili.

Poi però devi anche considerare che questi dati, che a 8kHz (limitamoci a 8 bit, non i 10 standard) sono 8kbyte al secondo, che di fatto è un PCM, e non si sa se tu debba campionare una porzione o sia un flusso da acquisire per un tempo indefinito. Il problema successivo, abbastanza importante direi, è che questo flusso lo devi poi "usare" o memorizzare, o trasferire... Se la CPU è impegnata nell'acquisizione non so se hai abbastanza tempo anche per farci "qualcosa". Insomma, a che ti serve?

Scusa non pensavo ti riferissi anche a post passati, comunque eseguita correzione in entrambi quelli passati.

Sono di nuovo qui per un consiglio e/o suggerimento.

Come sai sto tentando di memorizzare la voce e fare quindi un wav per ascoltarlo. Sono riuscito dietro tuoi suggerimenti a catturare dalla porta A0 dove ho piazzato il microfono 8000 campioni al secondo mediante la analogRead(A0).
Fatto questo volevo costruire un file wav ma quello che ottengo è una schifezza molto distorto; si capisce a malapena . Ora mi domando: una volta acquisito il campione con la analogread, lo stesso dato di 2 byte lo scrivo nel file o lo dovrei manipolare in qualche modo?

Spero che tu come al solito risolva brillantemente anche questo problema. Grazie.

paolo
P.S. Naturalmente prima dei dati ho inserito l'header dello wav che viene riconosciuto regolarmente.

Ho capito ci sono 2 pagine nella conversazione e la mia risposta è andata in coda alla seconda anche se l'avevo scritta nello spazio della prima pagina. Le mie considerazioni erano rivolte infatti a gpb01 credendo di scrivere subito dopo il suo messaggio.

Comunque non avevo letto il tuo docdoc ma nel codice tu fai riferimento a un DAC e un ADC o sono solo istr di ARDUINO? Sinceramente mai utilizzate. Nel primo caso però dovrei acquistare un oggettino del genere per continuare a provare.

Se usassi invece solo arduino da ciò che ho detto nei post subito precedenti mi sapresti dare la modalità corretta di memorizzazione dei campioni letti perchè il suono che viene fuori è un gracchio quasi incomprensibile.
Grazie
paolo

Purtroppo ho il vizio di non leggere tutto fino in fondo ma di andare un po' a grandi passi anche per il tempo che è sempre più tiranno.
Ora rileggendo un po' meglio, ma hai fatto un trattato per gestire input ed output veramente degno di plauso. Ora quando il tempo me lo permette lo leggerò più attentamente. Grazie
paolo

@magpa
Che microfono usi? Quale circuito usi? L'Arduino legge solo tensioni tra 0 e 5V, niente tensioni negative.
Una basetta con MAX4466 e relativo microfonino dovrebbe andare bene.

@docdoc
tra gli esempi della libreria TMRpcm ce n'è uno che scrive i dati acquisiti sulla SD.