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
- https://fr.wikipedia.org/wiki/Registre_%C3%A0_d%C3%A9calage
- https://fr.wikipedia.org/wiki/Bascule_(circuit_logique)
- Utilização de um registo de turnos
- Utilização de um Multiplexer
Retrouvez nos tutoriels et d’autres exemples dans notre générateur automatique de code
La Programmerie