Posts with «real time» 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.


Audio VU meter (AC microVoltmeter) with Extra wide Dynamic Range 69 dB.

O’K, after having some fun with stereo version of the VU meter I described in my previous blog-post, now it’s time to do a serious stuff. Studio grade VU meter !!! 24 steps, equally spaced every 3 dB, covering Extra wide Dynamic Range from -63  up to  +6 dB.  Single (mono) channel this time, no messing around, absolute precision at the stake. Plus, it keeps absolutely Top-Flat linear frequency response from 40 Hz up to 20 kHz(*).

 

 

I’m not going into details of RGB LEDs Display, which has no modification since “Tears of Rainbow” project, only plates installed in one line, form a single GIGANTIC bar-graph. There are some minor changes in mixing colors data tables, but they intuitively understandable.  The most important feature in this project is autoscaling. As you, probably know, Arduino has 10 bits ADC. Only it can’t process negative half-wave, and for this reason it has only 9 bits available for AC measurements.  According to DSP theory, maximum dynamic range is:

DR = 1.77 + 6.02 x B = 1.77 + 6.02 x 9 = 55.95 dB.

 As input audio waveform represents anything but perfect peak-to-peak 5V sine-wave, real dynamic range would be lower. How much? In first, there is a hardware limits.  OPA (NE5532), which is:

  • very low noise !!!
  •  high output-drive capability;
  •  high unity-gain and maximum-output-swing bandwidths;
  •  low distortion;
  •  high slew rate;
  •  input-protection diodes, and output short-circuit protection

 but, unfortunately,  isn’t rail-to-rail type. Test results show, that compression  become noticeable (~1 dB) when not scaled magnitude approaches level about 50 dB. That is in good agreement with observed on oscilloscope not distorted deviation peak-to-peak 2.5 V. Or only half of full range of 5V. And as theory says, half is one bit less, and real DR = 1.77 + 6.02 x 8 = 49.93  (~50 dB). In second, audio data is processed on “block” structure basis. It means, having average of the block 50 dB, doesn’t mean that there was no spikes in the sampling pull, that obviously would be clipped and introduce error in the measurements results.  This phenomenon is defined as Crest Factor. Different sources estimate crest factor of musical content between 10 – 20 dB.  So, taking direct approach, Arduino with OPA mentioned above as front-end could accurately cover only:              50 – 20 = 30 dB.  To get wider dynamic range, I have to scale input amplifier gain, and this is exactly what I did, building amplifier in two stages and selecting one cascade (by-passing second one) or two cascades using internal ADC multiplexer. As there is no switching IC in analog signal path involved, gain is defined with high stability, could be one time precisely measured – calibrated via coefficient stored in EEPROM (nice feature to add).

On the right side there are electrical drawings of “slightly” modified kit,  where stereo amplifier was converted into 2 stage mono version. First stage, with gain about  G1 = 1 + 10 k / 1 k = 11  is necessary to “bump-up” line-level signal, to create DC bias required for correct operation of the ADC, and also served as buffer to lower signal source impedance, as it seen by ADC input.  I set a gain of the second stage amplifier at 40 dB:  20 x Log_10 ( G2 ),     where    G2 = 1 + 100 k / 1 k = 101.

IMHO, setting gain limit for only 30 db per stage as it follows from paragraph above, is overkill, and would be justified for “real-time” radio broadcasting or audio processing for storage media, when high fidelity of audio program must be preserved. For visual display “clipping” of bursts in signal is not noticeable at all due high refresh rate of display, 78 Hz. Human just can’t see, if LED lights-up with such speed.  For steady AC amplitude measurements (micro Voltmeter mode) this is not a problem at all, and headroom as small as 3 dB would be sufficient, leaving wide 47 dB per stage.

 Software

  There are two thresholds are defined in program, where switching between one or two stage amplification is happening:

      if ( magn_new <=  44 ) sensitv = 1;

      if ( magn_new >= 47 ) sensitv = 0;

  44 and 47, with hysteresis 3 dB. First line defines switching to high sensitive mode (overall gain 1100), and second line, does exactly opposite. Look at the chart, hope it would save me a million words -);

 Couple words on using this device as precise AC micro-voltmeter. Having 1100 overall amplification as add-up to already quite sensitive Arduino ADC, driving overall sensitivity to enormously  5 / ( 1024 x 1100 ) = 4.439 uV Special care should be taken on grounding, shielding of amplifier PCB, probably, EMI suppressor ferrite chokes wouldn’t be an excess in power line and signal path.   In my project, w/o any modification to original kit’s board (except couple jumper wires to cascade two stage amplifier) of course, I was not expecting to get to such high sensitivity level. Moreover, in project arduino is driving LED display, “ADC noise reduction mode” is off, plus ADC is working on double speed – preselector set to 250 kHz!!!  And this is why constant 14 was subtracted in software from magn_new, just before it goes for BarGraph “mapping” procedure:

      magn_new  -= 14;

Basically 14 is a noise flour of my analog front-end.  Approximately 51 micro volts AC is turning on first LED bar. Look at the table, which reflect my current hardware set-up.

* Other things to keep in mind, there is a “gap” 78 Hz wide in frequency range at 10 kHz,  It introduces a small error, about  78 / 20.000 = 0.39% in white noise measurements result. For musical content, which has really low power density level at 10 kHz, magnitude of error would be much lower, probably, less than 0.05 %.

 Running FFT in code creates great opportunity to reject any interference in the audio band. For example, if there is a noticeable hum from electrical grid lines in the content, issue easily could be fixed NOT including bin[1] in final sum of magnitude calculation. Though to make it works more efficient, some adjustment in sampling period would be necessary, setting bin[1] frequency precisely at 50/60 Hz.

 One more advantage of having FFT based  filtering     (primary mission is HPF, look in stereo VU meter, how long kernel of the FIR filter has to be otherwise), is great opportunity to create “weighting” A, B, C or D curve for audio noise measurements. (:TO DO).

 Link to Download Arduino sketch:  Audio_VU_Meter_Mono_69dB


**********Stereo Audio VU meter on Arduino**********

This blog is a sequel of “Tears of Rainbow”.  Using the same hardware set-up of Gigantic RGB LED display, I decided to re-work software a little bit, in order to display the true RMS amplitude of musical content. Video clip on youtube:                       VU_Meter   640×480                                      VU_Meter_HD

Objective:

  • Stereo input, process both channel;
  • Full audio band, 40 Hz – 20 kHz;
  • Fast update rate of visual output.
  • Precision Full-Wave  measurements. 

To process stereo input, this time arduino is switching ADC multiplexer every time when it finish sampling input data array (size=128). Two channels “interleaved” with frame rate 78 Hz, so during each frame only one channel sampled / processed, and update rate per channel is equals to 78 / 2 = 39 Hz, which is more than enough for most audio applications.

 I’m using FFT Radix-4  to extract RMS magnitude of audio waveform, and this is why:

1.  Sampling rate in this application is 10 kHz. How I achieved  20 kHz stated in objective section, doing sampling only 10 ksps?  >>>Aliasing!<<<   What is considered to be nightmare when we need spectral information from FFT output, aliasing in this project is really helpful, reflecting all spectral components around  axis – 10 kHz back “to the field”. As all bins going to be sum-up there is no issue, only benefits. Due aliasing, I’m able to use low sampling rate, and reduce CPU workload down to 52%.

2.  In order to get accurate magnitude calculation of RMS,  which is defined as square root of the sum of squares divided by number of samples per specified period of time:    V(rms) = √ ( ∑ Vi ^2 ) / N) DC offset  must be subtracted from the input raw data of each sample    Vi = Vac + Vdc   (if you remember, AtMega328 ADC needs DC offset to read AC negative half-wave).  The problem here, DC offset value is never known with high accuracy due bunch of reason, like voltage stability of PSU,  thermal effects, resistors tolerance (+/- 1 or 5 %), ADC internal non-linearity etc. Cure for this, which works quite well for monitoring electrical grid power, high pass filter (HPF). Only instead of single 50/60 Hz frequency of power line,  I have a wide frequency range, starting from 20 Hz and ending at 20 kHz. When I feed specification of the HPF:

  • Sample Rate (Hz) ? [0 to 20000]                     ? 10000
  • Desired stop-band attenuation (dB) [10 to 200] ? 40
  • Stop-band edge frequency Fa [0 to 5000]         ? 0
  • Pass-band edge frequency Fp [0 to 5000]        ? 40

to  Parks-McClellan FIR filter design algorithm (one of the most popular, and probably, the best) it provides the result:

  • …filter length: 551 …beta: 3.395321

551 coefficient to be multiplied and sum up (MAC-ed) every 100 usec! No way. I’m not sure, if it could be done on 32-bits 100 MHz platform with build-in MAC hardware, but there is no way for 8-bit 16 MHz Arduino.

IIR filter wouldn’t make much difference here. It has lower quantity of multiplications, but more sensitive for truncation and rounding error, so I’d have to use longer (32-bits?) variables, which is not desirable on 8-bit microprocessor at all.

And here comes FFT Radix-4, which easily fulfill this extra-tough requirements in the most efficient and elegant way. All I have to do, is just NOT include bin[0] in final sum, and all DONE!. TOP-FLAT  linear frequency response  40 Hz – 20 kHz  ( -3 dB ), with complete suppression of DC, and low frequency rumble below 20 Hz attenuation.  Linearity is better than +-1 dB between 80 – 9960 Hz.

Last things, audio front-end. As VU meter was designed in stereo version, I’ve build another “line-in”  pre-amplifier based on this kit: Super Ear Amplifier Kit

Link to Download a sketch:  Stereo_VU_Meter.

 

Modified Stereo VU meter, Logarithmic scale, 8 bars per channel, spacing 6 dB.

Dynamic range: 8 x 6 = 48 dB.  Stereo_VU_Meter(Log10).
 Next blog:   Extending dynamic range to 72 dB!