fbpixel
Etiquetas: ,
0
(0)

Neste tutorial, veremos como gerir vários sensores com um registo de turnos. Vimos no último tutorial sobre o assunto, que o registo podia ser utilizado para conduzir LEDs. Veremos aqui, como ler o valor de 8 sensores numa única entrada analógica. Em electrónica, o número de entradas e saídas torna-se crítico quando se utilizam vários sensores. A utilização de um registo de turnos é uma boa solução para reduzir o número de pinos utilizados.

Neste artigo, utilizamos o registo de turnos 74HC595 mas é possível utilizar um multiplexador ou um 74HC165 (Paralelo ao serial, mais adequado para a leitura de sensores)

Material

  • Computador
  • Arduino UNO
  • Cabo USB A Macho/B Macho
  • Registo de turnos 74HC595

Princípio funcional

O registo de turno é um componente electrónico que contém chinelos de dedo síncronos. Estes são circuitos lógicos que mantêm na memória um estado alto ou baixo (como um pouco) ligados pelo mesmo relógio. O princípio da mudança vem do facto de cada memória ser escrita ou lida pouco a pouco.

Para gerir os sensores, utilizaremos a saída do registo de deslocamento como fonte de tensão e todas as saídas dos sensores serão ligadas a uma entrada analógica do Arduino. Os sensores serão alimentados um após o outro, o que nos permitirá recuperar, no pino analógico, o valor do sensor alimentado.

Esquema

O registo de turno requer 3 pinos de saída de um microcontrolador. É possível gerir vários registos ligados em série.

  • GND Ligação à terra do circuito integrado
  • Pino de potência Vcc. Normalmente ligado a 5V
  • SH_CP ou RCLK entrada de relógio de registo de turnos. O sinal do relógio de registo que determina se a memória é escrita para
  • ST_CP ou SRCLK entrada do relógio de registo de armazenamento. O sinal do relógio de armazenamento que define de que memória se está a ler ou a escrever.
  • DS ou SER entrada de dados. Sinal contendo os dados a registar (UP ou DOWN)
  • Q0-Q7 saída de dados paralelos. Pinos de saída do registo de turnos
  • Saída OE permitida, activa BAIXA. Pino ligado ao GND para activar as saídas
  • MR Master reset, activo BAIXO. Pino de reinicialização. Ligado a 5V
  • Q7′ saída de dados em série (pino utilizado apenas se vários registos estiverem ligados em série)

Assim que o registo de turno estiver devidamente ligado, ligaremos cada um dos botões. Para podermos detectar o estado de vários botões, precisamos de adicionar um díodo a cada saída, para que a corrente não flua de uma saída do registo de turnos para a outra.

Código

Para comunicar com o registo de turnos, faremos malabarismos com os seus pinos de entrada. Precisamos de colocar o pino RCLK baixo para escrever para um registo. Para escrever aos chinelos de dedo, precisamos de colocar o relógio de armazenamento em baixo. Com cada pulso de relógio, passamos para o próximo flip-flop. Para simplificar o nosso código, vamos definir este procedimento na função writeRegister().

Para gerir o grupo de sensores através do registo, vamos pulsar cada flip-flop e ler o valor do botão quando o flip-flop é alto, ou seja, uma corrente flui através do botão.

//Constants
#define number_of_74hc595s 1
#define numOfRegisterPins number_of_74hc595s * 8
#define SER_Pin 2
#define RCLK_Pin 3
#define SRCLK_Pin 4

//Parameters
const int grpBtnPin = A0;

//Variables
boolean registers[numOfRegisterPins] = {0, 0, 0, 0, 0, 0, 0, 0};
boolean grpBtnState[numOfRegisterPins] = {0, 0, 0, 0, 0, 0, 0, 0};
boolean oldGrpBtnState[numOfRegisterPins] = {0, 0, 0, 0, 0, 0, 0, 0};
int grpBtnVal[numOfRegisterPins] = {0, 0, 0, 0, 0, 0, 0, 0};

void setup() {
  //Init Serial USB
  Serial.begin(9600);
  Serial.println(F("Initialize System"));
  //Init register
  pinMode(SER_Pin, OUTPUT);
  pinMode(RCLK_Pin, OUTPUT);
  pinMode(SRCLK_Pin, OUTPUT);
  pinMode(grpBtnPin, INPUT);
}

void loop() {
  readGrpBtn();
}

void clearRegisters() { /* function clearRegisters */
  //// Clear registers variables
  for (int i = numOfRegisterPins - 1; i >=  0; i--) {
    registers[i] = LOW;
  }
}

void writeRegisters() { /* function writeRegisters */
  //// Write register after being set
  digitalWrite(RCLK_Pin, LOW);
  for (int i = numOfRegisterPins - 1; i >=  0; i--) {
    digitalWrite(SRCLK_Pin, LOW); int val = registers[i];
    digitalWrite(SER_Pin, val);
    digitalWrite(SRCLK_Pin, HIGH);
  }
  digitalWrite(RCLK_Pin, HIGH);
}

void setRegisterPin(int index, int value) { /* function setRegisterPin */
  ////Set register variable to HIGH or LOW
  registers[index] = value;
}

void readGrpBtn() { /* function readGrpBtn */
  //// Read each btn
  for (int i = numOfRegisterPins - 1; i >=  0; i--) {
    grpBtnState[i] = false;
    setRegisterPin(i, HIGH);
    writeRegisters();
    delay(20);
    grpBtnVal[i] = analogRead(grpBtnPin);
    setRegisterPin(i, LOW);
    writeRegisters();

    if (grpBtnVal[i] > 500) {
      grpBtnState[i] = true;
      if (oldGrpBtnState[i] != grpBtnState[i]) {
        Serial.print(F("Btn "));
        Serial.print(i);
        Serial.print(F(" detected -> State =  "));
        Serial.println(grpBtnVal[i]);
      }
    }
  }
}

Resultados

O estado do botão é actualizado cada vez que passa pela memória de registo correspondente e é possível ler 8 botões com uma única entrada analógica.

Aplicações

  • Gerir até 8 sensores com três pinos digitais e um pino analógico de um microcontrolador
  • Criar um dispositivo HID com múltiplas chaves

Encontre o nosso módulo de expansão de registo de turnos com conectividade simplificada, compatível com todos os tipos de microcontroladores (Arduino, ESP8266, ESP32, Raspberry Pi, etc.)

Fontes

Retrouvez nos tutoriels et d’autres exemples dans notre générateur automatique de code
La Programmerie

How useful was this post?

Click on a star to rate it!

Average rating 0 / 5. Vote count: 0

No votes so far! Be the first to rate this post.

As you found this post useful...

Follow us on social media!

We are sorry that this post was not useful for you!

Let us improve this post!

Tell us how we can improve this post?