Bem, estou fazendo um alarme para minha casa, nao optei por controle remoto mas sim por teclado, em virtude de custos.

o que preciso fazer é o seguinte, coloquei um sensor de abertura do portao para qdo eu chegar de carro, e gostaria de colocar um tempo de 30 segundos para desarme do alarme sem que o mesmo disparasse... porem qdo compilo, a função do teclado fica travada no delay de 30 segundos, enquanto nao passa esses 30 segundos nao posso digitar, e qdo passa a sirene dispara, incomodando... alguma sugestao de como eu executo esses "30" segundos sem travar no delay o teclado?

Exibições: 1382

Responder esta

Respostas a este tópico

Posta seu código para vermos como você está fazendo, mas eu acredito que aquele exemplo que tem no site do Arduíno para piscar un led sem delay (blink without delay) pode ser adaptado para seu projeto e solucionar esse problema

olha aquele codigo, o millis, realmente me abriu a mente para muitas coisas, mas ainda nao achei o que fazer, pq na verdade eu coloco um contador somado, por exemplo 30000, que sao os 30 segundos que preciso, so que a variavel que usei para comparar ela tambem sempre aumenta, o seja, nunca chego nos 30 segundos... vo colocar o que fiz de teste aqui com menos tempo para que possa ser facilmente entendido:

unsigned long buzzertimer = 0;
unsigned long buzzermillis = millis();
buzzercontador = (buzzermillis + 30000);
if(buzzermillis - buzzertimer > 1000)  

{
buzzertimer = buzzermillis;
tone(speakerPin,1500,300);
Serial.print(buzzercontador);
Serial.println();
}

coloquei um buzzer para informar que o alarme vai armar ou desarmar nessa função so que ele nunca arma ou desarma, so fica no buzzer, ou seja, num chega nos 30000 posteriores

Na verdade existe algumas incoerencias no seu codigo.

no IF, você deve verificar se o tempo que se passou é maior que o intervalo e ai executar a rotina para reativar o alarme, ou seja, o IF precisa ser como abaixo

if(buzzermillis - buzzertimer > 30000)

{

//rotina para reativar alarme

}

Lembrando que o buzzertimer deve ser difinido como zero apenas uma vez (fora do loop), e eu nao entendi a necessidade da variavel buzzercontador.

Tambem acredito ser necessário a verificação de mais uma variavel, que seria a responsavel por verificar se o sensor do portao foi ativado

hummmm qto a variavel do portao, eu coloquei esse seria so o tempo de saida... assim que terminar essa contagem, tem um condicional lendo o sensor para o caso de aberto disparar.

bem, agora fiquei confuso, if(buzzermillis - buzzertimer > 30000) ele so ira bipar apos 30 segundos nao? eu queria que ele bipasse o buzzer de 1 em 1 segundo, como uma contagem regressiva para sair antes do alarme disparar.

achei na função timer um recurso mais interessante, fiz com que ele conte de 1 em 1 segundos, agora so gerar uma variavel que, qdo ativar o alarme ele começe um contador de 1 a 30 para gerar a condição de alarme ativado e esperar que tenha violação do portão para que o mesmo ative... vc sabe me dizer como faço esse contador??? 

é to pra desistir, tanto com millis qto com timer1 nao da certo, so funciona com mudança de condição igual leds, mas para o que quero que é contar o tempo, tudo ta caindo no delay... tudo paralisa o sistema... olha o que fiz com o millis como vc me disse:

while (contador<30) {
long diferenca = millis() - timestamp;

if (diferenca > DELAY) {
Serial.println(contador);
digitalWrite(led13, !digitalRead(13));
timestamp = millis();
alarmearmado = 1;
contador++;

dai se eu quiser desarmar o alarme, ou se eu usar o mesmo codigo para hora que entrar e casa, ele "congela" o sistema durante os 30 segundos, ou seja so posso desligar o alarme depois desse tempo, e dai dispara a sirene enquanto nao entro a senha...

essas sao as variaveis definidas no setup

Que tal passar seu programa, aqui não temos bola de cristal, como podemos ajudar assim???

O que você fez ali é a mesma coisa que delay só que o led pisca enquanto espera, o fluxo do programa deve rodar o loop e a comparação do blinkwithoutdelay tem que ficar na raiz do loop, basicamente você tem que escrever um programa orientado a estados. Seu alarme edit:tambem tem RF ou é só o teclado??? A verificação deve junto ao scan do teclado se fui claro.

somente teclado, o programa esta enorme em virtude do teclado, vo te passar pelo menos as condições de armar e desarmar para que vc possa entender.

#include <TimerOne.h>

#include <Keypad.h>

const int led13 = 13; //alarme ligado

long previousMillis = 0;
long contadorbuzzer = 0;
long interval = 2000;

int zona1 = A2;
int z1 = 0;
int zona2 = A3;
int z2 = 0;
int zona3 = A4;
int z3 = 0;
int alarmeliberado = 0;
int alarmearmado = 1;
int value;
int sirene = A1;
int speakerPin = A5;

int led11 = 11; // led zona 3
int led10 = 10; // led zona 2
int led9 = 9; // led zona 1
int senha;
int senha2;
int senha3;
int val= 0;
//int addr = 0;
int variavel;
int variavel2;
int variavel3;
char state = 1;
int contador = 0;
const byte ROWS = 4;// 4 linhas.
const byte COLS = 4;// 3 colunas.
char keys[ROWS][COLS] = {
{'1','2','3'},
{'4','5','6'},
{'7','8','9'},
{'*','0','#'}
};
byte rowPins[ROWS] = {8, 7, 6, 5};
byte colPins[COLS] = {4, 3, 2};
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

long timestamp = 0;
const long DELAY = 1000;


void setup()
{
Serial.begin(9600); //Inicializa a comunicação serial a 9600 bps


pinMode(speakerPin, OUTPUT);
pinMode(led12, OUTPUT);
pinMode(led11, OUTPUT);
pinMode(led10, OUTPUT);
pinMode(led9, OUTPUT);
pinMode(sirene, OUTPUT);
pinMode(led13, OUTPUT);
pinMode(zona1,INPUT);
pinMode(zona2,INPUT);
pinMode(zona3,INPUT);
pinMode(door,OUTPUT);
Timer1.initialize(1000000);
Timer1.attachInterrupt(esperaalarme);

}

void loop(){
/* unsigned long tempobuzzer = millis();  desativei para testar com timer1
unsigned long currentMillis = millis();
if(currentMillis - previousMillis > interval) {
// save the last time you blinked the LED
previousMillis = currentMillis;
// if the LED is off turn it on and vice-versa:
if (ledState == LOW)
ledState = HIGH;
else
ledState = LOW;
// set the LED with the ledState of the variable:
digitalWrite(led13, ledState);
}

*/
//sensores de zona
z1 = digitalRead(zona1);
z2 = digitalRead(zona2);
z3 = digitalRead(zona3);
//leds de zona
if (z1 == 1) {
digitalWrite(led11, HIGH);
}
else {
digitalWrite(led11, LOW);
}
if (z2 == 1) {
digitalWrite(led10, HIGH);
}
else {
digitalWrite(led10, LOW);
}
if (z3 == 1) {
digitalWrite(led9, HIGH);
}
else {
digitalWrite(led9, LOW);
}
}

//disparo de alarme
if (digitalRead(zona1) == 1 && digitalRead(led13) == 1) { //compara se alarme ta ativado e se tem presença
digitalWrite(sirene, HIGH);
}
// if (digitalRead(zona2) == 1 && digitalRead(led13) == 1) { //compara se alarme ta ativado e se tem presença
// digitalWrite(sirene, HIGH);   por enquanto estou usando somente a zona1
// }
// if (digitalRead(zona3) == 1 && digitalRead(led13) == 1) { //compara se alarme ta ativado e se tem presença
// digitalWrite(sirene, HIGH);
// }

char key = keypad.getKey(); //espera entrada no teclado

switch (state) {

case 1: //estado de operação 1 - # 
switch (key)
{

case '#':
tone(speakerPin,440,100);
Set_state(2);
break;

default: ;
Set_state(1);
}
break;

case 2: //estado de operação 2 - 1 para desativar alarme, 2 para ativar alarme ou * para mudança de senha
switch (key) {

case '1':
tone(speakerPin,1000,200);
Set_state(3);
break;

case '*':
tone(speakerPin,1500,1000);
Set_state(5);
break;

case '2':  // é aqui ta o problema do timer
contador = 1;
tone(speakerPin,1000,1000);
digitalWrite(sirene,HIGH);  //apita sirena uma vez para sinalizar alarme armado
delay(800);
digitalWrite(sirene,LOW);

//calcula tempo para saida sem alarme disparar

while (contador<30) {
long diferenca = millis() - timestamp;

if (diferenca > DELAY) {
Serial.println(contador);
digitalWrite(led13, !digitalRead(13));
timestamp = millis();
alarmearmado = 1;
contador++;
}
}


/*    desativer para testar com millis, aqui foi uma rotina de testes com timer1
if(tempobuzzer - previousMillis > interval && tempobuzzer < 10000) {
previousMillis = tempobuzzer;
tone(speakerPin,1500,200);
digitalWrite(led9,HIGH);
} */

// for (int i=0; i <= 10; i++){
// tone(speakerPin,1500,200);     aqui esta a contagem que eu estava usando antes com delay
// delay(1500);
// }
// for (int i=0; i <= 15; i++){
// tone(speakerPin,1500,200);
// delay(1000);
// }
// for (int i=0; i <= 20; i++){
// tone(speakerPin,1500,200);
// delay(600);
// }
// for (int i=0; i <= 6; i++){
// tone(speakerPin,1500,200);
// delay(300);
// }

Set_state(11);
break;

default: ;

Set_state(2);   //desarme do alarme
}
break;

case 3:
switch (key) {
case '1':
tone(speakerPin,110,100);
variavel ++;
if (EEPROM.read(variavel)==1){
senha++;
}
else {
senha--;
}
break;

case '2':
tone(speakerPin,220,100);
variavel ++;
if (EEPROM.read(variavel)==2){
senha++;
}
else {
senha--;
}

break;
case '3':
tone(speakerPin,330,100);
variavel ++;
if (EEPROM.read(variavel)==3){
senha++;
}
else {
senha--;
}

break;
case '4':
tone(speakerPin,440,100);
variavel ++;
if (EEPROM.read(variavel)==4){
senha++;
}
else {
senha--;
}

break;
case '5':
tone(speakerPin,550,100);
variavel ++;
if (EEPROM.read(variavel)==5){
senha++;
}
else {
senha--;
}

break;
case '6':
tone(speakerPin,660,100);
variavel ++;
if (EEPROM.read(variavel)==6){
senha++;
}
else {
senha--;
}

break;
case '7':
tone(speakerPin,770,100);
variavel ++;
if (EEPROM.read(variavel)==7){
senha++;
}
else {
senha--;
}

break;
case '8':
tone(speakerPin,880,100);
variavel ++;
if (EEPROM.read(variavel)==8){
senha++;
}
else {
senha--;
}

break;
case '9':
tone(speakerPin,990,100);
variavel ++;
if (EEPROM.read(variavel)==9){
senha++;
}
else {
senha--;
}

break;
case '0':
tone(speakerPin,1000,100);
variavel ++;
if (EEPROM.read(variavel)==0){
senha++;
}
else {
senha--;
}

break;
default: ;
}
if (variavel ==5) {
Set_state(4);
}
break;    //o que era irrelevante retirei daqui para facil compreensão... nao sei se tem } a mais ai no final.

}

}
}

void Set_state(char index) {
state = index;
switch (state) {

case 1:
//Serial.print("BEM VINDO");
break;

case 2:
Serial.print(" Tecle 1 para entrar com a senha, 2 para armar alarme ou * para alterar senha ");
break;

case 3:
Serial.print("Insira a Senha:");
delay (100);
break;

case 4:
Serial.print("Verificando a senha");
if (senha == 5) {
alarmeliberado = 1;
alarmearmado = 0;
digitalWrite (led13,LOW);
digitalWrite(sirene, LOW);
Serial.print("Alarme Desativado");
digitalWrite(sirene,HIGH);
delay(800);
digitalWrite(sirene,LOW);
delay(1000);
digitalWrite(sirene,HIGH);
delay(800);
digitalWrite(sirene,LOW);
delay(5000);
senha=0;
variavel=0;
Set_state(1);
}
else {
Serial.print("Acesso Negado, alarme ativado");
delay(1000);
senha=0;
variavel=0;
Set_state(1);
}
break;

case 5:
Serial.print("Insira a Senha:");
delay (100);
break;

case 6:
Serial.print("Verificando a senha");
delay(1000);
if (senha2 == 5) {
senha2=0;
variavel2=0;
Set_state(7);
}
else {
Serial.print("Acesso Negado");
senha2=0;
variavel2=0;
Set_state(1);
}
break;

case 7:
Serial.print("Nova Senha:");
delay (100);
break;

case 11:
digitalWrite(led13,HIGH);
Serial.print("ALARME ATIVADO");

//INSERIR CONTADOR PARA SAIDA
//E APOS APITAR SIRENE 1 VEZ

senha=0;
variavel=0;
Set_state(1);
break;

case 12:
break;

default: ;

}
}

rapaz é o seguinte, entendi agora a logica do timer.... agora consegui fazer o contador, so me explica uma coisa, o contador do timer roda dentro de uma função fora do loop, dai como faço pra pegar o valor que ele vai atribuir a uma variavel para disparo do alarme e essa variavel responde no loop? para parece que uma função qdo chamada seus valores nao vao para o loop, é isso?:

RSS

© 2024   Criado por Marcelo Rodrigues.   Ativado por

Badges  |  Relatar um incidente  |  Termos de serviço