Microprocessor based meter project

Help Support GroupDIY:

JohnRoberts

Well-known member
Staff member
Moderator
Joined
Nov 30, 2006
Messages
21,494
Location
Hickory, MS
I have been asked off list to give advice about a microprocessor based meter project... I am more than willing to share stuff I learned the hard way, but am unwilling to engineer another one-off meter project for free...

Design with microprocessors is only a fraction about code and algorithms, and a significant part of glue circuitry (PS etc) and set up... Modern micros have a lot of flexibility so use requires setting the I/O  for proper mode, and firmware or middleware.

I typically use Microchip processors but know that other coders have different favorites.  So the floor is open for other suggestions.

The last micro project I did (not a meter actually) used a  PIC24HJ32GP304... I like the features but it might be worth looking at modern offerings in case there is newer better stuff in the years since I last looked at this stuff.

The PIC24H family is 16 bit  (I refuse to use 8 bit again, too much effort dealing with variables than need more resolution), 40 MIPS which seems adequately fast... Internal 12 bit A/D which in my experience is adequate dynamic range for most audio metering. (If needed one could scale inputs dynamically to handle wider range).

The PIC comes with an internal frc (free running clock) so you can run it at 7MHz without an external crystal.

I write in machine language but the PIC instruction set supports C compilers.

The chips come in a mix of flash memory, ram, and number of pins... You don't need a 44 pin package for a simple meter.  While I managed to use all 44 pins in an automatic mixer design.

I would use a PIC in combination with a TI LED latch driver... something like a TLC59025  (16 LED). These can be updated via SPI by pushing a 16bit word with 1 representing on, 0 representing off... These can be stacked in series to push out longer than 16 bit data streams, or chips can be networked in parallel with separate chip enable lines.... They also make 8 LED versions but 16 is a nice round number for meters.

FWIW In that console meter I did years ago, we used a  HCT logic shift register for the LED latches and I had some issues with the SPI communication.... Using a 3.3V micro driving a 5V logic chip with passive (open drain) pullup on the clock led to mis-clocking if there was noise on the passive pullup line...  I worked around that with my own SPI routine 9that I have used in designs ever since. 

I suspect with the same logic PS there would be no problem pushing data using the canned internal SPI firmware.

==========

I invite others to suggest other microprocessor families now before a family and path is chosen.

The rest is details. (lots of details)

JR
 

ruffrecords

Well-known member
Joined
Nov 10, 2006
Messages
13,964
Location
Norfolk - UK
As you hinted, factors other than just writing code come into the decision. One factor, especially if you write in machine code, is familiarity with a family of microprocessors. If one in that family will do the job it is a very hard sell to change to a different one.

Cheers

Ian
 

joaquins

Well-known member
Joined
Feb 25, 2012
Messages
1,927
Location
Argentina
  I don't think coding in machine language is optimal, at least not for a simple project like this that can be easily done in C, even if the code is not that efficient more powerful micros are cheap and time to code like this instead of in a higher language is expensive. Maybe for a really massive production might worth the effort to go with the tiniest micro possible but not for a DIY project

  I know is not seen as serious but I do like the arduino platform, is not much what you can do with the arduino environment alone but atmel documentation is great and you just can play with the registers and low level stuff directly without problems inside the same environment. Also boards availability is the best. Here I can get an arduino cheaper than an USB FTDI chip alone, even comparing it with the micro alone (here at least) the boards are cheap, I couldn't get that prize if building from spare parts.

  If I would go this way I'd probably grab an Arduino nano or a micro and drive the LEDs directly, 10 bit ADCs are a bummer but as you pointed you could do auto rescale if wanted. I know the MEGA has an internal PGA, I don't know about the small ones but if not there are solutions easy enough just using an extra pin. With this approach I would have one running in an hour maybe, and $5 worth per channel. PSU and all the glue is already in the board bought for $3, add a buffer if you prefer so, the LEDs and resistors and you are good to go.

Sorry for oversimplifying the project but I don't know if it deserves more.

JS
 

JohnRoberts

Well-known member
Staff member
Moderator
Joined
Nov 30, 2006
Messages
21,494
Location
Hickory, MS
ruffrecords said:
As you hinted, factors other than just writing code come into the decision. One factor, especially if you write in machine code, is familiarity with a family of microprocessors. If one in that family will do the job it is a very hard sell to change to a different one.

Cheers

Ian
Indeed, I got my feet wet supporting an existing product that was designed (by someone else) using an old 8 bit Microchip PIC... At this point I do not feel like learning a new batch of secret handshakes...

I Invite other family suggestions and other supporters...

I do not want to become the microchip support guy, either.

The meter code is kind of fun, everything else is like work...

JR
 

JohnRoberts

Well-known member
Staff member
Moderator
Joined
Nov 30, 2006
Messages
21,494
Location
Hickory, MS
joaquins said:
  I don't think coding in machine language is optimal, at least not for a simple project like this that can be easily done in C, even if the code is not that efficient more powerful micros are cheap and time to code like this instead of in a higher language is expensive. Maybe for a really massive production might worth the effort to go with the tiniest micro possible but not for a DIY project
Fine I nominate you to be the C guy....  I actually took one semester of C in night school (but it was a joke, c programs run on a PC). When I got serious about programming micro's I bought a C compiler (hundreds of dollars back then), but the machine language explanations for what the C did, made a ton more sense than C , so I never used that compiler, just wrote machine code that directly did what I wanted. 

Back in the '70s I wrote a ton of code using Basic, ran my mail order business with software I wrote myself, even a fancy filter design program. Back in college ('60s) we did engineering homework using Fortran (running  on an IBM 360 mainframe).
  I know is not seen as serious but I do like the arduino platform, is not much what you can do with the arduino environment alone but atmel documentation is great and you just can play with the registers and low level stuff directly without problems inside the same environment. Also boards availability is the best. Here I can get an arduino cheaper than an USB FTDI chip alone, even comparing it with the micro alone (here at least) the boards are cheap, I couldn't get that prize if building from spare parts.
One vote for arduino... I will vote for anything but PIC so I don't have to support it, make that 2 votes..  ;D
  If I would go this way I'd probably grab an Arduino nano or a micro and drive the LEDs directly, 10 bit ADCs are a bummer but as you pointed you could do auto rescale if wanted. I know the MEGA has an internal PGA, I don't know about the small ones but if not there are solutions easy enough just using an extra pin. With this approach I would have one running in an hour maybe, and $5 worth per channel. PSU and all the glue is already in the board bought for $3, add a buffer if you prefer so, the LEDs and resistors and you are good to go.

Sorry for oversimplifying the project but I don't know if it deserves more.

JS
No simple is good... Simple I do not have to do, is even better.

JR
 

Bo Deadly

Well-known member
Joined
Dec 22, 2015
Messages
2,746
Location
New Jersey, USA
You might consider something with slew rate limiting. I tried CAT4016 (which looks a lot like TLC59025) and I found the switching was so fast, no amount of bypassing could stop it from polluting grounds. I use MAX7221 which has the slew rate limiting but it's also the scanning / segmented type of driver which may not be right / necessary for a VU meter.

As for the processor, I use Arduino but I'm also driving relays, reading tactile buttons, saving state in EEPROM and doing things that are just not necessary for simple VU meter. So I would agree that PIC would be fine. And it would take up less space.

But if this is potentially going into something with sensitive high gain circuitry like a mic pre, then squelching ground noise would be my focus. And that is inextricably linked to the power supply which is another issue if this is going to be retrofitted into existing projects. You could put a DC-DC converter on your PCB and then AC isolate the entire thing from the sensitive analog bits with a common mode choke and caps. Although then you might need differential ADC inputs. Just thinking out loud though ...
 

JohnRoberts

Well-known member
Staff member
Moderator
Joined
Nov 30, 2006
Messages
21,494
Location
Hickory, MS
squarewave said:
You might consider something with slew rate limiting. I tried CAT4016 (which looks a lot like TLC59025) and I found the switching was so fast, no amount of bypassing could stop it from polluting grounds. I use MAX7221 which has the slew rate limiting but it's also the scanning / segmented type of driver which may not be right / necessary for a VU meter.
I don't know if this is an important difference but the 59025 series are current sinks, so edge rate will depend on stray capacitance and could easily be slowed down if you want... Of course the ground layout needs to be away from audio to prevent corrupting the ground.
As for the processor, I use Arduino but I'm also driving relays, reading tactile buttons, saving state in EEPROM and doing things that are just not necessary for simple VU meter. So I would agree that PIC would be fine. And it would take up less space.

But if this is potentially going into something with sensitive high gain circuitry like a mic pre, then squelching ground noise would be my focus. And that is inextricably linked to the power supply which is another issue if this is going to be retrofitted into existing projects. You could put a DC-DC converter on your PCB and then AC isolate the entire thing from the sensitive analog bits with a common mode choke and caps. Although then you might need differential ADC inputs. Just thinking out loud though ...
Yes, this is not heavy lifting for any micro...  I like the built in 12 B a/ds

The audio is getting significantly padded down to less than 3.3V full scale (from 30V), so ground differences should not be significant A differential input could be used for a stand alone meter.

JR

 

joaquins

Well-known member
Joined
Feb 25, 2012
Messages
1,927
Location
Argentina
JohnRoberts said:
Fine I nominate you to be the C guy....  I actually took one semester of C in night school (but it was a joke, c programs run on a PC). When I got serious about programming micro's I bought a C compiler (hundreds of dollars back then), but the machine language explanations for what the C did, made a ton more sense than C , so I never used that compiler, just wrote machine code that directly did what I wanted. 

Back in the '70s I wrote a ton of code using Basic, ran my mail order business with software I wrote myself, even a fancy filter design program. Back in college ('60s) we did engineering homework using Fortran (running  on an IBM 360 mainframe).One vote for arduino... I will vote for anything but PIC so I don't have to support it, make that 2 votes..  ;D

No simple is good... Simple I do not have to do, is even better.

JR


  Ok, now it's itching, now I have somewhere to be but maybe tonight I put something together. I've been out of the forum for a while, maybe a good way to come back. I think I have all the parts in the bin.

  I'm not a great programmer, I even use the GOTO function in C  :-\ (my coder friend is tired of kidding me with that, I call him for every serious coding project) but most I've done is C for embedded.

  I'd like to use your bar/dot display if you are ok with it.

squarewave said:
You might consider something with slew rate limiting. I tried CAT4016 (which looks a lot like TLC59025) and I found the switching was so fast, no amount of bypassing could stop it from polluting grounds. I use MAX7221 which has the slew rate limiting but it's also the scanning / segmented type of driver which may not be right / necessary for a VU meter.

As for the processor, I use Arduino but I'm also driving relays, reading tactile buttons, saving state in EEPROM and doing things that are just not necessary for simple VU meter. So I would agree that PIC would be fine. And it would take up less space.

But if this is potentially going into something with sensitive high gain circuitry like a mic pre, then squelching ground noise would be my focus. And that is inextricably linked to the power supply which is another issue if this is going to be retrofitted into existing projects. You could put a DC-DC converter on your PCB and then AC isolate the entire thing from the sensitive analog bits with a common mode choke and caps. Although then you might need differential ADC inputs. Just thinking out loud though ...

  I'd try to avoid extra chips and serial ports, single self contained unit is usually easier to deal with noise. I rather prefer to have a dedicated µC for each VU (maybe 2 channels) The things are cheap enough to try harder to drive several channels with a single chip, the wiring and lack of flexibility might be more trouble than a single unit per µC. Also my approach has it's own regulator so PS is already solved, you might want to have a lower rail dedicated as max input is 12V and driving the LEDs could end overheating the LDO, but unregulated 7V to 9 V should be fine.

  I do like the idea for differential ADC, I'm not sure I'm going to be able to fit it all in a single nano. I was counting the exact amount of pins to do dual channel, using 2 inputs, 2 pins reserved if gain changed is needed, 8 LEDs and the spare 2 for mode and hold. Just enough with the 22 I/O pins I have. For a single channel it's ok. If I end with differential ADC I'd be out of pins so I'd have to manage the ranging differently. (or do something clever to save a few pins)

JS
 

JohnRoberts

Well-known member
Staff member
Moderator
Joined
Nov 30, 2006
Messages
21,494
Location
Hickory, MS
joaquins said:
  Ok, now it's itching, now I have somewhere to be but maybe tonight I put something together. I've been out of the forum for a while, maybe a good way to come back. I think I have all the parts in the bin.

  I'm not a great programmer, I even use the GOTO function in C  :-\ (my coder friend is tired of kidding me with that, I call him for every serious coding project) but most I've done is C for embedded.
I used tons of goto statements in my old BASIC programs but is is supposed to be a no no for clean programming that doesn't get lost in lala land..

In machine language you don't even have to say goto, just "bra" (same thing) but you can attach all kinds of conditional constraints to the branch instructions, if this go there, etc..
  I'd like to use your bar/dot display if you are ok with it.
The patent is expired and it is free for the world to use.... I can't imagine a meter that doesn't use it, so please do.

I prefer to use equal weight 3dB steps so crest factor can be easily computed from the distance between dot and bar...
  I'd try to avoid extra chips and serial ports, single self contained unit is usually easier to deal with noise. I rather prefer to have a dedicated µC for each VU (maybe 2 channels) The things are cheap enough to try harder to drive several channels with a single chip, the wiring and lack of flexibility might be more trouble than a single unit per µC. Also my approach has it's own regulator so PS is already solved, you might want to have a lower rail dedicated as max input is 12V and driving the LEDs could end overheating the LDO, but unregulated 7V to 9 V should be fine.
I moved to external latch because the family of PIC I like doesn't drive LEDs adequately from all pins (just some)... the old 8 bit PICs is used could drive LEDs OK  (i even multiplexed rows and columns but that could get noisy). I refuse to write 8 bit code any more.


  I do like the idea for differential ADC, I'm not sure I'm going to be able to fit it all in a single nano. I was counting the exact amount of pins to do dual channel, using 2 inputs, 2 pins reserved if gain changed is needed, 8 LEDs and the spare 2 for mode and hold. Just enough with the 22 I/O pins I have. For a single channel it's ok. If I end with differential ADC I'd be out of pins so I'd have to manage the ranging differently. (or do something clever to save a few pins)

JS
Do whatever floats your boat...  less for me.

JR
 

Bo Deadly

Well-known member
Joined
Dec 22, 2015
Messages
2,746
Location
New Jersey, USA
Another thing to consider regarding avoiding ground noise is running it from bipolar power (which many audio projects have) so that you're not dumping current into ground at all. You really would need differential ADCs then but lots of micros have at least a differential mode.
 

JohnRoberts

Well-known member
Staff member
Moderator
Joined
Nov 30, 2006
Messages
21,494
Location
Hickory, MS
Martin Griffith said:
What sort of time constants, display attack and release times  seems acceptable, or are there any EBU type standars worth browsing?
I have been messing with this for decades and I have standardized on 4 mSec attack for Peak, 200 mSec attack for ave/VU, and 200 mSec release for both... Note: making the release rate the same for Peak and VU, with simultaneous displays, causes the two displays to decay equally when the music stops, making it easier to read crest factor (difference between peak and VU) .

JR
 

JohnRoberts

Well-known member
Staff member
Moderator
Joined
Nov 30, 2006
Messages
21,494
Location
Hickory, MS
squarewave said:
Another thing to consider regarding avoiding ground noise is running it from bipolar power (which many audio projects have) so that you're not dumping current into ground at all. You really would need differential ADCs then but lots of micros have at least a differential mode.
Treating audio paths differentially makes it possible to cancel out common mode noise.

LED displays are generally driven from single supply devices, so there will be a dirty grounds to manage... but they are being communicated with using digital logic, so ground noise is not an issue there.

Audio 0V should not be corrupted by display grounds, but it all matters .

JR
 

ruffrecords

Well-known member
Joined
Nov 10, 2006
Messages
13,964
Location
Norfolk - UK
I would also vote for the Arduino. A good range of processors, affordable , usable boards, free development tools that run on any platform and excellent community support.

Cheers

IAn
 

JohnRoberts

Well-known member
Staff member
Moderator
Joined
Nov 30, 2006
Messages
21,494
Location
Hickory, MS
JohnRoberts said:
I have been messing with this for decades and I have standardized on 4 mSec attack for Peak, 200 mSec attack for ave/VU, and 200 mSec release for both... Note: making the release rate the same for Peak and VU, with simultaneous displays, causes the two displays to decay equally when the music stops, making it easier to read crest factor (difference between peak and VU) .

JR
I just thought of another possible feature....  The 4mSec peak attack time is based on psychoacoustics regarding audibility of brief transients... but some digital paths do not like any overload no matter how brief***.

With digital decision making we can detect for brief transient peaks with no attack time slowing, but only report for the single highest peak amplitude level, hold for perhaps a second, then clear it. It would look visually different than the moving peak level so be easy to discern which is which.

I did something similar in my console meter. The customer had the option to turn off the peak and only see a slow VU/ave display, in that mode the top LED would be lit for just the max peak level (albeit slowed by the 4mSec attack).

This is not heavy lifting for any reasonable processor platform and adds a perhaps useful feature for audio paths sent to digital.

JR

*** old digital paths would roll-over beyond full scale and get really nasty... modern decent digital paths clip relatively harmlessly, acting more like analog in that respect.
 

joaquins

Well-known member
Joined
Feb 25, 2012
Messages
1,927
Location
Argentina
Well, I have something working at least. Last night I ended up with friends all night, tonight I'm on it.

Very crude but something working, attached 3 resistors and 1 cap to have a HPF to Vref/2 and attenuator from the signal going in to A0 of an aurduino nano, and 9 LEDs I found in the box already soldered to a resistor to digital pins 4 to 12.

A crude code, using a sample frequency of 9615Hz I get 10 useful bits, set the ADC for free running (one sample after another). The ADC takes 13 cycles to complete a convertion (16MHz / 128 prescaler / 13 cycles makes 9615.4 Sa/s)  but the sample and hold circuit takes less than 2 cycles I should get some response up to 31kHz, of course I'm oversampling and counting on aliasing but I can live with that. Frequency response won't be perfect, the thing as crude as it is does respond fine up to 20kHz sine waves. It does act up a little around fs, fs/2 and fs*2, but that's to be expected.

Using power of two as the divider for the filter I can avoid making a division and just shifting to make things faster. The VU filter ends b1=0.9995 and a1=0.0005 making the time constant about 200ms with fs=9600kHz (IIRC)

For the peak I used the maximum peak detection (easier to implement) no 4ms time constant here. Of course it could be changed. The same release timing makes it work as supposed.

Making the processing inside the conversion complete interrupt isn't optimal but saves some time and makes every captured sample to be processed, this could be optimized but I think it can work as a first step. I shift 10 bits up the sample, and the average has 10 bits after the decimal point. Using 32b unsigned I can play around with it loosing only one LSB per sample. I should be able to shift one bit more but up and loose nothing but then this would be the slowest filter I can implement in this way.

The output is done once every 100ms with the Arduino digitalWrite function, this could be optimized I guess writing directly to the registers. Value for each LED is given at the start of the code, for the 7 LEDs I used, 3 options commented for 1.5dB, 3dB and 6dB steps.

Here is the code:
unsigned long timeLEDs=0UL, delayLEDs=100UL, sampleAbs=0UL, VU=0UL, maxPeak=0UL;
int sample=0, DC=513;
unsigned int VUo=0U, maxPeako=0U;

//1.5dB steps:
//unsigned int L4=16462U, L5=19565U, L6=23253U, L7=27636U, L8=32846U, L9=39037U, L10=46396U, L11=55142U, L12=65535U;
//3dB steps:
unsigned int L4=4096U, L5=5793U, L6=8192U, L7=11585U, L8=16384U, L9=23170U, L10=32768U, L11=46341U, L12=65535U;
//6dB steps:
//unsigned int L4=256U, L5=512U, L6=1024U, L7=2048U, L8=4092U, L9=8192U, L10=16384U, L11=32768U, L12=65535U;

ISR(ADC_vect){
  sample=ADCL+(ADCH<<8 )-DC;
  sampleAbs=abs(sample);
  sampleAbs=sampleAbs<<10;
  VU=(VU*2047+sampleAbs)>>11;
  maxPeak=(maxPeak*2047)>>11;
  maxPeak=max(sampleAbs,maxPeak);
}
void setup(){
  ADMUX=  0b01000000;
  ADCSRB= 0b01000000;
  ADCSRA= 0b11101111;
  pinMode(4,OUTPUT);
  pinMode(5,OUTPUT);
  pinMode(6,OUTPUT);
  pinMode(7,OUTPUT);
  pinMode(8,OUTPUT);
  pinMode(9,OUTPUT);
  pinMode(10,OUTPUT);
  pinMode(11,OUTPUT);
  pinMode(12,OUTPUT);
 
}

void loop(){
  if(millis()>timeLEDs){
    timeLEDs=millis()+delayLEDs;
    if(VU>L4||(maxPeak>L4&&maxPeak<L5)){    digitalWrite(4,HIGH);}
    else{                                  digitalWrite(4,LOW);}
    if(VU>L5||(maxPeak>L5&&maxPeak<L6)){    digitalWrite(5,HIGH);}
    else{                                  digitalWrite(5,LOW);}   
    if(VU>L6||(maxPeak>L6&&maxPeak<L7)){    digitalWrite(6,HIGH);}
    else{                                  digitalWrite(6,LOW);}
    if(VU>L7||(maxPeak>L7&&maxPeak<L8)){    digitalWrite(7,HIGH);}
    else{                                  digitalWrite(7,LOW);}
    if(VU>L8||(maxPeak>L8&&maxPeak<L9)){    digitalWrite(8,HIGH);}
    else{                                  digitalWrite(8,LOW);}
    if(VU>L9||(maxPeak>L9&&maxPeak<L10)){  digitalWrite(9,HIGH);}
    else{                                  digitalWrite(9,LOW);}
    if(VU>L10||(maxPeak>L10&&maxPeak<L11)){ digitalWrite(10,HIGH);}
    else{                                  digitalWrite(10,LOW);}
    if(VU>L11||(maxPeak>L11&&maxPeak<L12)){ digitalWrite(11,HIGH);}
    else{                                  digitalWrite(11,LOW);}
    if(VU>L12||(maxPeak>L12)){              digitalWrite(12,HIGH);}
    else{                                  digitalWrite(12,LOW);}
  }
}
Well, waiting for comments...
JS
 

Attachments

  • VU3.jpg
    VU3.jpg
    350.3 KB · Views: 21

joaquins

Well-known member
Joined
Feb 25, 2012
Messages
1,927
Location
Argentina
ruffrecords said:
What happens when timeLEDS overflows?

Cheers

Ian
  I'll let you know in 49 days, 17 hours, 2 minutes and 47.3 seconds, but they could freeze, or they could just keep working fine as the variable overflows in time with the millis() function.

JS

PS: giving it a second thought, it might update the LEDs faster giving it a different look, that for some time every the 49 days and change, how much time would not be easily known as the updates aren't exactly in sync with the readings, and they could be interupted in the middle of the business but what is known is that it would be less than 100ms.
 

JohnRoberts

Well-known member
Staff member
Moderator
Joined
Nov 30, 2006
Messages
21,494
Location
Hickory, MS
joaquins said:
Well, I have something working at least. Last night I ended up with friends all night, tonight I'm on it.

Very crude but something working, attached 3 resistors and 1 cap to have a HPF to Vref/2 and attenuator from the signal going in to A0 of an aurduino nano, and 9 LEDs I found in the box already soldered to a resistor to digital pins 4 to 12.

A crude code, using a sample frequency of 9615Hz I get 10 useful bits, set the ADC for free running (one sample after another). The ADC takes 13 cycles to complete a convertion (16MHz / 128 prescaler / 13 cycles makes 9615.4 Sa/s)  but the sample and hold circuit takes less than 2 cycles I should get some response up to 31kHz, of course I'm oversampling and counting on aliasing but I can live with that. Frequency response won't be perfect, the thing as crude as it is does respond fine up to 20kHz sine waves. It does act up a little around fs, fs/2 and fs*2, but that's to be expected.
Yes you can undersample without problem as aliases are full amplitude, just folded down in pitch.  I dithered the sampling a little to prevent combing at sample frequency but that is not much of an issue in real world use.
Using power of two as the divider for the filter I can avoid making a division and just shifting to make things faster. The VU filter ends b1=0.9995 and a1=0.0005 making the time constant about 200ms with fs=9600kHz (IIRC)

For the peak I used the maximum peak detection (easier to implement) no 4ms time constant here. Of course it could be changed. The same release timing makes it work as supposed.
4 mSec peak time constant may be archaic with all the digital paths in use these days.
Making the processing inside the conversion complete interrupt isn't optimal but saves some time and makes every captured sample to be processed, this could be optimized but I think it can work as a first step. I shift 10 bits up the sample, and the average has 10 bits after the decimal point. Using 32b unsigned I can play around with it loosing only one LSB per sample. I should be able to shift one bit more but up and loose nothing but then this would be the slowest filter I can implement in this way.

The output is done once every 100ms with the Arduino digitalWrite function, this could be optimized I guess writing directly to the registers. Value for each LED is given at the start of the code, for the 7 LEDs I used, 3 options commented for 1.5dB, 3dB and 6dB steps.

Here is the code:Well, waiting for comments...
JS
Nice that looks short... mine was hundreds (thousands) of lines long.  But I was doing lots of extra stuff and multiplexing between 6 audio inputs to 4 meter outputs.

100mSec is probably fast enough to appear real time.

JR
 

joaquins

Well-known member
Joined
Feb 25, 2012
Messages
1,927
Location
Argentina
JohnRoberts said:
Yes you can undersample without problem as aliases are full amplitude, just folded down in pitch.  I dithered the sampling a little to prevent combing at sample frequency but that is not much of an issue in real world use.
It might be a nice touch to implement to the final version, I don't like that misbehavior that goes up and down with a sine. I would end with a lower sample rate but that should be fine. Same thing if using two channels.

4 mSec peak time constant may be archaic with all the digital paths in use these days.
I intend to have a mode switch and a peak hold to have different display modes, only VU, only peak, bar dot, floating bar. It could also have two peak time responses.
Nice that looks short... mine was hundreds (thousands) of lines long.  But I was doing lots of extra stuff and multiplexing between 6 audio inputs to 4 meter outputs.

100mSec is probably fast enough to appear real time.

JR
  In C things are much shorter, compilers are efficient enough if you have care (like avoiding unnecessary divisions and floating point) The code takes less than 2kB as it is and only 27 bytes of global variables. I don't like to use local variables in this kind of code as I only have 2kB of memory and using functions with not defined calls might overflow the memory, hard to keep track of that when the code gets larger. I do intend to add at least two channels. A gain reduction input option would also be nice so it can be used in compressors.

  100ms looks a bit slow but it was a decision I made, as the thing I don't like about analog meters is the blurring effect some have, it kind of appear half bright when the level is in the limit, with digital ones the LED is even on or off but it can blur if the update is too fast. I might make things a bit faster and add some hysteresis or hold so it looks smoother. I wish to know Dorrough's parameters!

  I still have to add some option for the extended range, as with only 10 bits it get's a bit short, using 9 LEDs, 6dB steps I would get the dot lit a few LEDs up. If intended to be used with 16 LEDs 3dB steps this would still be an issue. This µC doesn't have PGAs, so I have to implement something external, hopefully simple enough. I want to try using a digital pin as input (set to high Z) when not attenuating and as output (low Z) to attenuate. I have to overcome the DC offset, not to shift when switching, so I don't loose the sample, and the trigger for this, which could be the last conversion to go up and the output to go down in gain.

JS
 

Latest posts

Top