10 botões usando 1 interrupção
Componentes e suprimentos
| × | 1 | ||||
| × | 1 | ||||
| × | 21 | ||||
| × | 10 |
Aplicativos e serviços online
|
Sobre este projeto
Introdução
As interrupções são úteis. Eles, além de às vezes tornarem o código mais simples, podem ser usados para sincronismo preciso ou para acordar o Arduino do modo de hibernação.
Digamos que você tenha uma interface de usuário, um controlador remoto, por exemplo, que funciona com baterias. Você pode querer colocar o Arduino (ou ATmega autônomo) no modo de desligamento para economizar energia. Quando um Arduino entra no modo de desligamento, ele só pode ser ativado por uma interrupção externa. O chip ATmega328P usado em um Arduino Uno tem apenas duas interrupções de pino externas. (
INT0
e INT1
nos pinos 2 e 3) Como é provável que uma interface de usuário tenha mais de dois botões, isso é um problema. A maneira padrão de resolver
isso seria para conectar todos os botões normalmente, mas também conectá-los a um pino de interrupção com um diodo. No entanto, isso complica significativamente o circuito.
Além das interrupções externas padrão, o ATmega328P também possui interrupções de troca de pinos. Existem bibliotecas para lidar com eles e são uma boa solução para este problema.
No entanto, durante uma competição de programação, descobri como fazer isso usando interrupções externas padrão sem componentes elétricos extras.
O circuito
Temos alguns botões. Usei dez, que se encaixam perfeitamente na minha placa de ensaio. (Eu também não tenho mais.) Você pode ter um botão por pino, o que significa até 20 em um Uno e até 70 em um Mega! (Se você realmente precisa de 70 botões, eu recomendo o uso de multiplexação, você não precisa de um Mega inteiro para isso.)
Cada botão tem um lado conectado a um pino arbitrário. (4-13 no meu caso) Os outros lados de todos os botões são conectados juntos a um único pino com capacidade de interrupção. (2 no meu caso)
O código
O código está anexado abaixo. Para fazer este exemplo funcionar, carregue-o no seu painel. Abra seu monitor serial. Quando você pressiona um botão, seu número aparecerá. Como você pode ver, a função de loop não é usada de forma alguma.
Como funciona?
Obviamente, há uma interrupção. No meu caso, está conectado ao pino 2. Está configurado como
FALLING
. Para evitar o uso de diodos, o Arduino reconecta o circuito na hora. Existem duas configurações possíveis: Modo comum e modo distinto .
Modo comum
Na maioria das vezes, o circuito estará em modo comum. O pino de interrupção será configurado como
INPUT_PULLUP
e o resto será OUTPUT
e BAIXO
. void configureCommon () {pinMode (commonPin, INPUT_PULLUP); para (int i =0; i
No modo comum, pressionar qualquer botão puxará nosso pino de interrupção para baixo e disparará nossa interrupção. Assim que isso acontecer, nossa rotina de serviço de interrupção reconfigurará os pinos para o modo distinto.
Modo distinto
Assim que nossa interrupção for acionada, mudamos rapidamente para o modo distinto.
O modo distinto é o oposto do modo comum. O pino de interrupção será
OUTPUT
e BAIXO
e o resto será INPUT_PULLUP
. void configureDistinct () {pinMode (commonPin, OUTPUT); digitalWrite (commonPin, LOW); para (int i =0; i
No modo distinto, apenas os pinos correspondentes aos botões realmente pressionados serão puxados para baixo. Podemos facilmente examinar todos os pinos para descobrir qual deles acionou a interrupção.
Depois de fazer isso, o Arduino pode voltar ao modo comum e esperar por outra interrupção. Ou, dependendo do seu aplicativo, ele pode permanecer em modo distinto e processar a entrada do usuário como faria normalmente, voltando ao modo comum antes de o Arduino entrar no modo de espera.
Um exemplo mais complexo
Vamos tentar algo um pouco mais complexo. Vamos anexar um servo e mapear cada botão para um ângulo diferente. (1 =0 °, 2 =20 ° ... 10 =120 °) Também alimentaremos nosso Arduino com algumas baterias.
Neste exemplo, colocamos o Arduino no modo de desligamento após cinco segundos de inatividade para economizar energia. Você pode encontrar alguns tutoriais sobre o modo de suspensão online. Além disso, alimentamos o servo por meio de um transistor para desligá-lo quando não estiver em uso.
O código para este exemplo também está anexado a seguir.
Código
- Registrador serial
- Servo com modo de espera
Registrador serial Arduino
const int commonPin =2; const int buttonPins [] ={4,5,6,7,8,9,10,11,12,13}; unsigned long lastFire =0; void setup () {configureCommon ( ); // Configurar pinos para interrupção attachInterrupt (digitalPinToInterrupt (commonPin), pressInterrupt, FALLING); Serial.begin (9600);} void loop () {// Vazio!} Void pressInterrupt () {// ISR if (millis () - lastFire <200) {// Debounce return; } lastFire =millis (); configureDistinct (); // Configure os pinos para testar botões individuais para (int i =0; iServo com modo de espera Arduino
#include#include #include const int commonPin =2; const int buttonPins [] ={4,5,6,7,8 , 9,10,11,12,13}; const int servoEnablePin =A1; const int servoPin =A0; Servo servo; unsigned long lastFire =0; int status =0; void setup () {pinMode (commonPin, INPUT_PULLUP); configureCommon (); attachInterrupt (digitalPinToInterrupt (commonPin), pressioneInterrupt, FALLING); servo.attach (servoPin); pinMode (servoEnablePin, OUTPUT);} void loop () {if (millis () - lastFire> 5000) {digitalWrite (servoEnablePin, LOW); set_sleep_mode (SLEEP_MODE_PWR_DOWN); sleep_enable (); modo dormir(); } atraso (10);} void pressInterrupt () {sleep_disable (); power_all_enable (); if (millis () - lastFire <200) {return; } lastFire =millis (); configureDistinct (); for (int i =0; i
Esquemas
multiinterrupt_hoF76Oc4T5.fzz servo_with_sleep_u9ZqxF0jhY.fzzProcesso de manufatura
- Decodificador DTMF usando apenas Arduino
- Faça Monitor Ambilight usando Arduino
- Máquina de LEVITAÇÃO ULTRASÔNICA Usando ARDUINO
- Faça você mesmo voltímetro usando Arduino e Smartphone
- Monitor de freqüência cardíaca usando IoT
- WebServerBlink usando Arduino Uno WiFi
- Contador de carros usando Arduino + Processing + PHP
- Jogo Dino automatizado usando arduino
- Rádio FM usando Arduino e RDA8057M
- BLUE_P:Wireless Arduino Programming Shield