Ciotola automatica

Salve a tutti, avrei un problema con il mio software, apparentemente sembra non avere alcun problema, (per lo meno di sintassi), ma quando carico il programma in arduino e passo allo stato di Erogazione o a quello di Allarme il programma intero intero si blocca, questo però non succede se invece di passare a uno dei due torno ad uno stato precedente.

Programma:

File.c:
#include "CiotolaAutomatica.h"
#include "HX711.h"
#include "Timer.h"

void setup() {
  Iniz_Porti();
  Iniz_CiotolaAutomatica();

}

void loop() {
  MaSLCiotolaAutomatica();
}

CiotolaAutomatica.h:

#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include "HX711.h"
#include "Timer.h"
#include "Debounce.h"
#include "RTClib.h"

#define I2C_ADDR 0x27
#define BACKLIGHT_PIN 3
#define En_pin 2
#define Rw_pin 1
#define Rs_pin 0
#define D4_pin 4
#define D5_pin 5
#define D6_pin 6
#define D7_pin 7

RTC_DS3231 rtc;
LiquidCrystal_I2C lcd(I2C_ADDR, En_pin, Rw_pin, Rs_pin, D4_pin, D5_pin, D6_pin, D7_pin);

#define     bPulsOk     11
#define     bLed_Verde  12
#define     bLed_Rosso   4
#define     bMotore      5
#define     bPiu         2
#define     bMeno        3

const int pinTrigger = 6;
const int pinEcho    = 7;

int pinBuzzer =        8;

HX711 scale(9, 10);

#define     Tar       10
#define     POn        0
#define     POf        1

#define     UOn     HIGH
#define     UOf      LOW

bool        PulsOk;
bool        Piu;
bool        Meno;
bool        Led_Verde;
bool        Led_Rosso;
bool        Motore;

bool bEntry;
float Peso, PesoLim;
int Ora1 = 0, Minuto1 = 0, Secondo1 = 0, Ora2 = 0, Minuto2 = 0, Secondo2 = 0, c = 0;
String msg;
Timer T1;

void Iniz_Porti (void) {
  //Led
  pinMode(bLed_Verde, OUTPUT);
  pinMode(bLed_Rosso, OUTPUT);

  //Seriale
  Serial.begin(9600);
  Serial.println("********** macchina pronta **********");

  //Sensore Ultrasuoni
  pinMode(pinTrigger, OUTPUT);
  pinMode(pinEcho,    INPUT);
  Serial.begin(9600);

  //Cella di Carico
  scale.set_scale();
  scale.tare();

  //Pulsanti
  pinMode(bPulsOk, INPUT_PULLUP);
  pinMode(bPiu,   INPUT_PULLUP);
  pinMode(bMeno,  INPUT_PULLUP);

  //RTC DS3231
  if (!rtc.begin()) {
    Serial.println("Controlla le connessioni");
    while (true);
  }
  rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));

  //Buzzer
  pinMode(pinBuzzer, OUTPUT);

  //LCD I2C
  lcd.begin(16, 2);
  lcd.setBacklightPin(BACKLIGHT_PIN, POSITIVE);
  lcd.setBacklight(HIGH);

  lcd.home ();
  lcd.print("LCD Pronto");
  lcd.clear();
}

enum FasiPuls {ImpostaOra1 = 0, ImpostaMinuti1, ImpostaOra2, ImpostaMinuti2, ImpostaPeso, Attesa, Allarme, Erogazione} LsStato, LsPrec;

void Iniz_CiotolaAutomatica() {
  LsStato = ImpostaOra1;
  LsPrec  = Erogazione;
  T1.Enab();
}

volatile int stato = LOW;

void MaSLCiotolaAutomatica() {

  PulsOk = digitalRead(bPulsOk);

  DateTime now = rtc.now();
  scale.set_scale(-1156.85);

  if (LsStato != LsPrec)
  {
    bEntry = true;
    LsPrec = LsStato;
    Serial.println(LsStato);
  }
  else bEntry = false;

  switch (LsStato) {
    case ImpostaOra1:
      digitalWrite( pinTrigger, LOW );
      Motore    = UOf;
      Led_Rosso = UOf;
      Led_Verde = UOn;
      if (debounce(bPiu) == POn && state_incr == 0) {
        Ora1 = Ora1 + 1;
        state_incr = 1;
        if (Ora1 > 23) Ora1 = 0;
        Serial.print("Ora impostata alle:");
        Serial.print(Ora1);
        Serial.print(":");
        Serial.println(Minuto1);
      }
      if (debounce(bPiu) == POf && state_incr == 1) state_incr = 0;
      if (debounce(bMeno) == POn && state_incr == 0) {
        Ora1 = Ora1 - 1;
        state_incr = 1;
        if (Ora1 < 0) Ora1 = 23;
        Serial.print("Ora impostata alle:");
        Serial.print(Ora1);
        Serial.print(":");
        Serial.println(Minuto1);
      }
      if (debounce(bMeno) == HIGH && state_incr == 1) state_incr = 0;
      if (PulsOk == POn) {
        delay(Tar);
        LsStato = ImpostaMinuti1;
      }
      lcd.clear();
      lcd.home();
      lcd.print("h prima erog.");
      lcd.setCursor(0, 1);
      lcd.print(now.hour());
      lcd.print(":");
      lcd.print(now.minute());
      lcd.print(":");
      lcd.print(now.second());
      break;

    case ImpostaMinuti1:
      digitalWrite( pinTrigger, LOW );
      Motore    = UOf;
      Led_Rosso = UOf;
      Led_Verde = UOn;
      lcd.clear();
      lcd.home();
      lcd.print("m prima erog.");
      lcd.setCursor(0, 1);
      lcd.print(now.hour());
      lcd.print(":");
      lcd.print(now.minute());
      lcd.print(":");
      lcd.print(now.second());

      if (debounce(bPiu) == LOW && state_incr == 0) {
        Minuto1 = Minuto1 + 1;
        state_incr = 1;
        if (Minuto1 > 59) Minuto1 = 0;
        Serial.print("Ora impostata alle:");
        Serial.print(Ora1);
        Serial.print(":");
        Serial.println(Minuto1);
      }
      if (debounce(bPiu) == HIGH && state_incr == 1) state_incr = 0;
      if (debounce(bMeno) == LOW && state_incr == 0) {
        Minuto1 = Minuto1 - 1;
        state_incr = 1;
        if (Minuto1 < 0) Minuto1 = 59;
        Serial.print("Ora impostata alle:");
        Serial.print(Ora1);
        Serial.print(":");
        Serial.println(Minuto1);
      }
      if (debounce(bMeno) == HIGH && state_incr == 1) state_incr = 0;
      if (PulsOk == POn) {
        delay(10);
        LsStato = ImpostaOra2;
      }
      break;

    case ImpostaOra2:
      digitalWrite( pinTrigger, LOW );
      Motore    = UOf;
      Led_Rosso = UOf;
      Led_Verde = UOn;
      lcd.clear();
      lcd.home();
      lcd.print("h seconda erog.");
      lcd.setCursor(0, 1);
      lcd.print(now.hour());
      lcd.print(":");
      lcd.print(now.minute());
      lcd.print(":");
      lcd.print(now.second());
      if (debounce(bPiu) == LOW && state_incr == 0) {
        Ora2 = Ora2 + 1;
        state_incr = 1;
        if (Ora2 > 23) Ora2 = 0;
        Serial.print("Ora impostata alle:");
        Serial.print(Ora2);
        Serial.print(":");
        Serial.println(Minuto2);
      }
      if (debounce(bPiu) == HIGH && state_incr == 1) state_incr = 0;
      if (debounce(bMeno) == LOW && state_incr == 0) {
        Ora2 = Ora2 - 1;
        state_incr = 1;
        if (Ora2 < 0) Ora2 = 23;
        Serial.print("Ora impostata alle:");
        Serial.print(Ora2);
        Serial.print(":");
        Serial.println(Minuto2);
      }
      if (debounce(bMeno) == HIGH && state_incr == 1) state_incr = 0;
      if (PulsOk == POn) {
        delay(Tar);
        LsStato = ImpostaMinuti2;
      }
      break;

    case ImpostaMinuti2:
      digitalWrite( pinTrigger, LOW );
      Motore    = UOf;
      Led_Rosso = UOf;
      Led_Verde = UOn;
      lcd.clear();
      lcd.home();
      lcd.print("m seconda erog.");
      lcd.setCursor(0, 1);
      lcd.print(now.hour());
      lcd.print(":");
      lcd.print(now.minute());
      lcd.print(":");
      lcd.print(now.second());
      if (debounce(bPiu) == LOW && state_incr == 0) {
        Minuto2 = Minuto2 + 1;
        state_incr = 1;
        if (Minuto2 > 59) Minuto2 = 0;
        Serial.print("Ora impostata alle:");
        Serial.print(Ora2);
        Serial.print(":");
        Serial.println(Minuto2);
      }
      if (debounce(bPiu) == HIGH && state_incr == 1) state_incr = 0;
      if (debounce(bMeno) == LOW && state_incr == 0) {
        Minuto2 = Minuto2 - 1;
        state_incr = 1;
        if (Minuto2 < 0) Minuto2 = 59;
        Serial.print("Ora impostata alle:");
        Serial.print(Ora2);
        Serial.print(":");
        Serial.println(Minuto2);
      }
      if (debounce(bMeno) == HIGH && state_incr == 1) state_incr = 0;
      if (PulsOk == POn) {
        delay(Tar);
        LsStato = ImpostaPeso;
      }
      break;

    case ImpostaPeso:
      digitalWrite( pinTrigger, LOW );
      Motore    = UOf;
      Led_Rosso = UOf;
      Led_Verde = UOn;
      lcd.clear();
      lcd.home();
      lcd.print("selez. lim. peso");
      lcd.setCursor(0, 1);
      lcd.print(now.hour());
      lcd.print(":");
      lcd.print(now.minute());
      lcd.print(":");
      lcd.print(now.second());

      if (debounce(bPiu) == LOW && state_incr == 0) {
        PesoLim = PesoLim + 10;
        state_incr = 1;
        Serial.print("Limite peso imposatto a :");
        Serial.print(PesoLim);
        Serial.println(" grammi");
      }
      if (debounce(bPiu) == HIGH && state_incr == 1) state_incr = 0;
      if (debounce(bMeno) == LOW && state_incr == 0) {
        PesoLim = PesoLim - 10;
        state_incr = 1;
        if (PesoLim < 0) PesoLim = 0;
        Serial.print("Limite peso imposatto a :");
        Serial.print(PesoLim);
        Serial.println(" grammi");
      }
      if (debounce(bPulsOk) == HIGH && state_incr == 1) state_incr = 0;
      if (PulsOk == POn) {
        delay(Tar);
        LsStato = Attesa;
      }
      break;

    case Attesa:

      digitalWrite( pinTrigger, HIGH );
      delayMicroseconds( 10 );
      digitalWrite( pinTrigger, LOW );
      Led_Rosso = UOf;
      Led_Verde = UOf;
      Motore    = UOf;

      long Sens_UR = pulseIn( pinEcho, HIGH );
      if (Sens_UR > 875)  LsStato = Allarme;

      if (now.hour() == Ora1 && now.minute() == Minuto1) LsStato = Erogazione;
      if (now.hour() == Ora2 && now.minute() == Minuto2) LsStato = Erogazione;
      lcd.clear();
      lcd.home();
      lcd.print("Attesa orario");
      lcd.setCursor(0, 1);
      lcd.print(now.hour());
      lcd.print(":");
      lcd.print(now.minute());
      lcd.print(":");
      lcd.print(now.second());
      break;

    case Allarme:
      digitalWrite( pinTrigger, HIGH );
      delayMicroseconds( 10 );
      digitalWrite( pinTrigger, LOW );
      Led_Rosso = UOn;
      Led_Verde = UOf;
      Motore    = UOf;
      tone(pinBuzzer, 220, 3000);

      lcd.home();
      lcd.print("car. serbatoio");
      lcd.setCursor(0, 1);
      lcd.print(now.hour());
      lcd.print(":");
      lcd.print(now.minute());
      lcd.print(":");
      lcd.print(now.second());

      if (Sens_UR < 875) LsStato = Attesa;

      break;

    case Erogazione:
      Peso = scale.get_units();
      Led_Rosso = UOf;
      Led_Verde = UOn;
      Motore    = UOn;
      lcd.clear();
      lcd.home();
      lcd.print("Erogazione...");
      lcd.setCursor(0, 1);
      lcd.print(now.hour());
      lcd.print(":");
      lcd.print(now.minute());
      lcd.print(":");
      lcd.print(now.second());

      if (Peso >= PesoLim) {
        LsStato = Attesa;
      }
      break;

    default: LsStato = ImpostaOra1;
  };
  digitalWrite(bLed_Rosso, Led_Rosso);
  digitalWrite(bLed_Verde, Led_Verde);
  digitalWrite(bMotore,    Motore);
}

Debounce.h:

boolean state_incr;
int debounceDelay = 20;

boolean debounce(int pin)
{
  boolean state;
  boolean previousState;
  previousState = digitalRead(pin);
  for (int counter = 0; counter < debounceDelay; counter++) {
    delay(1);
    state = digitalRead(pin);
    if ( state != previousState) {
      counter = 0;
      previousState = state;
    }
  }
  return state;
}

Timer.h:

#ifndef TIMER_H
#define TIMER_H

//***********************************************************************************************
class Timer {
  public:
    // *** Funzioni pubbliche ***
    Timer ();                   // Contruttore
    bool           Run();                      // Timer in funzione? (non scaduto?)
    void           Start(unsigned long TWait); // Avvia timer con tempo di attesa TWait
    void           Enab();                     // Riprendi aggiornamento timer
    void           Disb();                     // Sospendi aggiornamento timer
    void           Restart();                  // Riavvia il timer col valore di preset precedente
    unsigned long  GetTime();                  // Ottieni tempo rimanente

    // *** Attributi pubblici ***
    // nessuno

  private:
    // *** Funzioni private ***
    unsigned long  Elaps();                     // Aggiorna timer interno e calcola tempo trascorso

    // *** Attributi privati ***
    unsigned long TOld;      // Tempo sistema catturato precedentemente
    unsigned long TNow;      // Tempo attuale del timer da decrementare
    unsigned long TPreset;   // Tempo di preset iniziale (Setup del timer)
    bool          Enable;    // true = abilitato, false = disabilitato.
};

//***********************************************************************************************
Timer::Timer()           // Costruttore: inizializza le variabili
{
  Enable = false;
  TPreset = 0;
  TOld = 0;
  TNow = 0;
}

bool Timer::Run()                       // Timer in funzione? (non scaduto?)
{ unsigned long Elapsed;
  unsigned long Tmillis;
  Tmillis = millis();
  if (Enable)
  {
    if ( TOld <= Tmillis )             // C'è stato roll-over dell'orologio?
      Elapsed = Tmillis - TOld;        // No: calcola il tempo trascorso
    else                                //     dall'ultima chiamata
      Elapsed = Tmillis + (0xFFFFFFFF - TOld + 1); // Si: Calcola il tempo trascorso
    TNow = (TNow > Elapsed) ? TNow - Elapsed : 0;  // Se TNow > Elapsed aggiorna, altrimenti poni a 0
  }
  TOld = Tmillis;
  return ((TNow == 0) ? false : true);     // Ritorna 'true' se timer ancora attivo, false se scaduto
}

void Timer::Start(unsigned long TWait) // Avvia timer con tempo di attesa TWait
{
  TOld = millis();  // Cattura l'ora di sistema
  TPreset = TWait;  // Registra il Preset del timer
  TNow = TWait;     // Pone l'ora di attesa pari al preset
}

void Timer::Enab()    // Riprendi aggiornamento timer
{
  Enable = true;
  TOld = millis();
}

void Timer::Disb()       // Sospendi aggiornamento timer
{
  Enable = false;
}

void Timer::Restart()    // Riavvia il timer col valore di preset precedente
{
  TOld = millis();       // Cattura l'ora di sistema
  TNow = TPreset;        // Riavvia il timer col tempo di Preset
  Enable = true;
}

unsigned long Timer::GetTime()  // Ottieni tempo rimanente
{
  return TNow;
}

//***********************************************************************************************

#endif

Buongiorno e benvenuto, :slight_smile:
essendo il tuo primo post, nel rispetto del regolamento della sezione Italiana del forum (… punto 13, primo capoverso), ti chiedo cortesemente di presentarti IN QUESTO THREAD (spiegando bene quali conoscenze hai di elettronica e di programmazione ... possibilmente evitando di scrivere solo una riga di saluto) e di leggere con molta attenzione tutto il succitato REGOLAMENTO ... Grazie. :slight_smile:

Guglielmo

P.S.: Ti ricordo che, purtroppo, fino a quando non sarà fatta la presentazione nell’apposito thread, nel rispetto del suddetto regolamento nessuno ti risponderà, quindi ti consiglio di farla al più presto. :wink:

Certamente, mi presento sono ciccio1234, e sono uno studente di elettronica dell'ultimo anno di superiori, le mie conoscenze con arduino non sono avanzatissime, ma nemmeno scarsissime, conosco sicuramente le basi del c/c++, spero vivamente che qualcuno possa aiutarmi con il mio problema che mi sta facendo impazzire.
grazie per il vostro aiuto.

Hai letto con attenzione il mio post? Dove va fatta la presentazione? ... è chiaramente indicato e ... qui sopra NON serve a nulla perché, in pochi giorni, nessuno la trova più.

Inolte leggi attentamente, come ti ho chieso, tutto il REGOLAMENTO perché ... è spiegato lo scopo della presentazione :wink:

Guglielmo

chiedo scusa per il fraintendimento, comunque ho appena effettuato la presentazione nelposto giusto, mi scuso ancora per prima e spero che qualcuno possa aiutarmi adesso.

... sicuramente, appena passa qualcuno che ha delle risposte per te, cercherà di aiutarti ... :slight_smile:

Guglielmo

Ma puoi usare il serial monitor per fare un pò di debug ?
Perchè tu dici che quando entra ad esempio in Erogazione si blocca... ma non sai di preciso dove all'interno del case Erogazione. Io metterei un pò di serial.print() vedere in quale punto NON arriva.

il monitor seriale mi dice che lui è dentro lo stato erogazione/allarme ma appena entra in quello stato si blocca senza stampare su display quello che deve

Quindi prima dello switch, dovrebbe aver stampato Serial.println(LsStato);
ma poi entra nel case Erogazione ma non arriva a stampare nulla su LCD.

esattamente ma ho anche scoperto che se gli stessi identici comandi li faccio fare ad un'altro stato li fa tutti correttamente senza problemi

Metti delle serial.println in quel case, per capire a quale riga si blocca

subito, entra nello stato e come entra si blocca

Tu mettilo lo stesso
Seguite da una flush ()

E già che ci sei dai uno sguardo alla logica di quei due stati

In allarme usi una variabile che hai dichiarato in attesa

E temo che la cosa non si possa fare