Close

Multiplexing leds and some coding

A project log for W-Ring

An RGB led Clock-Ring

EnriqueEnrique 08/16/2018 at 11:420 Comments

One of the most important things in this project is the display, 3 rgb leds, but 3 rgb leds means 3 * 3 colors = 9 pins. One solution is a charlieplexed arrangement, which allows me to use only 4 pins

so in theory, playing with different pin digital outputs and inputs is possible to turn an specific color.

So let's code a bit:

first I need a function that turns all off:

// turn all pins off by putting them in a high impedance state
void turnOff(){
  pinMode(PIN0, INPUT);
  pinMode(PIN1, INPUT);
  pinMode(PIN2, INPUT);
  pinMode(PIN3, INPUT);
}

The pinMode function allows to set a pin as a 0/1 (OUTPUT) or as a high impedance state (INPUT). Setting it as an input is like turning that pin off, no digital data coming out that pin.

So now I need a function for control which color of which led turn on, so there is:

// turns on one led one color at time, 3 available leds and 3 available colors (0 = BLACK, 1 = RED, 2 = GREEN, 3 = BLUE)
void turnOn(byte led, byte color){
  
  //turn all pins off
  turnOff();

  switch(led){
    case 0:
      // set the common cathode on
      pinMode(PIN0, OUTPUT);
      digitalWrite(PIN0, HIGH);

      // set the mapped pin to off
      if(color == 1){
        pinMode(PIN1, OUTPUT);
        digitalWrite(PIN1, LOW);
      }

      if(color == 2){
        pinMode(PIN2, OUTPUT);
        digitalWrite(PIN2, LOW);
      }

      if(color == 3){
        pinMode(PIN3, OUTPUT);
        digitalWrite(PIN3, LOW);
      }
      break;
    
    case 1:
      // set the common cathode on
      pinMode(PIN1, OUTPUT);
      digitalWrite(PIN1, HIGH);

      // set the mapped pin to off
      if(color == 1){
        pinMode(PIN2, OUTPUT);
        digitalWrite(PIN2, LOW);
      }

      if(color == 2){
        pinMode(PIN3, OUTPUT);
        digitalWrite(PIN3, LOW);
      }

      if(color == 3){
        pinMode(PIN0, OUTPUT);
        digitalWrite(PIN0, LOW);
      }
      break;
    
    case 2:
      // set the common cathode on
      pinMode(PIN2, OUTPUT);
      digitalWrite(PIN2, HIGH);

      // set the mapped pin to off
      if(color == 1){
        pinMode(PIN3, OUTPUT);
        digitalWrite(PIN3, LOW);
      }

      if(color == 2){
        pinMode(PIN0, OUTPUT);
        digitalWrite(PIN0, LOW);
      }

      if(color == 3){
        pinMode(PIN1, OUTPUT);
        digitalWrite(PIN1, LOW);
      }
      break;
  }
}

What this function does is to turn on one led one color (R/G/B) at time turning off the rest, so lets test it:

Now we want to represent decimal numbers as an octal color coded ones:

void drawNumber(int number, int milliseconds){

  float startedMilliseconds = millis();
  
  // run the while for the time set 
  while(startedMilliseconds + milliseconds > millis()){
        
    // loop for each led
    for(int i = 0; i < 3; i++){

      // n is the octal number corresponding to ith digit, this is the main decimal to octal conversion
      int n = (number/round(pow(8, i)))%8;

      // loop for each binary digit on n      
      for(int j = 0; j < 3; j++){      
        // we get the jth binary digit and check if is a 0 or a 1, turning on or off the corresponding color, for example 5 = 101 which would turn red and blue = magenta
        if((n/round(pow(2, j)))%2 == 1){
          turnOn(i, j+1);
        }else{
          turnOn(i, 0);
        }

      }
    }
  }
  turnOff();
}

We run the function in a while loop for the time that we want the leds turned on, after that, we convert the digital number ("number" variable) into 3 octal digits, each one corresponding to one led, this digit is called "n". Now we get the n and we decompose it into binary digits in the second loop. How the n is a number between 0-7, we only need 3 binary digits. Each binary digit is represents a RGB color on a led so for example the 5 = 101 would turn on the red led, would turn off the green led and turn on the blue, so we would get magenta. Let's see it in action:

And that's, sorry for the terrible quality, I had to compress the gif

So now, we can get any number between 0 - 511 and show it with 3 RGB leds and 4 microcontroller pins!

Stay tuned for the next log

Discussions