OK, I'm a complete novice to electronics, and micro controllers, let's get that straight right from the start. Also, I'm new to the board, so if I've posted this in the wrong place I'm very sorry - go easy on me. :-[
I recently bought a Arduino Duemilanove from the very helpful guys over at Oomlaut because I decided that I wanted to learn something new, and maybe try and develop my creative side.
I've been messing around with a few simple projects - probably the usual stuff that a noob like me does to get his hands dirty. My task for this evening was to try and simulate a PWM style brightness control on 8 LEDs driven through a 74HC595 shift register.
OK, first off, the circuit is basically identical to that shown here http://ardx.org/CIRC05 although my layout is slightly different just to get the LEDs in a straight line.
Here is the sketch::
/* ***********************************
* Pseudo PWM of 8 LEDs through a
* 74HC595 Bit Shift register
* By Slugsie - 19th Nov 2009
* ***********************************/
// Setup pin definitions for bit shift register
int dataPin = 2;
int clockPin = 3;
int latchPin = 4;
// Setup array to hold brightnesses for each LED
// Start each LED off with a different brightness
int ledBrightness[] = {0, 1, 2, 3, 4, 0, 1, 2};
// Delay time between each cycle - smaller the better to reduce flicker
int delayTime = 1;
void setup() {
pinMode(dataPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(latchPin, OUTPUT);
}
void loop() {
// Cycle through the brightness pattern BIT by BIT 256 times
for (int iLoop = 0; iLoop <= 256; iLoop++) {
// Stores the BIT pattern for the run
byte bitPattern = 0;
// Cycle through each LED
for (int loopLED = 0; loopLED <=7; loopLED++) {
bitPattern = bitPattern | getBit(loopLED);
}
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, bitPattern);
digitalWrite(latchPin, HIGH);
incrementPWMPosition();
delay(delayTime);
}
// Cycle through brightnesslevels 0 thru 4 for each LED
for (int loopLED2 = 0; loopLED2 <=7; loopLED2++) {
ledBrightness[loopLED2]++;
if (ledBrightness[loopLED2]>4) {
ledBrightness[loopLED2] = 0;
}
}
}
// Increment the position within the brightnessPattern[] from 0 thru 7
int pwmPosition = 0;
void incrementPWMPosition() {
pwmPosition++;
if (pwmPosition > 7) {
pwmPosition = 0;
}
}
// Pattern of BITs that we use to determine if an LED gets power this cycle or not
// The more 1 BITs in the pattern, the brighter the LED will be overall.
// The 1's are spread as much as possible in order to try and reduce flicker.
byte brightnessPattern[] = {B00000000, B00000001, B00010001, B01010101, B11111111};
// BIT mask used to look at an individual BIT in the brightnessPattern[],
// also to set the individual BIT for the LED
byte bitMask[] = {B00000001, B00000010, B00000100, B00001000,
B00010000, B00100000, B01000000, B10000000};
byte getBit(int led) {
if (brightnessPattern[ledBrightness[led]] & bitMask[pwmPosition]) {
return bitMask[led];
}
else {
return 0;
}
}
I did originally have 9 brightnessPattern[]s, but the difference between 6, 7, and 8 bits set was so negligible that I decided it would be better to trim it down a bit.
I'd like to hear any comments on the code. It's been about 20 years since I did any C so I'm very rusty in that area (although I am a software developer by trade so that helps a bit).
My ultimate aim for this is probably to have three 74HC595s running, each one controlling one colour of an RGB LED - although I need to source some of them cheaply first.