-
• #2
analogRead is limited more by the speed of execution than anything else. You might be looking at 2000 samples/sec?
There is however the Waveform class which will do what you want (it even contains an example of making a sound meter) - but I wouldn't push that much beyond 20kHz.
Having said that, if you try doing a spectrum analyser in Espruino you may find that you hit issues with Espruino's processing speed pretty quickly. It's not going to be great at doing realtime FFTs in JavaScript :)
I've implemented things like
E.variance(...)
to work around this a little, and I guess I could look at implementingE.convolve(a,b,offset)
which would allow you to quickly work out how much of a certain frequency was in a sound sample. -
• #3
Do you know any good FFT libraries in JavaScript?
Would it be worth looking into a hard solution for the audio analysing?
I'm very new to electronic but I found this chip which might help, MSGEQ7.
Or maybe an Arduino shield, https://www.sparkfun.com/products/10306 -
• #4
Yes, the MSGEQ7 would be the easiest solution, and it looks like it would be pretty easy to use with Espruino...
I'll see about adding that convolve function in Espruino 1v58 though, so you should be able to get a few bands of EQ quite easily.
I just gave FFT (using an LCD screen) a quick go:
// http://www-ee.uta.edu/eeweb/ip/Courses/DSP_new/Programs/fft.cpp function fft(data) { // data must be 2 more than required var mmax, m, istep, i; var wtemp, wr, wpr, wpi, wi, theta; var tempr, tempi; var n = data.length-1; var j = 1; for (i = 1; i < n; i += 2) { if (j > i) { tempr = data[j]; data[j] = data[i]; data[i] = tempr; tempr = data[j+1]; data[j+1] = data[i+1]; data[i+1] = tempr; } m = n >> 1; while (m >= 2 && j > m) { j -= m; m >>= 1; } j += m; } mmax = 2; while (n > mmax) { istep = 2*mmax; theta = 2*Math.PI/mmax; wtemp = Math.sin(0.5*theta); wpr = -2.0*wtemp*wtemp; wpi = Math.sin(theta); wr = 1.0; wi = 0.0; for (m = 1; m < mmax; m += 2) { for (i = m; i <= n; i += istep) { j = i + mmax; tempr = wr*data[j] - wi*data[j+1]; tempi = wr*data[j+1] + wi*data[j]; data[j] = data[i] - tempr; data[j+1] = data[i+1] - tempi; data[i] += tempr; data[i+1] += tempi; } wr = (wtemp = wr)*wpr - wi*wpi + wr; wi = wi*wpr + wtemp*wpi + wi; } mmax = istep; } } SPI1.setup({ baud: 1000000, sck:B3, mosi:B5 }); var g = require("PCD8544").connect(SPI1,B6,B7,B8); var wave = new Waveform(32); var floatData = new Float32Array(32+1); // note the +1 wave.on("finish", function(buf) { floatData.set(buf,1); floatData[0]=0; fft(floatData); g.clear(); for (var i=0;i<buf.length;i+=2) g.setPixel(i,24+Math.sqrt(floatData[i+1]*floatData[i+1] + floatData[i+2]*floatData[i+2])>>4); g.flip(); // go again wave.startInput(A0,1000); }); function onTimer() { print("Start"); } setTimeout(function() { wave.startInput(A0,1000); }, 1000);
It's only managing around 2 FPS at the moment. I guess with LEDs it would be significantly faster though...
-
• #5
I was briefly looking into the analog sampling speed when working on a solar panel diagnostics circuit. With the STM32F4 Discovery board I managed to collect my 100 samples at 12 bit resolution with a sampling speed of 5kHz. I also tried the Waveform which gives 8 bit data, at 100kHz, and I am still scratching my head trying to see if I can use the 8 bit resolution for the type of measurement I am doing. it may be possible but I need to figure out how to process the data. In my case I can collect the data and process it afterwards, so the delays in Espruino is not a major issue. It would be nice to be able to increase the sampling speed at 12 bit resolution with a factor of 5 or more, that would open up other applications.
-
• #6
Just FYI after having played with this, I'm not sure it can reach the 100kHz I'd guessed when doing it initially. It looks to be nearer 20kHz now - although maybe more on the F4 board.
I'd have to look into getting 12 bit. It's definitely possible though.
-
• #7
I did not actually time the Waveform capture, so I would need to repeat the test to know the actual capture rate. The AnalogRead spent 0.0196s to capture 100 samples.
Edit: I tried to repeat the Waveform capture and came up with different time values depending on how many data points I captured. at 200 points it seemed that the sample rate was around 42kHz, and if I increased the number of samples it seemed that the rate increased. However, I did not have the time to make real time measurements, I relied on getTime() readings before and after the capture. -
• #8
I know this thread is 2 years old. Has there been any progress? The chip spec says it can sample 12 bits st 2 MHz!
-
• #9
The speed is really limited by either the execution speed of the JavaScript in the case of analogRead, or the speed of the timer system for Waveforms - it's not really a hardware issue.
If you absolutely require the speed it'd be possible to use Poke commands to set the hardware up to use DMA with analogRead (or you could compile in your own code that did this in C, which might be easier).
What do you need it for though? Since Espruino doesn't execute JavaScript that quickly, you would struggle to actually do much with data captured at 2MS/sec unless you were just capturing it for use with something else.
Hello,
I'm wondering how fast analogRead() is at getting results?
I want to be able to sample analogue audio to build a spectrum analyser. What kind of sampling rates do you think I can get from the Espruino?