December 30, 2010 by caliliving714 I am attempting to make a pizzo VU meter. My goal is just to use 8 outputs to control 8 LED's. My problem is I don't understand the math/output of the function. Can anyone give me some insight as to how this works? I understand that "blocks" and then to "j" is what is driving the LED's. Guess my main question is how does it use this variable to determine which LED's. I figured if I knew the range in value I could just use if and while statements. Any help would be appreciated. Oh if anyone has the code for the 4 LED sound meter that was mentioned in the 2nd or 3rd newsletter, I sure code use it. Thanks, Mike `````` //diff between min and max represents sound level int16_t diff = max - min; uint8_t j; if(diff == 0) diff=1; double diff_d = 1.0* diff; //turn diff into a double double blocks_raw = 11.0*log10(diff_d) - 10.0; //take log of of the sound level and scale to fit onto the sound meter int8_t blocks; if(blocks_raw >= 0.0) blocks = blocks_raw; else blocks = 0; //sticky max represents the extra bar at the top that slowly appears to get "pushed" up by the sound bar // set new sticky max if(blocks > sticky_max){ sticky_max = blocks; decay_rate = 1; } //decay sticky max if(iterations % 4 == 0){ sticky_max = sticky_max - decay_rate; decay_rate++; //increase the reate of falling so the bar appears to be accelarating down } //redner blocks to display for(j = COLS; j > (COLS-blocks); j--){ ledarray_set_column(j-1,1); } for(; j > 0; j--){ ledarray_set_column(j-1,0); } //render sticky max ledarray_set_column(COLS - sticky_max,1); } return; } void do_bar_test(){ uint8_t i = 0; while(1){ for(i = 0; i < COLS; i++){ ledarray_set_column(i,1); delay_ms(1000); } ledarray_blank(); delay_ms(1000); } } int main() { ledarray_init(); sei(); // start up the Analog to Digital Converter adc_init(); while(1) { do_sound_meter(); do_scrolling_display(); } } `````` Hi caliliving714, The "range" in the math is really defined by the possible values of min and max. Since our ADC is 10 bits the maximum difference between them is 1024, which is the maximum amplitude the buzzer can read. From there we wanted to use a logarithmic scale to display sound since sound is best visualized on a logarithmic scale. Since we know we want to run the diff through a log, we just need to scale it to fit in the 24 bars we have. log10(1025) is about 3.3 so at first we scaled by 7. This was giving us a big baseline value just from ambient noise, so we added an offset of about 10 because it seems about right based on the numbers we were getting. After we subtracted 11, we upped the scale factor to fill out the 24 bars. So at its max 11*log10(1025)-10 is about 23.1, which should completely fill out the array. The process was not extremely scientific, but it works! Once we have a scaled value between 0 and 24 in the blocks variable, we just have to fill out the colums on the LED Array we want. We have two for loops on lines 29-34 of the code above that are responsible for turning on the correct columns. The first for loop starts from the top and turn on "blocks" number of columns on, then the second for loop turns the rest of the columns off. Hope that helps! Let me know if you have specific questions. Humberto Thanks for the reply. I some what understand. A couple more questions for you. If you may. So lets say I want to use 7 LED's. Since 7 goes into 24 evenly. So each LED would represent a 4V difference. Roughly. So I will take that value and say "while block <=5 turn led on."? Thanks for the help. Hi caliliving, I think your best bet is just to rescale blocks_raw into 7. You know for a fact that your maximum diff_d value is 1024. This will happen when the amplitude the sound is saturating the amplifier and your input is swinging from +5V to 0V. So I would try ``````double blocks_raw = 3.0*log10(diff_d) - 2; `````` This would make your max value 7.03 for blocks raw, and anything less than 10 on diff_d give you a value less than 1. After than you can just use if statements to turn on individual pins. Something like ``````if(blocks_raw > 1){ //turn on led 1; } if(blocks_raw > 2){ //turn on led 2; } .... `````` Hope that makes sense. Humberto The soundmeter.c for LCD seems to be incomplete. was it done on purpose? I dont see the function do_sound_meter()....just wondering Hi Rachid, I just went and looked at the file we serving up for sound_meter_lcd.c, and it defines the do_sound_meter() function starting on line 58. Perhaps the file you downloaded got corrupted somehow. Humberto