0

I want to store incoming data in flash or EEPROM and then apply FFT or some other method to detect frequency and intensity.

I am taking sound through microphone amplifying it with an LM741 and giving this amplified signal as input to an Arduino and then processing it at the same time.

But the problem is that the time taken in running the code is interfering with the sampling rate. I want to store say 50 inputs in flash and then process these 50 numbers, while at the same time the next set of 50 numbers is being stored, so that I can have data stored at a constant sampling rate.

Also how can I store data continuously? Because if I do this in loop() won't it again have time lag due to rest of the code?

I am new to Arduino, so please give details or some link to help me understand.

Thanks.

  • Writing to EEPROM is probably too slow. Just store it in memory. You can set the ADC to run in free running mode, where it will continually measure the voltage. You can then attach a function to the interrup so it run whenever a conversion is ready. You can store the values in a ring buffer. So the interrupt will fill the buffer with new data, while the loop will process the data and remove it from the buffer. – Gerben Dec 21 '16 at 9:13
  • But will I be able to measure the time between any two reading? I want to get the frequency and so I need the time between any two data which I intend to keep fixed. So to be clear, I should store data by setting clock frequency and using free mode in setup and attach a function (to process data) to interrupt when the ring buffer is full, and do nothing of this in Loop? – Ayush Dec 21 '16 at 9:42
  • Time between readings is constant in free running mode. I think you can even use a timer to trigger ADC conversions if you need a specific sampling frequency (instead of changing the ADC clock prescaler). You don't need an interrupt for when the buffer is full. Just have the loop check with a if statement if there is enough data in the buffer to start prosessing it. Ideally you'd process the data as it is coming in instead of waiting for a lot of data, and the process I'll this data in one chunk. But this depends on your situation. – Gerben Dec 21 '16 at 12:19
  • Thanks a lot. I am going to read more about it and try to implement it. – Ayush Dec 21 '16 at 12:47
2

A common method of overlapping data input with data processing uses double (or multiple) buffering. For example, one of two buffers is processed in the foreground (that is, in the loop() routine) while another buffer is filled in background (via interrupt handlers). Each time a buffer fills, the usage of the two buffers swaps: that which was being processed now refills, while the recently-filled buffer gets processed. To make this work, buffer processing must take less time than buffer filling.

For recording conversion times, because free-running ADC conversions each take the same amount of time, you can just save fill-start and fill-end times with each buffer, and interpolate to find out reading times.

If you plan to process audio data at near-normal speeds, it's likely most Arduinos won't be fast enough to keep up. However, using an Arduino Due probably is feasible. The Due is based on an ARM Cortex M3 processor with 72 MHz operating frequency, 32-bit arithmetic, large RAM (for an Arduino), etc.

An alternative method of processing audio data is to use a frequency analysis chip. Here is a low-end example: The MSGEQ7 Graphic Equalizer Display Filter is about $5 in an 8-pin DIP package from sparkfun.com. Apparently, it continuously measures peak spectral intensity in each of seven frequency bands, and can read the peaks out perhaps a thousand times per second. Audio goes in on the "Audio in" pin. A Reset pin resets an output-multiplexor counter to zero. Each time after you clock a strobe line, a band's reading is presented as an analog voltage on a "DC out" output line; the band's peak reading is decayed about 10%; and the multiplexor advances one band upward in frequency, rolling over from highest to lowest every seven strobes.

1

What I want to do is store incoming data from in flash or eeprom

No, for your application you absolutely do not want to do that. You want to use RAM instead.

The Arduino has three kinds of memory:

  1. Bytes in RAM (also called SRAM) can be written an unlimited times and written very quickly. RAM is designed for short-term storage of information while a sketch is running. The contents vanish when the Arduino is turned off, but this isn't a problem for you unless you need to process previously read information later on after the Arduino is turned back on. An Arduino Uno has 2048 bytes of RAM and all your C/C++ variables must fit in that.

  2. An EEPROM byte can be written around 100,000 times; writing it is much, much slower than writing a RAM location. This makes it very bad for doing intensive processing, as opposed to, e.g., just storing configuration variables that are rarely read. EEPROM is designed for storage of information across power cycles of the microcontroller; unlike RAM, previously written data are still there to be read when the Arduino is powered on. An Arduino Uno has 1024 bytes of EEPROM; this is only used when your code or library code explicitly requests data be written to or read from it.

  3. Each block of flash memory can be written around 10,000 times; writing it is much slower than RAM, though it can be read very quickly. Flash storage is designed for storing programs, not data; it's the memory from which instructions are read, though you can with care store "constant" data in it too. It's only changed when you upload a sketch via USB.* An Arduino Uno has 32768 bytes of Flash memory and your program and any constants you store in Flash must fit in it.

* Not technically true, but if you know how to use Flash for runtime data storage, this answer isn't providing you any useful information. :-)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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