Skip to content

Instantly share code, notes, and snippets.

@ShawnHymel
Created August 16, 2016 16:44
Show Gist options
  • Save ShawnHymel/228710d6a1093874c6be85992a35da2f to your computer and use it in GitHub Desktop.
Save ShawnHymel/228710d6a1093874c6be85992a35da2f to your computer and use it in GitHub Desktop.
Control 8 LEDs using a multiplexer
/**
* 8-Channel Multiplexer Demo
* August 16, 2016
* License: Public Domain
*
* Show PWM on 8 LEDs using 4 I/O pins and an analog input to
* adjust the PWM period.
*
* Hardware:
* Mux | Trimpot | Arduino
* ------|----------|---------
* VCC | | 5V
* GND | | GND
* Z | | 11
* S0 | | 2
* S1 | | 3
* S2 | | 4
* | 1 | 3.3V
* | 2 | A0
* | 3 | GND
*/
// Trimpot input
const int TPOT = A0;
// Z I/O pin
const int Z = 11;
// Mux select pins
const int S0 = 2;
const int S1 = 3;
const int S2 = 4;
// Light pattern
const uint8_t leds[] = {1, 2, 4, 8, 16, 32, 64, 100};
// Global variables
unsigned long pwm_period;
void setup() {
// Set up pins
pinMode(11, OUTPUT);
pinMode(S0, OUTPUT);
pinMode(S1, OUTPUT);
pinMode(S2, OUTPUT);
}
void loop() {
int i;
for ( i = 0; i < 8; i++ ) {
// Read value from trimpot to determine delay
pwm_period = map(analogRead(TPOT), 0, 1023, 2000, 50000);
// Switch to LED on mux and output PWM value
num2Mux(i);
pwm(leds[i]);
}
}
// Shift the last 3 bits out to address the multiplexer
void num2Mux(uint8_t n) {
uint8_t mask = 0x01;
digitalWrite(S0, (n & mask));
n = n >> 1;
digitalWrite(S1, (n & mask));
n = n >> 1;
digitalWrite(S2, (n & mask));
}
// Makeshift PWM
void pwm(uint8_t percent) {
unsigned long t1 = micros();
// Keep pin on if 100% and keep pin off if 0%
if ( percent >= 100 ) {
digitalWrite(Z, 1);
while ( micros() < (t1 + pwm_period) );
digitalWrite(Z, 0);
return;
} else if ( percent == 0 ) {
digitalWrite(Z, 0);
} else {
// Calculate the length of time to keep pin high
unsigned long t = (pwm_period * percent) / 100;
// Hold pin high for given percentage of period
digitalWrite(Z, 1);
while ( micros() < (t1 + t) );
digitalWrite(Z, 0);
}
// Wait to finish out the period
while ( micros() < (t1 + pwm_period) );
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment