Main Content

Circuitos_1

O circuito de hoje tem por objectivo podermos controlar bastantes LEDs com poucos pinos e sem recorrer a outros integrados. A técnica usada chama-se charlieplexing e foi proposto em 1994 por Charlie Allen da Maxim, tendo no entanto sido alvo de uma patente nos final dos anos 70 por parte da AEG-Telefunken.

A técnica usada por este método reduz o numero de pinos necessários para acender os LEDs pois os pinos assumem os três estados possíveis: alto, baixo e input (alta impedância ou desconectado).
Para se controlarem n(n-1) LEDs são necessários n pinos ou de outra forma para se controlarem L LEDs são necessários (1+sqrt(1+4L))/2.

PinsLEDs
10
22
36
412
520
630
742
856
972
1090
nn²-n

É preciso ter em atenção que este método recorre à propriedade da persistência de visão para que tenhamos a aparência de que estão vários LEDs acesos quando na pratica apenas está um. Para que essa aparência seja mantida é necessário que o refrescamento ocorra a mais de 50 Hz.

Por outro lado no circuito apresentado parte-se do principio que todos os LEDs são idênticos. Com LEDs diferentes torna-se necessário garantir que a “forward-voltage” dos LEDs é mais ou menos a mesma.

Esquemático

Circuitos_3_Schematics

Nota:
O circuito para o CSEduino pode ser consultado nesta página. Pode igualmente ser usado um Arduino.

Componentes (BOM)

  • 12x LED 5mm ou de 3mm (D1-D12)
  • 4x Resistências de 1K Ohms (R1-R4)

Código

O Sketch usado foi o seguinte:

#include "Chaplex.h"

byte ctrlpins[] = {10,11,12,13};    //Arduino pins controlling charlieplexed leds
#define PINS 4                //number of these pins

#define DELAY 500             //speed of switching leds in bar on and off

Chaplex myCharlie(ctrlpins, PINS);     //control instance

charlieLed myLeds[]  = {
  { 0 , 1 },
  { 0 , 2 },
  { 0 , 3 },
  { 1 , 0 },
  { 1 , 2 },
  { 1 , 3 },
  { 2 , 0 },
  { 2 , 1 },
  { 2 , 3 },
  { 3 , 0 },
  { 3 , 1 },
  { 3 , 2 }
};

byte timer2TCNT2 = 178;    //preload timer 256-16MHz/1024/78 = near 5 ms

void setup() {
  // initialize timer2
  noInterrupts();                 //disable all interrupts
  TCCR2A = 0;
  TCCR2B = 0;
  TCNT2 = timer2TCNT2;
  TCCR2B |= (1 << CS22) | (1 << CS21) | (1 << CS20);  //prescaler 1024 = 64 micro secs
  TIMSK2 |= (1 << TOIE2);        //enable timer overflow interrupt
  interrupts();                  //enable all interrupts
}

ISR(TIMER2_OVF_vect) {          //timer2 interrupt routine
  myCharlie.outRow();           //output for one led row
  TCNT2 = timer2TCNT2;          //preload timer for next interrupt
}

void loop() {
  for (int i=0; i< PINS*PINS-PINS; i++) {
    myCharlie.ledWrite(myLeds[i], ON);
    delay(DELAY);
  }
  for (int i=0; i<PINS*PINS-PINS; i++) {
    myCharlie.ledWrite(myLeds[i], OFF);
    delay(DELAY);
  }
}

O Sketch faz uso de uma biblioteca que pode ser descarregada neste link ou então localmente daqui