Interrupt non visualizza dati sul LCD

Ho un'altro problema, quando abilito la funzione "Allarme()" del programma il display del LCD non mi visualizza nessun dato.
Lo sketch è il seguente:

/********************  in test        *******************************
 * Derivato da Erogatore_v80_2xday_mod_test
 * 3 aprile 2022
 * editor: Arduino 1.8.16
 * motore: NEMA 17HS19
 * orologio: DS3231
 * micro: Arduino NANO
 * processore: ATmega328P (old bootloader)
 * porta: /dev/cu.wchusbserial1410
 * WiFi: SCF-01 e ADP-01 (miuPanel)
 * step motor: IN1 D12(15), IN2 D11(14), IN3 D10(13), IN4 D9(12)
 * i2C: SDA A4(23), SCL A5(24)      
 * interrupt: INT0 D2(5)
 * 
 * Modifiche:
 * Inserite 2 erogazioni giornaliere (8, 20) 
 * Massimo 32 erogazioni totali
 * Aggiunto visualizzazione dei dati su LCD
 *******************************************************************/
#include <Stepper.h>
#include <Wire.h>
#include <PCF8574_HD44780_I2C.h>
#include <DS3231.h>
#define STEPS 400
#define decremento 3    // decremento normale = 3 per 32 erogazioni
#define DS3231_I2C_ID 0x68    //I2C indirizzo del RTC DS3231

Stepper stepper(STEPS, 11, 10, 9, 8);
int passi = 900;    // passi alimentazione ruota 1/6 di giro
const byte interuptPin0 = 2;    //D2 pin5
int Max = 100;    // variabile per barra analogica   
volatile byte Ore = 0;
volatile byte Minuti = 0;
volatile byte orario = 0;
volatile boolean alarmFlag = false;
volatile boolean Empty = true;
volatile int flag = 0;

PCF8574_HD44780_I2C lcd(0x27,16,2);

DS3231 clock;

void alarmISR(){
  alarmFlag = true;
  }

void setup(){
  Serial.begin(9600);
  lcd.init();                   
  lcd.backlight(); 
  
  pinMode(interuptPin0,INPUT_PULLUP);
  alarmFlag = false;
  Wire.begin();
  stepper.setSpeed(100); // imposta la velocità del motore
  digitalWrite(11,LOW);
  digitalWrite(10,LOW);
  digitalWrite(9,LOW);
  digitalWrite(8,LOW);

  Allarme();    // attiva allarme su interrutp del RTC
  //readDate();
  displayLCD(0);
  displayLCD(1);
}

void loop(){

 }

/***************************        FUNZIONI          *************************/

void displayLCD(int flag){
  switch (flag) {
    case 0:   // inizio
        lcd.setCursor(1,0); // colonna, riga
        lcd.print("Starting...");
        lcd.setCursor(5,1); // colonna, riga
        lcd.print(Ore);
        lcd.print(":");
        lcd.print(Minuti);
        delay(3000);
        lcd.clear();
        lcd.home();
      break;
    case 1:   // fondo stabile
        lcd.clear();
        lcd.setCursor(0,0); // colonna, riga
        lcd.print("Dispenser ");
        lcd.setCursor(11,0); // colonna, riga
        lcd.print(Max);
        lcd.print("%");
        lcd.setCursor(0,1); // colonna, riga
        lcd.print("Ore 8");
        lcd.setCursor(9,1); // colonna, riga
        lcd.print("Ore 20");    
      break;
    case 2:   // ore 8
        lcd.setCursor(11,0); // colonna, riga
        lcd.print(Max);
        lcd.print("%");
        lcd.setCursor(7,1); // colonna, riga
        lcd.print("OK");         
      break;
    case 3:   // ore 20
        lcd.setCursor(11,0); // colonna, riga
        lcd.print(Max);
        lcd.print("%");
        lcd.setCursor(15,1); // colonna, riga
        lcd.print("OK");   
      break;
    case 4:   // azzera OK
        lcd.setCursor(7,1); // colonna, riga
        lcd.print("  ");
        lcd.setCursor(15,1); // colonna, riga
        lcd.print("  "); 
      break;
    case 5:   // riserva
        lcd.blink();
        lcd.setCursor(11,0); // colonna, riga
        lcd.print(Max);
        lcd.print("%");
      break;
    case 6:   // vuoto
        lcd.blink();
        lcd.setCursor(11,0); // colonna, riga
        lcd.print(Max);
        lcd.print("%");
        lcd.setCursor(0,1); // colonna, riga
        lcd.print("                "); 
      break;
  }
}   

void Allarme(){
    clock.begin();
    // Interrupt abilitato, onda quadra disabilitata
    clock.enableOutput(false);
    clock.armAlarm1(false);
    clock.clearAlarm1();
    
    // Day, Ore, Minuti, Second, Mode, Armed = true)
    // Set Alarm1 - il 10s in ogni minuto 
    //clock.setAlarm1(0, 0, 0, 10, DS3231_MATCH_S);
  
    // Set Alarm1 - il 1m e 1s in ogni ora
    clock.setAlarm1(0, 0, 1, 1, DS3231_MATCH_M_S);   
    attachInterrupt(digitalPinToInterrupt(interuptPin0), alarmISR, FALLING); // interrupt su fronte di discesa
  }

Se disabilito la funzione "Allarme()" il programma prosegue regolarmente.
Al momento lo sto testando con un Arduino UNO originale.
Ho bisogno un'altra volta del vostro aiuto.

Lello

Considera però poi che, su ESP, la sintassi delle ISR è diversa eh ... quindi devi andartela a strudiare.

Non capisco come dovrebbe funzionare la cosa ...
... quando scatta l'ISR viene semplicemente chiamata alarmISR() che mette una flag a true ... ma nel loop non c'è nulla e chi è che verifica che la flag e stata alzata ???

Inoltre, altro grave errore, se la variabile usata dalla ISR si chiama "flag", nella routine displayLCD() NON devi definire una nuova variabile "flag" o, quella locale, maschera quella globale.

Insomma ... codice da buttare, studiare come funzionano le ISR e riscrivere da capo :smiley:

Guglielmo

P.S.: e, nel titolo dei thread, NON tirare in ballo la libreria del LCD che NON c'entra nulla ed è solo fuorviante ! Questa volta ho corretto io.

... in pratica:

  1. definisco su quale pin è la ISR
  2. definisco la variabile della flag
  3. scrivo la ISR che altro non fa che alzare la flag
  4. nel setup() attacco la ISR al pin della ISR
  5. nel loop() controllo la flag, se la flag è attiva allora faccio quello che devo fare e la rimetto bassa pronta per il prossimo uso.

E' la tecnica del "deferred interrupt" che viene usata per rendere la ISR la più compatta e veloce possibile e permette di fare cose che dentro una ISR non sono permesse. Ampiamete usata nel caso di RTOS.

Guglielmo

Sicuro che l'RTC stia funzionando come previsto?

Vedo che non vai a verificare se risponde nella funzione Allarme() e non vorrei che le successive chiamate ai metodi enableOutput(), armAlarm1() etc etc siano in qualche modo bloccanti in caso di mancata risposta dal dispositivo.

Invece di disattivare la chiamata a tutta la funzione Allarme() prova ad assicurarti che l'rtc sia funzionante prima di proseguire, magari non è questo il problema però mi sembra un approccio più robusto.

void Allarme() {
  if (! clock.begin()) {
    Serial.println("Couldn't find RTC");
  } 
  else {
    // Interrupt abilitato, onda quadra disabilitata
    clock.enableOutput(false);
    clock.armAlarm1(false);
    clock.clearAlarm1();    
    // Set Alarm1 - il 1m e 1s in ogni ora
    clock.setAlarm1(0, 0, 1, 1, DS3231_MATCH_M_S);   
  }
  attachInterrupt(digitalPinToInterrupt(interuptPin0), alarmISR, FALLING); // interrupt su fronte di discesa
}

Grazie per i consigli.
Quello che ho postato non è tutto lo sketch completo.
Sto adattando a pezzetti uno sketch funzionante per visualizzare su Lcd alcuni dati.
L'rtc funziona perché in questo momento è attiva la gestione dell'erogazione del cibo.
Proverò a modificare il programma completo inserendo a step le chiamate al LCD.
Ovviamente mi documento sulla sintassi dell'ISR su ESP.
Questo è lo sketch originale funzionante e attualmente operativo che io devo modificare per inserire le visualizzazioni su LCD.
Il motivo è togliere tutte le linee del programma che fanno riferimento a "uPanel" che non esiste più, che è cessato operativamente.

/********************  in test        *******************************
 * Derivato da Erogatore_v80_2xday_mod_test
 * 6 marzo 2022
 * editor: Arduino 1.8.16
 * motore: NEMA 17HS19
 * orologio: DS3231
 * micro: Arduino NANO
 * processore: ATmega328P (old bootloader)
 * porta: /dev/cu.wchusbserial1410
 * WiFi: SCF-01 e ADP-01 (miuPanel)
 * step motor: IN1 D12(15), IN2 D11(14), IN3 D10(13), IN4 D9(12)
 * i2C: SDA A4(23), SCL A5(24)
 * interrupt: INT0 D2(5)
 * 
 * Descrizione:
 * Inserite 2 erogazioni giornaliere (8, 20) 
 * Massimo 32 erogazioni totali
 * 3 led per visualizzare in locale le erogazioni
 * Al restart dell'App ricarica la situazione precedente
 *******************************************************************/
#include <Stepper.h>
#include <Wire.h>
#include <DS3231.h>
#define STEPS 400
#define decremento 3    // decremento normale = 3 per 32 erogazioni
#define DS3231_I2C_ID 0x68    //I2C indirizzo del RTC DS3231

Stepper stepper(STEPS, 12, 11, 10, 9);
int passi = 900;    // passi alimentazione ruota 1/6 di giro
const byte interuptPin0 = 2;    //D2 pin5
String Msg;
int Max = 100;    // variabile per barra analogica    
int Min = 0;      // variabile per display a 7 segmenti
int v = 0;        // variabile per display a 7 segmenti
int d1 = 0;       // variabile per display a 7 segmenti
int d2 = 0;       // variabile per display a 7 segmenti
volatile byte Ore = 0;
volatile byte Minuti = 0;
volatile byte orario = 0;
unsigned char led_L1G = 0;  // led verde Automatico
unsigned char led_L2R = 0;  // led rosso Riserva
unsigned char led_L35 = 0;  // Led unità display
unsigned char led_L45 = 0;  // led decine display
unsigned char led_L5Y = 0;  // led giallo ore 8
unsigned char led_L7Y = 0;  // led giallo ore 20
unsigned char led_L8R = 0;  // led rosso Vuoto
volatile boolean alarmFlag = false;
volatile boolean Empty = true;
int ledVerde1 = 8;  // led ore 8  (D8)  pin 11
int ledVerde2 = 7;  // led ore 20 (D7)  pin 10
int ledRosso1 = 6;  // led riserva (D6) pin 9

DS3231 clock;

void alarmISR(){
  alarmFlag = true;
  }

void setup(){
  Serial.begin(57600);
  delay(5000);           
  Serial.println("");
  pinMode(interuptPin0,INPUT_PULLUP);
  alarmFlag = false;
  Wire.begin();
  SendPanel();
  stepper.setSpeed(100); // imposta la velocità del motore
  digitalWrite(12,LOW);
  digitalWrite(11,LOW);
  digitalWrite(10,LOW);
  digitalWrite(9,LOW);
  pinMode(ledVerde1, OUTPUT);
  pinMode(ledVerde2, OUTPUT);
  pinMode(ledRosso1, OUTPUT);
  digitalWrite(ledVerde1, LOW);
  digitalWrite(ledVerde2, LOW);
  digitalWrite(ledRosso1, LOW);
  Allarme();  // attiva allarme su interrutp del RTC
}

void loop(){
  int c;   
  while ((c = Serial.read()) > '\n') Msg += (char) c;  
  if (c == '\n')                                        
  { 
    if (Msg.substring(0,4).equals("#W01")) {Manuale();}     // Manuale 
    else if (Msg.substring(0,4).equals("$RES")) {SendPanel();} // In caso di reset 
    Msg = "";   // Clean message string
  }
  
 if (alarmFlag == true){   
      readDate();
    if (Ore == 8){
      Eroga(); 
      Serial.println("#L51");   // accende i led delle ore 8
      led_L5Y = 1;
      digitalWrite(ledVerde1, HIGH);
      orario = 20;
      }
    else if (Ore == 20){
      Eroga();
      Serial.println("#L71");  // accende i led delle ore 20
      led_L7Y = 1;
      digitalWrite(ledVerde2, HIGH); 
      orario = 0;  
      }
    else if (Ore == 0){
      Aggiorna();   
      orario = 8;
      digitalWrite(ledVerde1, LOW);
      digitalWrite(ledVerde2, LOW);
      }     
    alarmFlag = false;
    clock.clearAlarm1();
  }
}

/***************************        FUNZIONI          *************************/
void SendPanel(){   //  pannello principale
  Serial.print("\n$P:D!06F;-0{%100,y6!06FTf*15d2:Erogatore v9.0_2xday - © EzioGi;}=//{-r30!228,114*15{T:Automatico;|L1G:1;_T:Riserva;|L2R:0;_T:Vuoto;|L8R:0;}");
  Serial.print("|{^*10L35:0;&L45:0;_T:Erogazioni;}}//{T#FFF*15fa:Manuale;|*11W0G:0;}/10A1-*20-5r20!00F,DDD>:0:100:100:!00F;{T#FFF*15fa:% crocchette;}");
  Serial.println("//{-r30!228,114*8{T#FFF*20fa:ore 8;|L5Y:0;|||T#FFF*20fa:ore 20;|L7Y:0;}}");
  
    // Controlla lo stato di tutti gli oggetti del pannello
    if (led_L1G == 1) Serial.println("#L11");   // automatico
    if (led_L2R == 1) Serial.println("#L21");   // riserva
    if (led_L5Y == 1) Serial.println("#L51");   // ore 8
    if (led_L7Y == 1) Serial.println("#L71");   // ore 20
    if (led_L8R == 1) Serial.println("#L81"); // vuoto 
    Serial.print("#L3"); Serial.println(d1,DEC);
    Serial.print("#L4"); Serial.println(d2,DEC);
    Serial.print("#A1:");
    Serial.println(Max,DEC);
   }
    
void Eroga(){   // ruota l'aletta di 1/6th per erogare le crocchette
  if (Empty == true){   // se serbatoio ancora pieno
      stepper.step(passi);
      digitalWrite(12,LOW);
      digitalWrite(11,LOW);
      digitalWrite(10,LOW);
      digitalWrite(9,LOW); 
    incrCont();       // Incrementa Contatore Erogazioni 
    decrBarraAn();    // Decrementa livello barra A1
    }
  }

void Aggiorna(){   // resetta i led ad eccezione del contatore numerico e della barra analogica
    if (Empty == true){
        Serial.println("#L11");       // Accende il led L1 "automatico"
      }
    Serial.println("#L20");       // Spegne il led L2  "riserva"
    Serial.println("#L50");       // Spegne led5
    Serial.println("#L70");       // Spegne led7
  }

void incrCont(){    // incrementa contatori  
    v = v+1;       
    d1 = (v / 10) % 10;                        // Calcola la prima cifra LCD
    d2 = v % 10;                               // Calcola la seconda cifra LCD
    Serial.print("#L3"); Serial.println(d1,DEC);   // Aggiorna la prima cifra LCD
    Serial.print("#L4"); Serial.println(d2,DEC);   // Aggiorna la seconda cifra LCD
  }
  
void decrBarraAn(){  // decremento la barra analogica
    Serial.print("#A1:");
    Serial.println((Max -= decremento),DEC);
    if ( Max <= 19 && Max > 1)   // se contatore uguale o inferiore a 19 e contenitore non vuoto
      {
      Serial.println("#L21");  // Accende il led L2  "riserva"
      digitalWrite(ledRosso1, HIGH);
      }
    else if (Max <= 1){  // se contatore uguale o inferiore a 1 il contenitore è vuoto
      Max = 0;
      Serial.print("#A1:");
      Serial.println(Max,DEC);
      Serial.println("#L10");  // Spegne il L1 "automatico"
      Serial.println("#L20");  // Spegne il led L2  "riserva"
      Serial.println("#L81"); // Accende il led L8  "vuoto"
      Empty = false;  
      }
  }

void Manuale(){
      Serial.println("#W00");   // Accende lo Switch
      if (Empty == true){  // se vera eroga, se falsa salta erogazione
        Eroga();                 // Eroga una porzione
       }
      Serial.println("#W01");   // Spegne lo Switch    
  }

void readDate(){
  Wire.beginTransmission(DS3231_I2C_ID);
  Wire.write(0x1);  
  Wire.endTransmission();
  Wire.requestFrom(DS3231_I2C_ID, 2);  // scarica 2 bytes
  Minuti = bcd2dec (Wire.read() & 0b1111111);
  Ore = bcd2dec (Wire.read() & 0b00111111);
  }

  byte bcd2dec(byte val){ 
    return ((val / 16*  10) + (val % 16));
  }
  
void Allarme(){
    clock.begin();
    // Interrupt abilitato, onda quadra disabilitata
    clock.enableOutput(false);
    clock.armAlarm1(false);
    clock.clearAlarm1();
    
    // Day, Ore, Minuti, Second, Mode, Armed = true)
    // Set Alarm1 - il 10s in ogni minuto 
    //clock.setAlarm1(0, 0, 0, 10, DS3231_MATCH_S);
  
    // Set Alarm1 - il 1m e 1s in ogni ora
    clock.setAlarm1(0, 0, 1, 1, DS3231_MATCH_M_S);   
    attachInterrupt(digitalPinToInterrupt(interuptPin0), alarmISR, FALLING); // interrupt su fronte di discesa
  }

Questa è la versione modificata che non funziona:

/********************          *******************************
 * Derivato da Erogatore_v90_2xday_mod_test
 * 31 marzo 2022
 * 
 * editor: Arduino 1.8.13
 * motore: NEMA 17HS19
 * orologio: DS3231
 * micro: Arduino NANO
 * processore: ATmega328P (old bootloader)
 * porta: /dev/cu.wchusbserial1410
 * WiFi: SCF-01 e ADP-01 (miuPanel)
 * step motor: IN1 D11(13), IN2 D10(13), IN3 D9(12), IN4 D8(11)
 * i2C: SDA A4(23), SCL A5(24)
 * interrupt: INT0 D2(5)
 * erogazione manuale: Sw1 D12(15)
 * 
 * Descrizione:
 * Inserite 2 erogazioni giornaliere (8, 20) 
 * Massimo 32 erogazioni totali
 * Al restart dell'App ricarica la situazione precedente
 * Inserito visualizzazioni su LCD
 *******************************************************************/
#include <Stepper.h>
#include <Wire.h>
#include <PCF8574_HD44780_I2C.h>
#include <DS3231.h>
#define STEPS 400
#define decremento 3    // decremento normale = 3 per 32 erogazioni
#define DS3231_I2C_ID 0x68    //I2C indirizzo del RTC DS3231

Stepper stepper(STEPS, 11, 10, 9, 8);
int passi = 900;    // passi alimentazione ruota 1/6 di giro
const int ledpin = 13;   // Led rosso/giallo
const byte interuptPin0 = 2;    //D2 pin5
String Msg;
int Max = 100;    // variabile per barra analogica    
int Min = 0;      // variabile per display a 7 segmenti
int v = 0;        // variabile per display a 7 segmenti
int d1 = 0;       // variabile per display a 7 segmenti
int d2 = 0;       // variabile per display a 7 segmenti
volatile byte Ore = 0;
volatile byte Minuti = 0;
volatile byte orario = 0;
unsigned char led_L1G = 0;  // led verde Automatico
unsigned char led_L2R = 0;  // led rosso Riserva
unsigned char led_L35 = 0;  // Led unità display
unsigned char led_L45 = 0;  // led decine display
unsigned char led_L5Y = 0;  // led giallo ore 8
unsigned char led_L6Y = 0;  // led giallo ore 14
unsigned char led_L7Y = 0;  // led giallo ore 20
unsigned char led_L8R = 0;  // led rosso Vuoto
volatile boolean alarmFlag = false;
volatile boolean Empty = true;
volatile int flag = 0;

DS3231 clock;

PCF8574_HD44780_I2C lcd(0x27,16,2);

void alarmISR(){
  alarmFlag = true;
  }

void setup(){
  Serial.begin(57600);
  delay(5000);           
  Serial.println("");
  pinMode(interuptPin0,INPUT_PULLUP);
  alarmFlag = false;
  Wire.begin();
  SendPanel();
  stepper.setSpeed(100); // imposta la velocità del motore
  digitalWrite(11,LOW);
  digitalWrite(10,LOW);
  digitalWrite(9,LOW);
  digitalWrite(8,LOW);
  Allarme();    // attiva allarme su interrutp del RTC
  readDate();
  lcd.init();                   
  lcd.backlight();
  lcd.clear();
  displayLCD(0);
  displayLCD(1);  // pagina di fondo
}

void loop(){
  int c;   
  while ((c = Serial.read()) > '\n') Msg += (char) c;  
  if (c == '\n')                                        
  { 
    if (Msg.substring(0,4).equals("#W01")) {Manuale();}     // Manuale 
    else if (Msg.substring(0,4).equals("$RES")) {SendPanel();} // In caso di reset 
    Msg = "";   // Clean message string
  }
  
 if (alarmFlag == true){   
      readDate();     
    if (Ore == 8){
      Eroga(); 
      Serial.println("#L51");   // accende il led delle ore 8
      displayLCD(2);
      orario = 20;
      }
    else if (Ore == 20){
      Eroga();
      Serial.println("#L71");  // accende il led delle ore 20
      displayLCD(3);
      orario = 0;  
      }
    else if (Ore == 23){
      Aggiorna();
      displayLCD(4);   
      orario = 8;
      }     
    alarmFlag = false;
    clock.clearAlarm1();
  }
}

/***************************        FUNZIONI          *************************/
void SendPanel(){   //  pannello principale
  Serial.print("\n$P:D!06F;-0{%100,y6!06FTf*15d2:Erogatore v10.0-2xday - © EzioGi;}=//{-r30!228,114*15{T:Automatico;|L1G:1;_T:Riserva;|L2R:0;_T:Vuoto;|L8R:0;}");
  Serial.print("|{^*10L35:0;&L45:0;_T:Erogazioni;}}//{T#FFF*15fa:Manuale;|*11W0G:0;}/10A1-*20-5r20!00F,DDD>:0:100:100:!00F;{T#FFF*15fa:% crocchette;}");
  Serial.println("//{-r30!228,114*8{T#FFF*20fa:ore 8;|L5Y:0;|||T#FFF*20fa:ore 20;|L7Y:0;}}/{~1^%70,y10!06F#FFF{%50,y60M1*30fb:—:—;}");
  
    // Controlla lo stato di tutti gli oggetti del pannello
    if (led_L1G == 1) Serial.println("#L11");   // automatico
    if (led_L2R == 1) Serial.println("#L21");   // riserva
    if (led_L5Y == 1) Serial.println("#L51");   // ore 8
    if (led_L7Y == 1) Serial.println("#L71");   // ore 20
    if (led_L8R == 1) Serial.println("#L81"); // vuoto 
    Serial.print("#L3"); Serial.println(d1,DEC);
    Serial.print("#L4"); Serial.println(d2,DEC);
    Serial.print("#A1:");
    Serial.println(Max,DEC);
   }
   
void displayLCD(int flag){
  switch (flag) {
    case 0:   // inizio
        lcd.setCursor(1,0); // colonna, riga
        lcd.print("Starting...");
        lcd.setCursor(5,1); // colonna, riga
        lcd.print(Ore);
        lcd.print(":");
        lcd.print(Minuti);
        delay(3000);
        lcd.clear();
        lcd.home();
      break;
    case 1:   // fondo stabile
        lcd.setCursor(1,0); // colonna, riga
        lcd.print("Dispenser ");
        lcd.setCursor(11,0); // colonna, riga
        lcd.print(Max);
        lcd.print("%");
        lcd.setCursor(1,1); // colonna, riga
        lcd.print("Ore 8 ");
        lcd.setCursor(12,1); // colonna, riga
        lcd.print("20 ");    
      break;
    case 2:   // ore 8
        lcd.setCursor(11,0); // colonna, riga
        lcd.print(Max);
        lcd.print("%");
        lcd.setCursor(7,1); // colonna, riga
        lcd.print("OK");         
      break;
    case 3:   // ore 20
        lcd.setCursor(11,0); // colonna, riga
        lcd.print(Max);
        lcd.print("%");
        lcd.setCursor(15,1); // colonna, riga
        lcd.print("OK");   
      break;
    case 4:   // azzera OK
        lcd.setCursor(7,1); // colonna, riga
        lcd.print("  ");
        lcd.setCursor(15,1); // colonna, riga
        lcd.print("  "); 
      break;
    case 5:   // riserva
        lcd.blink();
        lcd.setCursor(11,0); // colonna, riga
        lcd.print(Max);
        lcd.print("%");
      break;
    case 6:   // vuoto
        lcd.blink();
        lcd.setCursor(11,0); // colonna, riga
        lcd.print(Max);
        lcd.print("%");
        lcd.setCursor(0,1); // colonna, riga
        lcd.print("                "); 
      break;
  }
}

void Eroga(){   // ruota l'aletta di 1/6th per erogare le crocchette
  if (Empty == true){   // se serbatoio ancora pieno
      stepper.step(passi);
      digitalWrite(11,LOW);
      digitalWrite(10,LOW);
      digitalWrite(9,LOW);
      digitalWrite(8,LOW); 
    incrCont();       // Incrementa Contatore Erogazioni 
    decrBarraAn();    // Decrementa livello barra A1
    Serial.print("$CLOUD SEND:PUSH:Porzione erogata ore ");
    Serial.println(Ore);
    }
  }

void Aggiorna(){   // resetta i led ad eccezione del contatore numerico e della barra analogica
    if (Empty == true){
        Serial.println("#L11");       // Accende il led L1 "automatico"
      }
    Serial.println("#L20");       // Spegne il led L2  "riserva"
    Serial.println("#L50");       // Spegne led7
    Serial.println("#L70");       // Spegne led21
  }

void incrCont(){    // incrementa contatori  
    v = v+1;       
    d1 = (v / 10) % 10;                        // Calcola la prima cifra LCD
    d2 = v % 10;                               // Calcola la seconda cifra LCD
    Serial.print("#L3"); Serial.println(d1,DEC);   // Aggiorna la prima cifra LCD
    Serial.print("#L4"); Serial.println(d2,DEC);   // Aggiorna la seconda cifra LCD
  }
  
void decrBarraAn(){  // decremento la barra analogica
    Serial.print("#A1:");
    Serial.println((Max -= decremento),DEC);
    if ( Max <= 19 && Max > 1)   // se contatore uguale o inferiore a 19 e contenitore non vuoto
      {
      Serial.println("#L21");  // Accende il led L2  "riserva"
      displayLCD(5);
      }
    else if (Max <= 1){  // se contatore uguale o inferiore a 1 il contenitore è vuoto
      Max = 0;
      Serial.print("#A1:");
      Serial.println(Max,DEC);
      Serial.println("#L10");  // Spegne il L1 "automatico"
      Serial.println("#L20");  // Spegne il led L2  "riserva"
      displayLCD(6);
      Serial.println("#L81"); // Accende il led L8  "vuoto"
      Empty = false;  
      }
      else{
        Serial.println("#L10");   // Spegne il led "automatico" 
        delay(1000);       
        Serial.println("#L11");   // Accende il led "automatico" 
      }
  }

void Manuale(){
      Serial.println("#W00");   // Accende lo Switch
      if (Empty == true){  // se vera eroga, se falsa salta erogazione
        Eroga();                 // Eroga una porzione
       }
      Serial.println("#W01");   // Spegne lo Switch    
  }

void readDate(){
  Wire.beginTransmission(DS3231_I2C_ID);
  Wire.write(0x1);  
  Wire.endTransmission();
  Wire.requestFrom(DS3231_I2C_ID, 2);  // scarica 2 bytes
  Minuti = bcd2dec (Wire.read() & 0b1111111);
  Ore = bcd2dec (Wire.read() & 0b00111111);
  }

  byte bcd2dec(byte val){ 
    return ((val / 16*  10) + (val % 16));
  }
  
void Allarme(){
    clock.begin();
    // Interrupt abilitato, onda quadra disabilitata
    clock.enableOutput(false);
    clock.armAlarm1(false);
    clock.clearAlarm1();
    
    // Day, Ore, Minuti, Second, Mode, Armed = true)
    // Set Alarm1 - il 10s in ogni minuto 
    //clock.setAlarm1(0, 0, 0, 10, DS3231_MATCH_S);
  
    // Set Alarm1 - il 1m e 1s in ogni ora
    clock.setAlarm1(0, 0, 1, 1, DS3231_MATCH_M_S);   
    attachInterrupt(digitalPinToInterrupt(interuptPin0), alarmISR, FALLING); // interrupt su fronte di discesa
  }

Lo sketch l'ho solo testato con Arduino UNO senza collegato RTC.
Perché non ho la possibilità di provarlo al completo.
Potrebbe essere questo il malfunzionamento?
Lello

Inserito il RTC a ripreso a funzionare.

Lello

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.