RGB LED Multiplexing කරමු.












ඔන්න මේක Arduino Sinhalen එකේ මගේ පලවෙනි පෝස්ට් එක. මම මේකෙන් ඔයාලට ඉදිරිපත් කරන්න  යන්නේ RGB LED වලින් HSV Color model එක පාවිච්චි කරලා Multiplexing කරන විදිය. මෙන්න මේ වීඩියෝ එකෙන් ඔයාලට බලාගන්න පුළුවන් මේක වැඩ කරන විදිය.



හරි එහෙනම් වැඩේ පටන් ගමු. මේකට ඕන වෙනවා මෙන්න මේ දේවල් ටික.

1.Arduino Uno
2.1K   - 03
3.82R - 01
4.68R - 02
5.ULN2803A - 01
6.RGB LED Common Cathode (Diffused) - 10

ඔය ලිස්ට් එකෙන්  ULN2803A IC එක යුනිටෙක් එකෙන් ගන්න පුළුවන්.යුනිටෙක් එකෙන් දෙන්නේ ULN2803APG IC එක. ඒකත් අවුලක් නෑ. RGB LED වල මතක ඇතුව  "Common Cathode" එකෙන් ගන්න ඕන, Common Anode ඒවා මේකට හරි යන්නේ නෑ. 

මේ තියෙන්නේ Common Cathode RGB LED එකක්.




දැන් මෙන්න මේ Diagram එකේ විදියට සේරම Components ටික සම්බන්ධ කරලා Resistor තුන පිළිවෙලට Arduino එකේ 9 , 10 , 11 Pin වලට සම්බන්ධ කරන්න.

Digital Pin 9 - රතු පාට
Digital Pin 10 - කොළ පාට
Digital Pin 11 - නිල් පාට

ඔන්න ඔය Pin තුනෙන් තමා LED වල පාට තුන පාලනය කරන්නේ.

ULN2803A IC එකේ Input වලට Arduino එකේ 2, 3, 4, 5, 6, 7, 8, 12 Pin අට සම්බන්ධ කරන්න.




හරි. දැන් Arduino එකට මෙන්න මේ කෝඩ් එක Upload කරන්න.

unsigned char Prescaler = 0;
#define PrescalerOverflowValue 4
ISR(TIMER2_OVF_vect)
{
  if (Prescaler < PrescalerOverflowValue)
    Prescaler++;
  else {
    Prescaler = 0;
    Multiplex();
  }
}


unsigned char CurrentLED = 1;
unsigned char LEDValues[8][3];
bool LEDMoveDir[8][3];
void Multiplex(void)
{    
  PORTD &= 0b00000011; // Control pin 0-5
  PORTB &= 0b11101110; // Control pin 6-7
  
  analogWrite(9, 255-LEDValues[CurrentLED][0]);  
  analogWrite(10, 255-LEDValues[CurrentLED][1]);
  analogWrite(11, 255-LEDValues[CurrentLED][2]);   
  
  switch (CurrentLED)
  {
    case 0:
      //digitalWrite(2, 1); // Turn on LED 1
      PORTD |= 0b00000100;        
      break;
    case 1:
      //digitalWrite(3, 1); // Turn on LED 1
      PORTD |= 0b00001000;              
      break;
    case 2:
      //digitalWrite(4, 1); // Turn on LED 1
      PORTD |= 0b00010000;              
      break;
    case 3:
      //digitalWrite(5, 1); // Turn on LED 1
      PORTD |= 0b00100000;                    
      break;
    case 4:
      //digitalWrite(6, 1); // Turn on LED 1
      PORTD |= 0b01000000;        
      break;
    case 5:
      //digitalWrite(7, 1); // Turn on LED 1
      PORTD |= 0b10000000;              
      break;
    case 6:
      //digitalWrite(8, 1); // Turn on LED 1
      PORTB |= 0b00000001;              
      break;
    case 7:
      //digitalWrite(12, 1); // Turn on LED 1
      PORTB |= 0b00010000;                    
      break;      
  }    

  CurrentLED++;
  if (CurrentLED > 7)
    CurrentLED = 0;  
}

void setPwmFrequency(int pin, int divisor) {
  byte mode;
  if(pin == 5 || pin == 6 || pin == 9 || pin == 10) {
    switch(divisor) {
      case 1: mode = 0x01; break;
      case 8: mode = 0x02; break;
      case 64: mode = 0x03; break;
      case 256: mode = 0x04; break;
      case 1024: mode = 0x05; break;
      default: return;
    }
    if(pin == 5 || pin == 6) {
      TCCR0B = TCCR0B & 0b11111000 | mode;
    } else {
      TCCR1B = TCCR1B & 0b11111000 | mode;
    }
  } else if(pin == 3 || pin == 11) {
    switch(divisor) {
      case 1: mode = 0x01; break;
      case 8: mode = 0x02; break;
      case 32: mode = 0x03; break;
      case 64: mode = 0x04; break;
      case 128: mode = 0x05; break;
      case 256: mode = 0x06; break;
      case 1024: mode = 0x7; break;
      default: return;
    }
    TCCR2B = TCCR2B & 0b11111000 | mode;
  }
}

int Red, Green, Blue;
int Hue1, Hue2, Hue3, Hue4, Hue5, Hue6, Hue7, Hue8, Saturation, Value;
void setup(void) {
  //Set the pin we want the ISR to toggle for output.
  pinMode(2,OUTPUT);
  pinMode(3,OUTPUT);
  pinMode(4,OUTPUT);
  pinMode(5,OUTPUT);   
  pinMode(6,OUTPUT);
  pinMode(7,OUTPUT);
  pinMode(8,OUTPUT);
  pinMode(12,OUTPUT);    

  pinMode(9,OUTPUT);   
  pinMode(10,OUTPUT);  
  pinMode(11,OUTPUT);    

  digitalWrite(2, 0); // Turn off LED 4
  digitalWrite(3, 0); // Turn off LED 4
  digitalWrite(4, 0); // Turn off LED 4
  digitalWrite(5, 0); // Turn off LED 4   
  digitalWrite(6, 0); // Turn off LED 4
  digitalWrite(7, 0); // Turn off LED 4
  digitalWrite(8, 0); // Turn off LED 4
  digitalWrite(12, 0); // Turn off LED 4     
 
  digitalWrite(9, 1);
  digitalWrite(10, 1); 
  digitalWrite(11, 1);   
  
  setPwmFrequency(9, 8);
  setPwmFrequency(10, 8);    
  setPwmFrequency(11, 8);    
  analogWrite(9, 255);
  analogWrite(10, 255);
  analogWrite(11, 255);
  
  LEDValues[0][0] = 100;
  LEDValues[0][1] = 0;
  LEDValues[0][2] = 20;  
  
  LEDValues[1][0] = 0;
  LEDValues[1][1] = 30;
  LEDValues[1][2] = 144; 

  LEDValues[2][0] = 66;
  LEDValues[2][1] = 245;
  LEDValues[2][2] = 3; 

  LEDValues[3][0] = 30;
  LEDValues[3][1] = 30;
  LEDValues[3][2] = 200;   

  //Start up the serial port
  Serial.begin(19200);
  
  //Signal the program start
  Serial.println("RGB LED Controller");
  
  // Enable Timer 2 interrupt (also used for PWM though)
  // This interrupt is divided by a prescaler, and takes care of the multiplexing
  TIMSK2 = 1<<TOIE2;
  
  Hue1 = 0;
  Hue2 = 10;
  Hue3 = 20;
  Hue4 = 30;  
  Hue5 = 40;  
  Hue6 = 50;  
  Hue7 = 60;  
  Hue8 = 70;    
  Saturation = 255;
  Value = 255;
}

unsigned char incomingByte = 0;
unsigned char getNumPos = 0;
unsigned char tempNum = 0;
unsigned char LEDSetNum = 0;
unsigned char LEDSetColor = 0;

void loop(void)
{
    delay(20);
    HSVtoRGB(&Red, &Green, &Blue, Hue1, Saturation, Value);
    
    LEDValues[0][0] = Red;
    LEDValues[0][1] = Green;
    LEDValues[0][2] = Blue; 
    
    Hue1++;  
    if (Hue1 > 359)
      Hue1 = 0;
      
    HSVtoRGB(&Red, &Green, &Blue, Hue2, Saturation, Value);
    
    LEDValues[1][0] = Red;
    LEDValues[1][1] = Green;
    LEDValues[1][2] = Blue; 
    
    Hue2++;  
    if (Hue2 > 359)
      Hue2 = 0; 
      
    HSVtoRGB(&Red, &Green, &Blue, Hue3, Saturation, Value);
    
    LEDValues[2][0] = Red;
    LEDValues[2][1] = Green;
    LEDValues[2][2] = Blue; 
    
    Hue3++;  
    if (Hue3 > 359)
      Hue3 = 0;   
   
    HSVtoRGB(&Red, &Green, &Blue, Hue4, Saturation, Value);
    
    LEDValues[3][0] = Red;
    LEDValues[3][1] = Green;
    LEDValues[3][2] = Blue; 
    
    Hue4++;  
    if (Hue4 > 359)
      Hue4 = 0;    
   
    HSVtoRGB(&Red, &Green, &Blue, Hue5, Saturation, Value);
    
    LEDValues[4][0] = Red;
    LEDValues[4][1] = Green;
    LEDValues[4][2] = Blue; 
    
    Hue5++;  
    if (Hue5 > 359)
      Hue5 = 0;    

    HSVtoRGB(&Red, &Green, &Blue, Hue6, Saturation, Value);
    
    LEDValues[5][0] = Red;
    LEDValues[5][1] = Green;
    LEDValues[5][2] = Blue; 
    
    Hue6++;  
    if (Hue6 > 359)
      Hue6 = 0;    

    HSVtoRGB(&Red, &Green, &Blue, Hue7, Saturation, Value);
    
    LEDValues[6][0] = Red;
    LEDValues[6][1] = Green;
    LEDValues[6][2] = Blue; 
    
    Hue7++;  
    if (Hue7 > 359)
      Hue7 = 0;          
      
    HSVtoRGB(&Red, &Green, &Blue, Hue8, Saturation, Value);
    
    LEDValues[7][0] = Red;
    LEDValues[7][1] = Green;
    LEDValues[7][2] = Blue; 
    
    Hue8++;  
    if (Hue8 > 359)
      Hue8 = 0;          
}

void HSVtoRGB( int  *r, int *g,int *b, int h, int s, int v )
{
        int f;
        long p, q, t;
 
        if( s == 0 )
        {
                *r = *g = *b = v;
                return;
        }
 
        f = ((h%60)*255)/60;
        h /= 60;
 
       p = (v * (256 - s)) / 256;
       q = (v * ( 256 - (s * f)/256 ))/256;       
       t = (v * ( 256 - (s * ( 256 - f ))/256))/256;
 
        switch( h ) {
                case 0:
                        *r = v;
                        *g = t;
                        *b = p;
                        break;
                case 1:
                        *r = q;
                        *g = v;
                        *b = p;
                        break;
                case 2:
                        *r = p;
                        *g = v;
                        *b = t;
                        break;
                case 3:
                        *r = p;
                        *g = q;
                        *b = v;
                        break;
                case 4:
                        *r = t;
                        *g = p;
                        *b = v;
                        break;
                default:
                        *r = v;
                        *g = p;
                        *b = q;
                        break;
        }        
}


මම මුලින්ම මේක හැදුවේ Arduino Uno එකක. ඊට පස්සේ Arduino Pro mini එකක් පාවිච්චි කරලා මේ විදියට වැඩි දියුණු කරලා හැදුවා.



ඉතින් ඔයාලත් උත්සාහ කරලා බලන්න මේක. ගැටළු තියෙනවා නම් කමෙන්ට් කරන්න. එහෙනම් තවත් ලිපියකින් හමුවෙමු :)

3 comments: