1

I'm trying to learn how to stream audio from the A0 pin of an ESP8266 NodeMCU board via UDP socket connection over to another windows computer that uses pyaudio to play it. At the moment, all I get on the windows computer are a series of "popping" sounds each spaced about half a second apart.

I'm new to working with these types of break out boards, so I found an online project that I'm using as a starting point:

Streaming audio from ESP8266 to pyaudio working in Arduino IDE

I figure I start troubleshooting my popping sound issue by inspecting the UDP packets my ESP8266 code. Below is the source code I'm working from:

#include <ESP8266WiFi.h>
#include <WiFiUdp.h>

const char* ssid = "change this";
const char* password = "change this";
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);
  }
  if (contconexion <50) {
      //para usar con ip fija
      IPAddress Ip(192,168,1,180); 
      IPAddress Gateway(192,168,0,1); 
      IPAddress Subnet(255,255,255,0); 
      WiFi.config(Ip, Gateway, Subnet); 

      Serial.println("");
      Serial.println("WiFi conectado");
      Serial.println(WiFi.localIP());
      //digitalWrite(5, HIGH);  
  }
  else { 
      Serial.println("");
      Serial.println("Error de conexion");
      //digitalWrite(15, LOW);
  }
}

void loop()
{
  Udp.beginPacket("192.168.0.26", 1234);

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

    float analog = analogRead(A0);
    if (analog > 255) {
      analog = 255;
    }
    else if (analog < 0){
      analog = 0;
    }
    Udp.write(int(analog));
    Serial.print(int(analog));
    Serial.print(",");
    while(micros()-old<87); // 90uSec = 1Sec/11111Hz - 3uSec para los otros procesos
  }
  Serial.print(";;;;;");
  Udp.endPacket();
  delay(5);
}

Notice near the bottom of the file, I print out each analog value separated by a comma, and each data packet separated by five semicolons.

Can someone suggest a way for me to re-construct these series of integers into a sound file that I can inspect via listening with my own ears? Then I can tell if the sound data being sent is complete? Or let me know if there's a better way to test if all the data packets are being sent correctly.

UPDATE

I tried to create a wav file by doing this:

  • Take the list of all integers from Serial.print(int(analog)) and paste it into a file. I make sure all integers are space delimited (ie. no more commas or semicolons)
  • I copied the file over to a linux machine that had ffmpeg installed
  • I ran the command ffmpeg -f u8 -ar 11111 -ac 1 -i myfileofintegers -y test.wav

When I listen to the test.wav file, I just hear a series of rapid popping noises. Not sure if I created the wav file properly?

5
  • 1
    You could convert it to the .wav file format. The simplest file format available. Feb 7, 2019 at 15:31
  • I just updated my question to show my attempt at making a wav file. Did I do it correctly? I hear more popping noises.
    – John
    Feb 7, 2019 at 15:58
  • 1) convert what to wav? 2) prints take time 3) what is wired to A0? 4) range of analogRead is 10 bit. you cut the input to 255
    – Juraj
    Feb 7, 2019 at 16:43
  • @Juraj To answer you questions 1) I'd like to convert the list of integers given by Serial.print(int(analog)) to a wav file. 3) A0 receives the output voltage of a pre-amplified electret microphone. The voltage amplitude seems to range between 0mv and 300mv.
    – John
    Feb 7, 2019 at 17:15
  • I gather because I was following the same guide. Unfortunately I do not receive any quality sound but only small pulses, the microphone that uses in the video is made by him, I have used two different types of microphones: KY-038 and / or MAX4466 with the same result. My need is to receive audio, send it to UDP and save it in WAV. Can someone help us?
    – Alessandro
    Mar 7, 2019 at 18:25

1 Answer 1

1

I'm trying to learn how to stream audio from the A0 pin of an ESP8266 NodeMCU board via UDP socket connection over to another windows computer that uses pyaudio to play it.

You have described several problems; one needs to break big problems into small problems:

  1. Sample the audio
  2. Send it to another computer
  3. Decode and playback the sound

At the moment, all I get on the windows computer are a series of "popping" sounds each spaced about half a second apart.

This sounds like you have got your timebases messed up; it is likely that you aren't recording enough data or playing it back incorrectly. N.b. it looks like you are recording ~92ms of audio data each 'packet' and if you get a series of pops at 2hz you are likely playing less than 1/10 of a second of audio for ever 5/10 of time, so your speaker moves for 1/10th of a second then stays still for 4/10ths and repeats; this produces your 2hz popping noises.

Your code has some other problems as well:

  • Serial.print() is Slow! Don't use it where performance matters!
  • Intertwining sampling and sending
  • Incorrectly scaling the analog reading
  • 11.1khz can only record signals up to 5.5khz

Lets start with the audio sampling. We have some sort of audio circuitry presenting a signal to an analog input, we need to sample it regularly and uniformly! The code presented is trying to sample at 11.1 kHz, but only does so for 1024 samples before hitting a discontinuity. We do not have circuitry dedicated to this so we will have to use the ADC circuitry on the Arduino.

First thing you will want to get you sampling regular and continuous. You will want to use an interrupt on the Arduino for this. The interrupt should take a single sample from the ADC and add it to a buffer or signal the main loop to read/buffer it.

This interrupt will need to fire regularly at the sample rate or the data will be ruined.

Second the audio circuitry should prepare the signal so that it is between 0-5v with a ~2.5v bias, this will use the ADC hardware to its fullest.

so in Pseudo code:

// include any libs etc.
// set up variables ect.
void interupt_sample();
// register and attach interrupt
void setup() { 
//do your setup etc. 
}
void loop() {
// if(new_sample) add_to_buffer(new_sample);
// if(buffer_full) send_and_flush_buffer();
}
1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.