Espruino Wifi and SPW2430(microphone)

Posted on
  • I have a problem with the SPW2430(microphone) only returning feedback to the Espruino Wifi. I have the DC pin of the SPW2430 attached to B0 of the Espruino Wifi and the correct GND pin. Ive utilized all links provided by espruino and arduino for audio recording using this hardware and its seems it should work. In the code i am using the waveform class, should i be using PWM? The intent is to record audio from the SPW2430 onto the espruino and output it to a small headphone attached to the correct pins on the espruino. The headphone was tested and works but im still having trouble with the audio recording. Any suggestions?

  • What you're doing sounds fine - and you've got the microphone powered from 3.3v as well? It sounds like the microphone won't output the complete 3.3v voltage range, but that's not a big deal - sound will just be maybe half as loud as it could be (and you can fix that in software afterwards by just multiplying the array up).

    The Waveform class is definitely what you want - PWM is only for output.

    The following code:

    var w = new Waveform(128);
    w.on("finish", function(buf) {
      for (var i in buf)
        console.log(buf[i]);
    });
    w.startInput(B0,2000,{repeat:false});
    

    Should record something... Could you try running it while there is some sound for the microphone to record, and then see if any nonzero values get printed out?

  • @Gordon Thanks for the quick response!

    We are getting a nonzero range in the IDE, the bias from the DC pin on microphone is reading an output of 0.75v(according the hardware doc it should read 0.67v on 3.3v) I have it connected to the USBV of the espruino(could this be the problem?) it is being supplied 4.88v. Say we take this output and write it to a .raw file on an SD card(already setup with e.connectSDcard and correct pinout). How will I then get it to output the voice recording through the small two wire headphone also connected to the Espruino Wifi, Is this were I would utilize PWM?(the hardware speaker was checked for functionality using the buzzer from the making sounds and music tutorial provided by espruino and functions properly)

    Hardware Link: https://www.adafruit.com/product/2716

  • Update: We are using PWM to output to the speaker attached to the espruino wifi, We are trying to play files we know work that we externally put on the attached SD card, we are only receiving fluctuating frequency. We have tried changing sample rate in the waveform class as well as the frequency of the analogWrite and w.startOutput functions cant find to get one to work but it does have an effect on the audio being output through the speaker.

  • Ok - so you think recording may be working now, but it's the playback that isn't?

    Yes, on the WiFi you'd use PWM for output (it's only the original espruino board that has a DAC inside it).

    Where is your speaker wired? Try this on your WiFi. I have the speaker wired between GND and B3, and it seems to work fine - it plays a 'ding' noise (which is uploaded in the base64 code).

    var wave = atob("e357fnp/eoB4g3hxknV4gW2OgWOXe22FhW­OQgW2CgnGJgWmJgWqMgGyIgG2JgmqJgGqNgmmKgG­mMgGqOf2iNgGmNgGmNgWmOgWiNgWiNgWiMgmiMgm­eMgmaNgWiNgmiNgWqLgmuKgWyHgmyHgG6FgmyIgG­yKf2yKf22JgG2JgG6HgHCIfm+IfnGGf3GGfnGGgH­GFf3KEgHGGf3KEf3KEfnSDf3SDfnaBf3WCfXiAfn­aCfHl+gHaCe3t7g3CSjWJ7gHuKhnx9bHx9jXt5dX­GGhX18cHh+in16d3GDhX1/cXl9hoB6d3OAhX6Acn­p7hoB9dnZ7iHuFa46JY4F4gYOBhnljfnaOhHhtdI­R+kXZpgHOKjHdvdn2BkXhsfm+Jj3Z2c3iCkXtuf2­uHkXZ8c3GDjn5yfWmEk3WBc22Ei4B1e2mBkneCdW­uEiYJ5emx/k3iDdmqGhoJ8dm1+kXqEdmeIg4GBcm­5+jXyGdmaJgoCFb25+in+Hd2WJgICJa26AhoKIeG­WIf36NaW2BgoWKd2eHfX2OaWyCfoiLeGmFfXuOam­qEeYuKgG98f4CVZ2SDgIWKeXZ/dnqVa2KCfYeKeH­l+dnqUcGOAfIiLdnx8d3ePemN7eIiOd358dXqPem­l1fIOdeXB/f4eDcmmBbn6RhHpsdo6GdW59c32Qhn­5scY+Hd3B5dXuMhoNtbY6HeXN3dnqJhoZvao2Ien­Z0eHqGh4hxZ4qIfXhxeHmCiYpzZYeIf3tveXl+io­x2ZIGIgX5uenl6iox6ZXuHhIBuenl2i4x9aHaGh4­JueXpzi4x9bHGDiYRueXpxiox/cG2BjIVweXpwiY­yAdGh+joVyeHpwiIuBeGV7kIZ0eHhwhYqDfGN2kY­Z3eHdxg4mEgWJxkYd7eHVygYeFhGNtkYd+enJzgI­WHh2Rpj4eCe290foSIiWVljoeFfW11fYGJimhji4­iGf2t2fX+Ji2xhiIiIgml2fX2JjG9gg4mJhGl1fn­uIjHJhf4mJhml0f3mIi3VjeoiLh2p0f3iHinhmdo­iMh2xzgHeGiXprcoaMiG1zgHeEiHtvcIKNiG9ygH­eDiHt0bn6OiXFygHaBh3x4bnuNiXRygHZ/hnx7cH­eMiXZyf3h9hnx+cXSLiXhxf3l7hX2AdHGIinpxfn­t5hH2AeHCFin1xfH14g32Be2+CiX9yen93gX6Bfm­9/iIFzd4B3gH+AgXB8h4F1doF3foB/hHF5h4F2dY­B5fIB/h3R1hoF4dX96e39+indyhYF5dn16en9+i3­pvhIB6eHp7en5+jH5sgoB6end6en5+joFrgIB6fX­V5e3x/joVqfoF5f3J3fHx/j4hpe4F6gnF0fXuAj4­prd4F6hHFxfnuAj4xtdIF5hXJuf3qBj4xwcn97h3­Nrf3qBkI1zcH17iHRpf3mBkI12b3p8iXZofnmBko­16bnZ8iXhmfXmAkox9b3J7inpme3mAk4x/cG96in­xmeXl/lIyBc2x4in9ndnh+lY2DdGl3iYFoc3h9lI­6Fd2d1iINrcHl8k4+GeWZzhoVtbXh8kpCHfGdwhI­Vxa3d9j5KIfmhugYZ1aXZ9jZOJf2ltf4V4aHR+i5­OLgWxrfIR7aXJ/iJOMgm5peYN+anB/hpKOhHJodo­KAbG5/hZGPhXZndIGBb2x9g5CPhnlncYCCc2t7go­+Qh31obX+Cdmx4gI6Qh4Fpa36BeW12f4yQiIRqaH­2BfG5zfouQiIdtZXuAfnBxfYmQiIlwZHp/gHNue4­iQiYp0Y3h+gnZseoaPiop3Y3Z8gnpreYWNi4p6ZX­N7gn1qeIOLjYp9Z3F6g4Bpd4OIjop+am94g4NqdY­KFj4p/bW12goVrc4KDkIp/cWx0godscoGAkIt/dW­xygolvcIB+kI1+eGxwgYpxbn99j45+em1ugYp0bX­19jpB9fG5tgYp2bHt8jZB9fHBsgIp5bHh8jJF9fX­JsgIl8bHV9i5F9fHNsgIh9bnJ8ipF+fHVtgId/b2­98iZB/fHZtf4aAcmx7iY+Ae3huf4aBdGp5iY+Ben­lvfoWBd2l3iI6DeXpwfoWBeWh1ho2FeHpxfYaCe2­hzhYyHeHpze4eCfWlwhIuJeHl1eYeDfmpugoqLeH­d3d4eFfmxsgImNeXV5doaGf29qfYiOe3R7doWHf3­Fpe4aOfnN8doOIgHRpeIWNgHN8d4CIgHdqdoSLg3­R7eH6HgHpsc4OKhHV7eXyGgHxucIKIhXh6enuEgH­9xbYCGhnt5e3uDgIB0a3+EhX54e3uBf4J3an2DhI­J4e3t/f4N6anuCg4V5e3t8foN9a3iBgYd6e3x6fY­OAbHaAgIl7e314fIKCb3R+f4p9en53e4KDcnJ8fo­p/en91e4GDdnF6fYqAe4B0eYGCeXF4fYmCe4F0eI­GBfXJ1fImDfIJ0doGAgHRze4iEfIN0dIB+gndxeo­eFfYN1coB9g3pveYaFfoN2cYB8g31veIWGf4N4cH­58goBud4SGgIJ5b318goJvdYSHgYF7b3t8gYRxdI­OHgoB7cHp8f4Vzc4GHg398cXh8foV1c4CGhH98c3­d8fYV3c3+GhX98dHZ7fIV5c36FhX98dnZ6fIR7c3­2Ehn98d3V6e4N9dHyDhoB7eHV5eoJ/dXyDhoF7eH­Z5eYCBdnuChYJ7eXZ5eX+Cd3uChIN7eHd4eH6DeH­qCg4R7eHd4eHyDenmCg4R8d3h3eHuDfHiCgoR9dn­l3eHqCfniBgoR/dnl3eHqBf3mBgYSAdXl4d3qAgH­mAgYOCdXl4dnp/gXp/gIODdXl5dXp+gnx+gIKEdn­h6dHp9gn19f4GFd3h6dHp9gn98foGGeXd7c3p9gY­B8foCGe3Z7c3l9gIJ7fYCGfXZ7c3l+gIN7fH+Gf3­Z6dHh+f4R8en+FgHZ5dHd+f4R8en6Egnd4dXd+fo­R9eX6DhHh4dXZ+foR+eX2DhHl3dnZ+foN/eHyChX­t2d3V+foKBeHyBhXx2d3V9f4KCeHqAhX52d3V8f4­GDeXl/hYB2d3V8gH+Denh+hIF3d3V7gH+DfHd+g4­J4d3V6gX6DfXZ9goN6d3Z5gX6CfnV8goN7d3Z4gX­+CgHV7gYN9dnd4gH+BgXV6gIN/d3d4f3+AgnZ5f4­KAd3d4foB/gnd4f4GCeHd4fYB+gnl3foCDeXd5fI­B+gnp3fX+Dend6e4B+gXt3fH6Ee3Z7en9/gH13e3­2EfXZ7en5/f354enyEf3d8en6Af355eXuDgHd8en­yBfn56eHqCgnh8enuBfn97d3qBg3l8e3qBfX58d3­mAg3p7e3qBfX59d3l/hHx6fHmBfn1+d3l+g316fH­mAfn1/d3l9gn96fHp/fnx/d3h9gYF6fHp+fnyAd3­h9gIJ7e3t9fnyAeHh8f4R8ent9fnyAeXd8foR9eX­t8fnx/end8fYR/eHt8fn1/end8fISAeHt8fn1/e3­d8fIOCeHt8fX1+fHd7fIKDeXp8fX1+fXd6fIGEeX­l8fX59fXd6fICEenl7fX59fXh6fX+EfHl7fH58fX­l5fX+EfXh7fH58fnp5fX6Efnl7e358fXt5fX2DgH­l6e358fXx5fX2CgXl6e318fX15fHyBgnl6en18fH­56fHyAg3p6enx9fH56fHx/g3t6ent9fH57fHx+g3­x6enp9fH59fHx9g316enl9fH5+fHx8g356e3h8fH­1/fHx8gn96e3h7fX1/fXt7gYB6e3h6fX2Afnt7gI­F7e3h5fnyAf3t7f4F7e3h4fXyAgHt6foJ8e3h3fX­2AgXx6fYJ9e3h2fX2Agnx6fIF+e3l2fH2Agn16e4­CAe3l1e35/g316e4CAe3l1en5/g356en+BfHl1eX­5/hH96en6BfXl1eH5/hH96en2CfXl2d35/g4B7en­yBfnl2d31/g4F7e3uBf3l2dn1/g4J7e3uAgHl2dn­x/g4J7e3p/gXp2dnt/goN8fHp+gXp2dnp/goN9fH­t9gnt2dnp/gYN9fHt8gnx2dnl+gYN+fHt7gX12dn­h+gYN/fHx6gX12d3h+gYN/fHx6gH53d3h9gYKAfH­x6f393d3h9gYKAfH17f393d3h8gYGAfX17foB4d3­h8gYGAfX17fYB5d3h7gIGAfn18fX95d3h6gICAfn­18fH96d3h6gIB/f318fH97d3h6gIB/f319fH58eH­h5f4B+f319fH58eHh5foB+f319fX19eXh5foB+f3­18fX19eXh5fYB+f318fXx9enh5fIB+f358fnx9e3­h5fIB+f358fnx9fHl5e4B+fn58fnx8fHl5e39+fn­98fnx8fXl6e35+fn98fnx7fnp6e35+fX98fn17fn­p6e31+fX99fn16fnt6e3x+fX99fn16fnx6e3x9fX­99fn16fn16e3t9fX5+fX16fX56fHt8fX5+fX16fX­57fHt8fn5+fn16fH97fHt7fX5+fn16fH98fHt6fX­5+fn16e398fHt6fX5+fn16e399fHt5fX5+fn17en­9+fHx5fH5+f317en5+fXx5fH5+f317en5/fXx5e3­5+f317en1/fXx5e359f317enx/fnx5en59f357en­x/fn15en59f357e3t/f316eX19f357e3t/f316eX­19f357e3t+f316eX19f397e3t+gH17eXx9fn97e3­t9gH57eXx9fn98e3t8gH57eXt9fn98e3t8gH97eX­t9fn98e3t7f398enp9fn99e3x7f398enp8fn99e3­x7foB8enp8fn9+e3x7foB9e3l8fn9+e3x7fYB9e3­l7fn9+e3x7fYB9e3p7fn5+fHx7fIB9fHp6fX5+fH­t7fIB+fHp6fX5+fXt7e39+fHt6fX5+fXt7e39/fH­t5fX5+fXx7e35/fHt5fH5+fnx7e35/fXx5fH5+fn­x7e31/fXx6e35+fnx7e31/fXx6e35+fnx7e3x/fX­x6en5+fn17e3x/fnx6en5+fn17e3x+fn17en1+fn­17e3x+fn17en1+fn57e3x9fn17en1+fn57e3x9fn­18enx+fn58e3x9fn18enx+fn58e3x8fn18ent+fn­58e3x8fn58ent+fn59e3x8fn58e3t+fn59e3x8fX­59e3t9fn59e3x8fX59e3t9fn59e3x8fX59fHt9fn­5+e3x8fH59fHt8fn5+e3t8fH59fHt8fn5+fHt8fH­59fHt7fn5+fHt8fH5+fHt7fX5+fHt8fH5+fHx7fX­5+fHt8fH1+fHx7fX5+fXt8fH1+fHx7fX5+fXt8fH­1+fHx7fH5+fXt8fHx+fXx7fH5+fXx8fHx+fXx8fH­5+fXx8fHx+fXx8e35+fXx7fHx9fXx8e31+fXx7fH­x9fXx8e31+fX17fHx9fXx8e31+fX17fHx9fX18e3­x+fX18fHx9fX18e3x+fX18fHx8fX18fHx+fX18e3­x8fX18fHx+fX18e3x8fX19fHx9fX18e3x8fX19fH­t9fX19e3x8fX19fHt9fX19e3x8fX19fHt9fX19fH­x8fH19fHx8fX19fHx8fH19fHx8fX19fHx8fH19fH­x8fX19fHx9fH19fHx8fX19fHx8fH19fXw=");
    var w = new Waveform(wave.length);
    w.buffer.set(wave);
    analogWrite(B3, 0.5, {freq:40000});
    w.startOutput(B3,4000);
    
  • I tested it and I hear no sound through the headphone. when I take a meter to it and send your code to the espruino I receive 1.59V for a short duration, which should indicate at least the signal is going through. Im using pin A7 but tried it with B3, both give me the 1.59V when code is deployed. I will try with a few different speakers I shouldn't need an amp to power a single small two wire earphone speaker right?

  • Update: tried new headphone its much louder than the last one and your code worked. Though still having similar problems as before with playing a voice recording. The code we are using is posted below.

    // SD card setup
    //DI(mosi) = B15
    //DO(miso) = B14
    //CK(sck = B10
    //CS(CD pin) = B1
    var spi = new SPI(); 
    spi.setup({mosi:B15, miso:B14, sck:B10});
    E.connectSDCard(spi, B1);
    console.log(require("fs").readdirSync())­;
    
    var f = E.openFile("X-File.raw","r");
    
    var w = new Waveform(2048,  {doubleBuffer:true});
    // load first bits of sound file
    w.buffer.set(f.read(w.buffer.length));
    w.buffer2.set(f.read(w.buffer.length));
    var fileBuf = f.read(w.buffer.length);
    // when one buffer finishes playing, load the next one
    w.on("buffer", function(buf) {
      buf.set(fileBuf);
      fileBuf = f.read(buf.length);
      if (fileBuf===undefined) w.stop(); // end of file
    });
    // start output
    analogWrite(A7, 0.5);
    w.startOutput(A7,8000,{repeat:true});
    

    Where "X-File.raw" is a file I made in audacity using the guide lines provided in the waveform documentation and is in the proper format of .raw(header-less) unsigned 8-bit PCM with a 8000hz playback speed. As I play the file I can accurately make out each spoken word in the sentence however it is very fuzzy to the point where you can barely make out the words and a single high pitch tone can be heard overtop of that audio. Can you recommend anything that can possibly fix this?

  • Glad something is happening now!

    Try analogWrite(A7, 0.5, {freq:40000}); instead of analogWrite(A7, 0.5); - that'll shift the base frequency for the PWM above the audible range, which should improve the quality and also remove the tone

  • That worked perfectly! still getting a small amount of feedback that isn't a huge deal. Any recommendations to clean up the audio signal slightly more?

  • What do you mean by feedback? You could add some external hardware to try and clean up the signal a bit by removing the high frequency element (just a resistor and a capacitor).

  • Its slight noise, I think the hardware recommendation will fix it. Is there anyway to get volume control without adding more hardware such as a digital potentiometer?

  • Okay, so after trouble shooting that im now back to my original question, regarding using SPW2430(microphone). The code you had given me works to give me non zero values from the IDE.

    var w = new Waveform(128);
    w.on("finish", function(buf) {
      for (var i in buf)
        console.log(buf[i]);
    });
    w.startInput(B0,2000,{repeat:false});
    

    How can I record for X amount of time then save it as a .raw file to an SD connected to the espruino? this is my current code but its not functioning correctly.

    var spi = new SPI(); 
    spi.setup({mosi:B15, miso:B14, sck:B10});
    E.connectSDCard(spi, B1);
    console.log(require("fs").readdirSync())­;
    
    var w = new Waveform(128, {bits:16});
    w.on("finish", function(buf) {
      require("fs").writeFileSync("sound.raw",­buf);
    });
    w.startInput(B0,2000,{repeat:false});
    
    
    

    IDE error code:

    in function called from system
    Uncaught Error: Expecting first argument to be an array, not undefined
    at line 1 col 16
    buf.set(fileBuf);
                  
    
  • Is there anyway to get volume control without adding more hardware such as a digital potentiometer?

    Just multiply the values in the buffer? E.mapInPlace(buffer,buffer,x=>x*0.5); should work ok.

    back to my original question

    You're getting an error for the line buf.set(fileBuf); but that's not in the code you've posted... Do you have other code in the file that you're not showing?

    The other option is you've previously saved code to Espruino, and it's not getting reset properly before upload so when you upload the new code it's causing errors

  • It wasn't reset properly. This is the code im currently using for the voice recording using the SPW2430(microphone)

    var spi = new SPI(); 
    spi.setup({mosi:B15, miso:B14, sck:B10});
    E.connectSDCard(spi, B1);
    console.log(require("fs").readdirSync())­;
    
    require("fs").writeFileSync("X.raw");
    
    var w = new Waveform(512,{doubleBuffer:true,bits:16}­);
    var a = new Uint16Array(512);
    w.on("buffer", function(buf) {
      a.set(buf);
      E.FFT(a);
      require("fs").appendFileSync("X.raw", a);
      var m=0,n=-1;
      for (var i=100;i<1000;i++)if(a[i]>n)n=a[m=i];
      console.log(m.toFixed(0)+"Hz @ "+n);
    });
    
    analogWrite(B0, 0.5, {freq:20000});
    w.startInput(B0,2000,{repeat:true});
    //w.stop();
    setInterval(function() {
      w.stop();
    },10000);
    
    

    would the Hardware drive the values for var i? meaning if my mic can record from 100Hz to 10kHz do i put i=100,i<10000?

    with the code above the IDE writes

    >[
      "System Volume Information",
    "X.raw"
     ]
    =undefined
    105Hz @ 4
    127Hz @ 6
    194Hz @ 5
    128Hz @ 5
    444Hz @ 6
    423Hz @ 5
    181Hz @ 4
    107Hz @ 6
    101Hz @ 4
    506Hz @ 22
    470Hz @ 7
    469Hz @ 8
    425Hz @ 6
    233Hz @ 7
    152Hz @ 6
    130Hz @ 5
    121Hz @ 6
    438Hz @ 7
    481Hz @ 10
    168Hz @ 6
    >
    

    I still cannot get proper voice playback so I thought maybe my sample rate needed to go up but, when I change the sample rate to 1024 in waveform and and Uint16array the IDE gives me an error code.

    in function called from system
    Uncaught Error: Insufficient stack for computing FFT
     at line 2 col 10
      E.FFT(a);
    
  • Ok, I think there are a few things here...

    • 512 isn't the sample rate, it's the size of the buffer. Using 1024 could be a good idea though.
    • The sample rate is in w.startInput - you're using 2000 currently (and the code you posted up is playing back at 8000). It'd be worth trying to use 4000 for both as a starting point (8000 might be possible, but for now let's not push it)
    • You don't need analogWrite - you're trying to record so you want to input, not output.
    • You definitely don't need E.FFT or any of that code with the FOR loops. FFT is something totally different to recording sound - and on Espruino at the moment you're going to struggle to record proper audio and do an FFT to pick out frequencies.
    • Also appendFileSync has to find the file, open it, append, and close it - which can be quite slow. E.openFile is probably better.

    Something like this should work:

    var spi = new SPI(); 
    spi.setup({mosi:B15, miso:B14, sck:B10});
    E.connectSDCard(spi, B1);
    console.log(require("fs").readdirSync())­;
    var f = E.openFile("X.raw","w");
    var w = new Waveform(1024,{doubleBuffer:true,bits:16­});
    w.on("buffer", function(buf) {
      f.write(buf);
    });
    w.startInput(B0,4000,{repeat:true});
    
    setTimeout(function() {
      w.stop();
      f.close();
    },10000);
    
  • Thank you for clearing all that up! I really appreciate the fast response too, thank you for that. This is the first time im really trying to code something, im still very new to this. I had accidentally put analogWrite but I had meant to put analogRead, I thought I needed it because the signal is coming from the DC pin on mic into ADC of the espruino. When I run code you posted I get

    >[
      "System Volume Information",
      "X.raw"
     ]
    =undefined
    > 
    

    I tried playing the new file changing proper parameters and Im getting static.

  • Ahh, ok - try changing bits:16 to bits:8 - because the code to play the wave file is expecting 8 bit audio. It should make everything run a bit better too, since you're shifting half the amount of data around :)

  • That did the trick! I play around with some of the values to try and up the quality, but I think im going to need external hardware for that. Thank you so much!

  • @Gordon,

    Do you have any suggestions on how to trouble shoot the audio for 16 bits? I keep trying to get sound at 16 bits but it's giving me back static, do you need to specify 16 bits in the playback code as well?

  • Hi - I'll answer your email in a bit, but in answer to this: yes, you need the same number of bits for playback and record.

    If you record at 16 bits, but then play back at 8, basically what you're doing is playing back the high byte, then the low byte, and so on - so it'll be half-speed, and badly garbled :)

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

Espruino Wifi and SPW2430(microphone)

Posted by Avatar for jruroede @jruroede

Actions