Tentativo di strumentazione digitale scooter

fratt ho rimosso il post, ho fatto degli errori, riprovo e riporto gli esiti. Scusami x la leggerezza!

ok il codice che sto usando adesso è questo:

void loop() {
  StatoPulsante = digitalRead(BUTTON);                        // legge il valore del BUTTON e lo conserva
  delay(15);                                                  // Aspetto 15ms per far alzare il dito
  if (StatoPulsante != StatoPulsantePrecedente) {             // compara lo stato del pulsante attuale con il precedente
    if (StatoPulsante == HIGH) {                                // se lo stato è cambiato incrementa il contatore

      ContatorePulsantePremuto++;                              // se lo stato corrente è alto, il pulsante è passato da off a on

      if (ContatorePulsantePremuto > 4) {

        // inizializzazione delle variabili

        ContatorePulsantePremuto = 0;
        StatoPulsante = 0;
        StatoPulsantePrecedente = 0;

      }
    }
    StatoPulsantePrecedente = StatoPulsante;                  // salva lo stato corrente nella variabile che indica lo stato precedente per il loop successivo
  }

  switch (ContatorePulsantePremuto) {
    case 1:  // controlla se il pulsante è stato premuto una volta

      durationhigh = pulseIn(pin, HIGH);                    // imposto funzione lettura numero giri
      durationlow = pulseIn(pin, LOW);
      durationgiro = durationhigh + durationlow;
      if (durationhigh > 0 && durationlow > 0) {
        durationgiro = durationhigh + durationlow;
        giri = 60000000 / durationgiro;
        Serial.println(giri);                                 // stampa sulla console "giri"
        lcd.clear();
        lcd.setCursor(2, 0);
        lcd.print("Giri");
        lcd.setCursor(2, 1);
        lcd.print(giri);
        if (abs(giri - giri_prec) > 250) {
          lcd.setCursor(2, 1);
          lcd.print(giri);

          Serial.println(giri);
          giri_prec = giri;

        }
      }

      break;

    case 2:  // controlla se il pulsante è stato premuto due volte
      sensors.requestTemperatures();                       // Invia il comando di lettura delle temperatura
      Serial.print("Temperatura di: ");                    // stampa a video la temperatura
      Serial.print(temperatura);
      Serial.println(" C");

      lcd.clear();
      lcd.setCursor(2, 0);
      lcd.print("Temp");
      lcd.setCursor(0, 1);
      lcd.print(temperatura);
      lcd.setCursor(6, 1);
      lcd.print("\337C""C");
      if (abs(temperatura - temperatura_prec) > 1) {
        lcd.setCursor(0, 1);
        lcd.print(temperatura);
        lcd.setCursor(6, 1);
        lcd.print("\337C""C");

        Serial.print("Temperatura di: ");                    // stampa a video la temperatura
        Serial.print(temperatura);
        Serial.println(" C");
        temperatura_prec = temperatura;
      }
      break;

    case 3:  // controlla se il pulsante è stato premuto tre volte
      lettura = analogRead(analogPin);
      voltage = (13.3 / 1024) * lettura;                    // 13.75 sono i volts teorici della batteria a pieno carico
      Serial.print(voltage);
      Serial.println("V");

      lcd.clear();
      lcd.setCursor(2, 0);
      lcd.print("Batt");
      lcd.setCursor(0, 1);
      lcd.print(voltage);
      lcd.setCursor(5, 1);
      lcd.print("V");
      if (abs(voltage - voltage_prec) > 1) {
        lcd.setCursor(0, 1);
        lcd.print(voltage);
        lcd.setCursor(5, 1);
        lcd.print("V");

        Serial.print(voltage);
        Serial.println("V");

        voltage_prec = voltage;
      }

      break;

    case 4:  // controlla se il pulsante è stato premuto quattro volte
      Serial.println("data e ora");                              // stampa sulla console "data e ora"
      break;

  }
}

e purtroppo dalla stampa seriale vedo che la variabile continua a essere stampata sempre e quindi il display refresha .

mi salta all'occhio una cosa strana...

    case 1:  // controlla se il pulsante è stato premuto una volta

      durationhigh = pulseIn(pin, HIGH);                    // imposto funzione lettura numero giri
      durationlow = pulseIn(pin, LOW);
      durationgiro = durationhigh + durationlow;
      if (durationhigh > 0 && durationlow > 0) {
        durationgiro = durationhigh + durationlow;
        giri = 60000000 / durationgiro;
        Serial.println(giri);                                 // stampa sulla console "giri"
//        lcd.clear();
//        lcd.setCursor(2, 0);
//        lcd.print("Giri");
//        lcd.setCursor(2, 1);
//        lcd.print(giri);

        if (abs(giri - giri_prec) > 250) {
          // fai tutto dentro l'if
          lcd.clear();
          lcd.setCursor(2, 0);
          lcd.print("Giri");
          lcd.setCursor(2, 1);
          lcd.print(giri);

          Serial.println(giri);
          giri_prec = giri;

        }
      }

      break;

ovviamente non devo refreshare fuori dall'if... ma solo dentro l'if

Grande! In effetti adesso va. Pensavo che la prima stampa potessi farla fuori dall'if e poi l'if avrebbe regolato il tutto. Evidentemente quando penso di aver capito una cosa, puntualmente scopro che non l'ho capita.

Ok sta cosa pare risolta. Mo ho notato che se faccio fare più cicli al programma, pigiando i pulsanti, a volte va tutto liscio a volte s'inpunta. Hai un'idea del perchè accade? Noto che la parte più pesante è quando il programma deve passare dalla temperatura al voltmetro. E' come se il micro fosse impegnato a fare altro. Ma cosa se gli abbiam detto di stare tranquillo per quel grado di scarto che gli abbiamo imposto.

a dir la verità sta "tranquillo" solo riguardo l'aggiornamento dello schermo, ma tutte le altre operazioni le fa comunque... quindi letture di sensori, calcoli, ecc comunque vengono eseguite e richiedono tempo.
non so dirti quanto tempo nello specifico, perché non conosco quel sensore.

forse prevedendo un intervallo di tempo tra le letture la situazione migliora, ma non ne sono certo...
potresti provare a mettere tutto lo switch-case dentro un if che controlla quanto è passato dalla lettura precedente:
prevedi una variabile tempo che inizializzi con millis() nel setup() e poi nel loop() prima dello switch-case metti un nuovo if

if ((millis()-tempo) > 500) { // intervallo di mezzo secondo
  // qui ci metti tutto lo switch-case

  // prima di chiudere l'if aggiorni la variabile tempo
  tempo = millis();
}

ribadisco che non sono sicuro che la situazione migliori. non riesco a testare il codice, quindi vado un po' a sensazione...

mi sembra che nella temperatura non inizializzi la variabile... temperatura = sensors.getTempCByIndex(0);
stampa dei valori sensati?

La variabile temperatura l'ho dichiarata così :

float temperatura =sensors.getTempCByIndex(0);

e i valori stampati sono esatti. Ho sbagliato?

Testo il suggerimento millis() e riporto. Per ovvi motivi lo userò nel case temperatura e voltmetro. per i giri e l'ora serve il real
time.

Grazie fratt

  1. non sono pratico di sensori di temperatura, ma secondo me l'istruzione "temperatura =sensors.getTempCByIndex(0);" devi metterla nel case dopo il "sensors.requestTemperatures();" altrimenti stamperà sempre la stessa temperatura letta all'inizio del programma.

  2. nell'esempio che ho messo io c'è un intervallo di mezzo secondo... credo che sia ininfluente anche su giri e orario...
    per i giri forse anche 1 secondo di intervallo non crea problemi... con uno scooter di quanto possono variare i giri in un secondo?
    per l'orario, se visualizzi solo ora e minuti direi che un intervallo di qualche secondo è comunque ininfluente...

Ok, provo a spostare la variabile temperatura e ti dico....

Ma l'intervallo in questione, deve x forza coinvolgere tutto lo switch case o può essere selettivo solo x i case che mi interessano?

Per la variazione dei giri, bhe in un secondo se do una forte accelerata possono salire anche di qualche mugliaio.

io per semplicità avevo pensato ad un unico if comprendente tutto lo switch-case, ma nulla vieta di mettere l'if dentro il case.

Allora prove effettuate. Prima il codice attuale:

void loop() {

  StatoPulsante = digitalRead(BUTTON);                        // legge il valore del BUTTON e lo conserva
  if (StatoPulsante != StatoPulsantePrecedente) {             // compara lo stato del pulsante attuale con il precedente
    if (StatoPulsante == HIGH) {                                // se lo stato è cambiato incrementa il contatore

      ContatorePulsantePremuto++;                              // se lo stato corrente è alto, il pulsante è passato da off a on

      if (ContatorePulsantePremuto > 3) {

        // inizializzazione delle variabili

        ContatorePulsantePremuto = 0;
        StatoPulsante = 0;
        StatoPulsantePrecedente = 0;

      }
    }
    StatoPulsantePrecedente = StatoPulsante;                  // salva lo stato corrente nella variabile che indica lo stato precedente per il loop successivo
  }
  if ((millis() - tempo) > 500) {
    switch (ContatorePulsantePremuto) {
      case 1:  // controlla se il pulsante è stato premuto una volta

        durationhigh = pulseIn(pin, HIGH);                    // imposto funzione lettura numero giri
        durationlow = pulseIn(pin, LOW);
        durationgiro = durationhigh + durationlow;
        if (durationhigh > 0 && durationlow > 0) {
          durationgiro = durationhigh + durationlow;
          giri = 60000000 / durationgiro;
          if (abs(giri - giri_prec) > 250) {
            lcd.clear();
            lcd.setCursor(2, 0);
            lcd.print("Giri");
            lcd.setCursor(2, 1);
            lcd.print(giri);

            Serial.println(giri);

            giri_prec = giri;

          }
        }

        break;

      case 2:  // controlla se il pulsante è stato premuto due volte
        sensors.requestTemperatures();                       // Invia il comando di lettura delle temperatura
        if (abs(temperatura - temperatura_prec) > 1) {
          lcd.clear();
          lcd.setCursor(2, 0);
          lcd.print("Temp");
          lcd.setCursor(0, 1);
          lcd.print(temperatura);
          lcd.setCursor(6, 1);
          lcd.print("\337C""C");

          Serial.print("Temperatura di: ");                    // stampa a video la temperatura
          Serial.print(temperatura);
          Serial.println(" C");

          temperatura_prec = temperatura;
        }
        break;

      case 3:  // controlla se il pulsante è stato premuto tre volte
        lettura = analogRead(analogPin);
        voltage = (13.3 / 1024) * lettura;                    // 13.75 sono i volts teorici della batteria a pieno carico
        if (abs(voltage - voltage_prec) > 1) {
          lcd.clear();
          lcd.setCursor(2, 0);
          lcd.print("Batt");
          lcd.setCursor(0, 1);
          lcd.print(voltage);
          lcd.setCursor(5, 1);
          lcd.print("V");

          Serial.print(voltage);
          Serial.println("V");

          voltage_prec = voltage;
        }

        break;

        tempo = millis();
    }

  }
}

Il programma dopo il primo ciclo, dopo s'impunta sempre e addirittura salta le funzioni. Che nervi!

il "tempo = millis();" devi metterlo fuori dallo switch, prima della graffa che chiude l'if (in pratica spostalo sotto la graffa)

Fatto, ma c'è qualcosa di strano, dopo il primo ciclo, eseguito con scioltezza, poi, l'esecuzione del programma si blocca, o meglio se premo il pulsante vedo il led a bordo di Arduino lampeggiare, ma il ciclo non riparte più. :o

led? quale led? è normale che lampeggi?
sicuro che non sia un problema hardware?

purtroppo non potendo provare lo sketch non saprei cosa dire...
la logica dovrebbe essere corretta, così come il codice...

il BUTTON è sul pin 13 è normale che lampeggi. Io intendevo dire che con il lampeggio sono sicuro che il comando arriva ad Arduino ma il ciclo non riparte.

spetta, spetta, mi sa che ho detto una cazzata...
messo così, se premi il pulsante a metà dell'intervallo il contatore aumenta comunque, quindi le schermate potrebbero non essere in sequenza...

a questo punto mi sa che avevi ragione tu... forse conviene mettere l'if dentro ogni case...
è brutto andare per tentativi, ma non riuscendo a provare il codice...

Figurati, tutto posso fare tranne che aver ragione io. Domattina provo.
Grazie mille del super supporto.
Ciao

Neanche cosi va:

void setup() {
  tempo = millis();
  lcd.begin(8, 2);                                  //impostiamo il numero di colonne ed il numero di righe di lcd
  pinMode(BUTTON, INPUT);                           // imposta input
  pinMode(pin, INPUT);
  sensors.begin();                                  // avvia libreria DS18B20
  Serial.begin(9600);                               // apre la porta seriale e la inizializza a 9600 bps
  Serial.println("messaggio");                 // messaggio inizializzazione
  lcd.clear();
  lcd.setCursor(1, 0);
  lcd.print("mess");
  lcd.setCursor(0, 1);
  lcd.print("mess");
}

void loop() {

  StatoPulsante = digitalRead(BUTTON);                        // legge il valore del BUTTON e lo conserva
  delay(15);
  if (StatoPulsante != StatoPulsantePrecedente) {             // compara lo stato del pulsante attuale con il precedente
    if (StatoPulsante == HIGH) {                                // se lo stato è cambiato incrementa il contatore

      ContatorePulsantePremuto++;                              // se lo stato corrente è alto, il pulsante è passato da off a on
      if (ContatorePulsantePremuto > 3) {

        // inizializzazione delle variabili

        ContatorePulsantePremuto = 0;
        StatoPulsante = 0;
        StatoPulsantePrecedente = 0;

      }

    }
    StatoPulsantePrecedente = StatoPulsante;                  // salva lo stato corrente nella variabile che indica lo stato precedente per il loop successivo
  }

  switch (ContatorePulsantePremuto) {

    case 1:  // controlla se il pulsante è stato premuto una volta

      durationhigh = pulseIn(pin, HIGH);                    // imposto funzione lettura numero giri
      durationlow = pulseIn(pin, LOW);
      durationgiro = durationhigh + durationlow;
      if (durationhigh > 0 && durationlow > 0) {
        durationgiro = durationhigh + durationlow;
        giri = 60000000 / durationgiro;
        if (abs(giri - giri_prec) > 250) {
          lcd.clear();
          lcd.setCursor(2, 0);
          lcd.print("Giri");
          lcd.setCursor(2, 1);
          lcd.print(giri);

          Serial.println(giri);

          giri_prec = giri;

        }
      }

      break;

      if ((millis() - tempo) > 500) {
      case 2:  // controlla se il pulsante è stato premuto due volte

        sensors.requestTemperatures();            // Invia il comando di lettura delle temperatura
        if (abs(temperatura - temperatura_prec) > 1) {
          lcd.clear();
          lcd.setCursor(2, 0);
          lcd.print("Temp");
          lcd.setCursor(0, 1);
          lcd.print(temperatura);
          lcd.setCursor(6, 1);
          lcd.print("\337C""C");

          Serial.print("Temperatura di: ");                    // stampa a video la temperatura
          Serial.print(temperatura);
          Serial.println(" C");

          temperatura_prec = temperatura;

        }

      }

      break;
      tempo = millis();

      if ((millis() - tempo) > 500) {
      case 3:  // controlla se il pulsante è stato premuto tre volte

        lettura = analogRead(analogPin);
        voltage = (13.3 / 1024) * lettura;                    // 13.75 sono i volts teorici della batteria a pieno carico
        if (abs(voltage - voltage_prec) > 1) {
          lcd.clear();
          lcd.setCursor(2, 0);
          lcd.print("Batt");
          lcd.setCursor(0, 1);
          lcd.print(voltage);
          lcd.setCursor(5, 1);
          lcd.print("V");

          Serial.print(voltage);
          Serial.println("V");

          voltage_prec = voltage;

        }

      }

      break;
      tempo = millis();
  }

}

dopo il primo ciclo si blocca. uffa!

Ciao Droid, non credo sia giusto mettere i case dentro un if

if ((millis() - tempo) > 500) {
      case 2:  // controlla se il pulsante è stato premuto due volte

poi

  break;
      tempo = millis();
  }

}

[/code]

poi forse:

  break;
  }
      tempo = millis();

}

(Porta pazienza ma nn seguo bene il filo del tuo codice :frowning:

Stefano

Ho tre case che faccio switchare con button. A causa della lentezza dello switch, sto tentando di usare millis() per far effettuare meno calcoli al micro e snellire la ciclata tra le tre funzioni.