digo está funcionando direitinho, o problema é que ele está fazendo múltiplas leituras quando um cartão está presente e não toma a ação enquanto não remover o cartão do leitor.
Por exemplo: Se eu aproximar e remover bem rápido um cartão do leitor RFID, ele lê o conteúdo e toma a ação necessária, porém se eu deixar o cartão em cima do leitor RFID, ele fica lendo múltiplas vezes a mesma coisa e não toma ação nenhuma (como se o RFID estivesse "ocupado")
O que preciso de ajuda
Gostaria da ajuda de vocês para que ele fizesse a leitura apenas algumas vezes do conteúdo do cartão e já tomasse a ação necessária. Tentei usar o millis() mas não tive sucesso, pode ser que não tenha usado da forma correta. Conseguem me dar um auxilio?
Sketch
--------------------------------------------------------------------------------------------
//Programa: Leitor RFID RDM6300#include <SoftwareSerial.h>
#include <RDM6300.h>
#define Rele 7 //Definição do pino de controle do Rele
//Inicializa a serial nos pinos 2 (RX) e 3 (TX)
SoftwareSerial rfid(0, 1);
#define ADD_TAG_CODE "ACBBB0136BDF" // TAG ID que adiciona cartões permitidos
#define DEL_TAG_CODE "210014E2BD6A" //TAG ID que deleta cartões permitidos
String msg;
String ID = "01001C9D55D5,0100179C54DE"; //string para guardar cartões permitidos
int Buzzer = 10;
void setup()
{
Serial.begin(9600);
Serial.println("Serial Ready");
rfid.begin(9600);
Serial.println("RFID Ready");
pinMode(Rele, OUTPUT); //Pino declarado como saída
pinMode(Buzzer, OUTPUT); //Pino Buzzer declarado como saída
}
char c;
void loop(){
while(rfid.available()>0){
c=rfid.read();
msg += c;
Serial.println(msg);
Serial.println(msg.length());
}
msg=msg.substring(1,13);
if(msg.indexOf(ADD_TAG_CODE)>=0) add();
else if(msg.indexOf(DEL_TAG_CODE)>=0) del();
else if(msg.length()>10) verifica();
msg="";
}
void add(){
Serial.print("Para qual cartão deseja dar acesso?: ");
msg="";
while(msg.length()<13){
while(rfid.available()>0){
c=rfid.read();
msg += c;
}
}
if(ID.indexOf(msg)>=0) {
Serial.println("\nAcesso garantido para este cartão.");
msg="";
}
else{
Serial.print("Card: ");
Serial.println(msg);
ID += msg;
ID += ",";
//Serial.print("ID: ");
// Serial.println(ID);
msg="";
Serial.println("Acesso permitido para este cartão.");
}
}
void del(){
msg="";
Serial.print("Qual TAG você deseja negar o acesso?: ");
while(msg.length()<13){
while(rfid.available()>0){
c=rfid.read();
msg += c;
}
}
msg=msg.substring(1,13);
if(ID.indexOf(msg)>=0){
Serial.println(msg);
Serial.println("TAG encontrada. Acesso permitido para este cartão.");
//ID.replace(card,"");
int pos=ID.indexOf(msg);
msg="";
msg += ID.substring(0,pos);
msg += ID.substring(pos+15,ID.length());
ID="";
ID += msg;
//Serial.print("ID: ");
//Serial.println(ID);
} else Serial.println("\nTAG não encontrada ou já negada");
msg="";
}
void verifica(){
msg=msg.substring(1,13);
if(ID.indexOf(msg)>=0){
Serial.println("Acesso permitido.");
tone(Buzzer, 2500, 150);
digitalWrite(Rele, HIGH);
delay(1000);
digitalWrite(Rele, LOW);
delay(1000);
return;
}
else Serial.println("Acesso negado.");
tone(Buzzer, 500, 300);
}
--------------------------------------------------------------------------------------------…
liderados por Sergey Lebedev Alekseevich a partir do final de 1948 no Instituto de Eletrônica e Tecnologia de Kiev, cuja exploração é começou em 1951 depois de vários testes com sucesso. Inicialmente, o trabalho sobre a MESM, tinha objetivos apenas deinvestigación e interesses na área dos computadores de construção elementares. Mas depois de testes bem-sucedidos de sua operação e uma necessidade crescente de todos os tipos de cálculos (especialmente no serviço militar), decide terminar o projeto foi capaz de usar a máquina como uma ferramenta para resolver problemas reais.Em 1949 atrasado, nós projetamos a arquitetura e identifica esquemas MESM funcionamento de seus blocos. Em 1950, a máquina foi montada em um prédio de dois andares de um antigo mosteiro Fofaniya (cerca de Kiev). Em 6 de novembro de 1950 foi o primeiro teste da máquina executando-laoperación Y + Y = 0, Y (0) = 0, Y (π) = 0. Em 4 de janeiro de 1951, as operações foram realizadas unasucesión soma de números ímpares de fatorial de um número e de um elevador de energia. 25 de dezembro de 1951, começou a operação normal e regular da máquina.O MESM tinha as seguintes características:PunchcardA máquina aritmética: ação, universal paralelo, com base no biestável simples.Representação de números: Encoma, binário fixo, com 16 bits para Labase e um bit para indicar o sinal.Memória operacional: com base nos dados biestáveis para 31 dígitos para o comando de 63 dígitos.Memória volátil: a-31-dígitos dados para os dígitos de comando-63.Velocidade de processamento: c (o tempo de ciclo total é de cerca de 17,6 ms, a operação de divisão é realizada numa gama de 17,6-20,8 ms).Comandos do sistema: três vias, com 20 dígitos para o comando, os quatro primerosdígitos indicam theCode de laoperación, o 5 endereço próximo do primeiro operando, a 6 após o segundo operando e os restantes 5 endereço de armazenamento resultado laoperación .Operação disponível: adição, subtração, multiplicação, divisão, comparação do deslocamento, considerando o sinal, em comparação com o valor absoluto, redirecionar, transmitido números de uma bobina magnética, Soma de comandos, pare.Thermionic válvulas: a 6000 (3500 apox 2500 triodes e diodos.)Área ocupada: cerca de 60m ².Consumo de energia: cerca de 25 kW.A leitura dos dados é realizada por meio de cartões perfurados também pode usar uma bobina magnética, cuja capacidade de armazenamento foi de aproximadamente 5000 comandos ou números.A saída dos dados é realizada por um dispositivo, ou por um dispositivo imprentaelectromecánico fotográfica sobre uma película fotográfica.STRELAA Strela computador (ЭВМ "Стрела") foi o primeiro computador de grande porte construído na União Soviética a sério desde 1953. Strela significa seta.O projetista-chefe foi Yuri Basilevsky. Entre seus assistentes foi Boris Rameyev, designer-chefe da série computador Ural. Ele foi projetado para o projeto especial Gabinete 245, de Moscou.Os Strelas foram fabricados em Moscou Usina de Informática e Máquinas analíticos (Московский завод счетно-аналитических машин) entre 1953 e 1957, foram construídos sete máquinas. Foram instalados no Centro de Computação da Academia Russa de Ciências, Keldysh Instituto de Matemática Aplicada, Universidade Estadual de Moscou, e centros de computação de alguns ministérios (relacionada com a defesa e economia).Estes computadores de primeira geração eram 6.200 e 60.000 válvulas diodos semicondutores. O Strela tinha uma velocidade de 2.000 operações por segundo. Sua aritmética de ponto flutuante foi baseado em palavras de 43 bits com mantissa assinado e 35 bits de expoente 6 bits assinados. A tubos de RAM Williams tinha 2048 palavras. Ele também foi um programas ROM semicondutores. A entrada de dados foi através de cartões perfurados ou de fitas. A saída de dados foi realizada por fita magnética, cartões perfurados ou impressora.A versão mais recente do Strela usado um cilindro magnético de 4.096 palavras girando a 6.000 rpm.Em 1954, os designers Strela foram agraciados com o Stalin Medalha 1. grau.MINSKA Minsk foi uma família de computadores de grande porte foram desenvolvidos e produzidos no Soviética Bielo-Rússia República Socialista entre 1959 e 1975. Sua produção foi interrompida pela decisão política de mudar para um clone IBM 360 conhecido como ES EVM para o comprimento conhecido como "distensão", em que a União Soviética e os EUA aliviou tensões e houve um "degelo" da Guerra Fria.O modelo mais avançado era o Minsk-32, desenvolvido em 1968. Suportado COBOL, FORTRAN e ALGAMS (uma versão do ALGOL). Este e versões anteriores também usou uma linguagem de máquina orientada chamado AKI (por sua sigla (AvtoKod "Inzhener.") Estava entre os nativos linguagem assembly SSK (Kodirovaniya Sistema Simvolicheskogo, ou "sistema de código simbólico") de altura e Línguas nível como FORTRAN. M-20, M-220 e M-222 eram um grupo de máquinas de uso geral projetados e fabricados na URSS. Essas máquinas foram desenvolvidas pelo Instituto de Pesquisa Científica de máquinas eletrônicas (NIIEM) e construído no Moscou Usina de Computação e Análise de Máquina (SAM) e Usina Kazan de máquinas de computação, sob a supervisão do Ministério da Indrustria URSS.URALA série Ural computador foi desenvolvido pelo manifacturer de Computação Eletrônica Produção de Penza, e foi produzido entre 1959 e 1964. O seu designer chefe era Bashir Rameyev foram fabricados um total de 139. Foi amplamente utilizado na década de 60, especialmente nos países socialistas, mas também exportados para a Europa Ocidental e na América Latina.Modelos 1 a 4 da Ural foram baseados em tubos de vácuo (válvulas), com hardware que o fizeram capaz de atingir os 12.000 cálculos de ponto flutuante por segundo. Uma palavra é constituída por 40 bits e foi capaz de conter um número ou de duas instruções. Foi utilizado um núcleo de ferrite para criar a memória de trabalho. A nova série (o 11 eo 14, produzido entre 1964 e 1971) foram baseados em semicondutores.Permitido para tarefas matemáticas em centros de informática, instalações e indrustriales científicos instalações. A máquina ocupa aproximadamente 90-100 metros quadrados. O computador estava funcionando e tinha uma tensão trifásica 30kVA lastro magnéticos capazes.As principais unidades do sistema foram: teclado unidade de controle, e leitura, memória, a memória de ferrite unidade aritmeticológica, unidade central de processamento e fonte de alimentação.Estações de trabalho. e computadores pessoais.SM EVMO EVM SM (russo М ЭВМ, curto Система Малых ЭВМ - literalmente Minicomputadores Sistema) era o nome de vários tipos soviéticos minicomputadores 70 e 80. Sua produção começou por volta de 1975. Muitos deles eram clones do DEC PDP-11 e VAX. SM-1 e SM-2 clones foram criados por minicomputadores Hewlett Packard. O sistema operacional mais comum para esses computadores foram traduzidas versões do RSX-11 (ОС РВ) para modelos high-end e RT-11 (РАФОС, ФОДОС) para modelos low-end. Houve também um clone de UNIX disponível, MOS, por gama alta PDP-11 clones.MIRMIR (МИР, "paz" ou "mundo" em russo) é o nome de uma série de computadores soviéticos, desenvolvido entre 1965 (miR-1) para 1969 (o MIR-2) por um grupo liderado por Viktor Glushkov. Um acrônimo para "Машина для Инженерных Расчётов" (cálculos de engenharia de máquinas). Ele foi projetado como um computador "pequena" para uso em aplicações de engenharia e científicos. Entre outras inovações, continha uma implementação em hardware de uma linguagem de programação de alto nível pode fazer cálculos com frações, polinômios, derivadas e integrais. Outra característica inovadora para a época era de que a interface de usuário combinado com um teclado, monitor e uma caneta de luz usado para escrever e editar texto na tela. Pode ser considerado como um dos primeiros computadores pessoais.
Fonte:
http://histinf.blogs.upv.es/2011/01/10/aproximacion-historia-info-urss/…
r identificar posteriormente).
1) de fato, no Arduino UNO vc pode usar os pinos 2 e 3 como pinos de IRQ (Interrupt Request). Para esclarecer sua dúvida, iniciemos pelo trecho de código onde estou configurando o Arduino para usar o pino 2 como "fonte" de uma IRQ. Veja na figura:
(clique na figura para "zoom")
Observe que marquei a linha 315. Mas na linha anterior, o pino 2 (chamado de "pino_Encoder" devido ao #define no início do código), é configurado como pino de entrada, com um "Resistor de Pullup". Isto é necessário, pois esta é a configuração do Hardware do pino, o qual tem que ser uma entrada para poder receber as IRQs (que virão do sinal do Encoder). O "Resistor de Pullup", é apenas uma questão de garantir que o pino não fique "flutuando" (em alta impedância), caso durante seus testes com o Sistema ligado, vc desconecte o Sensor em algum momento (isso tem diversas consequências, e algumas das mais importantes até a veiarada desconhece).
Mas na linha marcada (linha 315), é feita a configuração da IRQ, através da chamada à função "attachInterrupt", cujo link no site do Arduino, é este: "attachInterrupt"
Observe que o "attachInterrupt" tem três parâmetros, e o primeiro muitas vezes causa confusão nas pessoas. Veja que este parâmetro parece estar relacionado justamente com o número do pino do Arduino. Mas na verdade, este parâmetro deve ser o número da Interrupção, que conforme vc mesmo disse, no Arduino UNO pode-se usar a "Interrupt 0" ou a "Interrupt 1".
O Problema aqui, é a diversidade de Arduinos existentes: UNO, Mega, Due, ESP32, etc. Imagine que vc use então o pino 2 do UNO no seu Projeto: vc vai e liga o sinal do Encoder no pino 2 do UNO e aí coloca no primeiro parâmetro da função "attachInterrupt" o valor "0", já que a "Interrupt 0" é a que está associada ao pino 2 do UNO. Tudo bem. Mas e se amanhã vc quiser usar outro Arduino, o que vai acontecer? Ocorre que o pino 2 poderá estar associado a outra IRQ neste outro Arduino, e aí vai dar zica porque quando o Encoder gerar o sinal de IRQ, vai disparar sim uma interrupção, mas não será a "Interrupt 0" que está sendo especificada no seu código. Bem e o que acontece neste caso? O "firmware" do Arduino chamará uma outra ISR (Interrupt Service Routine) que não será a que vc especificou. Conclusão: ele não vai executar o código da ISR que vc esperava que ele executasse.
Para evitar esse problema e "universalizar" o código, de forma que o mesmo código funcione em qualquer Arduino (desde que o pino que vc escolheu suporte IRQs, é claro), ao invés de se especificar "na bucha" o número da IRQ, nós podemos chamar uma função que descubra para nós qual é a IRQ a partir do número do pino que estamos usando. Esta função é a "digitalPinToInterrupt(pino)", onde "pino" é o número do pino que estaremos usando para gerar as IRQs. Como isso funciona? Da seguinte forma: essa função sabe qual é a placa pra qual vc está compilando o código, e a partir disso, ela busca em uma Tabela, qual é o Interrupt (a IRQ) associado com aquele pino, para aquela placa. Então não tem erro. Em resumo: deixe que a "digitalPinToInterrupt" faça esse mapeamento pra vc, descobrindo automaticamente qual é a Interrupt que precisa ser usada para a placa que vc está compilando. Fazendo dessa forma, quando a IRQ ocorrer, certamente seu código irá executar a ISR que vc especificou no "attachInterrupt", seja pra qual placa vc estiver compilando.
2) sobre a definição do "step_Graus", conforme mostrado na figura a seguir:
(clique na figura para "zoom")
Observe que isto é a definição de um valor constante, pois 360 é uma constante, e "total_Furos" é igual a 64, também constante. Inclusive podemos fazer a conta de quanto vai dar: step_Graus = 360/64 = 5.625 graus. Um valor fixo, com 3 dígitos após o ponto decimal.
No entanto, dependendo de onde vc usar este "define", o resultado poderá não ser o que vc espera. Aqui, o risco é que o Compilador do Arduino (Linguagem C++), assuma por conta dele (na verdade por "convenção" da Linguagem), que deve usar apenas a parte inteira do valor, que neste caso seria apenas o "5", descartando a fração ".625", o que provocaria no seu código, um erro no cálculo da posição angular.
Para evitar isso, independente de onde vc usar a constante "step_Graus" no seu código, usamos um "qualificador" do tipo que queremos como resultado pra aquela constante. Tecnicamente isto é chamado de "casting", e é muito usado por quem domina "seriamente" a Linguagem C/C++. Pra fazer este "casting", colocamos na frente da constante, o tipo que queremos como resultado, neste caso o "float", porém deve estar entre parênteses (pois é a sintaxe do casting na Linguagem C/C++) conforme vc notou, ou seja: (float). Isto vai garantir que independente do local onde vc use o "step_Graus" no seu programa, ele sempre resulte em um valor fracionário (o "float").
Bem, vc pode estar perguntando: mas em que situação poderia resultar em um valor inteiro com o descarte da parte fracionária? Isto é mais comum do que vc provavelmente imagina (e causa muitos problemas no código do povo mundo afora). Mas vou aguardar que vc estude mais sobre o "casting" em C/C++, pois certamente vc além de descobrir a resposta, irá aprender muito mais sobre os tipos na Linguagem, que é uma das coisas mais importantes a saber.
3) sobre a questão do "volatile", conforme a figura a seguir:
(clique na figura para "zoom")
Conforme vc mesmo disse, o "volatile" está relacionado a um tipo de otimização que o compilador possa vir a fazer. A questão aqui é: por que "possa"? Ele não faz sempre? E quando ele faz, qual o problema com essa otimização? Mas afinal que raio de otimização ele faz?
É uma otimização, mas pode ser vista também como uma "esperteza" do Compilador, na tentativa de obter duas coisas: diminuir o tamanho do código resultante, e aumentar a velocidade de execução deste código.
Você deve ter ouvido falar, que o Processador (no Arduino UNO seria um AVR de 8 bits) tem Registradores internos. Esses Registradores são usados para armazenar de forma temporária, valores durante a execução do código. Mas por que se usa estes Registradores? Simplesmente porque o acesso a eles costuma ser muito mais rápido que o acesso à Memória RAM do Processador (em processadores "comuns", pode chegar a ser quatro vezes mais rápido, o que é uma grande diferença de velocidade). Então, é comum que o Compilador use os Registradores para armazenar de forma temporária os valores que seu código está trabalhando. Mas porque de forma temporária? Porque seu código pode ter muitas variáveis, as quais estão armazenadas na Memória RAM, e a quantidade de Registradores é limitada, de forma que não dá pra ter todas os valores presentes nos Registradores. Ou seja, quando vc vai utilizar uma determinada variável, o código busca ela na Memória, copiando-a para um Registrador, e como este é bem mais rápido, o código que vai fazer todo o processamento com o valor daquela variável, irá executar mais rápido.
Mas há um grande problema nisso tudo: e se sua variável estiver sendo também alterada dentro de uma ISR, o que vai acontecer? Aí vc estará em maus lençóis, porque se um código trouxe para um Registrador o valor de uma variável, vc supõe que aquela variável não vai mudar, a não ser que vc faça isso explicitamente neste trecho de código. Mas quando uma IRQ ocorre e é aceita, o Processador "suspende" temporariamente a execução do código, e vai executar a ISR daquela IRQ. Tranquilo, quando a ISR terminar, o Processador retoma a execução que ele tinha "suspendido". Mas e se na ISR, vc alterou o valor da Variável que o código "suspenso" estava usando (e que ele achava que não iria mudar) ? Pois é: quando a ISR terminar, e a execução do código suspenso for retomada, a Variável estará com um valor diferente do que estava quando ela foi carregada no Registrador, e aí este trecho de código vai estar trabalhando com uma cópia "desatualizada" da Variável. Um grande problema.
Como resolver? Declare a variável com o qualificador "volatile". E o que ele faz? Faz o seguinte: toda vez que vc declara uma variável como "volatile", isso obriga o compilador a gerar um código que sempre lê da memória o valor daquela variável, toda vez que ela estiver sendo usada num trecho de código. Isto "garante" que mesmo que uma variável seja alterada dentro de uma ISR, o "resto" do código sempre esteja com o valor atualizado daquela variável, já que em qualquer lugar onde aquela variável estiver sendo usada, será lido sempre o valor da memória (ao invés de usar a esperteza, considerando que um Registrador já tem a cópia da variável). Claro, como a variável será sempre lida da memória toda vez que a acessarmos (ao invés de usar uma presumida cópia presente em um registrador), isso sacrificará um percentual de velocidade, mas em geral é muito pouco, já que são poucas as variáveis que acessamos dentro das ISRs (e por isso deve-se evitar acessar um caminhão de variáveis globais dentro de uma ISR).
Mas há um ponto a mencionar: o "volatile" não irá funcionar corretamente em todos as situações. Estes casos onde o "volatile" poderá não ser a solução completa, estão relacionados com o tamanho da variável (1 byte, 2 bytes, 4 bytes) e se o Processador é de 8 bits, 16 bits, ou 32 bits (inclusive se estende para mais bits, como 64 ou mais). O problema ocorre quando o tamanho da variável é maior que o "tamanho" do Processador. Exemplo: vc está usando uma variável do tipo "int" que tem o tamanho de 16 bits no Arduino UNO, e o Processador do UNO todos sabemos que é um Processador de 8 bits. Num caso assim, o "volatile" poderá não ser suficiente pra resolver o problema exposto. Além do "volatile" será necessário usar uma técnica chamada "atomicidade", que apesar de ser simples, não irei abordar neste momento pra não me estender mais.
Ah sim: após a explicação acima, nem precisa dizer nada sobre a Flag "trigger_Dados" que vc perguntou. Mas mesmo assim dizendo: esta Flag não está sendo alterada dentro da ISR (dê uma olha e confira), e por isso não precisou do "volatile".
4) sobre a variável "valor_PWM", que vc mencionou o fato dela não ter sido inicializada. Veja: sempre que vc estiver usando uma variável em algum lugar no seu código, vc espera que esta variável tenha um valor que faça sentido. Pra garantir isso, é comum se inicializar as variáveis no momento que as declaramos. Mas se vc tiver certeza que antes de usar o valor de uma variável, o seu código garanta que aquela variável irá receber um valor válido e que faça sentido, não será necessário inicializar a variável (e inclusive seria uma "perda de tempo"). Analise os momentos que o código usa a variável "valor_PWM", e vc verá que é esse justamente o caso.
Claro, se vc não tiver certeza, sempre inicialize com um valor que faça sentido quando sua variável for usada pela primeira vez no seu código.
Mas aqui há uma curiosidade que vale a pena mencionar. Por padrão, a Linguagem C/C++, sempre inicializa todas as variáveis "globais", mesmo que vc não faça isso. Quase sempre (em 99,99% dos casos), este valor é "0" (zero). Ou seja: quando vc não inicializar, saiba que assim que o código começar a executar, a variável será será sim inicializada e com gigantesca probabilidade será com o valor zero. Se vc não acreditar, faça o teste.
5) sobre a questão do "static unsigned long ref_Tempo" na rotina "verifica_Encoder" (esta é uma rotina, função, e de jeito nenhum é uma "Flag" como vc disse). Isto foi uma distração, pois fiz algum "Control C" e "Control V", e acabei esquecendo de deletar aquela linha na "verifica_Encoder". Por favor, desconsidere, pois está sobrando ali.
6) sobre a questão do "Serial.println( Posicao_Graus, 2 )", peço que veja este link, do site do Arduino: "Serial - Arduino"
Mas na figura abaixo há um print traduzido do site, onde vc pode ver a resposta na parte que marquei em verde e azul:
(clique na figura para "zoom")
7) sobre o que vc perguntou em ter mais de uma Interrupção, sim, pode sim.
Veja, vc pode não saber, mas enquanto seu código está executando no Arduino, além da "sua" Interrupção no pino "2", várias poderão estar ocorrendo. Vou citar as mais evidentes: Interrupção para cadenciar o "millis" (como vc acha que o "millis" vai sendo incrementado a cada mili-segundo?), Interrupção da Serial do Arduino (sim, ela acontece uma vez pra cada caracter que vc envia ou recebe através da Serial), Interrupção do I2C (sim, esta também ocorre toda vez que vc usa o I2C, porém esta é uma das mais problemáticas e mal resolvidas, tipo adolescente mesmo, e pra cada byte que vc envia ou recebe através do I2C, pelo menos 2 Interrupções ocorrem). E há outras ainda.
Então, a sua Interrupção é apenas mais numa na jogada. Logo, se vc tiver duas ou mais, não será nenhum problema, desde que vc saiba usar adequadamente o Mecanismo de Interrupções, escrevendo ISRs corretamente e respeitando as regras para isso (algumas são chatinhas).
Interrupções são sensacionais, mas é preciso usá-las adequadamente. Eu já fiz diversos projetos comerciais onde existem dezenas de Interrupções concorrentes, desde as mais simples até as mais sofisticadas. E tudo funciona perfeitamente.
Sobre o tal Botão pra "resetar tudo", provavelmente não vale a pena gastar um pino de IRQ pra fazer isso (acredito que seria melhor usar uma outra técnica convencional). Mas se vc achar que deve fazer usando IRQ...
8) finalmente sobre sua questão de que o Motor está desligado no início, no setup(). Sim, vc está correto nas suas afirmações, pois como o Motor está inicialmente desligado, não existirão os Pulsos no sinal do Encoder. No entanto , veja que isso não se aplica à simulação que fiz no Proteus, pois como expliquei no post anterior, o Encoder que implementei está desvinculado do Motor, e funciona cadenciado por um Gerador de Pulsos. Então este é o motivo de eu ter usado a Flag "habilita_Monitor", pois o Gerador de Pulsos para o Encoder, já está funcionando quando o setup é executado. Ter a Flag não faz mal algum, mesmo se na prática o Encoder é cadenciado pelo Motor. Além disso, usar esta Flag foi uma ótima oportunidade para demonstrar a técnica de como fazer esse "controle".
Espero ter esclarecido. Mas se tiver algo mais, não deixe de perguntar.
Abrçs,
Elcids…
Adicionado por Elcids Chagas ao 14:13 em 8 agosto 2019
Ultrasônico SR04, um relé deverá ativar e também será gerado uma tensão utilizando PWM. Os valores de tensão e distância devem ser mostrados num LCD 16x2.
Só que como está no sketch, a distância lida sempre consta como 0, se poderem analisar e ver algo fora do normal e me dizer seria de boa ajuda.
Print do Sketch: https://pastebin.com/print/wuLdCi9T
#include "Ultrasonic.h"
#include <LiquidCrystal.h>
Ultrasonic ultrasonic(13, 12); // 13 Echo 12 Trig
LiquidCrystal lcd (11, 10, 9, 8, 7, 6);
int valor_pwm; //Variável para armazenar o sinal PWM
int entrada_rele1 = 1; //Define o relé 1 no pino 1
int entrada_rele2 = 2; //Define o relé 2 no pino 2
int entrada_rele3 = 3; //Define o relé 3 no pino 3
int entrada_rele4 = 4; //Define o relé 4 no pino 4
void setup() {
pinMode(entrada_rele1, OUTPUT);
pinMode(entrada_rele2, OUTPUT);
pinMode(entrada_rele3, OUTPUT);
pinMode(entrada_rele4, OUTPUT);
digitalWrite(entrada_rele1, HIGH); // Deixa o relé desligado
digitalWrite(entrada_rele2, HIGH); // Deixa o relé desligado
digitalWrite(entrada_rele3, HIGH); // Deixa o relé desligado
digitalWrite(entrada_rele4, HIGH); // Deixa o relé desligado
Serial.begin(9600);
lcd.begin(16, 2);
lcd.setCursor( 0, 0);
lcd.print(" Gerando tensao ");
lcd.setCursor( 0, 1);
lcd.print(" pela distancia ");
delay(3000);
lcd.clear();
}
void loop()
{
int tensao = valor_pwm; //Define a tensão o valor dado pelo pwm
int distancia = (ultrasonic.Ranging(CM)); //Distancia dada pela leitura do Sensor
if (distancia < 100) {
if (distancia < 70) {
if (distancia < 50) {
if (distancia < 30) {
if (distancia < 10) {
analogWrite(valor_pwm, 0);//Ativa 0vcc
lcd.setCursor(0, 0);
lcd.print("Tensao ");
lcd.print(tensao); //Escreve no display o valor da tensao obtida pelo pwm
lcd.print(" V"); //Escreve V
lcd.setCursor(0, 1);
lcd.print("Distancia ");
lcd.print(distancia);//Escreve no display o valor da distancia em CM.
Serial.print(distancia);
Serial.println();
}
}
else {
analogWrite(valor_pwm, 64);//Ativa ~1,2 vcc
digitalWrite(entrada_rele1, LOW); //Aciona o Relé
lcd.setCursor(0, 0);
lcd.print("Tensao ");
lcd.print(tensao); //Escreve no display o valor da tensao obtida pelo pwm
lcd.print(" V"); //Escreve V
lcd.setCursor(0, 1);
lcd.print("Distancia ");
lcd.print(distancia); //Escreve no display o valor da distancia em CM.
Serial.print(distancia);
Serial.println();
}
}
else {
analogWrite(valor_pwm, 127);//Ativa ~2,5 vcc
digitalWrite(entrada_rele2, LOW); //Aciona o relé 2
lcd.setCursor(0, 0);
lcd.print("Tensao ");
lcd.print(tensao); //Escreve no display o valor da tensao obtida pelo pwm
lcd.print(" V"); //Escreve V
lcd.setCursor(0, 1);
lcd.print("Distancia ");
lcd.print(distancia);//Escreve no display o valor da distancia em CM.
Serial.print(distancia);
Serial.println();
}
}
else {
analogWrite(valor_pwm, 191);//Ativa ~ 3,7vcc
digitalWrite(entrada_rele3, LOW); //Aciona o Relé 3
lcd.setCursor(0, 0);
lcd.print("Tensao ");
lcd.print(tensao); //Escreve no display o valor da tensao obtida pelo pwm
lcd.print(" V"); //Escreve V
lcd.setCursor(0, 1);
lcd.print("Distancia ");
lcd.print(distancia);//Escreve no display o valor da distancia em CM.
Serial.print(distancia);
Serial.println();
}
}
else {
analogWrite(valor_pwm, 255); //Ativa 5vcc
digitalWrite(entrada_rele4, LOW); //Aciona o Relé 4
lcd.setCursor(0, 0);
lcd.print("Tensao ");
lcd.print(tensao); //Escreve no display o valor da tensao obtida pelo pwm
lcd.print(" V"); //Escreve V
lcd.setCursor(0, 1);
lcd.print("Distancia ");
lcd.print(distancia);//Escreve no display o valor da distancia em CM.
Serial.print(distancia);
Serial.println();
}
}
…
Adicionado por Gildeon Jr ao 15:38 em 17 outubro 2018