Go Down

Topic: funzione di tempo (Read 2547 times) previous topic - next topic

francusallen

scusate ma non riesco a far eseguire un comando.
praticamente in tre punti dello skatch devo far partire una pompa, ma il tempo della pompa attiva non deve sorpassare 15 min altrimenti suona un allarme. io ho creato una funzione void attivazione_pompa () che la richiamo nelle tre occasioni, ma probabilmente sbagliop qualcosa e non mi parte il timer, sapreste indicarmi il motivo?  grazie

void azionamento_pompa (){
boolean allarmeAttivo = false;
if (val < vSelect){digitalWrite(pompa,HIGH);//val e vSelect sono il valore di 2 sensori pressione
if ( !allarmeAttivo ) // se l'allarme NON è attivo
      {allarmeAttivo=true;
      tempoAttivazione=millis();
   }
}else{
    allarmeAttivo=false;//disattiva il timer per l'allarme, siamo tornati ok
  }
if (millis()-900000L > tempoAttivazione) //15 minuti in millisecondi sono 15 * 60 * 1000 = 900000
//però se scrivi il numero e basta arduino pensa sia un int(max 65000 circa, quindi gli diciamo che è un long, scrivendo L)

{digitalWrite(allarme,HIGH);}   //fai suonare la sirena
}

leo72

Questo pezzo di codice non è molto significativo, non sappiamo come e quando e da dove viene chiamata la funzione.
Potresti postare TUTTO lo sketch?

Cmq allarmeAttivo è una variabile locale, quindi ogni volta che chiami la funzione questa sarà sempre false. Non so se è corretto così oppure no. Bisogna vedere il resto del programma.

giangi72

C'è qualcosa che non mi quadra.

all'inizio imposti allarmeAttivo = false
poi fai if( val < vSelect )

  • se si fai if(!allarmeAttivo), ma if è sempre false perchè lo avevi appena impostato così e quindi entra sempre

  • se no metti allarmeAttivo=false ma lo era già



Non è che per caso allarmeAttivo deve essere una variabile statica o globale?


EDIT: ops io e leo abbiamo scritto quasi contemporaneamente

francusallen

scusate ma sono molto indietro con gli studi dell'arduino,
e se io riassumo così?
void azionamento_pompa (){

if (val < vSelect){digitalWrite(pompa,HIGH);//val e vSelect sono il valore di 2 sensori pressione
      tempoAttivazione=millis();
   }

if (millis()-900000L > tempoAttivazione) //15 minuti in millisecondi

{digitalWrite(allarme,HIGH);}   //fai suonare la sirena
}
dovrebbe funzionare?

giangi72

Scusa, traduco quello che hai scritto e poi tu vedi se era quello che volevi ottenere.

Se val < VSelect accendi la pompa e salva tempoAttivazione (tempo passato da quando arduino è in funzione)
e poi
se sono passati 15 minuti fai suonare la sirena

Da quello che penso tu voglia ottenere ho qualche dubbio.
Innanzi tutto se il metodo entra varie volte mentre la prima condizione è verificata, la variabile tempoAttivazione viene valorizzata sempre e quindi la sirena non suonerà mai
Poi la sirena e la pompa non vengono mai spente. Assicurati di averlo fatto da qualche altra parte.
Infine c'è un dubbio "esecutivo" se i sensori di pressione sono collegati a quello che la pompa controlla, appena la pompa stessa entra in gioco la pressione si abbassa e la pompa si spegne (dovrebbe spegnersi da qualche altra parte), quindi la pressione riaumenta, si aziona la pompa, ...
In pratica la pressione rimane sempre sul valore massimo impostato, il classico grafico a dente di sega posizionato sul massimo dei sensori. Ma questo potresti averlo già gestito altrove.

francusallen

si, in effetti è così, cioè se la porta della pompa rimane alta per 15 min. di seguito, vuol dire chè nel materasso (antidecubito) c'è una perdita, quindi suona l'allarme, atrimenti una volta raggiunta la pressione di vSelect, dovrebbe continuare con il suo ciclo.
comunque ti tolgo tutti  dubbi sul funzionamento perchè l'ho già messo in pratica e non funziona
non ho capito molto bene sul dubbio "esecutivo" che hai.
praticamente il funzionamento è questo:
il sensore vSelect rileva il peso del paziente, poi si innesta la pompa e gonfia i due settori del materasso insieme (la pompa non deve funzionare per più di 15 min consecutivi altrimenti allarme), fino al livello vSelect controllando la pressione tramite il sensore val.
quando la pressione arriva al livelli vSelect inizia un ciclo di gonfiaggio alternato dei due settori.
posso anche postare lo sketch completo che ho fatto, ma ci sono dei gran casini
ciao

giangi72


francusallen

non ridete troppo di questo sketch, sono un principiante, so che ci sono parecchi errori altrimenti mi funzionerebbe.
praticamente è una centralina per antidecubito.
l'ho messa in pratica e va subito in allarme e poi quando val raggiunge vSelect, le elettrovalvole vanno a livello Low e non succede più niente.
praticamente non mi fa il conteggio del tempo.
riassumendo il funzionamento doveva essere questo:
1)rilevo il peso con il sensore vSelect e lo visualizzo
2)apro le due elettrovalvole dei 2 settori del materasso
3)aziono la pompa per gonfiare i due settori fino al livello vSelect controllando la pressione con il sensore val, ma la pompa non deve funzionare per 15 min consecutivi altrimenti suona l'allarme, questo perchè per gonfiare il materasso occorrono 10 min circa, quindi se la pompa rimane attiva per 15 min senza che si stacchi (tramite il sensore pressione) vuol dire che c'è una perdita.
4) inizia un ciclo alternato di gonfiaggio e sgonfiaggio dei 2 settori del materasso, cioè, sgonfio un settore, attendo 10 min, lo rigonfio e sgonfio l'altro settore e così via.
per il momento vorrei riuscire a fargli fare queste cose poi aggiungerò altro, ma testandolo non mi fa sto benedetto ciclo e non capisco gli errori, qualcuno mi può aiutare?
// includo la library del display
#include <LiquidCrystal.h>
#define pompa 13
#define elettrovalvola1 10
#define elettrovalvola2 9
#define allarme 8
unsigned long tempoAttivazione;
unsigned long timeralternanza;
unsigned long timeralternanza2;
// inizializzo la library con il numero dei pin di interfaccia
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
// Variabile array contenente i messaggi da stampare per le varie voci di menù
char* menu[]={"attendere gonfiaggio", "da 40 a 60kg", "da 60 a 80kg", "da 80 a 100kg", "da 100 a 120kg", "oltre 120kg"};
// Costante valore sensore sensore peso
const int sensore_peso = 2;
// costante valore sensore press
const int sensore_press = 1;
// Variabile contenente il valore letto dal pressostato della lettura del peso in ingresso
int vSelect=0;
// Variabile contenente il valore letto dal pressostato della lettura del peso di uscita
int val=0;

void setup(){
  // imposto il numero di righe e colonne del display LCD
lcd.begin(16, 2);
  // Stampo a display una riga di credits
lcd.setCursor(0, 0);
lcd.clear();
lcd.print(" centralina");
lcd.setCursor(4, 1);
lcd.print("Antidecubito");
delay(3000);
lcd.clear();
lcd.print("by Viano Franco");
delay(3000);
pinMode(pompa, OUTPUT);
pinMode(elettrovalvola1, OUTPUT); //elettrovalvola settore materasso1
pinMode(elettrovalvola2, OUTPUT);//elettrovalvola settore materasso2
pinMode(allarme, OUTPUT);//allarme buco

unsigned long tempoAttivazione;
unsigned long timeralternanza;
unsigned long timeralternanza2;
boolean allarmeAttivo = false;


void loop(){
lcd.setCursor(0, 0);
lcd.clear();
lcd.print(" Peso Paziente:");
// Leggo il valore del sensore peso
vSelect=map(analogRead(sensore_peso), 300, 1023, 1, 6); // valore da 1 a 6 del peso del paziente
lcd.setCursor(0, 1);
lcd.print(menu[vSelect-1]);
delay(400);
// Leggo il valore del sensore press
val = map(analogRead(sensore_press), 300,1023,1,6); // valore da 1 a 6 della pressione del materasso

digitalWrite(elettrovalvola1, HIGH); //aziono l'elettrovalvola 1
digitalWrite(elettrovalvola2,HIGH);//aziono l'elettrovalvola 2
azionamento_pompa ();
while(val==vSelect)//se il valore del rilevatore di peso e il sensore pressione sono uguali si verifica il ciclo sottostante
{
delay (5000);
settoreuno();
settoredue();}
}

void azionamento_pompa (){
boolean allarmeAttivo = false;
if (val < vSelect){digitalWrite(pompa,HIGH);
if ( !allarmeAttivo ) // se l'allarme NON è attivo
      {allarmeAttivo=true;
      tempoAttivazione=millis();
   }
}else{
    allarmeAttivo=false;//disattiva il timer per l'allarme, siamo tornati ok
  }
if (millis()-900000L > tempoAttivazione) //15 minuti in millisecondi sono 15 * 60 * 1000 = 900000
//però se scrivi il numero e basta arduino pensa sia un int(max 65000 circa, quindi gli diciamo che è un long, scrivendo L)

{digitalWrite(allarme,HIGH);}   //fai suonare la sirena
}


void settoreuno(){
digitalWrite(elettrovalvola1,LOW); //apro la valvola 1 e scarico l'aria dal settore 1 del materasso
timeralternanza=millis();//parte il timer per alternare i cuscini
if (millis() >timeralternanza+600000L)
{digitalWrite(elettrovalvola1, HIGH); //aziono l'elettrovalvola 1
azionamento_pompa();}
}

void settoredue(){
digitalWrite(elettrovalvola2,LOW); //apro la valvola 1 e scarico l'aria dal settore 2 del materasso
timeralternanza2=millis();//parte il timer per alternare i cuscini
if (millis() >timeralternanza2+600000L)
{digitalWrite(elettrovalvola2, HIGH); //aziono l'elettrovalvola 2
azionamento_pompa();}
}

giangi72

Allora.
Cominciamo con dire ceh se il peso del paziente rimane invariato in tutto il procedimento metterei
Code: [Select]
// Leggo il valore del sensore peso
vSelect=map(analogRead(sensore_peso), 300, 1023, 1, 6); // valore da 1 a 6 del peso del paziente
lcd.setCursor(0, 1);
lcd.print(menu[vSelect-1]);

nel setup e, quindi, fuori dal loop.

Poi leggi il sensore di pressione e apri le 2 elettrovalvole per svuotare il materasso e lanci azionamento_pompa().
Qui torniamo al problema di un altro post boolean allarmeAttivo = false; deve essere fuori, in setup perchè deve essere globale.

Poi, se la pressione materasso è inferiore al peso del paziente accendi la pompa e, se l'allarme non è attivo attivalo, altrimenti spegni l'allarme.
Poi se sono passati più di 15 minuti suona l'allarme.
Uhm
C'è qualcosa che non va.
Ma questo ultimo if viene eseguito sempre, mentre dovrebbe essere eseguito solo se l'allarme è attivo, o sbaglio?
Quindi dovrebbe essere
Code: [Select]
if ( allarmeAttivo && (millis()-900000L > tempoAttivazione) )

Comincia a fare queste modifiche e poi dicci che problema ti da ancora.
Riposta il codice, e se ci riesci cerca di indentare un poco che così è un macello leggerlo.

francusallen

per il momento grazie della risposta.
il rilevamento peso dovrei inserirlo nel loop perchè vorrei che il paziente si possa sdraiare sul materasso anche a ciclo iniziato quindi, alla fine del loop se nel ciclo while che ho inserito, val !=  da vSelect, esce dal ciclo while e va a ricalcolare il peso all'inizio del loop. penso.......

giangi72


francusallen

ciao, vi spiego cosa succede.
faccio partire arduino rileva il peso, apre le elettrovalvole, fa partire la pompa e suona l'allarme, (e non dovrebbe perche sole se la pompa rimane attiva per 15 min. dovrebbe suonare) poi gonfia i due settori e dopo qualche secondo ne sgonfia prima uno poi l'altro. tutto qua.
praticamente non mi fa partire i millis che ho salvato e non so perchè

giangi72

L'unico motivo per cui la pompa si possa attivare è che val<vSelect e fin qui...

L'unico motivo per cui l'allarme possa suonare è che l'if sul tempo sia verificato, qui torniamo un poco su;
se tempoAttivazione è stato appena assegnato sarà più o  meno = a millis() quindi
millis()-900000L > millis() -> -900000L > 0 cioè mai, questo vuol dire che nell'if precedente di assegnazione tempoAttivazione non è entrato e qui abbiamo 2 problemi, uno logico e uno generico di programamzione.

  • allarmeAttivo non è false

  • tempoAttivazione viene assegnato SOLO nell'if, questo è un errore perchè poi lo utilizzi e, quindi se non valorizzato avrà valore casuale




  • Come prima cosa, quindi, metti una inizializzazione tempoAttivazione = 0 nel setup

  • Poi metti un digitalWrite(pompa,LOW); sempre nel setup (scusa ma la pompa non si spegne mai?)

  • Poi riposta il codice (cerca di indentarlo per favore) e dicci cosa succede.


Go Up