Posts with «advanced projects.» label

Sound Camera.

 

 

One more project, that shows breathtaking beauty of the FFT (Fast Fourier Transform). Once again, like in last 3D Ultrasonic Radar Project,    Arduino DUE was nominated to be Maestro, doing major part of the Digital Signal Processing in real time.  As you can see below, the hardware includes 4 “modules”:

  1. Sensor board
  2. Arduino DUE
  3. Bluetooth shield
  4. Android tablet.

Last two items aren’t strictly necessary. Alternative would be to connect TFT display directly to arduino, but I decided not to spend my time on re-inventing drawing-rendering software. Better to delegate all visualization stuff to the equipment that was  specifically design by big monsters in high tech industry.  I spend quite time digging into android graphics subject anyway, only hoping I can apply my knowledge somewhere else later on.

Sensor board holds 4 microphones from  SFE.  Plus a few decoupling components, capacitors and inductor in power line.

Software.

   Brief summary: Arduino sampling 4 analog inputs, close to 41 kHz,  x 4 = 164 ksps,  software library Radix4 posted on this blog was imported into project practically intact. DMA feature on Arduino DUE allows sampling rate up to 1 MSPS, and I already successfully tested its capability in 3D Radar project.  Having 2048 fft size, at the first processing stage  output there are 1024 bins 20 Hz each. Than, using arctangent LUT, phase of each bin is extracted.  Difference in phases two vertically position microphones gives Y component, and two horizontally spaced mic’s – X component. Sound source is localized with accuracy ~ 0.5 degree. Have to say, that on the lower frequency end, 100 Hz – 1 kHz , where wavelength is huge compare to spacing between two mic’s ( 3.4 meters at 100 Hz ), accuracy is deteriorating proportionally to wavelength.

Arduino is calculating data really fast, providing  X,  Y, and M  every 50 milliseconds. M – is for magnitude. Than, all this data stream flows to android over BT.  Everything else is obvious, watch the video.

Speaker outputs white noise, as for single tone (frequency) only one pixel would be visible on screen. Android software “colorized” picture based on a frequency, low range – starting from red, and up to violet on high end of the frequency band, through all 1024 color wheel possibilities.  You can see, that picture saturated with green and blue, and there is almost no red color. There are two things, first is a speaker, not performing well at low end. Second nuance is the fact, that low frequencies are not “grouped” so effectively, due to the localization error, what I tried to explain in a paragraph above. I created an option in the menu to select different types of colorization, based on a frequency or based on a magnitude. They are look pretty similar for white noise source, so there is only one video clip.

Have fun.

 

 Edited on 21 Oct. 2014:

 If you come across this page searching an old  “Localizator” project, published over 2 years ago, here is working material I was able to find:   Localizator.


Sound Camera.

 

 

One more project, that shows breathtaking beauty of the FFT (Fast Fourier Transform). Once again, like in last 3D Ultrasonic Radar Project,    Arduino DUE was nominated to be Maestro, doing major part of the Digital Signal Processing in real time.  As you can see below, the hardware includes 4 “modules”:

  1. Sensor board
  2. Arduino DUE
  3. Bluetooth shield
  4. Android tablet.

Last two items aren’t strictly necessary. Alternative would be to connect TFT display directly to arduino, but I decided not to spend my time on re-inventing drawing-rendering software. Better to delegate all visualization stuff to the equipment that was  specifically design by big monsters in high tech industry.  I spend quite time digging into android graphics subject anyway, only hoping I can apply my knowledge somewhere else later on.

Sensor board holds 4 microphones from  SFE.  Plus a few decoupling components, capacitors and inductor in power line.

Software.

   Brief summary: Arduino sampling 4 analog inputs, close to 41 kHz,  x 4 = 164 ksps,  software library Radix4 posted on this blog was imported into project practically intact. DMA feature on Arduino DUE allows sampling rate up to 1 MSPS, and I already successfully tested its capability in 3D Radar project.  Having 2048 fft size, at the first processing stage  output there are 1024 bins 20 Hz each. Than, using arctangent LUT, phase of each bin is extracted.  Difference in phases two vertically position microphones gives Y component, and two horizontally spaced mic’s – X component. Sound source is localized with accuracy ~ 0.5 degree. Have to say, that on the lower frequency end, 100 Hz – 1 kHz , where wavelength is huge compare to spacing between two mic’s ( 3.4 meters at 100 Hz ), accuracy is deteriorating proportionally to wavelength.

Arduino is calculating data really fast, providing  X,  Y, and M  every 50 milliseconds. M – is for magnitude. Than, all this data stream flows to android over BT.  Everything else is obvious, watch the video.

Speaker outputs white noise, as for single tone (frequency) only one pixel would be visible on screen. Android software “colorized” picture based on a frequency, low range – starting from red, and up to violet on high end of the frequency band, through all 1024 color wheel possibilities.  You can see, that picture saturated with green and blue, and there is almost no red color. There are two things, first is a speaker, not performing well at low end. Second nuance is the fact, that low frequencies are not “grouped” so effectively, due to the localization error, what I tried to explain in a paragraph above. I created an option in the menu to select different types of colorization, based on a frequency or based on a magnitude. They are look pretty similar for white noise source, so there is only one video clip.

Have fun.


Power Quality Meter.

Arduino UNO project, Power Quality Meter, someone would call it’s PQ Monitor or PQ Analyzer.

I had already published  a blog  devoted RMS measurements on full band  20 – 20 000 Hz  audio signals. ( Following my own style, I’d refer to already published materials whenever it’s possible, to save my time ).  This time measurements performed on single AC Power Grid frequency. ( 60 Hz in Canada. Algorithm would works with 50 Hz as well).

Features:

  • Graphic LCD display 128×64;
  • First 5 harmonics presentation;
  • RMS Voltage Indicator;
  • Frequency Monitoring;
  • THD calculation;
  • Internal data up to 63-d !!! harmonics components in Real-Time;

The Holy Grail of this project, is a method of sampling input waveform. As there is only one main frequency (fundamental) at the input, I came up with idea to do a sampling period VARIABLE. There are at least 2 great advantages in this brilliant ( may I ? ) invention:

  1. It’s completely eliminate necessity of the windowing.
  2. Only ONE period of input waveform is enough for precise calculation.

First of all, windowing is really BAD on metrological side (for accuracy of results), smashing one single frequency bin to over 3 – 5 of it’s neighbors, significantly deteriorating input sensitivity, and plus it’s not able to eliminate limits discontinuity effects well – only attenuate them. Secondly, from software timing performance point of view, introducing windowing in the Real-Time application would automatically require to DOUBLE data throughput, as Overlap – Add procedure would be mandatory.

In it’s essence, I created a software PLL (Phase Lock Loop). Compare to a project with hardware based PLL (IC 74HC4046), no need for external chip this time. Engine is running on Timer1 features – CTC mode and capability to drive ADC Auto trigger. I will go into details in software section.

Hardware.

As you can see on the drawings, circuitry is quite simple, one LCD ( I used SparkFun LCD-00710, could be different ) and one IC, LM311 – comparator. Pay attention, that GEDA doesn’t have a library for such display, all details on LCD configuration, pin numbering etc you can find here.  I haven’t experienced any difficulties with assembling LCD, except soldering bunch of wires and installing control brightness level pot. Thanks author of the GLCD library (great work!), there was no any troubles with software also.

Transformer is doing galvanic isolation, as they say – safety first! There is no part number ( requirements ), anything with primary windings for your local AC main ( 110V,  220V ) and about 10 V on secondary will be o’k.  Values of the resistive voltage divider ( 22k and 2 x 4.7k ) may be adjusted proportionally for transformer with different secondary voltage output. Trick is to keep voltage level close to ~2V AC peak value at the arduino analog input # 5.  There are two caps 2200 pF to filter out RF interference, and one trim pot to adjust comparators threshold ( not strictly necessary, you can replace with constant two resistors voltage divider ). Good decoupling of the +5V power lines should be done if LCD installed on the same board (as I did), otherwise, arduino goes crazy when it’s received a basket of interrupts on pin 2 (INT0).

SOFTWARE.

 I’ve read an article in December’s issue of the Elektor magazine, that actually inspired me on this project. Even I had such idea in my mind for quite awhile, nevertheless Elektor’s publication accelerate this process. Do you still remember I called my method “brilliant”? And this is why: compare to  project published in well known and respectful electronics magazine, my code is running 140 !!! TIMES faster ( compare 5 milliseconds to 700 milliseconds competitors ). I didn’t tweak any optimization. My software is running REAL-TIME in each AC period, keeping load of the microprocessor below 30 %. It’s capable to do a Real-Time monitoring of three phase power line. The only things which is slow down process, is LCD display refreshment. In current version, algorithm averages data over 32 cycles before outputs summary data report  on the display, around 0.53 seconds period ( 1 / 60 / 32). During update display procedure (23 milliseconds or so) which is longer than 16.66 milliseconds period of the AC 60 Hz, one cycle is skipped. Depends on application, the task of updating screen could be split over many sub-frames, so instead of one big chunk of code, 32 smaller size chunks will go unnoticeable in background, fixing an issue of 33-rd lost frame. But I don’t think it’s necessary for monitoring purposes, may be only in Power Energy Meter project? I just can’t imagine, Elektor’s 2100 milliseconds overall time per cycle, when everything could be done in less than 7 milliseconds ( using split display subroutine ). It’s 300 times difference!.

THE MAGIC.

 Software PLL / FLL – Frequency Lock Loop is build on TIMER1 VCO. Well, it’s not quite correct to call it VCO, probably FCO – Frequency Controlled Oscillator. Software adjusts oscillator in such a way, that number of captured samples  per one AC waveform has to be exactly 128 .  Look here:

   if ( smpl_Nmbr > FFT_SIZE ) smpl_Time++;
   if ( smpl_Nmbr < FFT_SIZE ) smpl_Time–; 

    OCR1A = smpl_Time;
    OCR1B = smpl_Time;

If during one AC period ( 1 / 60 Hz = 16.66 milliseconds ) timer restarts more often than necessary (FFT_SIZE = 128), smpl_Time variable increasing, so TIMER1 FCO slow down. In opposite case, smpl_Time is decreasing, forcing clock to run faster. Track on quantity of captured samples goes as usual, via indexing input array variable – smpl_Nmbr, which increments every ADC “start conversion” event, triggered via channel B:

   ISR(TIMER1_COMPB_vect)
   { 
     if ( smpl_Nmbr < FFT_SIZE )
       {
         x_r[smpl_Nmbr] = ADC – adc_Offst; // 
       }   
    smpl_Nmbr++;
    }

( Paralleling Timers two  channel A and B was invented here.)  The comparators main duty is to trigger digital pin 2 (INT0) exactly in the same point in time, relatively to input signal periodicity. Not necessary at zero. Synchronization point could be at any voltage level on the input waveform, it’s has nothing to do with zero-crossing. As software calculates complete FFT subroutine, for both REAL and IMAGINARY part (btw, referring link) , adjusting point (via pot) to exactly zero-cross simply push all energy in imaginary part (sine). Bringing this point to 45 degree would splits energy equally between real and imaginary parts. Later on, extracting square root from sum of two squares ( magnitude calculation ) simply annihilate any difference, magnitude is not changing with moving synchronization point up and down at all.

DC offset is adjusted in every cycle based on REAL (cosine) bin-0 magnitude:

  temp = f_r[0];
  if ( temp > 0 ) 
      adc_Offst++;
  if ( temp < 0 ) 
      adc_Offst–;

Rolling Filter, the easiest one to implement and understand, and very efficient against spikes.

Arduino UNO sketch:  download.

To be continue….

6 January, 2013.

I did some “resource  management” in software, because data calculation in each cycle of AC waveform is not really necessary. Let me explain. There are 3 major hardware limits :

  • ADC resolution
  • Memory size / CPU performance
  • Update Rate

In first version, calculation of harmonics magnitude content goes up to 63-rd. But as resolution of the Arduino ADC limited by 10-bits ( 9 plus sign ) it doesn’t make much sense for real world electrical grid, simply because magnitude starting from 5-th  harmonics drops below noise floor –  6.02 x 9 + 1.76 = 55.94 dB (0.16%) There are two way to solved this issue: increase the FFT size, or use oversampling technics. First method is not possible due memory limits. Second one makes update rate too low for practical use.

In this software release, I limit calculation to first 7 harmonics, and show all of them on display (see photo). FFT size is the same, 128. But sampling clock running 8 times lower, so 8 AC cycles necessary to fill up input array with new data. Method – oversampling in time domain. It gives 3-bit gain in resolution, same as have 12-bit ADC, overall dynamic range 6.02 x 12 + 1.76 = 74 dB. (0.02%)

Version 2:  download.


UnDecima. Audio Output from Arduino.

Added Part 2, on 26 August, 2012.

I already have one project where arduino outputs audio signal to USB speakers via software 10-bits PWM.  In first, I was not satisfied with quality of sound generated via PWM. There are just not enough speed in arduino engine  to run PWM well.  For example for 20.000 Hz audio, PWM has to be at least 2 – 3 times higher  above normal frequency range, or 40 – 60 kHz. If we multiply this value with 10-bits resolution, we would get 40 – 60 MHz, that is too much for small arduino to drive.

In second, the idea to create multichannel  audio system was boggling my mind for about a year now. This is how UNDECIMA project was born.  1 + 11,  or 12 channel !!! audio system running on arduino UNO board with full 10-bits resolution – maximum available with internal ADC. Project gets its name because there is 1 Master channel, and 11 linearly delayed copy of the same audio stream, or Puppets channels,  In its essence, this is acoustic  Phase Array.

      HARDWARE.

 As you can see on posted drawings, the “heart” of the project is 10-bit multiplying (parallel) digital analog converter DAC1022.  Output of the IC than buffered with OPA and “demultiplex’d”  via two 74HC4051 8-channel analog switches. Outputs of the switches loaded by sampling and hold capacitors 0.01 uF, to filter out unwanted sampling frequency noise.  DAC is configured for single supply power line. Usually, they recommend to buffer output with / high input impedance / high slew rate / rail – to – rail / OPA in such configuration. Which I don’t have, and it costs about half a price of DAC itself, So, this is why I implemented two variable voltage references based on NE5532 and couple of pots. Difference in voltages between two references forms a “span”. Lower voltage creates an off-set for cheap non rail-to-rail OPA LF351, with adequate slew rate 13 V/usecond.  OPA is heavily loaded by sampling and hold capacitors, which it sees as connected in parallel at its output, 0.12 uF overall!  To minimize distortion level due overloading of the OPA, span couldn’t be adjust too wide, and preset in current design 1.414 V, providing exactly 1V RMS output for pure sine wave. I know, that 12 buffers / filters inserted after switches would solve a problem, but idea to solder more than 100 electronics components on a breadboard doesn’t look attractive for me.

( *I will try to find another  IC / circuits capable to drive big capacitive load later on. )

SOFTWARE.

 Software part of the project is straightforward ”sample-delay-output” function, completely wrapped inside interrupt  subroutine. Main loop is empty. In setup 16 digital pins configured as outputs, 10 of them represent data bus, 5 are address bus and last one is check-point to measure performance with oscilloscope. Timer 2 defines a “heartbeat”, and fires interrupt  every 25 usec, or at 40 kHz. ADC configured to take samples on analog input A5 (first 4 analog pins belong to data bus). Conversion prescaler: 1 MHz, allowing sampling to be completed with fast speed. I left two digital pins D0 and D1 free, as my initial attempts to use them in data bus failed. Arduino periodically refuses to reload updates, I’m not sure if it’s Linux problem or on-board USB/RS232 converter.  Each sample, received from the ADC, is shifted left on two bits to skip D0 and D1, and plus one bit more (3 bits left shift overall) to fix “imperfection” of input preamplifier stage, as NE5532 (again) “non rail-to-rail” OPA. Look for drawings in “Audio Input” blog.  Measurements show that each channel is receiving a data for about 1 usec “window”, which is quite fast, nevertheless not fast enough to run 16 channels or to do something else with data before sending them out. In current hardware implementation the “bottle neck” is OPA, as DAC has settling time only 500 nanoseconds.

  Link to arduino UNO sketch: UnDecima.

 To be continue….

  Part 2.

  After I expressed my concern about heavily loaded OPA,  I was thinking, that it would be nice to run some measurements, in order to decide what part number would be better for this specific hardware realization (LF351 replacement), or if I have a few candidates, it would make sense to compare them based on measurements results, instead of what I can hear with my own ears. It didn’t take long to download and install JAAA application, which turn my laptop (Linux) into “home-brew” DSP laboratory.  To cancel any distortion generated in ADC (plus another non rail-to-rail OPA*) on performance evaluation of the OUTPUT stage, I modified sketch adding sine-wave LUT table, basically turning it into Sine test generator.  20 – 20.000 Hz, sweeping  along frequency axis by pot, connected to same pin A5, ground and +5V power rail.

 First of all, I check if my “off-set” 2.000 V was set correctly, as according to data sheet 3V is a minimum.

  Test confirmed, that 2V off-set was a mistake. The best results at 3V, with distortion level IMD-2 and IMD-3 less than 0.03%.  And there is no surprise, that level goes up with a Span ( difference in V-1 and V-2), simply because OPA is loaded harder.  All data were taken with phasor equals to 0. Look at the last line, where phasor was set to 11, approximately “worst case scenario” – when load of the OPA jumping up and down, in other words, when one channel is charging its capacitor, in less than 0.5 microseconds next channel connected to OPA output  asking just opposite, to discharge a cap. It happens, when relation between phasor and test frequency forms 180 degree phase difference in neighboring channels. OPA just have no time to “settle” in between. Still not bad,  for $0.60 “obsolete” OPA.

 Second test, variation of the distortion level over frequency range. I’d not comment, just look at the pictures:

 Summary: the results are quite remarkable.  They show, that Arduino is capable to run 12 channels audio system with less than 0.03 % THD.  Distortion level would be a little bit higher than 0.03 % if all 12 channel outputs not “in phase” melody, but not much than 0.05 % or so, as it’s quite unusual to have exactly 180 degree out-of-phase 100% magnitude ( what I highlighted in red line in posted table). Anyway, I will fix it replacing LF351.

  Link to arduino UNO sketch:  Generator

 * Things to DO:  I have to test INPUT for distortion level as well, more to come in part 3….


RADIX-4 FFT (integer math).

Updates on 30 Sept. 2014:

Everything below is correct, and may worth to read. But new  code based on Split Radix Real is published. Faster, lower memory demands, both version for UNO and DUE available as libraries.  New algorithm makes it possible to run FFT_SIZE =  512 on UNO board in less than 9.6 milliseconds.

/**************************************************************************************************************************************

Tweaking the FFT code, that I’ve published earlier in my series of blogs, I hit a “stone wall”. There are nothing could be improved in the “musical note recognition” version of the code, in order to make it faster. At least, nothing w/o completely switching to assembler language, what I’m trying to avoid for now.  I’m sure, it’s the fastest C algorithm. Looking around it didn’t take long to find out that there is other option: change RADIX-2 algorithm for RADIX with higher order, 4, 8, or split-radix approach. Putting split-radix aside, (would it be my next adventure?), RADIX-4 looks promising, with theoretically 1/4 reduction in number of multiplications (what I believe is an “Achilles heel”).

Googling for awhile, I couldn’t find fixed point version in plain C or C++ language. There is TI’s “Autoscaling Radix-4 FFT for MS320C6000TM” application report, which I find useful , but the problem is it’s “bind” with TI microprocessors hardware multiplier, and any attempt to re-write code would, probably, make it’s performance even worse than RADIX-2. Having “tweaking” experience with fix_fft source code from:  http://www.jjj.de/             I decide to follow same path, as I did before, adapting fix_fft for arduino: take their floating point source, disassemble it to the pieces, and than combine all parts back as fixed point or integer math components.    And you know what ? Thanks God, I successed!!!

I decided not all parts to re-assemble back again, this is why fft_size has to be power of 4 ( 16, 64, 256, 1024 etc.). Next, the software is “adjustable” for different level of the optimization. Trade is always the same, accuracy against speed. I’d highlight 3 level at this point:

1. No optimization, all math operation 15-bits.   The slowest version. Not tested at all.

2. Compromise version.  Switches: 12-bits Sine table, regular multiplication (long) right shifted >>12, Half-Scaling in the sum_dif_I (RSL) >>1. Recorded measurements result:  24 milliseconds with N = 256 fft_size.

3. Maximum optimization. Switches: 8-bits Sine table, macro assembler multiplication short cut, no scaling in the core. Timing 10.1 millisecond!!!

Fastest. Best of the Best Ever written FFT code for 8-bit microprocessor.   Enjoy the meal:   https://docs.google.com/open?id=0Bw4tXXvyWtFVMldRT3NFMGNTZVN0Y0d4eVRsenVZdw

Here is slightly modified copy, where I moved sine table from RAM to FLASH memory using progmem utility. For someone, who was curious to find the answer: how much progmem slower compare to access data in the RAM, there is an answer. 10.16 milliseconds become 10.28, or 120 usec slower. Divide by 84 x 6 = 504 number of readings, each progmem costs 0.24 useconds. Its about 4 cycles CPU.

https://docs.google.com/open?id=0Bw4tXXvyWtFVQjZpZkw1c3VUZXlmaF9sOEJwMmpEUQ

Screenshot from the running application, signal generator running on the computer, feeding audio wave to OPA and than analog input 0. Look for hardware setup configuration on the “color organ” blog-post.

BTW, there is one more important thing, I missed to emphasize in my short introductory paragraph, code offers FLEXIBILITY over SNR ratio. Basic FFT algorithm has an intrinsic “build-in” GAIN: G(in) = FFT_SIZE / 2 . (in) stands for intrinsic. That is perfect value for fft_size = 64 ( Gain = 64 / 2 = 32) and arduino (Atmel AtMega328)  10-bit ADC ( max value = 1023 ). FFT output would be 32 x 1023 = 32736, exactly 15 bit + sign. In other words, scaling in the algorithm core doesn’t required at all! That alone improve speed and lower rounding noise error significantly. The same time G(in)  grows too high with FFT_SIZE = 256, when G = 256 / 2 = 128 and output of the FFT would overflow size of 16-bit integer math. But again, scaling don’t have to be 100%, as long as there is a way to keep it in balance with ADC data. In this particular case, with 10-bit ADC, we can keep gain just below 32, it’s not necessary to make it exactly “1″.  For 12-bit ADC upper G limit would be 8, still not “1″. To manipulate the gain, division by 2 (>> 1) in the “sum_dif_I” could be set, to prevent overflow with fft_size > 64. Right shift “gain limiter” creates a square root adjustment, according to new formula: G(rsl) = SQRT (FFT_SIZE) / 4 . (rsl) stands for right-shift-limiter.

  1.  G = 1 for fft_size = 16,
  2.  G = 2 for fft_size = 64,
  3.  G = 4 for fft_size = 256,
  4.  G = 8 for fft_size = 1024.

Summing up, for using RADIX-4 with arduino ADC and FFT_SIZE <= 64, keep division by 2 (>> 1) in the “sum_dif_I” commented out. In any other circumstances, >10 bits external ADC, >64 fft_size, uncomment it.

To be continue…..