sketch per calcolo frequenza non va su display

ciao
per favore mi potete dare una occhiata a questo sketch, non riesco a visualizzare il valore di frequenza, lo schema consiste in un semplice pulsante collegato al pin 2 dell’interrupt, l’interrupt non perde colpi ma non viene eseguito il codice dentro lo switch
grazie

/*
determinazione della frequenza di lavoro
*/
//#include <Wire.h>
//#include <PCF8574_HD44780_I2C.h>
//PCF8574_HD44780_I2C lcd(0x27, 20, 4); // Address 0x27, 20 chars, 4 line display

//int statosensore1 = HIGH;  //stato iniziale del sensore 1

volatile int i;

float freq = 0.0;//per la frequenza degli eventi di interrupt

unsigned long tempo[2] = {0, 0}; //vettore memorizza l'istante di tempo in cui accade l'evento
unsigned long delta_tempo;//tempo di attesa in mancanza di eventi sensore 1

void setup()
{
  // lcd.init();           // LCD Initialization
  // lcd.backlight();      // Backlight ON
  //  lcd.clear();          // Clear the display

  i = 0;
  pinMode(2, INPUT_PULLUP);
  attachInterrupt(0, sensore, FALLING); //sensore collegato al pin 2

  Serial.begin(9600); //per debug
  delay(1000);
}

void loop()
{
  switch (i)
  {
    case 1:
      tempo[0] = millis();  //memorizzazione dell'istante di tempo
      Serial.println(tempo[0]); //per debug
      break;

    case 5:
      tempo[1] = millis();  //memorizzazione dell'istante di tempo
      freq = 4.0 * 1000 / (tempo[1] - tempo[0]);//calcolo della frequenza
      //  lcd.clear();
      //  lcd.write(freq);   // Print the first word
      i = 0;
      Serial.println(freq); //per debug
      break;
  }

  delta_tempo = millis() - tempo[1];  //tempo trascorso

  if (delta_tempo > 5000)
  {
    //  lcd.clear();
    freq = 0.0;  //azzeramento della frequenza dopo attesa di 5 sec
    //Serial.println("reset"); //per debug
  }
}

void sensore() //pin 2 a cui attaccare il sensore induttivo
{
  i++;
  //Serial.println(i); //per debug

}

untitled.pdf (13.5 KB)

aggiorno
con questo sketch

/*
determinazione della frequanza di lavoro
*/
//#include <Wire.h>
//#include <PCF8574_HD44780_I2C.h>
//PCF8574_HD44780_I2C lcd(0x27, 20, 4); // Address 0x27, 20 chars, 4 line display

//int statosensore1 = HIGH;  //stato iniziale del sensore 1

volatile int i;

float freq = 0.0;//per la frequenza degli eventi di interrupt

unsigned long tempo[2] = {0, 0}; //vettore memorizza l'istante di tempo in cui accade l'evento
unsigned long delta_tempo;//tempo di attesa in mancanza di eventi sensore 1

void setup()
{
  // lcd.init();           // LCD Initialization
  // lcd.backlight();      // Backlight ON
  //  lcd.clear();          // Clear the display

  i = 0;
  pinMode(2, INPUT_PULLUP);
  attachInterrupt(0, sensore, FALLING); //sensore collegato al pin 2

  Serial.begin(9600); //per debug
  delay(1000);
}

void loop()
{


  delta_tempo = millis() - tempo[1];  //tempo trascorso

  if (delta_tempo > 5000)
  {
    //lcd.clear();
    freq = 0.0;  //azzeramento della frequenza dopo attesa di 5 sec
    //Serial.println("reset"); //per debug
  }
}

void sensore() //pin 2 a cui attaccare il sensore induttivo
{
  i++;
   //   Serial.println(i); //per debug
  switch (i)
  {
    
    case 1:
      tempo[0] = millis();  //memorizzazione dell'istante di tempo
     // Serial.println(tempo[0]); //per debug
      break;

    case 5:
      tempo[1] = millis();  //memorizzazione dell'istante di tempo
      freq = 4.0 * 1000 / (tempo[1] - tempo[0]);//calcolo della frequenza
      //  lcd.clear();
      //  lcd.write(freq);   // Print the first word
      i = 0;
      Serial.println(freq); //per debug
      break;
  }


}

ho ottenuto questo output sul serial monitor

7.18
14.93
26.32
15.87
9.26
4.56
14.44
10.23
inf
inf
2000.00
9.76
6.21
7.42
5.06

ma da dove salta fuori “inf”

Stampa 1.0/0, se esce inf è normale.

http://en.cppreference.com/w/cpp/io/c/fprintf

Ciao.

grazie, mi studio il link, ho fatto un passo avanti e ho provato a collegare un display con schedina per I2C
ma non visualizza niente ho la sensazione che faccia anche botte con la comunicazione seriale, le librerie se non ricordo male sono di TESTATO e con gli esempi forniti funzionano, questo è lo sketch
grazie

/*
determinazione della frequanza di lavoro
*/
#include <Wire.h>
#include <PCF8574_HD44780_I2C.h>
PCF8574_HD44780_I2C lcd(0x27, 20, 4); // Address 0x27, 20 chars, 4 line display

volatile byte i;

float freq = 0.0;//per la frequenza degli eventi di interrupt

unsigned long tempo[2] = {0, 0}; //vettore memorizza l'istante di tempo in cui accade l'evento
unsigned long delta_tempo;//tempo di attesa in mancanza di eventi sensore 1

void setup()
{
   lcd.init();           // LCD Initialization
  // lcd.backlight();      // Backlight ON
    lcd.clear();          // Clear the display

  i = 0;
  
  pinMode(2, INPUT_PULLUP);
  attachInterrupt(0, sensore, FALLING); //sensore collegato al pin 2

  Serial.begin(9600); //per debug
  delay(1000);
}

void loop()
{
  delta_tempo = millis() - tempo[1];  //tempo trascorso

  if (delta_tempo > 5000)
  {
  //  lcd.clear();
    freq = 0.0;  //azzeramento della frequenza dopo attesa di 5 sec
    //Serial.println("reset"); //per debug
  }
}

void sensore() //pin 2 a cui attaccare il sensore induttivo
{
  i++;
 // Serial.println(i); //per debug
      switch (i)
  {    
    case 1:
      tempo[0] = millis();  //memorizzazione dell'istante di tempo
     // Serial.println(tempo[0]); //per debug
      break;

    case 5:
      tempo[1] = millis();  //memorizzazione dell'istante di tempo
      freq = 4.0 * 1000 / (tempo[1] - tempo[0]);//calcolo della frequenza
        lcd.clear();
        lcd.write(freq);   // Print the first word
      i = 0;
      //Serial.println(freq); //per debug
      break;
  }
}

non ho l'hw sotto mano per provare, anche la seriale usa gli interrupt, ma che succede se stampi sul serial monitor dal setup ? se stampi senza dichiarare attachInterrupt ?

non ricordavo il legame tra il serial e l'interrupt, dopo cena faccio prove grazie

questo è l’ultima versione dello sketch, sul display non visualizza niente, sul pulsante c’è un antirimbalzo con il delay nell’interrupt che non si fa lo so, ma è solo per fare prove, la frequenza non è alta a me interressa massimo 4 Hz

/*determinazione della frequenza di lavoro
*/
#include <Wire.h>
#include <PCF8574_HD44780_I2C.h>
PCF8574_HD44780_I2C lcd(0x27, 20, 4); // Address 0x27, 20 chars, 4 line display

volatile byte i;

float freq = 0.0;//per la frequenza degli eventi di interrupt

unsigned long tempo[2] = {0, 0}; //vettore memorizza l'istante di tempo in cui accade l'evento
unsigned long delta_tempo;//tempo di attesa in mancanza di eventi sensore 1

void setup()
{

  lcd.init();           // LCD Initialization
  // lcd.backlight();      // Backlight ON
  lcd.clear();          // Clear the display
  lcd.print("hello world");

  i = 0;

  pinMode(2, INPUT_PULLUP);
  attachInterrupt(0, sensore, FALLING); //sensore collegato al pin 2
  delay(1000);
}

void loop()
{
  delta_tempo = millis() - tempo[1];  //tempo trascorso

  if (delta_tempo > 5000)
  {
    //lcd.clear();
    freq = 0.0;  //azzeramento della frequenza dopo attesa di 5 sec
  }
}

void sensore() //pin 2 a cui attaccare il sensore induttivo
{
  i++;
  delay(10);
  switch (i)
  {
    case 1:
      tempo[0] = millis();  //memorizzazione dell'istante di tempo
      break;

    case 5:
      tempo[1] = millis();  //memorizzazione dell'istante di tempo
      freq = 4.0 * 1000 / (tempo[1] - tempo[0]);//calcolo della frequenza
      //lcd.clear();
      lcd.setCursor(0, 1);
      lcd.write(freq);   // Print the first word
      i = 0;
      break;
  }
}

Scuda ma stai dicendo che non stampa assolutamente nulla ? Cioè nemmeno quello che hai nel setup ? lcd.print("hello world");

scusate sono stato troppo drastico, quello nel setup viene stampato correttamente

Per discriminare se il problema è della libreria o nel programma, aggiungi ad ogni lcd.print anche un serial.print Così ti accorgi se l interrupt e la logica del programma va bene.

Fai anche la prova di lasciare solo i serial.print

per completezza questa è la schedina che ho acquistato http://www.ebay.it/itm/171511193597?ssPageName=STRK:MEWAX:IT&_trksid=p3984.m1423.l2649

aggiornamenti
ho fatto questa modifica nel setup()

  lcd.clear();          // Clear the display
  delay(1000);

ma ho dovuto caricare lo sketch due volte prima di vedere questa modifica

ho fatto questo

void sensore() //pin 2 a cui attaccare il sensore induttivo
{
  i++;  
  delay(100);
  Serial.println(i);
  lcd.write(i);   // Print the first word  

}

ma come output sul serial monitor
compare solo il primo impulso

1

e niente sul display

aggiornamento
questo funziona non entra nello switch penso per problemi di debounce vediamo quando metterò il sensore

void loop()
{
    Serial.println(i);
  lcd.print(i);   // Print the first word
  delay(1000);
  lcd.clear();
    switch (i)
  {
    case 1:
      tempo[0] = millis();  //memorizzazione dell'istante di tempo
      break;

    case 5:
      tempo[1] = millis();  //memorizzazione dell'istante di tempo
      freq = 4.0 * 1000 / (tempo[1] - tempo[0]);//calcolo della frequenza
      //lcd.clear();
      lcd.setCursor(0, 0);
      lcd.write(freq);   // Print the first word
      Serial.println(i);
      i = 0;
      break;
  }
  /*
  delta_tempo = millis() - tempo[1];  //tempo trascorso

  if (delta_tempo > 5000)
  {
    //lcd.clear();
    freq = 0.0;  //azzeramento della frequenza dopo attesa di 5 sec
  }*/
}

void sensore() //pin 2 a cui attaccare il sensore induttivo
{
  i++;  
  delay(100);
}

ok almeno hai la certezza che non ci sono problemi con la libreria

volevo capire perchè nel post #11 non viene visualizzato 1 sul display ma solo sul serial monitor

certo che scrivi con i piedi :) questo esempio funziona ma non entra nello switch cosa dovrebbe significare ? visto che hai un lcd print ed un serial print prima dello switch signifuca che ti ha stampato su entrambi

si esatto, non riuscivo a visualizzare su display, abbiamo appurato che il display funziona grazie alle librerie rilasciate, ma nel post #11 perchè non viene eseguito l'lcd.print serve un delay prima di lcd.print()?

Nella funzione agganciata ad un interrupt non è possibile usare codice che richiede gli interrupt abilitati globalmente. La libreria Serial e Twi richiedono l'abilitazione globale degli interrupt.

Per cui non puoi stampare sulla seriale e nemmeno sul LCD.

Per capirci qualcosa occorre evitare di usare attachInterrupt e vedere il codice che il compilatore inserisce all'ingresso e all'uscita di una ISR. Il codice in ingresso viene detto 'prologo', quello in uscita 'epilogo'. Il prologo salva SREG, disabilita gli interrupt e l'epilogo ripristina il registro SREG con in valore salvato prima. Tra prologo ed epilogo ci sta il codice utente.

Nota che un prologo ed epilogo viene inserito anche in ogni funzione, solo che il codice inserito svolge altre funzioni, as esempio non disabilita gli interupt.

Ciao.

tradotto in altre parole:
quando l’interrupt viene evocato il loop si ferma viene registrata la posizione vengono eseguiti i comandi sotto interrupt e poi il loop riprende da dove era stato interrotto, è corretto?
Ho scritto questo spero funzioni appena risolvo i problemi di rimbalzo

#include <Wire.h>
#include <PCF8574_HD44780_I2C.h>
PCF8574_HD44780_I2C lcd(0x27, 20, 4); // Address 0x27, 20 chars, 4 line display

volatile byte i;

float freq = 0.0;//per la frequenza degli eventi di interrupt

unsigned long tempo[2] = {0, 0}; //vettore memorizza l'istante di tempo in cui accade l'evento
unsigned long delta_tempo;//tempo di attesa in mancanza di eventi sensore 1

void setup()
{
  lcd.init();           // LCD Initialization
  // lcd.backlight();      // Backlight ON
  lcd.clear();          // Clear the display
  lcd.print("hello world");

  i = 0;

  pinMode(2, INPUT_PULLUP);
  attachInterrupt(0, sensore, FALLING); //sensore collegato al pin 2
  delay(1000);
  lcd.clear();          // Clear the display
  delay(1000);
  // Serial.begin(9600);
}

void loop()
{
  
  switch (i)
  {
    case 1:
      tempo[0] = millis();  //memorizzazione dell'istante di tempo
      break;

    case 5:
      tempo[1] = millis();  //memorizzazione dell'istante di tempo
      freq = 4.0 * 1000 / (tempo[1] - tempo[0]);//calcolo della frequenza
      lcd.clear();
      lcd.print(freq);   // Print the first word
      i = 0;
      
      break;
  }

  delta_tempo = millis() - tempo[1];  //tempo trascorso

  if (delta_tempo > 5000)
  {
    lcd.clear();
    freq = 0.0;  //azzeramento della frequenza dopo attesa di 5 sec
  }
}

void sensore() //pin 2 a cui attaccare il sensore induttivo
{
  i++;
}

avevo dimenticato sta cosa :) infatti il discorso di non usare il delay() nella ISR non e' solo prassi, e' obbligatorio perche' il delay di arduino usa un interrupt per incrementare

cosi' ora dovrebbe funzionare, hai dichiarato anche volatile la i quindi e' ok