Cos'è ElectroYou | Login Iscriviti

ElectroYou - la comunità dei professionisti del mondo elettrico

tempo tra un lampeggio e il successivo

Progetti, interfacciamento, discussioni varie su questa piattaforma.

Moderatori: Foto UtenteMassimoB, Foto UtenteWALTERmwp, Foto Utentexyz

0
voti

[1] tempo tra un lampeggio e il successivo

Messaggioda Foto Utentedanielealfa » 14 feb 2021, 21:06

buona sera a tutti , vorrei chidervi qualche consiglio su un programma che ho scritto prendendo esempio
da cio che ho trovato in giro .
si tratta di misurare il tempo tra un lampeggio ed il successivo .
nel caso che il led lampeggi ad una distanza minima di 2 secondi non fa nulla
se lampeggia veloce, effettua un reset, attende 39 secondi e si riavvia.
secondo voi ce qualche miglioria da fare? e sicuramente delle correzioni
grazie e buona serata
Codice: Seleziona tutto
boolean flag = 0;
boolean total_reset = 1;
byte premuto = 0; //segnale_memoria
long tt = 0; //tempo_trascorso
long tm = 0; //tempo_memoria
unsigned long T_pertenza  = 0; // tempo avvio macchina
unsigned long o = 0;
float T_media = 0.0;
byte conta = 0;
int sensorValue = 0;
void setup() {
  pinMode(13, OUTPUT);
  pinMode(A5, INPUT);
  Serial.begin(9600);
  Serial.println (F("  xxxxx "));
}
void loop() {
  sensorValue = analogRead(A5);
  if (sensorValue >= 500  ) {
    o = millis();
    if (premuto == 0) {
      premuto = 1;
      tt = millis() - tm;
      Serial.print (F("  premuto  "));
      Serial.println (conta);
      tm = millis();
    }
  }
  if (sensorValue < 500) {
    if (premuto == 1) {
      premuto = 0;
      conta = conta + 1;
      T_media += tt;
    }
  }
  //||se total_reset == calcolo il tempo delle pressioni
  if (total_reset == 0) {
    //||se non aggiorno sensorValue resetta il sistema
    if (millis() - o > 10000) {
      Serial.println (F("reset tempo"));
      total_reset = 1;// avvio procedura reset
    }
    //conto fino a 5 e faccio la media
    if (conta >= 5 && premuto == 0) {
      conta = 0;
      Serial.print (F("tt ")); Serial.println (tt );
      Serial.print (F("T_media "));
      Serial.println (T_media / 5 );
      Serial.println(F(" controllo"));
      //dentro a conta >= 5   valuto  il tempo T_media / 2
      if (T_media / 5 < 2000 ) { //se vera
        total_reset = 1;// avvio procedura reset
      }
      else {
        Serial.println(F("  no azioni"));
      }
      T_media = 0.0;
    }
  }
  if (total_reset == 1 ) {
    if (flag == 0 ) {
      T_media = 0.0;
      conta = 0;
      T_pertenza = millis();
      Serial.println(F(" reset HIGH"));
      digitalWrite(13, HIGH);
      delay(1000);
      Serial.println(F(" reset LOW"));
      digitalWrite(13, LOW);
      flag = 1;
    }
    // tempo di avvio da reset
    if (millis() - T_pertenza > 30000) {
      Serial.println(F(" avvio"));
      flag = 0;
      total_reset = 0;
    }
  }
}
Avatar utente
Foto Utentedanielealfa
228 2 4 7
Expert
Expert
 
Messaggi: 1227
Iscritto il: 27 mag 2009, 22:51

0
voti

[2] Re: tempo tra un lampeggio e il successivo

Messaggioda Foto UtenteWALTERmwp » 15 feb 2021, 2:48

Ciao @danielealfa.
Chiedo, potresti essere un po' più esplicito nella descrizione ?
E magari scrivere cosa non accade rispetto a quel che invece ti aspetti ?

Saluti
W - U.H.F.
Avatar utente
Foto UtenteWALTERmwp
25,1k 4 8 13
G.Master EY
G.Master EY
 
Messaggi: 7442
Iscritto il: 17 lug 2010, 18:42
Località: le 4 del mattino

0
voti

[3] Re: tempo tra un lampeggio e il successivo

Messaggioda Foto UtenteIlGuru » 15 feb 2021, 11:08

Mi perplime un po' veder usare il tipo float su un AVR ad 8 bit.
Ma quando assegni tt di tipo long a T_media di tipo float senza castarlo il compilatore non si incazza?
\Gamma\nu\tilde{\omega}\theta\i\ \sigma\epsilon\alpha\upsilon\tau\acute{o}\nu
Avatar utente
Foto UtenteIlGuru
4.729 2 10 13
Master EY
Master EY
 
Messaggi: 1690
Iscritto il: 31 lug 2015, 23:32

0
voti

[4] Re: tempo tra un lampeggio e il successivo

Messaggioda Foto UtenteMarcoD » 15 feb 2021, 12:19

Premetto che è molto faticoso e sgradevole esaminare un listato altrui.

Ti propongo una semplificazione marginale consistente nel modificare il sensorValue da intero a boolean e a scriverlo una sola volta.
Inoltre suggerisco di allineare le parentesi { } in modo da facilitare la comprensione.

O_/

Codice: Seleziona tutto
  sensorValue = analogRead(A5);
  if (sensorValue >= 500  ) {
    o = millis();
    if (premuto == 0) {
      premuto = 1;
      tt = millis() - tm;
      Serial.print (F("  premuto  "));
      Serial.println (conta);
      tm = millis();
    }
  }


..........modifica proposta:...............
boolean  sensorValue;
.......................
  if (analogRead(A5)>500) {sensorValue = high } else {sensorValue = low }
  if (sensorValue )
   {
     o = millis();
     if (premuto == 0)
       {
        premuto = 1;
        tt = millis() - tm;
        Serial.print (F("  premuto  "));
        Serial.println (conta);
        tm = millis();
       }
    }
...................

Avatar utente
Foto UtenteMarcoD
8.844 4 9 13
Master EY
Master EY
 
Messaggi: 4123
Iscritto il: 9 lug 2015, 16:58
Località: Torino

0
voti

[5] Re: tempo tra un lampeggio e il successivo

Messaggioda Foto UtenteWALTERmwp » 15 feb 2021, 12:52

MarcoD ha scritto:Premetto che è molto faticoso (...)
certo, dall'OP mi pare anche mal posta la questione.
Si chiede perché non si sa come fare, comprensibile, ma è auspicabile un pochino d'impegno nell'esposizione: eviterebbe di dover interpretare quel che dovrebbe essere chiaro.

Saluti
W - U.H.F.
Avatar utente
Foto UtenteWALTERmwp
25,1k 4 8 13
G.Master EY
G.Master EY
 
Messaggi: 7442
Iscritto il: 17 lug 2010, 18:42
Località: le 4 del mattino

0
voti

[6] Re: tempo tra un lampeggio e il successivo

Messaggioda Foto Utentedanielealfa » 15 feb 2021, 16:33

grazie delle vostre attenzioni.
no il listato funziona, era una domanda per sapere se poteva essere migliorato.

IlGuru ha scritto:Mi perplime un po' veder usare il tipo float su un AVR ad 8 bit.
Ma quando assegni tt di tipo long a T_media di tipo float senza castarlo il compilatore non si incazza?


no non mi da errori, niente di niente, questa e una cosa che mi farebbe piacere come la faresti tu, anche per imparare qualcosa di piu',
MarcoD ha scritto:Ti propongo una semplificazione marginale consistente nel modificare il sensorValue da intero a boolean e a scriverlo una sola volta.
Inoltre suggerisco di allineare le parentesi { } in modo da facilitare la comprensione.


come suggerito metto il tutto corretto, per il momento vi ringrazio delle vostre critiche e consigli

Codice: Seleziona tutto
boolean flag = 0;
boolean total_reset = 1;
byte premuto = 0; //segnale_memoria
long tt = 0; //tempo_trascorso
long tm = 0; //tempo_memoria
unsigned long T_pertenza  = 0; // tempo avvio macchina
unsigned long o = 0;
float T_media = 0.0;
byte conta = 0;
boolean sensorValue = 0;
void setup() {
  pinMode(13, OUTPUT);
  pinMode(A5, INPUT);
  Serial.begin(9600);
  Serial.println (F("  xxxxx "));
}
void loop() {
  if (analogRead(A5)>500)
  {
    sensorValue = HIGH;
  }
  else
  {
    sensorValue = LOW;
    }
  if (sensorValue== HIGH )
   {
     o = millis();
     if (premuto == 0)
       {
        premuto = 1;
        tt = millis() - tm;
        Serial.print (F("  premuto  "));
        Serial.println (conta);
        tm = millis();
  }
  }
 
  if (sensorValue == LOW)
  {
    if (premuto == 1)
    {
      premuto = 0;
      conta = conta + 1;
      T_media += tt;
    }
  }
  //||se total_reset == calcolo il tempo delle pressioni
  if (total_reset == 0)
  {
    //||se non aggiorno sensorValue resetta il sistema
    if (millis() - o > 10000)
    {
      Serial.println (F("reset tempo"));
      total_reset = 1;// avvio procedura reset
    }
    //conto fino a 5 e faccio la media
    if (conta >= 5 && premuto == 0)
    {
      conta = 0;
      Serial.print (F("tt ")); Serial.println (tt );
      Serial.print (F("T_media "));
      Serial.println (T_media / 5 );
      Serial.println(F(" controllo"));
      //dentro a conta >= 5   valuto  il tempo T_media / 2
      if (T_media / 5 < 2000 ) { //se vera
        total_reset = 1;// avvio procedura reset
      }
      else {
        Serial.println(F("  no azioni"));
      }
      T_media = 0.0;
    }
  }
  if (total_reset == 1 )
  {
    if (flag == 0 ) {
      T_media = 0.0;
      conta = 0;
      T_pertenza = millis();
      Serial.println(F(" reset HIGH"));
      digitalWrite(13, HIGH);
      delay(1000);
      Serial.println(F(" reset LOW"));
      digitalWrite(13, LOW);
      flag = 1;
    }
    // tempo di avvio da reset
    if (millis() - T_pertenza > 30000)
    {
      Serial.println(F(" avvio"));
      flag = 0;
      total_reset = 0;
    }
  }
}
Avatar utente
Foto Utentedanielealfa
228 2 4 7
Expert
Expert
 
Messaggi: 1227
Iscritto il: 27 mag 2009, 22:51

0
voti

[7] Re: tempo tra un lampeggio e il successivo

Messaggioda Foto UtenteMarcoD » 15 feb 2021, 18:31

ho fatto solo qualche abbellimento estetico funzionale al programma, sperando di non aver introdotto errori.

Devi scrivere qualche riga di commento e descrizinoe di cosa fa all'inizio del programma, e una data di inizio sviluppo, così ti rendi conto di quanto tempo ci passi sopra.

Un programma è un poco come una poesia o uno scritto impaginato, deve facilitare la lettura e la comprensione, se no, dopo qualche mese, non comprendi che cosa hai fatto.

Poi ognuno ha il suo stile di programmazione....e non si cura molto di quelli altrui...

//15/2/2021
//programma di misura del tempo.....
//

boolean flag = 0;
boolean total_reset = 1;
byte premuto = 0; //segnale_memoria
long tt = 0; //tempo_trascorso
long tm = 0; //tempo_memoria
unsigned long T_pertenza = 0; // tempo avvio macchina
unsigned long o = 0;
float T_media = 0.0;
byte conta = 0;
boolean sensorValue = 0;

void setup() {
pinMode(13, OUTPUT);
pinMode(A5, INPUT);
Serial.begin(9600);
Serial.println (F(" xxxxx "));
}

void loop() {
if (analogRead(A5)>500) { sensorValue = HIGH } else { sensorValue = LOW;}

if (sensorValue== HIGH )
{
o = millis();
if (premuto == 0)
{
premuto = 1;
tt = millis() - tm;
Serial.print (F(" premuto "));
Serial.println (conta);
tm = millis();
}
}

else // di sicuro allora è LOW if (sensorValue == LOW)
{
if (premuto == 1)
{
premuto = 0;
conta = conta + 1;
T_media += tt;
}
}

//||se total_reset == calcolo il tempo delle pressioni
if (total_reset == 0)
{
//||se non aggiorno sensorValue resetta il sistema
if (millis() - o > 10000)
{
Serial.println (F("reset tempo"));
total_reset = 1;// avvio procedura reset
}
//conto fino a 5 e faccio la media
if (conta >= 5 && premuto == 0)
{
conta = 0;
Serial.print (F("tt ")); Serial.println (tt );
Serial.print (F("T_media "));
Serial.println (T_media / 5 );
Serial.println(F(" controllo"));
//dentro a conta >= 5 valuto il tempo T_media / 2
if (T_media / 5 < 2000 )
{ //se vera
total_reset = 1;// avvio procedura reset
}
else {
Serial.println(F(" no azioni"));
}
T_media = 0.0;
}
}
if (total_reset == 1 )
{
if (flag == 0 ) {
T_media = 0.0;
conta = 0;
T_pertenza = millis();
Serial.println(F(" reset HIGH"));
digitalWrite(13, HIGH);
delay(1000);
Serial.println(F(" reset LOW"));
digitalWrite(13, LOW);
flag = 1;
}
// tempo di avvio da reset
if (millis() - T_pertenza > 30000)
{
Serial.println(F(" avvio"));
flag = 0;
total_reset = 0;
}
}
}
Avatar utente
Foto UtenteMarcoD
8.844 4 9 13
Master EY
Master EY
 
Messaggi: 4123
Iscritto il: 9 lug 2015, 16:58
Località: Torino

2
voti

[8] Re: tempo tra un lampeggio e il successivo

Messaggioda Foto Utentelemure64 » 15 feb 2021, 18:47

danielealfa ha scritto:grazie delle vostre attenzioni.
no il listato funziona, era una domanda per sapere se poteva essere migliorato.


Come detto, interpretare un sorgente non scritto da sé stessi è veramente impegnativo e vedo che stanno partecipando al thread persone che la sanno molto più lunga di me quindi taccio :) Però ho visto ancora dei float in giro; per il poco che ne so, vanno evitati a meno che non esista un'altra soluzione formulata in termini di interi. Se si ha davvero ma davvero bisogno di un float su un micro sospetto che possa non essere un problema da risolvere con un micro.

Se può esserti d'aiuto a iniziare a pensare diversamente (laddove occorra) a me è comodo inventare unità di misura e scalare le grandezze in modo che possano entrare nello spazio dei tipi interi. Per cose afferenti al seguire alba e tramonto per esempio mi sono tornati comodi i "decasecondi" (1 unità == 10 s), e così via. In altri casi mi è stato utile 1 unità == 10 ms. Forse qualcosa del genere potrà tornarti utile per i prossimi progetti.
Avatar utente
Foto Utentelemure64
675 3 6
Stabilizzato
Stabilizzato
 
Messaggi: 382
Iscritto il: 23 giu 2020, 12:26

1
voti

[9] Re: tempo tra un lampeggio e il successivo

Messaggioda Foto Utentedjnz » 15 feb 2021, 20:00

danielealfa ha scritto:per sapere se poteva essere migliorato

Déjà vu... si può usare una logica molto più semplice:
Codice: Seleziona tutto
//========================================================
byte          conta = 0;
byte          primoGiro = 1;
byte          premuto = 0;
unsigned long tm;  //tempo_memoria
//========================================================
void setup(){
    pinMode(13, OUTPUT);
    pinMode(A5, INPUT);
}
//========================================================
void loop(){
    unsigned long now = millis();
    byte sensorValue = analogRead(A5) > 500;
    byte fronte = sensorValue && !premuto;
    premuto = sensorValue;

    if (fronte){
        if (!primoGiro) conta = (now-tm < 2000) ? conta+1 : 0;
        primoGiro = 0;
        tm = now;
    }

    if (5 == conta  ||  (now-tm > 10000)){
        digitalWrite(13, HIGH);
        delay(1000);
        digitalWrite(13, LOW);
        delay(30000);
        conta = 0;
        primoGiro = 1;
        tm = now;
    }
}
//========================================================
Avatar utente
Foto Utentedjnz
355 1 5
Frequentatore
Frequentatore
 
Messaggi: 146
Iscritto il: 26 lug 2020, 14:52

0
voti

[10] Re: tempo tra un lampeggio e il successivo

Messaggioda Foto Utentedanielealfa » 15 feb 2021, 21:23

grazie delle info
Codice: Seleziona tutto
if (!primoGiro) conta = (now-tm < 2000) ? conta+1 : 0;

non riesco a capirla, nel uso del ? e del 0 finale.

unsigned long now = millis();
unsigned long now = millis();
byte sensorValue = analogRead(A5) > 500;
byte fronte = sensorValue && !premuto;
premuto = sensorValue;

cosa cambia se vengono inizializzate prima del setup o nel loop a questo modo?
now = millis();
sensorValue = analogRead(A5) > 500;
fronte = sensorValue && !premuto;
premuto = sensorValue;



grazie ancora delle spiegazioni
Avatar utente
Foto Utentedanielealfa
228 2 4 7
Expert
Expert
 
Messaggi: 1227
Iscritto il: 27 mag 2009, 22:51

Prossimo

Torna a Arduino

Chi c’è in linea

Visitano il forum: Nessuno e 1 ospite