Scusate ma sono proprio io rinco, e non riesco a sbrigare sta cosa...dove sbaglio??
in pratica ho bisogno di un conto alla rovescia e quando scade il tempo suona, ma a sua volta se un circuito passa da NC a NO (un cavo che si scollega) comunque deve suonare.
grazie 1000 per l'aiuto
#include <LiquidCrystal.h>
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);
int runTimer = 1;
int runFor = 10; // time in secondi
int buzzerPin =8;
int relayPin=13;
int cable=11;
int data = 0;
int val = 0;
void setup() {
Serial.begin(9600);
pinMode(buzzerPin, OUTPUT);
pinMode(relayPin,OUTPUT);
pinMode(cable,INPUT);
lcd.begin(16, 2);
}
void loop()
{
val = digitalRead(cable); // legge il valore dell'input e lo conserva
if((runTimer == 1) || (val == HIGH)){
digitalWrite(relayPin,LOW); // relay is OFF during countdown
lcd.clear();
lcd.print("TIME = ");
//Start timer
timer();
}
else {
digitalWrite(relayPin,HIGH); // relay is ON when time expired
/* *change to LOW if you want the relay to be OFF when the time expired */
}
Ciao,
per prima cosa dovresti racchiudere il codice negli appositi tag, così si legge meglio 
Poi usa "millis()" per il timer e nel frattempo controlli se si è scollegato il cavo.
La funzione "millis()" fa proprio al caso tuo, dai una occhiata qui per capire come funziona.
Attilio
Ciao, posta il codice completo perché così non si capisce cosa fa la funzione timer()
Inoltre quando metti il codice utilizza l'apposito tag perchè altrimenti risulta difficile capirlo e potrebbero esserci errori di visualizzazione (Capitolo 5 del regolamento)
Così a naso runTimer non viene rivalorizzata da nessuno, potrebbe essere quello il problema?
Infine un consiglio, aggiornare l'lcd ad ogni ciclo di loop non è una buona idea, ci sono buone probabilità che l'lcd vada in crisi per i troppi refresh (almeno a me è capitato). Ti conviene aggiornarlo solo quando è necessario variare il testo visualizzato (nel tuo caso credo ogni secondo)
#include <LiquidCrystal.h>
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);
int runTimer = 1;
int runFor = 10; // time in secondi
int buzzerPin =8;
int relayPin=13;
int cable=11;
int data = 0;
int val = 0;
void setup() {
Serial.begin(9600);
pinMode(buzzerPin, OUTPUT);
pinMode(relayPin,OUTPUT);
pinMode(cable,INPUT);
lcd.begin(16, 2);
}
void loop()
{
val = digitalRead(cable); // legge il valore dell'input e lo conserva
if((runTimer == 1) || (val == HIGH)){
digitalWrite(relayPin,LOW); // relay is OFF during countdown
lcd.clear();
lcd.print("TIME = ");
//Start timer
timer();
}
else {
digitalWrite(relayPin,HIGH); // relay is ON when time expired
/* *change to LOW if you want the relay to be OFF when the time expired */
}
runTimer = 0;
lcd.noDisplay();
delay(25);
for(int duration = 0; duration < 100; duration ++){
digitalWrite(buzzerPin, LOW);
delayMicroseconds(500);
digitalWrite(buzzerPin, HIGH);
delayMicroseconds(500);
}
lcd.display();
delay(250);
}
void timer() {
for(int timer = runFor;timer > 0; --timer){
if(timer >= 10) {
lcd.setCursor(8,0);
} else {
lcd.setCursor(8,0);
lcd.print("0");
lcd.setCursor(9,0);
}
lcd.print(timer);
lcd.print(" SECONDI");
digitalWrite(buzzerPin, LOW);
delayMicroseconds(500);
digitalWrite(buzzerPin, HIGH);
delayMicroseconds(500);
digitalWrite(buzzerPin, LOW);
delayMicroseconds(500);
digitalWrite(buzzerPin, HIGH);
delayMicroseconds(500);
digitalWrite(buzzerPin, LOW);
delayMicroseconds(500);
digitalWrite(buzzerPin, HIGH);
delayMicroseconds(500);
delay(940);
}
lcd.setCursor(0,0);
lcd.clear();
lcd.print("tempo oppure ");
lcd.setCursor(1,2);
lcd.print("contatto aperto");
}
Ciao, credo che il codice che hai postato è frutto dell'unione di più codici trovati su internet perché in realtà non fa nulla di ciò che chiedi, almeno non lo fa in modo chiaro. Appena parte entra nel primo if perchè la variabile runTimer è = 1 suona e scrive sull'lcd e poi non vi rientra più perchè dopo metti la solita variabile a 0.
Con la strada che hai intrapreso sarà difficile arrivare al risultato sperato. Il consiglio è quello di tralasciare per il momento tutta la parte lcd+buzzer e concentrarti sulla creazione all'interno del loop di tutta la parte della logica che dovrà verificare le condizioni per l'attivazione della suoneria. Per fare questo genere di controlli devi utilizzare la funzione millis() (come indicato anche da ultimo_53) in modo da poter verificare ad ogni ciclo di loop se il cavo è stato scollegato o se il tempo massimo è trascorso. Se parti da questa base utilizzando il serial monitor per verificare il funzionamento quando arriverai al funzionamento della parte logica sarà molto semplice integrare le funzionalità necessarie per l'lcd e il buzzer.
OK...allora... con un approccio diverso possiamo dire che:
nel primo listato qui sotto riesco a fare buona parte di quello che mi serve.
dal secondo listato ho preso spunto dopo averlo adattato alle mie esigenze.
entrambe funzionano alla perfezione, se presi singolarmente, però devo unir le due variabili
cioè...parte l'allarme se finisce il tempo o se si sconnette il cavo
#include <LiquidCrystal.h>
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);
int runTimer = 1;
int runFor = 20; // time in seconds
int buzzerPin =8;
int relayPin=13;
void setup() {
Serial.begin(9600);
pinMode(buzzerPin, OUTPUT);
pinMode(relayPin,OUTPUT);
lcd.begin(16, 2);
}
void loop() {
if(runTimer == 1)
{
digitalWrite(relayPin,LOW); // relay is OFF during countdown
lcd.clear();
lcd.print("TIME = ");
//Start timer
timer();
}
else {
digitalWrite(relayPin, HIGH);
}
runTimer = 0;
lcd.noDisplay();
delay(25);
for(int duration = 0; duration < 100; duration ++){
digitalWrite(buzzerPin, LOW);
delayMicroseconds(500);
digitalWrite(buzzerPin, HIGH);
delayMicroseconds(500);
}
lcd.display();
delay(250);
}
void timer() {
for(int timer = runFor;timer > 0; --timer){
if(timer >= 10) {
lcd.setCursor(8,0);
} else {
lcd.setCursor(8,0);
lcd.print("0");
lcd.setCursor(9,0);
}
lcd.print(timer);
lcd.print(" SECONDI");
digitalWrite(buzzerPin, LOW);
delayMicroseconds(500);
digitalWrite(buzzerPin, HIGH);
delayMicroseconds(500);
digitalWrite(buzzerPin, LOW);
delayMicroseconds(500);
digitalWrite(buzzerPin, HIGH);
delayMicroseconds(500);
digitalWrite(buzzerPin, LOW);
delayMicroseconds(500);
digitalWrite(buzzerPin, HIGH);
delayMicroseconds(500);
delay(940);
}
lcd.setCursor(0,0);
lcd.clear();
lcd.print("tempo oppure ");
lcd.setCursor(1,2);
lcd.print("contatto aperto");
}
#define relayPin 13 // SIRENA collegato al pin digitale 13
#define cable 10 // pin di input dove è collegato il CAVO
int val = 0; // si userà val per conservare lo stato del pin di input
void setup() {
pinMode(relayPin, OUTPUT); // imposta il pin digitale come output
pinMode(cable, INPUT); // imposta il pin digitale come input
}
void loop() {
val = digitalRead(cable); // legge il valore dell'input e lo conserva
if (val == HIGH) { // controlla che l'input sia HIGH (CAVO INSERITO)
digitalWrite(relayPin, LOW); //TIENE SPENTA LA SIRENA FINO ALLA RIMOZIONE DI UN CAVO ERRATO
}
else {
digitalWrite(relayPin, HIGH); //ACCENDE SIRENA PER 20 SECONDI
delay(20000);
digitalWrite(relayPin, LOW); //SPEGNE SIRENA PER 20 SECONDI
delay(20000);
}
}
entrambe funzionano alla perfezione, se presi singolarmente, però devo unir le due variabili
cioè...parte l'allarme se finisce il tempo o se si sconnette il cavo
Non ho guardato il codice ma dalla descrizione mi pare chiaro ti serva un operatore 'OR'.
Prima i controlli e poi le azioni.
Controlla scadenza tempo
Scaduto?
SI: tempoScaduto = true;
NO: tempoScaduto = false;
Controllo connessione cavo
Connesso?
SI: cavoConnesso = true;
NO: cavoConnesso = false;
Controllo combinato
if ( (cavoConnesso == false) || (tempoScaduto == true) {
// Azione: accendi l'allarme
}
L'operatore 'OR' in C equivale al carattere '|', mentre '||' è sempre un operatore 'OR' che però non esegue la verifica della condizione posta a destra se quella posta a sinistra risulta falsa. Nel caso specifico se cavoConnesso vale true la condizione a sinistra viene valutata false e come conseguenza la condizione a destra non viene valutata affatto.
Ciao.
Ciao, si i due programmi funzionano se presi singolarmente perchè come puoi notare utilizzano i delay e non le millis come ti abbiamo suggerito. Per ottenere ciò che desideri devi per forza cambiare la logica con cui sono implementati utilizzando la funzione millis().
Per imparare ad utilizzare la millis() ti consiglio di iniziare provando a creare un semplice sistema di attesa di n secondi, poi lo modifiche per ottenere un countdown con relativo aggiornamento dell'lcd solo al variare dei secondi rimanenti. Fatto questo integrarlo con la lettura del pin sarà una passeggiata.