Controllo sulla struttura , alcuni comandi non arrivano via seriale

Ho trovato unì esempio dove ho preso spunto per fare un esempio test, in modo da capire quante funzioni posso mandare in funzione in modo indipendente utilizzando il void.
Da quanto ho capito, le 4 funzioni, sono indipendenti e senza il problema del DELAY

ho trovato uno stano errore, che sicuramente dipende dalla struttura:
ho realizzato 4 funzioni:

Una che conta i numeri
una che fa accendere/spegnere un led
una che si occupa di inviare alla seriale il valore di una variabile quando il suo valore è=4
ed infine, una funzione dedicata al tastierino numerico.

gli invii tramite seriale delle tre funzioni vanno bene, quello che non va bene è il tastierino che su 10 volte che premo uno dei 9 tasti, mi scrive il comando una o due volte, come se ci fosse qualcosa che impedisce di ricevere il comando dal tastierino.
si tratta sicuramente di struttura, potete capire voi il problema?

//Includi libreria
#include "DHT.h"
#include <Keypad.h>

const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
//definisci i simboli dei tasti tastierino
char hexaKeys[ROWS][COLS] = {
  {'0','1','2','3'},
  {'4','5','6','7'},
  {'8','9','A','B'},
  {'C','D','E','F'}
};
byte rowPins[ROWS] = {3, 2, 1, 0}; //connessione dei pin RIGHE del tastierino
byte colPins[COLS] = {7, 6, 5, 4}; //connessione dei pin COLONNE del tastierino

//Inizializza l' istanza class NewKeypad
Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS); 

DHT dht;
const byte ledPin =  13; // the number of the LED pin
byte ledState = 0; // ledState used to set the LED
unsigned long tempMillis1 = 0; // porta la variabile tempMillis1 a valore=0
unsigned long interval1 = 1000;  // porta la variabile interval1 a valore=100
unsigned long tempMillis2 = 0; // porta la variabile tempMillis12 a valore=0
unsigned long interval2 = 1000; // porta la variabile interval1 a valore=1000
unsigned int countanumeri = 0; // porta la variabile countanumeri a valore=0
void setup() {
  Serial.begin(19200);  //inizializza il baud rate della porta seriale
  delay(1000); //spetta 2 secondi prima di partire
  pinMode(ledPin, OUTPUT); // tutto quello che si chiama ledPin, è configurato come OUTPUT
  dht.setup(22); // data pin 2
}

//queste sono due funzioni distinte indipendenti
void loop() {
  CONTEGGIONUMERI();//è il nome della funzione
  contatore_volte();//è il nome della funzione
  LEGGITEMPERATURA();//OGNI 4 CICLI, LEGGI LA TEMPERATURA
  TASTIERINO();//LEGGI VALORI DA TASTIERINO
  
}

//FUNZIONE che aggiunge +1 alla variabile CONTANUMERI ogni volta che la funzione IF viene vera
void CONTEGGIONUMERI() {
  //fai una comparazione tra MILLIS che è il tempo
  if (millis() - tempMillis1 > interval1) {
    tempMillis1 = millis(); // save the last time you blinked the LED
    // if the LED is off turn it on and vice-versa:
    ledState ^= 1; 
    countanumeri = (countanumeri + 1);
    digitalWrite(ledPin, ledState);
    Serial.print("FLAG"); //increment the counter and print it on the serial
    Serial.print(" =");
    Serial.println(ledState);
  }
}
//FUNZIONE che azzera la variabile COUNTANUMERI quando il suo valore è uguale a 4 e stampa il valore sulla seriale
void contatore_volte() {
  //fai una comparazione tra MILLIS che è il tempo
  if (countanumeri == 4) {
    countanumeri = 0;
    digitalWrite(ledPin, ledState);
    Serial.println("azzeramento"); //increment the counter and print it on the seriale
  }
  }
  //FUNZIONE che legge temperatura DH100
void LEGGITEMPERATURA() {
  delay(dht.getMinimumSamplingPeriod());
  float humidity = dht.getHumidity();
  float temperature = dht.getTemperature();
  Serial.print(humidity, 1);
  Serial.print(" - ");
  Serial.println(temperature, 1);
  }
 //FUNZIONE TASTIERINO
void TASTIERINO() {
  char customKey = customKeypad.getKey();
  if (customKey){
  Serial.print("K");
  Serial.println(customKey);
  Serial.print("F");
  }
}

I pulsanti di una tastiera sono comuni contatti elettrici, e come tali soffrono dei cosiddetti “rimbalzi”, ossia la pressione di un pulsante non genera un singolo impulso ma la natura del contatto fa partire diversi segnali elettrici, col risultato che il tuo programma non legge 1 pressione ma ne legge diverse. Sarà questo il tuo problema?

Le letture dei pulsanti si fanno in genere in 3 passaggi:

  1. leggo lo stato del pulsante
  2. se lo vedo premuto, attendo un piccolo periodo di tempo (30-50 ms)
  3. rileggo lo stato del pulsante: se è ancora premuto, solo allora considero la pressione “vera” ed eseguo la funzione corrispondente.

@Leo : Leo, mi sembra che lui stia usando la libreria KeyPad, fatta apposta per leggere la tastiera ... ... NON la consco, ma mi auguro bene che il debouncing sia implementato nella libreria e che se io chiedo getKey() ... sia la libreria a fare "le pulizie" ed a restituirmi il tasto premuto ;)

Guglielmo

Conosco il problema del' anti rimbalzo, lo facevo con le porte logiche sugli eperimenti in elettronica. Il problema non è che ho una ripetizione del carattere sulla seriale, non mi appare proprio quando lo vado a premere. Su 10 pressioni ne prende uno solo. credo sia un problema di tutto lo sketch. se prendo solo il programmino singolarmente funziona bene e non ho neanche il problema del' anti rimbalzo.

@Guglielmo: non mi ricordo se la Keypad che ho usato tempo fa io ce l'aveva o meno, ma usando la funzione classica per leggere un tasto premuto ho implementato lo stesso un antirimbalzo perché avevo letture multiple.

@edstarink: cos'è questo?

delay(dht.getMinimumSamplingPeriod());

Che fa questo delay? Quanto può durare? Se dura parecchio (parlo di centinaia di ms) può influenzare la lettura della tastiera: se premi un tasto mentre il codice è in quel delay, perdi la pressione.

Caspita, me ne sono accorto prima che tu lo scrivessi... Ho visto quel maledetto delay impostato dalla libreria ad un secondo. Scusami, ma rileggendo il codice mi è saltato all' occhio.

In questo caso dovrei sostituirlo e fare quel giochetto con il millis :relaxed: spero di farcela...

leo72: @Guglielmo: non mi ricordo se la Keypad che ho usato tempo fa io ce l'aveva o meno, ma usando la funzione classica per leggere un tasto premuto ho implementato lo stesso un antirimbalzo perché avevo letture multiple.

@Leo : Ok ... me la sono scaricata e ... proprio nel costruttore c'è :

setDebounceTime(10);

... quindi ... dieri che il debouncing lo fa la libreria :grin: :grin: :grin:

Guglielmo

Ho risolto il problema, alla fine mi è servito studiare :slight_smile:

Ho inserito altre due variabili, una per il tempo e l’ altra per l’ aggiornamento di stato.
posto lo sketch modificato magari date una controllata che sia preciso perchè credo sia un po confusionale

//Includi libreria
#include "DHT.h"
#include <Keypad.h>

const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
//definisci i simboli dei tasti tastierino
char hexaKeys[ROWS][COLS] = {
  {'0','1','2','3'},
  {'4','5','6','7'},
  {'8','9','A','B'},
  {'C','D','E','F'}
};
byte rowPins[ROWS] = {3, 2, 1, 0}; //connessione dei pin RIGHE del tastierino
byte colPins[COLS] = {7, 6, 5, 4}; //connessione dei pin COLONNE del tastierino

//Inizializza l' istanza class NewKeypad
Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS); 

DHT dht;
const byte ledPin =  13; // the number of the LED pin
byte ledState = 0; // ledState used to set the LED
unsigned long tempMillis1 = 0; // porta la variabile tempMillis1 a valore=0
unsigned long interval1 = 1000;  // porta la variabile interval1 a valore=100
unsigned long tempMillis2 = 0; // porta la variabile tempMillis12 a valore=0
unsigned long tempMillis3 = 0; // porta la variabile tempMillis12 a valore=0
unsigned long interval2 = 1000; // porta la variabile interval1 a valore=1000
unsigned long interval3 = 1000; // porta la variabile interval1 a valore=1000
unsigned int countanumeri = 0; // porta la variabile countanumeri a valore=0
void setup() {
  Serial.begin(19200);  //inizializza il baud rate della porta seriale
  delay(1000); //spetta 2 secondi prima di partire
  pinMode(ledPin, OUTPUT); // tutto quello che si chiama ledPin, è configurato come OUTPUT
  dht.setup(22); // data pin 2
}

//queste sono due funzioni distinte indipendenti
void loop() {
  CONTEGGIONUMERI();//è il nome della funzione
  contatore_volte();//è il nome della funzione
  LEGGITEMPERATURA();//OGNI 4 CICLI, LEGGI LA TEMPERATURA
  TASTIERINO();//LEGGI VALORI DA TASTIERINO
  
}

//FUNZIONE che aggiunge +1 alla variabile CONTANUMERI ogni volta che la funzione IF viene vera
void CONTEGGIONUMERI() {
  //fai una comparazione tra MILLIS che è il tempo
  if (millis() - tempMillis1 > interval1) {
    tempMillis1 = millis(); // save the last time you blinked the LED
    // if the LED is off turn it on and vice-versa:
    ledState ^= 1; 
    countanumeri = (countanumeri + 1);
    digitalWrite(ledPin, ledState);
    Serial.print("FLAG"); //increment the counter and print it on the serial
    Serial.print(" =");
    Serial.println(ledState);
  }
}
//FUNZIONE che azzera la variabile COUNTANUMERI quando il suo valore è uguale a 4 e stampa il valore sulla seriale
void contatore_volte() {
  //fai una comparazione tra MILLIS che è il tempo
  if (countanumeri == 4) {
    countanumeri = 0;
    digitalWrite(ledPin, ledState);
    Serial.println("azzeramento"); //increment the counter and print it on the seriale
  }
}
  //FUNZIONE che legge temperatura DH100
void LEGGITEMPERATURA() {
  if (millis() - tempMillis3 > interval3) {
    tempMillis3 = millis(); 
  float humidity = dht.getHumidity();
  float temperature = dht.getTemperature();
  Serial.print(humidity, 1);
  Serial.print(" - ");
  Serial.println(temperature, 1);
}}
 //FUNZIONE TASTIERINO
void TASTIERINO() {
  char customKey = customKeypad.getKey();
  if (customKey){
  Serial.println(customKey);}

Ho risolto un problema e magicamente se n’ è creato un’ altro.
Il file funziona, nel senso che ogni istruzione si comporta autonomamente e i tasti da tastierino vanno a meraviglia, ma perchè continua a stamparmi sulla seriale il comando “K8F”?
“K” è il primo carattere che invio, il secondo carattere è il numero del tastierino premuto, il terzo è il carattere di fine riga usato per capire che l’ istruzione è completa.
Perchè appare sempre quel comando, è forse skiattato arduino? voi potete provarlo?

si tratta della funzione TASTIERINO situata in fondo, ma non vedo anomalie

//Includi libreria
#include "DHT.h"
#include <Keypad.h>

const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
//definisci i simboli dei tasti tastierino
char hexaKeys[ROWS][COLS] = {
  {'0','1','2','3'},
  {'4','5','6','7'},
  {'8','9','A','B'},
  {'C','D','E','F'}
};
byte rowPins[ROWS] = {3, 2, 1, 0}; //connessione dei pin RIGHE del tastierino
byte colPins[COLS] = {7, 6, 5, 4}; //connessione dei pin COLONNE del tastierino

//Inizializza l' istanza class NewKeypad
Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS); 

DHT dht;
const byte ledPin =  13; // the number of the LED pin
byte ledState = 0; // ledState used to set the LED
unsigned long tempMillis1 = 0; // porta la variabile tempMillis1 a valore=0
unsigned long interval1 = 1000;  // porta la variabile interval1 a valore=100
unsigned long tempMillis2 = 0; // porta la variabile tempMillis12 a valore=0
unsigned long tempMillis3 = 0; // porta la variabile tempMillis12 a valore=0
unsigned long interval2 = 1000; // porta la variabile interval1 a valore=1000
unsigned long interval3 = 1000; // porta la variabile interval1 a valore=1000
unsigned int countanumeri = 0; // porta la variabile countanumeri a valore=0
void setup() {
  Serial.begin(19200);  //inizializza il baud rate della porta seriale
  delay(1000); //spetta 2 secondi prima di partire
  pinMode(ledPin, OUTPUT); // tutto quello che si chiama ledPin, è configurato come OUTPUT
  dht.setup(22); // data pin 2
}

//queste sono due funzioni distinte indipendenti
void loop() {
  CONTEGGIONUMERI();//è il nome della funzione
  contatore_volte();//è il nome della funzione
  LEGGITEMPERATURA();//OGNI 4 CICLI, LEGGI LA TEMPERATURA
  TASTIERINO();//LEGGI VALORI DA TASTIERINO
  
}

//FUNZIONE che aggiunge +1 alla variabile CONTANUMERI ogni volta che la funzione IF viene vera
void CONTEGGIONUMERI() {
  //fai una comparazione tra MILLIS che è il tempo
  if (millis() - tempMillis1 > interval1) {
    tempMillis1 = millis(); // save the last time you blinked the LED
    // if the LED is off turn it on and vice-versa:
    ledState ^= 1; 
    countanumeri = (countanumeri + 1);
    digitalWrite(ledPin, ledState);
    Serial.print("FLAG"); //increment the counter and print it on the serial
    Serial.print(" =");
    Serial.println(ledState);
  }
}
//FUNZIONE che azzera la variabile COUNTANUMERI quando il suo valore è uguale a 4 e stampa il valore sulla seriale
void contatore_volte() {
  //fai una comparazione tra MILLIS che è il tempo
  if (countanumeri == 4) {
    countanumeri = 0;
    digitalWrite(ledPin, ledState);
    Serial.println("azzeramento"); //increment the counter and print it on the seriale
  }
}
  //FUNZIONE che legge temperatura DH100
void LEGGITEMPERATURA() {
  if (millis() - tempMillis3 > interval3) {
    tempMillis3 = millis();
  float humidity = dht.getHumidity();
  float temperature = dht.getTemperature();
  Serial.print("T");
  Serial.print(humidity, 1);
  Serial.print(" - ");
  Serial.println(temperature, 1);
  }
}
 //FUNZIONE TASTIERINO
void TASTIERINO() {
  char customKey = customKeypad.getKey();
  if (customKey){
  Serial.print("K");
  Serial.print(customKey);
  Serial.println("F");}
}

Forse (non conosco la libreria) la funzione "customKeypad.getKey()" ritorna sempre l'ultimo tasto premuto, se premi altro ritorna nuovo tasto ma se non premi nulla ritorna sempre l'ultimo. Stà a te "azzerare" quando hai recepito il tasto e fatto quello che deve fare quel tasto. Non ne sono sicuro però, è solo una ipotesi.

La cosa strana è che se prendo l' esempio contenente nella libreria, funziona bene. l' esempio è custom keypad almeno credo. Nel mio esempio non ho fatto altro che copiarlo e annidarlo dentro ad un void e funziona bene, solo che è come se avessi sempre premuto il tasto 8. la cosa ancora piu strana è che dal terminal non mi appare in modo molto frequente, ma solo quando varia lo stato della temperatura...credo ogni secondo. Ho controllato più e più volte il mio sketch, ma non vedo strane anomalie. Ho paura che via andato il pin di arduino, ma allora avrebbe dovuto presentarsi l' errore anche dallo sketch di esempio che per fortuna, non da segni di anomalie.