Site icon AranaCorp

Gestão de vários sensores com um registo de turnos

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

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.

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

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

Exit mobile version