Created
November 1, 2015 20:49
-
-
Save atuline/2e8e165d73b9a57a39a7 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* 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