Publicidade:

quinta-feira, 15 de janeiro de 2015

Arduino - Vários botões no mesmo pino + OO

Algum tempo atrás fiz um vídeo mostrando como ligar vários botões no mesmo pino, utilizando as portas analógicas.

Hoje estou postando um vídeo novo, onde dei uma boa melhorada no código, onde implemento uma classe que facilita o uso desse tipo de solução.






vídeo anterior:




código atualizado:



class BotaoSerialAnalogico{
  private:
    int  _pino;
    int  _quantidade;
    int* _ref_botao;              
  public:
    BotaoSerialAnalogico(int pino, int quantidade, int resistores[], int resistor_gnd){
      _ref_botao = new int[quantidade];
      _pino          = pino;
      _quantidade    = quantidade;
      
      float r_eq = 0;
      for(int i=0;i<_quantidade;i++){
        r_eq += resistores[i];
        _ref_botao[i] = 1023 - ( r_eq*1023 / (resistor_gnd + r_eq) ); 
      }
      
      int anterior;
      for(int i=0;i<_quantidade;i++){
        int temp = _ref_botao[i];
        _ref_botao[i] = (i==0 ? 1024 : ( anterior + temp ) / 2);
       
        anterior = temp;
      }
    }
  
  int get_button(){
    int v = analogRead(_pino);
    if (v == 0) return -1; //nenhum botao pressionado
    int b = 0;
    for(int i=0;i<_quantidade;i++){ if (_ref_botao[i] > v) { b=i; } else { break; } }
    return b;
  }
  
  void print(){
    Serial.print("|");
    for(int i=0;i<_quantidade;i++){
      Serial.print(_ref_botao[i]);
      Serial.print("|");
    }
    Serial.print("analog=");
    Serial.print(analogRead(_pino));
    Serial.print("|b=");
    Serial.println(get_button());
  }
};



BotaoSerialAnalogico *b;

int RESISTORES[] = {0, 1500, 1500, 2700, 4700};   //resistores dos botões

void setup() {
  Serial.begin(9600);
  
  b  = new BotaoSerialAnalogico(A0, 5, RESISTORES, 1000); //1000-> 1K -> resistor ligado entre o gnd e o pino analógico
}

void loop() {
  
  int botao = b->get_button();
  
  if (botao >= 0) {
    b->print();
    delay(200);
  }
  
  if (botao == 0){}  //programar botao 01
  if (botao == 1){}  //programar botao 02
  if (botao == 2){}  //programar botao 03
  if (botao == 3){}  //programar botao 04
  if (botao == 4){}  //programar botao 05
  
}

quarta-feira, 7 de janeiro de 2015

Arduino - Expansão dinâmica de portas


Vaja como fazer para o Arduino identificar a quantidade de expansores (74hc595, max7219, etc) conectados em série. veja o vídeo.






vídeo anterior sobre o 74HC595:
http://youtu.be/SwQECcYdEkI

Link para o artigo:
http://www.arduinoecia.com.br/2014/04/Painel-de-led-max7219.html


código:



int conta_modulos(int pino, float Rb, float Rp){
  float La = analogRead(pino);
  double N = ( 1 / (  ((1023*Rb)/La) - Rb ) )  / ( 1 / Rp );
  int n = round(N);
    
  Serial.print(N);
  Serial.print(" arredondado: ");
  Serial.println(n);
  
  return n;
}

void setup() { Serial.begin(9600); }

void loop() {
  int q1 = conta_modulos(A0, 1000, 10000);  //resistor gnd->1K, resistor paralelo 10k
  delay(1000);
}


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);    
  }
}