K8055 Bar graph VU meter

Hi everyone,

I had fun building my K8055 kit and then I had some more fun modifying the “K8055 Demo” VC# example code to make the board switch the 8 digital outputs on/off in sequence according to the music level from an audio source attached to the A1/A2 analog inputs.

It took me a couple days to refine my code. For the sake of performance, I’ve split the original code that was on the timer1_tick() event handler into 2 threads (thread 1 reads the analog inputs & thread 2 parses these values and finds the correct channel # according to the peak level); besides that, there’s a third thread that actually controls the bar graph based on the results from the 1st and 2nd threads.
The whole effect is switchable via a button on the UI - in order to obtain maximum responsiveness of the LED bar, I had to disable the original 2 timers when the board is put in “Bar graph Mode” (that means: there’s no reading the other inputs or playing with the digital and analog ouputs when the board is in “Bar graph Mode”). I also added a “Bar/Dot Mode” switch to it.

[ul][li]A few known minor “issues”:
[list]
[]Flicker: Those who download my code will notice the bar graph “flickers” a bit. It’s not an annoyance, but it’s noticeable. This is due to the fact I have to blank all the LEDs before I update them with the current voltage value. This blanking interval runs at every 1/4th of a millisecond - it shouldn’t really be noticeable, but since we also have machine cycles being eaten by the code routines and the board itself can only run so fast as the PIC (which is also running code to read the USB data and toggle the digital outputs) we do have some delay being introduced to the process as a whole.
I couldn’t for the life of me, get this working to a point where there’s no flicker and still, the bar graph responds at a reasonable speed to the ever-varying voltage levels. I did spend a considerable amount of time attempting to write some double-buffering routines, but the result always ended up sacrificing the resolution (aka, responsiveness of the bar graph) in exchange for a flickerless display. I decided (since I am the programmer!) to go for resolution rather than “smoothness”. If someone else finds a way to make the best of both worlds, please do not hesitate and share your results.[/li]
[li]“Dot Mode”: Due to the above issues, you may notice that sometimes the “Dot” looks like it’s “all over the place”. Since the LEDs are flickering at a rate that’s slightly slower than the update frequency, sometimes the eye can miss “a dot or two”.[/li]
[li]UI responsiveness: I worked hard to squeeze every cycle out of the program while keeping the UI controls as responsive as I could. But in order to keep the bar graph running at an acceptable speed, the threads’ wait states have a short span, so you may notice that ocasionally, clicking the “Connect” button will yield a “Card Not Found” message. Don’t fret! Just click it again, and this time it should say “Card Connected” as one would expect.[/li][/ul][/
:m][/list:u]

The results have reached a level I’m satisfied with (or, maybe I’m too tired to experiment some more). Due to the board’s response time (and also because my code performs some inevitable loops when in ‘Bar Mode’ to simulate the filling of the LEDs) the effect is not so fast, but it’s quite noticeable.

I know this isn’t really a practical application but I felt like doing it to see how it would look. And I am enjoying watching my board respond to music!

Besides, I believe there’s someone out there crazy enough to wire up each of the 8 digital outputs to thyristors (TRIAC) and assemble a giant bar graph using AC-powered lamps (hi-powered LED, bulb or even those electronic fluorescent type). If anyone actually accomplishes this, I would love to hear about it!

[ul][li]Download:
[list]
The .zip with the VS 2010 (v2.0) project is downloadable from my Google Drive. For those not programming-inclined, the compiled .exe can be found inside the “…\K8055Demo\bin\x86\Release” folder.[/ul][/li][/list:u]

[ul][li]Important notes:
[list]
[]To get the best results from your board’s A/D converter, you need to place a resistor in each of R8/R9 positions (to increase the gain factor, according to the manual). In my experiments, I found that 2 x 820ohm resistors in parallel (2 in each position) will give you maximum peak levels with the audio source volume set to its fullest.[/li]
[li]Don’t forget you’ll need the K8055D.dll file always!![/li][/ul][/
:m][/list:u]

Update: I’ve fixed all of the issues above!
The “UI responsiveness” was fixed just by starting the 2 threads (mentioned earlier) a little bit later than before - Actually, I moved 2 lines of code to the “Connect” button event handler and that was good enough. So now, the UI will respond accordingly when the Connect button is hit (but still, during “Bargraph Mode” the board needs to focus solely on updating the bargraph, so there’s no point in clicking the other controls as both the timer components are disabled in this mode).

The “flicker” was (as I explained) due to some blanking that I was doing on all of the LEDs prior to updating their current value according to the analog voltage level read by the first thread (I was using ClearAllDigital()/SetDigitalChannel(Channel: int)). This is gone, because whilst going through the K8055.dll API documentation one more time I, erm, discovered there’s a slick function, (it goes by the name WriteAllDigital(Data: Longint)), which accepts an integer argument, that will tell it which LEDs I want on or off (according to the binary conversion on the integer), thus allowing me to set them on/off AT ONCE! With that, I no longer needed to blank all of the outputs at every cycle, and as a bonus, I also got rid of the loop that I was performing earlier, in order to simulate the “Bar Mode” LEDs lighting up! So, no more bottlenecks in performance (regardless of “Dot” or “Bar” display mode being selected). Truly amazing.

Aside from those fixes, I’ve also re-factored the class that hosts my threads and thus, I provided a more elegant way to kill any thread at any given time. Finally, I’ve fine-tuned the parser thread (It’s purpose is to break down the analog voltage levels into 8 voltage “ranges”, and then determines which digital output channel each “range” should be assigned to). That “tuning” yielded a slightly more responsive bargraph display that’s a bit more pleasing on the eye than before.
I’ve branded this release v3.0 - I thought it deserved its own new version # as I consider this achievement a new milestone!

The download link to this release is right below. Happy New Year folks!
[ul][li]Download v3.0[/li][/ul]