Publicidade:

sexta-feira, 5 de abril de 2019

Arduino - Charlieplexing

Nesse vídeo demonstro o funcionamento da técnica de multiplexação de leds chamada Charlieplex.



Código-Fonte:

/*************************************************************************************************************
*******************************BIT ARRAY *********************************************************************
**************************************************************************************************************
mais informações aqui: http://fabianoallex.blogspot.com.br/2015/09/arduino-array-de-bits.html
**************************************************************************************************************/
class BitArray{
  private:
    int _num_bits;   //quantidade de bits a serem gerenciados
    int _num_bytes;  //quantidade de bytes utilizados para armazenar os bits a serem gerenciados
    byte * _bytes;   //array de bytes onde estaram armazenados os bits
  public:
    BitArray(int num_bits){
      _num_bits  = num_bits;
      _num_bytes = _num_bits/8 + (_num_bits%8 ? 1 : 0) + 1;
      _bytes = (byte *)(malloc( _num_bytes * sizeof(byte) ) );
    }
     
    void write(int index, byte value) {
      byte b = _bytes[ index/8 + (index%8 ? 1 : 0) ];
      unsigned int bit = index%8;
      if (value) { b |= (1 << bit); } else { b &= ~(1 << bit);  }
      _bytes[ index/8 + (index%8 ? 1 : 0) ] = b;
    }
     
    void write(byte value) {
      for(int j=0; j<_num_bytes;j++) { _bytes[j] = value ? B11111111 : B00000000;  } 
    }
     
    int read(int index) {
      byte b = _bytes[ index/8 + (index%8 ? 1 : 0) ];
      unsigned int bit = index%8;
      return (b & (1 << bit)) != 0;
    }
 
   ~BitArray(){ free( _bytes ); }
};
/*************************************************************************************************************
*******************************FIM BIT ARRAY *****************************************************************
**************************************************************************************************************/

class Charlieplexing {
  private:
    byte _numPins;       //numero de pinos utilizados
    int  * _pins;        //ponteiro para array com os pinos utilizados
    byte _ledsOnPerGroup;//quantidade de leds de um mesmo grupo que pode ser ligada ao mesmo tempo
    BitArray * _states;     //armazenas o estados do leds
  public:
    Charlieplexing(int * pins, byte numPins, byte _ledsOnPerGroup=2);
    int numLeds() { return _numPins * _numPins - _numPins; }
    void update(int delay_=10, int repeat=1);
    void turnOn(int i);  //liga led i
    void turnOff(int i);  //desliga led i
    void clear();
    byte getState(int i);  //retorna status led i
};

Charlieplexing::Charlieplexing(int * pins, byte numPins, byte ledsOnPerGroup){
  _ledsOnPerGroup = ledsOnPerGroup;
  _numPins = numPins;
  _pins    = pins;
  _states  = new BitArray(numLeds());
}

void Charlieplexing::turnOn(int i){
  if (i < numLeds()){
    _states->write(i, HIGH);
  }
}

void Charlieplexing::turnOff(int i){
  if (i < numLeds()){
    _states->write(i, LOW);
  }
}

byte Charlieplexing::getState(int i){
  if (i < numLeds()){
    return _states->read(i);
  }
}

void Charlieplexing::clear(){
  _states->write(LOW);
}

void Charlieplexing::update(int delay_, int repeat){
  if (repeat <=0) { repeat = 1; }
  for (int q=0; q<repeat; q++) {
    for (int i=0; i<_numPins; i++) {
      digitalWrite(_pins[i], LOW);
      pinMode(_pins[i], OUTPUT);

      byte cont = 0; //conta se há algum led a ser ligado

      for (int j=0;j<_numPins;j++){
        if (i != j) {
          pinMode(_pins[j], INPUT);
          digitalWrite(_pins[j], LOW);
        }
      }

      for (int j=0; j<_numPins; j++) {
        if (i != j) {
          int posLed = 0; 

          if (i>j){
            posLed = i * i - i + 2 * j + 1;  //baseado no calculo do numero triangular
          } else {
            posLed = j * j - j + 2 * i;      //baseado no calculo do numero triangular
          }

          if (_states->read(posLed) == HIGH){
            pinMode(_pins[j], OUTPUT);
            digitalWrite(_pins[j], LOW);
            cont++;
          } 
        }

        if (cont == _ledsOnPerGroup && cont > 0 ) {
          cont = 0;
          digitalWrite(_pins[i], HIGH);
          delay(delay_); 
          digitalWrite(_pins[i], LOW);

          for (int jj=0;jj<=j;jj++){
            if (i != jj) {
              pinMode(_pins[jj], INPUT);
            }
          }
        }
      }
      if (cont > 0){
        cont = 0;
        digitalWrite(_pins[i], HIGH);
        delay(delay_); 
        digitalWrite(_pins[i], LOW);
      }
    }
  }
}



int pins[] = {12, 11, 10, 9, 8};
int qtPins = 5;
int qtLedsOn = 2;

Charlieplexing cp(pins, qtPins, qtLedsOn);  //pinos, qtpinos, qtledsOn


void setup(){
  cp.turnOn(0);
  cp.turnOn(2);
  
  cp.turnOn(4);
  cp.turnOn(8);
  cp.turnOn(14);
  
  cp.turnOn(7);
  cp.turnOn(18);
  
  cp.turnOn(13);
  cp.turnOn(15);
  cp.turnOn(17);
  cp.turnOn(19);
}

void loop() { 
  cp.update(5, 20); //delay, repeat
}

3 comentários:

  1. Fabiano ! boa tarde, poderia me dar uma dica sobre um código seu? do logoff

    //Gostaria de saber se vc pode me ajudar a incluir neste código a função "Fechar a aba do browser" logo após ficar 2 segundos nesta ultima sua que informa "Você não esta mais conectado".
    Tenho esse código em html que faz isso no crhome :

    language="javascript"
    function popup(){
    window.opener=self;
    setTimeout("window.close()",1000);
    }


    href="javascript:popup();">Fechar Janela<



    Sabe me dizer se da para adaptar nesta função sua logoff? lhe Agradeço!

    ResponderExcluir
    Respostas
    1. olá Marcos, infelizmente no momento não to podendo te ajudar pois to sem local pra testar. futuramente devo voltar a trabalhar com arduino e eletronica ai consigo rever esses probleminhas, mas atualmente to sem condição. abraço.

      Excluir
  2. Este comentário foi removido por um administrador do blog.

    ResponderExcluir