Skip to content

Instantly share code, notes, and snippets.

@atuline
Created November 1, 2015 20:49
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save atuline/2e8e165d73b9a57a39a7 to your computer and use it in GitHub Desktop.
Save atuline/2e8e165d73b9a57a39a7 to your computer and use it in GitHub Desktop.
/* Arduino UNO with 3x3 LED Array using row column scanning with PWM and only using built in ports.
*
* Author: Andrew Tuline
*
* Date: July 14, 2012
*
* This does not use any 3rd party chips, thus easy to use in a Lilypad.
*
* Uses synchronized PWM to support LED brightness.
*
* Neither the Arduino's analogWrite, nor the softPWM library worked for me with row/column scanning.
* The LED's blinked, so I created a synchronized PWM capability in order to minimize blinking.
*
* The default for cathodes is HIGH and LOW for anodes. We will be applying PWM to the cathodes,
* which lends itself nicely to a common anode configuration for RGB LED's later on.
*
* Seems to crash every so often, so I'm trying to be careful with usage of variables.
*
*/
int mydelay = 500; // used to determine how often to change LED values
int oldmillis = 0; // a counter to support the delay value above
const int row[] = {3, 5, 6}; // rows are anodes. Consider them 'common' anodes
const int col[] = {11, 10, 9}; // columns are cathodes and will have PWM applied to them
int pixels[3][3]; // 2-dimensional array of pixels;
int mycounter = 0; // used for PWM on each LED
void setup () {
for (int i=0; i<3; i++) {
pinMode(row[i], OUTPUT); // initialize Arduino ports as OUTPUT for the rows and columns
pinMode(col[i], OUTPUT);
digitalWrite(col[i], HIGH); // turn off pixel to start by setting the cathode HIGH
} // for
randomSeed(analogRead(0)); // randomizer
Serial.begin(9600); // console setup, only used for debugging
} // setup()
void loop() {
readSensors();
refreshScreen();
} // loop()
void readSensors() { // this routine changes the value of the LED's, but only after a delay time
if (int(millis()/mydelay) == oldmillis) { // only change values if we've not done so in 'mydelay' milliseconds
++oldmillis; // increase the counter used to count the time between changing LED values
mycounter = 0; // reset the refresh counter that's used for PWM so it doesn't cause the 9999 value below to strobe occasionally
for (int x=0; x<3; x++) { // change the values for ALL of the LED's
for (int y=0; y<3; y++) {
pixels[x][y] = int(random(0, 5)*20); // this is a PWM value, the higher the number, the fewer the times the LED will be pulsed
if (pixels[x][y] == 80) { // even a long duration of PWM is > 0 pulses, so let's represent OFF somehow
pixels[x][y] = 9999; // this value represents an LED that is turned off. Testing has shown that 'mycounter' doesn't go this high
}
}
}
}
} // readSensors()
void refreshScreen() {
mycounter++; // use a counter that will be bitwise AND'ed with the pixel value to determine if a LED is turned on or not
for (int thisRow = 0; thisRow<3; thisRow++) { // enable a row by setting the anode to high
digitalWrite(row[thisRow], HIGH);
for(int thisCol = 0; thisCol<3; thisCol++) { // now we go column by column
int thisPixel = pixels[thisRow][thisCol];
if ((mycounter & thisPixel) == thisPixel) { // depending on the PWM value we will turn on the LED . .
digitalWrite(col[thisCol], LOW); // by setting the cathode LOW
digitalWrite(col[thisCol], HIGH); // now, set the column high again to turn if off
}
} // for thisCol
digitalWrite(row[thisRow], LOW); // once the columns are done, turn off the row (anode)
} // for thisRow
} // refreshScreen()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment