Like the bouncing ball the Knight Rider effect is something that just has to be done with the Blinkenlight Shield. I will not demonstrate a boring version that switches just some LEDs on and off. I want to have this original style glowing effect. Some of the LEDs must not be fully on but „glow“. This requires so called „pulse width modulation“. That is some of the LEDs will be toggled on and off in rapid succession. If this is done fast enough the eye is does not see a flicker but some dimmer light.
// // www.blinkenlight.net // // Copyright 2011 Udo Klein // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see http://www.gnu.org/licenses/ void setup() { for (uint8_t pin=0; pin<20; ++pin) { pinMode(pin, OUTPUT); } } uint8_t brightness(const int8_t led, const int8_t pos) { switch (abs(led-pos)) { case 0: return 32; case 1: return 16; case 2: return 6; case 3: return 2; default: return 1; } } void pulse_width_modulation(const uint8_t pos) { for(uint8_t times=0; times<10; ++times) { for (uint8_t pass=0; pass<32; ++pass) { for (int8_t led=0; led<20; ++led) { digitalWrite(led, (brightness(led, pos) > pass)); } } } } void loop() { static uint8_t pos=0; while(pos<20) { pulse_width_modulation(pos); ++pos; } while(pos>0) { --pos; pulse_width_modulation(pos); } }
Let’s analyze the sketch. The underlying idea is that the glowing effect is some kind of cursor that has a position that moves back and forth. This is what the main loop takes care of. The brightness function will compute the desired brightness of an LED depending on the LED’s number and the position of the cursor. In between is the pulse_width_modulation. This function will cycle 10 times through 32 phases. For each phase it will cycle through all LEDs. Depending on any LED’s desired brightness and the phase it will switch the LED on and off. For example suppose the brightness function returns 16 for an LED. In this case the LED will be on for phase in 0..15 and off for phase in 16..31. Thus the LED would be on half of the time. Accordingly it will be visibly on but dimmer as an LED that is always on.
Follow me here to other similar effects.
These sketches return many compilation errors. e.g:
for (uint8_t pin=0; pin<20; ++pin) {
Same happened with the bounce sketch.
Could someone refer me to debugged sketches for al theose Blinken lights
Thanks
On my system the sketches compile. Would you kindly give me the error messages from your compiler runs and more details about your system setup such that I can analyze your issue?
All Blinken sketches here return compilation errors e.g.
for (uint8_t pin=0; pin<20; ++pin) {
above
Would appreciate a reference to sketches that work
Thanks
On basic as copied and pasted:
Error Message:
Sorry I could not copy and paste the error message. But if you copy and paste the sketch above that I copied and pasted from:
https://blog.blinkenlight.net/experiments/counting-resets/
you will see the errors. ( after removing line numbers)
In particular the syntax pin<20, and pos<, seem to be repeating in all sketches.
Also the sketches on your web have line numbers that copy along with the code and have to be removed. This too is a pain unless there is an easier way to to copy the sketches
Hope you’ll be able to replicate my sketch and errors per my sketch above .
Thanks for your help.
You copied the markup instead of the sketch. Hover the mouse in the upper right corner to get the plain text file. This should do it.
Indeed that helped eliminate the line numbers. However at the top of the “markup” when I move the mouse at the top right, four icons appear: View source, Copy to Clip board, Print, and “help”. When I click View Source I get a sketch without line numbers which is OK. however, there are some characters in the markup sketch such as “pin<20;” that reappear verbatum that the compiler flags as error. If I correct “pin<20;” to “pin>20;” the error clears and the compiler passes. however the following line 40 still gives error:
40 digitalWrite(led, (brightness(led, pos) > pass));
I’m using UNO 022 on Vista.
I’m still not able to show you the characters giving errors. When I type them as in the sketch, I note in the reply panel, they get corrected. there is something dynamic between the sketch either markedup or as viewed that converts these characters. Once again the character stream in question is ( pin & 1 t ; 20 ) that translate in the transmission to you as pin>20. Same applies wherever this expression is used as in pos, pass, times etc
Hope this help clarify the issue
You are still copying markup instead of code. Please do not click “view source” to copy the sketch. Click “Copy to Clipboard”. Then copy the contents of the clipboard into the editor. This should fix it.
By now I figured out that some of the sketches (3 in total) actually had improper markup. All others were fine. I fixed the 3 affected sketched. Thanks for pointing out this issue to me. I was somewhat thrown off track because you stated that all of my sketches had this issue.
Copy to clipboard works for me with no problems 🙂 I don’t have the shield yet (soon as I can afford it!) but the code copies/pastes clean.
Worked perfectly well on my system!
Great! Do you want to share which kind of system this was? I am running Ubuntu Linux. What about you?
Udo I would just like to thank you for your interesting LED coding for examples, like the Knightrider with PWM. I am finding it useful as a learning exercise modifying your code and just using the eight LED’s in a line that I tend to use for trying and modifying peoples code as an aid to developing my very basic coding skills. I just declared an eight element array so I could change the 20 in the setup for loop down to the 8 required for my minimal setup. It runs perfectly on my Windows XP system. Anyway thanks again and hopefully I’ll see you on the Arduino forum.
Peter Newman / Pedro147 on Arduino forum.
I also took the liberty of slightly modifying your code for beginners and posted it here
http://www.mediafire.com/download/dsfwmiu844r428d/_8_LED_Blinkenlight.ino
I got the uno today and tried this out as my first experiment it worked a treat. Thanks 😀
Clever code. Really, really clever. Took me a bit of time to figure out your fake PWM function, which I do by trying to comment code (forces me to analyse it thoroughly). I adapted it to my own nefarious purposes, but thought perhaps my comments may be handy to those who want to learn from your example. Pardon my conversion of uint8_t to Arduino shorthand – it was an extra level of distraction I didn’t need while parsing out your logic.
//Assign ring levels to appropriate I/O line
#define r1 13
#define r2 12
#define r3 11
#define r4 10
#define r5 9
#define r6 8
#define r7 7
const int ledRings[] = {r1, r2, r3, r4, r5, r6, r7}; //Set me up the list of pins to be used with the LEDs
int ringCount = 7; // Number of elements we’re USING in array (0 to 5 = 6)
void setup()
{
for (int thisRing = 0; thisRing < ringCount; thisRing++) {
pinMode(ledRings[thisRing], OUTPUT);
}
}
byte brightness(const int led, const int pos) { //Test each LED for distance from focused position. The further way it is, ramp the brightness down
switch (abs(led-pos)) {
case 0: return 32; // LED IS the Pos'n? Make it full bright (32/32)
case 1: return 16; // 1 LED away from Pos'n? Make it 1/2 bright (16/32)
case 2: return 6; // 2 LEDs away? 6/32 (19% bright)
case 3: return 1; // 3 LEDs away? 1/32 on (3% bright)
default: return 1; // Even further away? Just make it barely on (3%)
}
}
void pulse_width_modulation(const byte position) { //Position is the present focused LED location
for(byte times=0; times<80; ++times) { // Loop "times" higher for a slower action
for (byte brightLevel=0; brightLevel<32; ++brightLevel) { // Start of "fake" PWM. Looping thru all 32 levels of brightness that are available, from off (0) to full on (32)
for (int led=0; led brightLevel)); //If tested brightness value is greater than brightLevel, turn it on
}
}
}
}
void loop() {
static int pos=0;
while(pos0) {
–pos;
pulse_width_modulation(pos);
}
*/
}
/*
Let’s analyze the sketch.
The underlying idea is that the glowing effect is some kind of cursor that has a position that moves back and forth.
This is what the main loop takes care of.
The brightness function will compute the desired brightness of an LED depending on the LED’s number and the position
of the cursor.
In between is the pulse_width_modulation. This function will cycle 10 times through 32 phases.
For each phase it will cycle through all LEDs.
Depending on any LED’s desired brightness and the phase it will switch the LED on and off.
For example: Suppose the brightness function returns 16 for an LED.
In this case the LED will be on for phase in 0..15 and off for phase in 16..31.
Thus the LED would be on half of the time. Accordingly it will be visibly on but dimmer as an LED that is always on.
*/
Whups. Had some of the code collapsed. Let’s try that again… This time on Pastebin. What was I thinking…
http://pastebin.com/7Qwirhcz
I modified your code lightly to terms I was more familiar with as well as declaring an eight element array so I could change the 20 in the setup for loop down to the 8 required for my minimal setup. I have posted this code at
http://www.mediafire.com/download/dsfwmiu844r428d/_8_LED_Blinkenlight.ino
Hello Sir,
After reading this, I took the liberty of creating a visual representation of how the code loops work using Microsoft Excel in the following link:
https://www.dropbox.com/s/nn9ltsphrnzgxjp/Knight%20Rider%20code%20visualization.xlsm?dl=0
I’m hoping that this might be an added value to anyone who finds this interesting or finds the code a little bit confusing to follow.
I would be more than glad if you could put this sheet here as a helping tool 🙂
Many thanks for sharing your great experiments.
—
Shereef
Hi Shereef,
cool work and thanks for sharing. I would prefer to upload it to my site instead of having some dropbox link. Please add your copyright and a license note to your excel and I will upload it. For example GPL would be a very suitable license because my stuff is GPLed as well.
Best regards,
Udo
very njce implementation of software pwm , thanks for the very smart code. we have made a knight rider 15LED with my son on an arduino mini (pin2 until pin16 AKA A2).
for the others that find the code a bit kryptic , the times value sets the speed, and if you want the LEDs to fade completely on the right side use a higher value than the number of LEDs you have here while(pos<20) {
Unfortuntaley doing the same on the left side is not so easy, as negative numbers don't work well 🙂
thanks again for the fishes