Publicidade:

sexta-feira, 2 de janeiro de 2015

Arduino - Classe para 74HC595

No vídeo abaixo mostro como criar uma classe para facilitar o uso do Registrador 74HC595 com o Arduino.








Código:

ATENÇÃO:

o código abaixo foi melhorado, e publicado em um novo post. Clique aqui para o código atualizado.


class Expansor74HC595 {
  private:
    int  _pin_clock;
    int  _pin_latch;
    int  _pin_data;
    int  _num_cis;
    int* _pins;
    int  _envio_automatico;
  public:
    Expansor74HC595(int pin_clock, int pin_latch, int pin_data, int num_cis=1);
    void startWrite()         { _envio_automatico = false; };
    int  get_num_portas() { return _num_cis * 8; };
    void limpar() { for (int i=0;i < _num_cis * 8;i++){ _pins[i] = LOW; } enviar();  };
    int  read(int pin)  { if (pin >= get_num_portas()) {return LOW;} return _pins[pin]; };
  
    void enviar();
    void writeByte(int num_ci, byte values, bool q0=true);
    void write(int pin, int value);
};

Expansor74HC595::Expansor74HC595(int pin_clock, int pin_latch, int pin_data, int num_cis){
  _pin_clock        = pin_clock;
  _pin_latch        = pin_latch;
  _pin_data         = pin_data;
  _num_cis          = num_cis;
  _envio_automatico = true;
  _pins             = new int[_num_cis*8];
  
  pinMode(_pin_clock,OUTPUT);
  pinMode(_pin_latch,OUTPUT);
  pinMode(_pin_data, OUTPUT);
  limpar();
}

void Expansor74HC595::writeByte(int num_ci, byte b, bool q0) { 
  for(int i=(num_ci*8-1),j=q0?7:0;  i>=(num_ci-1)*8;  i--, q0?j--:j++) {
    _pins[i]  = (b & (1 << j)) ?  HIGH  :  LOW;
  }     
  
  if (_envio_automatico) { enviar(); }
}

void Expansor74HC595::write(int pin, int value) {
  if (pin >= get_num_portas()) {return;}
  _pins[pin] = value ? HIGH : LOW;
  if (_envio_automatico) { enviar(); }
}

void Expansor74HC595::enviar(){
  digitalWrite(_pin_latch, LOW); 
  
  for (int i=(_num_cis*8-1); i>=0; i-- ) {  
    digitalWrite(_pin_clock, LOW); 
    digitalWrite(_pin_data,  _pins[i]);
    digitalWrite(_pin_clock, HIGH); 
    digitalWrite(_pin_data,  LOW);
  }
  
  digitalWrite(_pin_latch,HIGH);
  
  _envio_automatico = true;
}


/*----------------------*/



const int PIN_CLOCK = 2; 
const int PIN_LATCH = 3; 
const int PIN_DATA  = 4; 

Expansor74HC595 *exp1;
 
void setup() {
  exp1 = new Expansor74HC595(PIN_CLOCK, PIN_LATCH, PIN_DATA, 16);
  
  Serial.begin(9600);
}


void conta_tempo(void(*p)(), String descricao){
  long m1, m2;
  m1 = millis();
  (*p)(); //executa a função
  m2 = millis();
 
  Serial.print(descricao + ": m1= ");
  Serial.print(m1);
  Serial.print(" - m2 = ");
  Serial.print(m2);
  Serial.print(" - dif = ");
  Serial.print(m2 - m1);
  Serial.println(" milissegundos");
}

void enviar(){
  exp1->enviar();
}
 
void loop() {
  
  for (int i=0; i<=255; i++) {                    //i=0-> B00000000   i=255-> B11111111
    exp1->startWrite();
    
    exp1->writeByte(1, i);         //q0 será o menos significativo   
    exp1->writeByte(3, i, false);  //q7 será o menos significativo
    
    exp1->write(8, 1); 
    exp1->write(9, 0);
    exp1->write(10, 1);
    exp1->write(11, 0);

    conta_tempo(enviar, "teste");

    //exp1->enviar();
  
    delay(500);
  
    exp1->startWrite();

    exp1->write(8, 0);
    exp1->write(9, 1);
    exp1->write(10, 0);
    exp1->write(11, 1);

    exp1->enviar();
    
    delay(500);  
    
    exp1->limpar();
    delay(300);    
  }
}

5 comentários:

  1. De que forma poderia acionar um LED e que ele fique acionado no próximo envio?
    eu não consegui pegar a lógica, pois aciono um LED e quando aciono outro qualquer entre os 8 o primeiro que acionei apaga. de que forma eu poderia manter ele acionado?

    ResponderExcluir
    Respostas
    1. Na verdade ele já faz isso que vc perguntou, se eu entendi sua dúvida.

      pra ativar qualquer uma das saídas do CI, basta chamar essa função:

      exp1->write(3, 1); //saida 3

      se vc quiser alterar, por exemplo, outra saída .

      exp1->write(5, 1); //saida 5

      a anterior vai continuar ativa.

      uma chamada, não interfere na outra.

      acho que o vídeo que deu uma certa confusão, pois to mandando limpar depois de um tempo, mas foi só pra dar um efeito.


      Excluir
  2. Resumindo, é como acionar relés usando o CI!

    ResponderExcluir
  3. qual e esse programa q vc usa pra simular direto no pc ?

    ResponderExcluir
  4. Boa noite Fabiano
    Vc poderia me ajudar, tenho um arduino uno e preciso expandir as entradas com 39 botoes para acionar 39 reles.
    Achei um exemplo com 74hc165 mas não entendi como ele acionaria o 74hc595, ai eu me perdi.

    ResponderExcluir