ARDUINO E VOCE

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.

Ciao zoomx scusa il ritardo della risposta ma sono stato fuori in altre faccende affaccendato. Ritorno ora a trattare la voce con arduino.
Si uso un micro del genere che menzioni tu ma campionando la voce a 8khz, inviandola poi tramite wifi e risentirla al telefono non è un granchè. Sinceramenteavrei necessità di 2 certezze: primo campionando il segnale in UINT_16 audio = analogread(A0) e poi replicarlo sul telefono.

UINT_16 value = analogread(A0)
audioBuffer[i++] = value & 0xff;
audioBuffer[i++] = value >>8 & 0xff

l'audio buffer lo trasferisco verso il telefono dove un app me lo memorizza in file wav

Risentendo il file wav con cool edit c'è un ronzio di fondo e poi la voce non è così intellegibile

So che le info che ti sto dando non sono molto dettagliate, ma sapresti ugualmente darmi qualche suggerimento?

Ho tentato di far girare l'app Recording del TMRpcm ma su arduino UNO e su arduino nano mi da dei problemi di compilazione

Grazie in anticipo del tuo tempo.
Ciao
paolo

Il ronzio penso sia dovuto all'alimentazione di Arduino se collegato al PC via USB.
In ogni caso su Arduino ci sono diverse fonti di interferenze, potrebbe anche essere la trasmissione via wifi. Se usi UDP può anche essere che si perde qualche pacchetto ma in sostanza il succo è che per adesso non sembra che Arduino sia adatto per un compito del genere.
Esistono però delle shield audio, così come altre board, come la costosa Teensy che ha uno shield audio e dietro una persona, quello che la produce, che la supporta bene.

Quello che vorrei fare è prendere un audio da un altoparlante e tramite esp8266 dopo campionamento inviarlo in wifi verso un app di un telefono che potrebbe replicarla. Sto praticamente impazzendo a trasferire questi campioni in wifi sia per lentezza di timing sia per motivi che alcune volte non capisco nemmeno. Che tu sappia ci sono schede che potrebbero fare questo?

paolo

Non ho trovato microfoni che funzionino in WiFi, solo wireless.

Su ESP8266 ho trovato alcuni link
https://perso.aquilenet.fr/~sven337/english/2016/07/14/DIY-wifi-baby-monitor.html
ma alla fine c'è scritto che è rumoroso

The ESP8266 is not a perfect fit for a project like that : it doesn’t have a decent ADC, it doesn’t have a decent DAC, and it tends to be electrically noisy in such a way that the electret pickup circuit can be affected by wifi transfers. On the other hand it’s cheap, easy to use, and has plenty of processing power.

https://www.esp8266.com/viewtopic.php?f=6&t=11427
ma fa uso di un STM32 oltre all'esp8266

ma lo sketch va modificato perché tìinefficiente.

Forse la soluzione più semplice sarebbe quella di usare un vecchio smartphone.

Qualcosa sono riuscito a fare. Ricevo sufficientemente bene ossia si capisce ma va a scatti. Utilizzo per lo speech sul telefono android AudioTrack che però non so rendere continuo. Sto cercando su Internet, ma senza successo. Eppure di streaming se ne fanno sui telefoni. POssibile che a nessuno è venuto di realizzare uno streaming in casa?

Un'altra cosa che mi capita è che l'ESP qualche volta va lentissimo nella audioclient.write(). La scrittura sul client non schioda qualche volta per 1-2 sec. Lo ricarico e qualche volta riparte ma non sempre. Potrebbe dipendere da chi riceve che essendo piuttosto lento rallenta anche il mittente?

Ti tengo aggiornato se aggiornamenti ci saranno
Ciao
paolo

Lo streaming si fa usando il traffico UDP non TCP, come mi è sembrato di capire.
Significa che chi manda i pacchetti non si cura se arrivino o meno ma spara in continuazione.

Ho trovato degli esempi cercando Walkie Talkie invece di streaming
Questo è per Proton (Broadcom BCM43362 Wi-Fi chip+STM32F205 120Mhz ARM Cortex M )

Questo invece usa ESP8266 ma ha anche lui problemi

Tieni conto che alcuni dei problemi sono dovuti al fatto che anche come ricevitore viene usato un dispositivo analogo e l'ESP8266 non ha un DAC, però ha un'uscita I2S che è poi quella usata dai ricevitori di web radio in streaming.

Poi c'è una libreria che fa uso del chip nRF24L01 che va sui 2.4GHz ma usa un protocollo tutto suo, purtroppo.

Un RaspberryPI 3B+ potrebbe farlo ma non ha ingresso audio, devi usare una scheda audio USB, ma ha il WiFi al contrario dei precedenti modelli.

Grazie dei suggerimenti ma con UDP sembra si perda il 90% dei pacchetti. Esp8266 spedisce alla grande ma il telefono ne prende uno ogni tanto. In effetti sono parecchi al secondo.
Sono ritornato al socket e ieri sera è andato alla grande mi sono sentito la radio la telefono. Grandioso.
Dopo tutte le prove che avevo fatto ho salvato subito il tutto. Inutilmente stamani l'ho ripreso e balbettava come al solito. l'ESP8266-12E fa quello che vuole oghi tanto riesce a star dietro alle spedizione altre volte rallenta e sospende proprio l'elaborazione.

Se blocco l'app sul telefono che riceve l'ESP riprende alla grande e va velocissimo.

E' la connessione socket che lo mette in crisi. Cosa si potrebbe fare per guarirlo.

Stando in debug sull'app del telefono e metto un break sulla ricezione e dopo qualche secondo lo tolgo mantiene per qualche secondo un audio perfetto e poi ricomincia a balbettare.

Ieri sera gli girava bene e non ha perso un colpo.

Tra un po' mi sa che mollo. Non ci riesco a fare una cosa stabile e ripetibile. Mi sa che dovrei mettere un mini computer più potente.

Ciao zoomx, mi dispiace no averti dati belle notizie

Da quello che scrivi il problema potrebbe stare nell'app che non è abbastanza veloce per prendere tutti i pacchetti ed elaborarla. Però è anche vero che in rete i pochi progetti che ho visto son sembrati tutti fallimentari proprio su questo punto.

In ogni caso sappi che ho imparato un poco, nel senso che adesso sono un po' più informato.
Può essere che applicherò parte di quanto imparato per trasmettere segnali più lenti, tipo un campionamento a 200Hz o meno.

Ho trovato un ESP più veloce anzi veloce il doppio e sto facendo i primi test e devo dire che catturare la voce ed inviarla su wifi è eccitante e lo fa abbastanza bene. Ora devo pensare a fare il processo inverso ma sto vedendo che è più rognoso tra le varie codifiche audio che si intrecciano tra android, le varie codifiche wav , ESP e circuiteria spicciola.
Staremo a vedere

Hai preso l'ESP32 oppure hai raddoppiato il clock dell'ESP8266?

Ciao Zoomx ho preso l'esp32 ma devo dire che sono deluso dai risultati della trasmissione voce da e verso il telefono. Non riesco ad ottenere un suono decente. Tutti gracchii, voce che prima parte bene e poi si affievolisce e si confonde con il rumore. L'ho provate tutte o quasi ma non riesco ad ottenere quello che credevo abbastanza facile. Sai cos'è secondo me la cosa particolare che il telefono non ragiona a byte ma solo a int, mentre l'invio verso l'esp32 deve essere a byte quindi prima traduzione. L'esp ragiona a int ma spedendo (ho tanti esempi) traduzione in byte arrivato al telefono altra traduzione. Non riesco a dare un taglio preciso a tutto questo.

Forse l'unica che mi va abbastanza bene è la trasmissione dal telefono all'esp32, ma il contrario è disastroso.

hai sotto mano magari qualche esempio di trasmissione di questo tipo? magari non l'ho ancora provato.

Continuo anche se con poco entusiamo a fare qualche altra prova.

A presto

Purtroppo non ho alcun esempio.
La storia byte e int. L'int è, di solito, 2 byte ma dipende dall'architettura della MCU per questo c'è int16_t e uint16_t che sono sicuramente 2 byte.
L'altra seccatura e l'ordine dei byte nell'int (big endian e little endian) che dipende daccapo dall'architettura della MCU e a questo punto della CPU del telefono. Ad esempio se tu mandi il valore decimale 1500 questo va in 2 byte, 05 hex in uno e DC hex nell'altro. Il problema sorge su quale byte viene prima, quindi per alcuni va scritto 05 DC per altri CD 05.
Non sono sicuro però che qui il problema sia questo.

Tieni conto che parlando di audio le sorgenti di disturbo possono essere diverse per cui mi è venuto in mente di provare a trasmettere un'onda sinusoidale sintetica a 440Hz (o altra frequenza) e vedere se dall'altro lato ti arriva la nota giusta.
L'array con i dati te lo puoi generare qui
http://www.daycounter.com/Calculators/Sine-Generator-Calculator.phtml

Buongiorno, spero di non essere arrivato molto tardi.
Mi accodo in quanto anch'io vorrei prelevare un suono mediante un Microfono collegato in analogico al NodeMCU, spedirlo ad un Raspberry o PC e da li gestirlo.

Attualmente acquisisco il suono e lo spedisco via UDP.

Il microfono KY-038, collegato al NodeMCU mediante pin analogico "A0".

Lo Sketch su NodeMCU:

#include <ESP8266WiFi.h> // libreria per la gestione del wifi di ESP
#include <WiFiUdp.h> // libreria per utilizzare i moduli UDP

const char* ssid = "------"; // inserisci SSID della rete wifi a cui si collegherà NodeMCU
const char* password = "------"; // password della rete wifi a cui si collegherà NodeMCU

int contconexion = 0;

WiFiUDP Udp;

void setup()
{
  Serial.begin(115200);
  Serial.println();

  pinMode(5, OUTPUT);  //D1 Led de estado
  digitalWrite(15, LOW);

  WiFi.mode(WIFI_STA); //para que no inicie el SoftAP en el modo normal
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED and contconexion <50) { //Cuenta hasta 50 si no se puede conectar lo cancela
    ++contconexion;
    delay(250);
    Serial.print(".");
    digitalWrite(5, HIGH);
    delay(250);
    digitalWrite(5, LOW);
  }
  
}

void loop()
{
  //Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
  Udp.beginPacket("---.---.---.---", 1234); // indirizzo IP della macchina su cui sta il server

  for(int i=0; i<1024;i++){
    int old=micros();

    float analog = analogRead(17); 

    analog = ((analog / 1) - 385);
    if (analog > 255){
      analog = 255;
    }
    else if (analog < 0){
      analog = 0;
    }
    
    Udp.print(int(analog)); // mando i pacchetti mediante il canale UDP
    
    Serial.println(int(analog)); // visualizzo grafico audio in Plotter seriale

    while(micros()-old<124); // 90uSec = 1Sec/11111Hz - 3uSec para los otros procesos
  }
  Udp.endPacket();
  delay(5);
}

Il Server scritto in Python:

import pyaudio
import socket

UDP_IP = "---.---.---.---" # indirizzo IP della macchina su cui sta il server
UDP_PORT = 1234 # porta che rimane in ascolto

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind((UDP_IP, UDP_PORT))


p = pyaudio.PyAudio()

print("pyaudio: ", p)
stream = p.open(format=32, channels=1, rate=111111, output=True)

print("stream: ", stream)

try:
    while True:
        data, addr = sock.recvfrom(1024) # buffer de 1024 bytes
        print ("data: ", data)
        print ("addr: ", addr) 
        stream.write(data) # mi fa sentire l'audio negli altoparlanti
        
except KeyboardInterrupt:  #precionar Crtl + C para salir
    print("Cerrando...")
    stream.stop_stream()
    stream.close()
    p.terminate()

L'audio che riproduco dagli speaker del PC è completamente distorto e incomprensibile. Visualizzando il Plotter seriale, le oscillazioni si vedono bene.

Deduco possa essere un problema di acquisizione e spedizione pacchetti (visto che la lettura del canale analogico avviene (apparentemente) correttamente).