Go Down

Topic: ARDUINO E VOCE (Read 2412 times) previous topic - next topic

magpa

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

zoomx

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

alessandro87gatto

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:

Code: [Select]


#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:

Code: [Select]


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).




zoomx

Intanto stai usando un microfono un po' sordo in quanto pensato per accendere e spegnere qualcosa con un battito di mani.

Poi fai un clipping feroce qui
Code: [Select]
    analog = ((analog / 1) - 385);
    if (analog > 255){
      analog = 255;
    }
    else if (analog < 0){
      analog = 0;
    }


Dovresti prendere un microfono con un MAX, dalla Cina costa poco più di quello che stai usando.

Potrebbe essere che al prosto di UDP.print dovresti usare UDP.write perché mi sa che print te lo stampa in ascii.

Non ho capito poi questo pezzo di codice
Code: [Select]
(analog / 1)

alessandro87gatto

Grazie per la risposta.

cosa intendi per Clipping feroce?

Per il microfono potrei procurare altro anche se avrei una certa fretta quindi chissà se lo riuscirò a trovare in italia. Ma ti riferisci a qualcosa simile a: MAX4466.
Io ho preso l'idea dal video youtube: Proyecto #1 ESP8266 - Micrófono Espía, Audio Streaming por UDP

https://www.youtube.com/watch?v=1dA81w7C4kg

Credo utilizzi un sistema microfonico simile anche se la scheda la costruisce lui.

Come potrei impacchettare l'audio? Nel senso, dal video spedisce lo streaming, io invece vorrei campionare a 4000 hz quindi per Nyquist dovrei avere il doppio ovvero 8000 valori. Ho pensato che (1/8000)*1000=0,125 millisecondi ovvero ogni 0,125 millisecondi dovrei leggere 8000 valori, metterli in un vettore e sparare l'intero vettore in UDP. E' corretto il ragionamento?

alessandro87gatto

Ho testato, con:

Code: [Select]
Udp.print(int(analog));

o

Code: [Select]
Udp.write(int(analog));

la situazione a livello di audio non cambia, cambia solo l'output nel Monitor seriale che come dicevi tu giustamente, visualizza piuttosto che numeri, codici ascii.

Ho ordinato i microfoni da te consigliati (MAX) e di preciso MAX9814 e MAX4466, li ho presi entrambi anche se credo che nel mio caso dovrebbero svolgere la medesima funzione.

Nel frattempo che arrivino (ordinati in Italia per accorciare i tempi) vorrei andare avanti e magari creare i buffer e spedire i buffer via UDP piuttosto che a casaccio quello che passa passa.

NOTA. Strano che nel video passa bene l'audio, il circuito sembra uguale.

zoomx

Ho visto il video.
Intanto nello sketch c'è
Code: [Select]
Udp.write(int(analog));
come dicevo io.
Poi il circuiti del microfono è diverso, non usa quella schedina rossa, l'ho usata anche io e non va bene.

Per quanto riguarda il clipping. L'ESP8266 campiona a 10 bit, quindi valori da 0 a 1023. Lo sketch divide il valore per 1, forse prima era qualcosa di diverso ma adesso dividere per 1 non serve.
Quindi sottrae un valore fisso che probabilmente corrisponde alla media dei valori che escono fuori dal convertitore se non c'è alcun segnale.
Poi, se il valore è maggiore di 255 lo tronca a 255.
Infine controlla se con la sottrazione non è andato sotto zero, se si lo porta daccapo a zero.

Il motivo per cui non usa 2 byte è dovuto al fatto che con 2 byte le cose si complicano perché dall'altra parte nel flusso quando prendi 2 byte non sai se appartengono allo stesso campione oppure a due campioni consecutivi. Devi usare un protocollo oppure trasmettere una coppia di byte ogni tanto che servono per sincronizzare i flussi (con UDP i pacchetti possono andare persi e non si ha correzione).

I microfoni che hai preso vanno bene, sono anche quelli che ho usato io. Forse prenderai un po' di rumore lo stesso perché ci sono un sacco di interferenze. Mentre il microfono con la scheda rossa ti fornisce zero se non c'è segnale questi col MAX lavorano come il circuito del video, ti forniranno un valore intorno a 512. Questo perché il convertitore funziona solo con tensioni positive mentre il microfono ne fornisce negative. Quella rossa credo che le elimini, quella con MAX invece somma una tensione positiva in moto da avere sempre valori positivi. Non so se mi son spiegato bene.

Non ho ancora ascoltato il video.

alessandro87gatto

Grazie
Quote
zoomx
.

Forse mi manca qualche parte, ma non capisco cosa intendi:
Quote
Il motivo per cui non usa 2 byte è dovuto al fatto che con 2 byte le cose si complicano perché dall'altra parte nel flusso quando prendi 2 byte non sai se appartengono allo stesso campione oppure a due campioni consecutivi. Devi usare un protocollo oppure trasmettere una coppia di byte ogni tanto che servono per sincronizzare i flussi (con UDP i pacchetti possono andare persi e non si ha correzione).
Per il discorso del microfono, si infatti mi sembrava strano che lo aveva costruito lui uguale a quello o che quello potesse andar bene, anche perché il codice è molto semplice figurati.

Rimane, lasciando stare il microfono che è stato spedito oggi, il problema di come dovrei passare queste tracce al pc o Raspberry. Io mi vorrei trovare sul pc o Raspberry una traccia wav ad esempio ogni 10 secondi o più di acquisizione.

Pensavo di fare due vettori, ne riempivo uno e lo sparavo, mentre lo sparavo, ne riempivo un altro, in modo ciclico. Tipo swap. Ma non saprei come fare. Penso che lavorando su wav potrei riuscire.

Come avevo scritto:
Quote
Ho pensato che (1/8000)*1000=0,125 millisecondi ovvero ogni 0,125 millisecondi dovrei leggere 8000 valori, metterli in un vettore e sparare l'intero vettore in UDP. E' corretto il ragionamento?
dovrei prendere e riempire il vettore con 8000 celle ogni 0,125 millisecondi.. ehmmm..

zoomx

Il convertitore è a 10 bit per cui avrai valori tra zero e 1023. Poiché in un byte al massimo puoi avere 256 valori (0-255) il risultato del convertitore va messo in 2 byte, i primi 8 in uno e i restanti 2 nell'altro. L'altro quindi avrà solo 2 bit, valori da 0 a 3.
Ora quando trasmetti in UDP può capitare che qualche byte vada perso.
Dall'altro lato, quando ricevi un byte, non puoi sapere se questo contiene i primi 8 o i restanti 2. Diciamo che se contiene valori superiori a 3 allora si tratta dei primi 8 ma non ne puoi essere sicuro.

Puoi fare anche un'altra cosa in attesa del microfono: mandare dei dati artificiali e vedere come arrivano dall'altra parte.
Pr esempio puoi trasmettere ques'onda sinusoidale (a 8 bit!)
Code: [Select]
uint8_t  sine_wave[256] = {
  0x80, 0x83, 0x86, 0x89, 0x8C, 0x90, 0x93, 0x96,
  0x99, 0x9C, 0x9F, 0xA2, 0xA5, 0xA8, 0xAB, 0xAE,
  0xB1, 0xB3, 0xB6, 0xB9, 0xBC, 0xBF, 0xC1, 0xC4,
  0xC7, 0xC9, 0xCC, 0xCE, 0xD1, 0xD3, 0xD5, 0xD8,
  0xDA, 0xDC, 0xDE, 0xE0, 0xE2, 0xE4, 0xE6, 0xE8,
  0xEA, 0xEB, 0xED, 0xEF, 0xF0, 0xF1, 0xF3, 0xF4,
  0xF5, 0xF6, 0xF8, 0xF9, 0xFA, 0xFA, 0xFB, 0xFC,
  0xFD, 0xFD, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0xFE, 0xFD,
  0xFD, 0xFC, 0xFB, 0xFA, 0xFA, 0xF9, 0xF8, 0xF6,
  0xF5, 0xF4, 0xF3, 0xF1, 0xF0, 0xEF, 0xED, 0xEB,
  0xEA, 0xE8, 0xE6, 0xE4, 0xE2, 0xE0, 0xDE, 0xDC,
  0xDA, 0xD8, 0xD5, 0xD3, 0xD1, 0xCE, 0xCC, 0xC9,
  0xC7, 0xC4, 0xC1, 0xBF, 0xBC, 0xB9, 0xB6, 0xB3,
  0xB1, 0xAE, 0xAB, 0xA8, 0xA5, 0xA2, 0x9F, 0x9C,
  0x99, 0x96, 0x93, 0x90, 0x8C, 0x89, 0x86, 0x83,
  0x80, 0x7D, 0x7A, 0x77, 0x74, 0x70, 0x6D, 0x6A,
  0x67, 0x64, 0x61, 0x5E, 0x5B, 0x58, 0x55, 0x52,
  0x4F, 0x4D, 0x4A, 0x47, 0x44, 0x41, 0x3F, 0x3C,
  0x39, 0x37, 0x34, 0x32, 0x2F, 0x2D, 0x2B, 0x28,
  0x26, 0x24, 0x22, 0x20, 0x1E, 0x1C, 0x1A, 0x18,
  0x16, 0x15, 0x13, 0x11, 0x10, 0x0F, 0x0D, 0x0C,
  0x0B, 0x0A, 0x08, 0x07, 0x06, 0x06, 0x05, 0x04,
  0x03, 0x03, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01,
  0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x03,
  0x03, 0x04, 0x05, 0x06, 0x06, 0x07, 0x08, 0x0A,
  0x0B, 0x0C, 0x0D, 0x0F, 0x10, 0x11, 0x13, 0x15,
  0x16, 0x18, 0x1A, 0x1C, 0x1E, 0x20, 0x22, 0x24,
  0x26, 0x28, 0x2B, 0x2D, 0x2F, 0x32, 0x34, 0x37,
  0x39, 0x3C, 0x3F, 0x41, 0x44, 0x47, 0x4A, 0x4D,
  0x4F, 0x52, 0x55, 0x58, 0x5B, 0x5E, 0x61, 0x64,
  0x67, 0x6A, 0x6D, 0x70, 0x74, 0x77, 0x7A, 0x7D
};


usando qualcosa del genere
Code: [Select]
 for (int i = 0; i <= 255; i++) {
    UDP.write(sine_wave[i]);
  }

alessandro87gatto

Ho appena ricevuto il microfono MAX esattamente il modello:

Quote
Max4466 Amplificatore Microfono Voice module Microphone Audio Amplifier Arduino
inserzione baia:

Quote
113225058600
Ho compilato nuovamente lo sketch, avviato il server ma la situazione non cambia. Il microfono funziona in quanto: sia il Monitor Seriale che il Plotter Seriale, stampano valori e onde; come con il microfono "scheda rossa". Ho provato a ruotare il potenziometro senza alcuna emissione di segnale sonoro, solo segnale distorto come se passasse qualcosa ad intervalli irregolari tipo piezoelettrico.

Non mi resta che aspettare l'altro microfono che ho ordinato:

Quote
MAX9814 AMPLIFICATORE MICROFONO sensore suono audio ARDUINO MODULO
inserzione baia:

Quote
254004249876

alessandro87gatto

#40
Mar 07, 2019, 06:39 pm Last Edit: Mar 07, 2019, 06:52 pm by alessandro87gatto
Il convertitore è a 10 bit per cui avrai valori tra zero e 1023. Poiché in un byte al massimo puoi avere 256 valori (0-255) il risultato del convertitore va messo in 2 byte, i primi 8 in uno e i restanti 2 nell'altro. L'altro quindi avrà solo 2 bit, valori da 0 a 3.
Ora quando trasmetti in UDP può capitare che qualche byte vada perso.
Dall'altro lato, quando ricevi un byte, non puoi sapere se questo contiene i primi 8 o i restanti 2. Diciamo che se contiene valori superiori a 3 allora si tratta dei primi 8 ma non ne puoi essere sicuro.

Puoi fare anche un'altra cosa in attesa del microfono: mandare dei dati artificiali e vedere come arrivano dall'altra parte.
Pr esempio puoi trasmettere ques'onda sinusoidale (a 8 bit!)
Code: [Select]
uint8_t  sine_wave[256] = {
  0x80, 0x83, 0x86, 0x89, 0x8C, 0x90, 0x93, 0x96,
  0x99, 0x9C, 0x9F, 0xA2, 0xA5, 0xA8, 0xAB, 0xAE,
  0xB1, 0xB3, 0xB6, 0xB9, 0xBC, 0xBF, 0xC1, 0xC4,
  0xC7, 0xC9, 0xCC, 0xCE, 0xD1, 0xD3, 0xD5, 0xD8,
  0xDA, 0xDC, 0xDE, 0xE0, 0xE2, 0xE4, 0xE6, 0xE8,
  0xEA, 0xEB, 0xED, 0xEF, 0xF0, 0xF1, 0xF3, 0xF4,
  0xF5, 0xF6, 0xF8, 0xF9, 0xFA, 0xFA, 0xFB, 0xFC,
  0xFD, 0xFD, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0xFE, 0xFD,
  0xFD, 0xFC, 0xFB, 0xFA, 0xFA, 0xF9, 0xF8, 0xF6,
  0xF5, 0xF4, 0xF3, 0xF1, 0xF0, 0xEF, 0xED, 0xEB,
  0xEA, 0xE8, 0xE6, 0xE4, 0xE2, 0xE0, 0xDE, 0xDC,
  0xDA, 0xD8, 0xD5, 0xD3, 0xD1, 0xCE, 0xCC, 0xC9,
  0xC7, 0xC4, 0xC1, 0xBF, 0xBC, 0xB9, 0xB6, 0xB3,
  0xB1, 0xAE, 0xAB, 0xA8, 0xA5, 0xA2, 0x9F, 0x9C,
  0x99, 0x96, 0x93, 0x90, 0x8C, 0x89, 0x86, 0x83,
  0x80, 0x7D, 0x7A, 0x77, 0x74, 0x70, 0x6D, 0x6A,
  0x67, 0x64, 0x61, 0x5E, 0x5B, 0x58, 0x55, 0x52,
  0x4F, 0x4D, 0x4A, 0x47, 0x44, 0x41, 0x3F, 0x3C,
  0x39, 0x37, 0x34, 0x32, 0x2F, 0x2D, 0x2B, 0x28,
  0x26, 0x24, 0x22, 0x20, 0x1E, 0x1C, 0x1A, 0x18,
  0x16, 0x15, 0x13, 0x11, 0x10, 0x0F, 0x0D, 0x0C,
  0x0B, 0x0A, 0x08, 0x07, 0x06, 0x06, 0x05, 0x04,
  0x03, 0x03, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01,
  0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x03,
  0x03, 0x04, 0x05, 0x06, 0x06, 0x07, 0x08, 0x0A,
  0x0B, 0x0C, 0x0D, 0x0F, 0x10, 0x11, 0x13, 0x15,
  0x16, 0x18, 0x1A, 0x1C, 0x1E, 0x20, 0x22, 0x24,
  0x26, 0x28, 0x2B, 0x2D, 0x2F, 0x32, 0x34, 0x37,
  0x39, 0x3C, 0x3F, 0x41, 0x44, 0x47, 0x4A, 0x4D,
  0x4F, 0x52, 0x55, 0x58, 0x5B, 0x5E, 0x61, 0x64,
  0x67, 0x6A, 0x6D, 0x70, 0x74, 0x77, 0x7A, 0x7D
};


usando qualcosa del genere
Code: [Select]
  for (int i = 0; i <= 255; i++) {
    UDP.write(sine_wave[i]);
  }

Ho fatto quello che mi hai consigliato, ho creato il codice (lato client):

Code: [Select]

#include <ESP8266WiFi.h> // Libreria per inviare e ricevere dati in WiFi con ESP8266
#include <WiFiUdp.h> // Libreria per la gestione di Client-Server UDP in WiFi

const char* ssid = "nome_rete_wifi";
const char* password = "password_rete_wifi";

int contconexion = 0;

WiFiUDP Udp;

uint8_t  sine_wave[256] = {
  0x80, 0x83, 0x86, 0x89, 0x8C, 0x90, 0x93, 0x96,
  0x99, 0x9C, 0x9F, 0xA2, 0xA5, 0xA8, 0xAB, 0xAE,
  0xB1, 0xB3, 0xB6, 0xB9, 0xBC, 0xBF, 0xC1, 0xC4,
  0xC7, 0xC9, 0xCC, 0xCE, 0xD1, 0xD3, 0xD5, 0xD8,
  0xDA, 0xDC, 0xDE, 0xE0, 0xE2, 0xE4, 0xE6, 0xE8,
  0xEA, 0xEB, 0xED, 0xEF, 0xF0, 0xF1, 0xF3, 0xF4,
  0xF5, 0xF6, 0xF8, 0xF9, 0xFA, 0xFA, 0xFB, 0xFC,
  0xFD, 0xFD, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0xFE, 0xFD,
  0xFD, 0xFC, 0xFB, 0xFA, 0xFA, 0xF9, 0xF8, 0xF6,
  0xF5, 0xF4, 0xF3, 0xF1, 0xF0, 0xEF, 0xED, 0xEB,
  0xEA, 0xE8, 0xE6, 0xE4, 0xE2, 0xE0, 0xDE, 0xDC,
  0xDA, 0xD8, 0xD5, 0xD3, 0xD1, 0xCE, 0xCC, 0xC9,
  0xC7, 0xC4, 0xC1, 0xBF, 0xBC, 0xB9, 0xB6, 0xB3,
  0xB1, 0xAE, 0xAB, 0xA8, 0xA5, 0xA2, 0x9F, 0x9C,
  0x99, 0x96, 0x93, 0x90, 0x8C, 0x89, 0x86, 0x83,
  0x80, 0x7D, 0x7A, 0x77, 0x74, 0x70, 0x6D, 0x6A,
  0x67, 0x64, 0x61, 0x5E, 0x5B, 0x58, 0x55, 0x52,
  0x4F, 0x4D, 0x4A, 0x47, 0x44, 0x41, 0x3F, 0x3C,
  0x39, 0x37, 0x34, 0x32, 0x2F, 0x2D, 0x2B, 0x28,
  0x26, 0x24, 0x22, 0x20, 0x1E, 0x1C, 0x1A, 0x18,
  0x16, 0x15, 0x13, 0x11, 0x10, 0x0F, 0x0D, 0x0C,
  0x0B, 0x0A, 0x08, 0x07, 0x06, 0x06, 0x05, 0x04,
  0x03, 0x03, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01,
  0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x03,
  0x03, 0x04, 0x05, 0x06, 0x06, 0x07, 0x08, 0x0A,
  0x0B, 0x0C, 0x0D, 0x0F, 0x10, 0x11, 0x13, 0x15,
  0x16, 0x18, 0x1A, 0x1C, 0x1E, 0x20, 0x22, 0x24,
  0x26, 0x28, 0x2B, 0x2D, 0x2F, 0x32, 0x34, 0x37,
  0x39, 0x3C, 0x3F, 0x41, 0x44, 0x47, 0x4A, 0x4D,
  0x4F, 0x52, 0x55, 0x58, 0x5B, 0x5E, 0x61, 0x64,
  0x67, 0x6A, 0x6D, 0x70, 0x74, 0x77, 0x7A, 0x7D
};


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

  pinMode(5, OUTPUT);  //D1 Led di stato
  digitalWrite(15, LOW);

  WiFi.mode(WIFI_STA); // avvio SoftAP (access point abilitato al software) in modalità normale
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED and contconexion <50) { // Conteggio fino a 50, se non riesce cancella la connessione
    ++contconexion;
    delay(250);
    Serial.print(".");
    digitalWrite(5, HIGH);
    delay(250);
    digitalWrite(5, LOW);

  } // fine while()
 
} // fine setup()

void loop()
{
  Serial.println("sono nel loop \n"); // per capire se entro nel loop - solo di test
  Udp.beginPacket("ip_rete_wifi", 1234);
  Serial.println("\nsono dentro"); // per capire se entro nel loop - solo di test

  for (int i = 0; i <= 255; i++) {
    Udp.write(sine_wave[i]);
  }

  Udp.endPacket();
  delay(2000); // secondi, 2 secondi
} // fine loop()


Ho creato il codice (lato server):

Code: [Select]

import pyaudio
import socket

UDP_IP = "ip_rete_wifi"
UDP_PORT = 1234

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

print("IP e': ", UDP_IP)
print("Porta e': ", 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 ("--------------------------\n")
        print ("data: ", data)
        print ("\n")
        print ("addr: ", addr)
        print ("\n")
        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()


Avvio il server dal terminale:
Quote
python nome_file_server.py
L'output è:

Quote
data:  b'\x80\x83\x86\x89\x8c\x90\x93\x96\x99\x9c\x9f\xa2\xa5\xa8\xab\xae\xb1\xb3\xb6\xb9\xbc\xbf\xc1\xc4\xc7\xc9\xcc\xce\xd1\xd3\xd5\xd8\xda\xdc\xde\xe0\xe2\xe4\xe6\xe8\xea\xeb\xed\xef\xf0\xf1\xf3\xf4\xf5\xf6\xf8\xf9\xfa\xfa\xfb\xfc\xfd\xfd\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfd\xfd\xfc\xfb\xfa\xfa\xf9\xf8\xf6\xf5\xf4\xf3\xf1\xf0\xef\xed\xeb\xea\xe8\xe6\xe4\xe2\xe0\xde\xdc\xda\xd8\xd5\xd3\xd1\xce\xcc\xc9\xc7\xc4\xc1\xbf\xbc\xb9\xb6\xb3\xb1\xae\xab\xa8\xa5\xa2\x9f\x9c\x99\x96\x93\x90\x8c\x89\x86\x83\x80}zwtpmjgda^[XUROMJGDA?<9742/-+(&$" \x1e\x1c\x1a\x18\x16\x15\x13\x11\x10\x0f\r\x0c\x0b\n\x08\x07\x06\x06\x05\x04\x03\x03\x02\x02\x02\x01\x01\x01\x01\x01\x01\x01\x02\x02\x02\x03\x03\x04\x05\x06\x06\x07\x08\n\x0b\x0c\r\x0f\x10\x11\x13\x15\x16\x18\x1a\x1c\x1e "$&(+-/2479<?ADGJMORUX[^adgjmptwz}'
Ad ogni iterazione l'output giustamente è uguale. Testato anche con altre reti internet (velocità diverse), l'output non cambia.

zoomx

A me sembra che i valori non arrivino correttamente oppure non sono gestiti correttamente dal python
x80}zwtpmjgda^[XUROMJGDA?<9742/-+(&$"

alessandro87gatto

Si effettivamente se quello che mando dovrebbe arrivare con lo stesso ordine, non arrivano con lo stesso ordine. Ma le varie iterazioni, anche da connessioni diverse, quindi più o meno veloci, danno lo stesso output. Deduco che forse è il lato server che non gestisce bene quello che riceve.

Per venirne a capo, quale potrebbe essere il modo corretto per far ascoltare l'audio ambientale al microfono, spedirlo al server che applicherà la fft (o gliela faccio processare al NodeMCU) e confrontare tale audio ricevuto con i suoni presenti sul server? Confrontarli per fare un riconoscimento (stile Shazam)


zoomx

#43
Mar 08, 2019, 12:09 pm Last Edit: Mar 08, 2019, 12:13 pm by zoomx
Io ancora il python non l'ho studiato, mi ha bloccato il fatto che fa la 2.x e 3.x ci siano incomprensioni profonde (già a livello di print). Ma è diventato molto di moda anche nel mondo della ricerca.

Prova magari con queta app per Win10 o qualcosa di simile per altri sistemi operativi, giusto per vedere se il problema è chi trasmette o chi riceve, c'è sempre la possibilità che sia l'ESP8266 a trasmettere male.
https://www.microsoft.com/en-us/p/udp-sender-reciever/9nblggh52bt0?activetab=pivot:overviewtab

La risposta al tuo ultimo quesito credo dipenda dalla complessità del segnale da riconoscere. PEr segnali semplici esistono persino semplici progettini per Arduino(!) di riconoscimento vocale (ancora mai provati) ma se devi andare sul complesso credo che il segnale audio debba essere di buona qualità.
Per cui io intanto partirei da un RaspberryPI con scheda audio USB e poi valuterei se fosse possibile scendere a qualcosa di meno complesso.

Edit:Accidenti volevo provare l'app ma è per telefoni!
Edit2: Sembra che vada pene anche per PC.
Edit3: forse questa è meglio https://packetsender.com/

alessandro87gatto

Grazie per i consigli e sincerità
Quote
zoomx
Comunque acquisizione e salvataggio con raspberry e OS X mediante microfono usb la faccio tranquillamente..contavo di utilizzare NodeMCU per una questione di spazio e prezzo. Chissà se mai riuscirò..esempio con raspberry potrebbe essere una buona idea quella di acquisire, processare e creare un db con "mongo db". Almeno questo mi hanno consigliato. Qualcuno lo ha usato o lo usa?

Go Up