Gate Home

In questo progetto ho trasformato l'Arduino in un apri cancello automatico.

Componenti :

Schema progetto :

Progetto Fritzing - Arduino Shield

Progetto Fritzing - Connessione Relè Motori

Progetto Fritzing - Connessione Relè Lampeggiante

Codice :


#define _DEBUG_

#define TEMPO_VIAGGIO_PIN A0 // PIN
#define TEMPO_VIAGGIO_MIN 1000 // Millisecondi
#define TEMPO_VIAGGIO_MAX 20000 // Millisecondi

#define TEMPO_BATTENTE_PIN A1 // PIN
#define TEMPO_BATTENTE_MIN 500 // Millisecondi

#define MOTORE1_ALIMENTAZIONE_PIN 2 // PIN
#define MOTORE1_DIREZIONE_PIN 3 // PIN

#define MOTORE2_ALIMENTAZIONE_PIN 4 // PIN
#define MOTORE2_DIREZIONE_PIN 5 // PIN

#define LAMPADA_PIN 6 // PIN
#define LAMPADA_FREQUENZA 500 // Millisecondi

#define RICEVENTE_PIN 12 // PIN
#define SELETTORE_PIN 10 // PIN

enum enmStato {
  stato_fermo,
  stato_apri,
  stato_chiudi
};

class clsBottone {
  private:
    int Pin;
    unsigned long lastDebounceTime = 0;
    long debounceDelay = 50;
    int buttonState = HIGH;
    int lastButtonState = HIGH;
    int ledState = LOW;

  public:
    clsBottone(int _Pin) {
      Pin = _Pin;
      pinMode(Pin, INPUT_PULLUP);
    }

    int Stato() {
      int ret = ledState;
      ledState = LOW;
      return  ret;
    }

    void Aggiorna() {
      int reading = digitalRead(Pin);
      unsigned long currentTime = millis();

      if (reading != lastButtonState) {
        lastDebounceTime = currentTime;

      }
      else if ((currentTime - lastDebounceTime) > debounceDelay) {
        if (reading != buttonState) {
          buttonState = reading;

          if (reading == LOW) {
            ledState = HIGH;

          }
        }
      }

      lastButtonState = reading;
    }
};

clsBottone Ricevente = clsBottone(RICEVENTE_PIN);

class clsStato {
  private:
    enmStato StatoPrecedente;
    enmStato StatoAttuale;
    unsigned long TempoLavoro;

  public:
    clsStato() {
      StatoPrecedente = stato_fermo;
      StatoAttuale = stato_fermo;
    }

    void Aggiorna(int Stato_Ricevente, unsigned long Tempo_Viaggio, unsigned long Tempo_Battente) {
      unsigned long currentTime = millis();

      if (Stato_Ricevente == HIGH) {
        switch (StatoAttuale) {
          case stato_fermo:
            switch (StatoPrecedente) {
              case stato_fermo:
#if defined(_DEBUG_)
                Serial.println("STATO PRIMO APRI");
#endif
                StatoAttuale = stato_apri;
                break;

              case stato_apri:
#if defined(_DEBUG_)
                Serial.println("STATO CHIUDI");
#endif
                StatoAttuale = stato_chiudi;
                break;

              case stato_chiudi:
#if defined(_DEBUG_)
                Serial.println("STATO APRI");
#endif
                StatoAttuale = stato_apri;
                break;
            }
            break;

          case stato_apri:
#if defined(_DEBUG_)
            Serial.println("STATO FERMO IN APERTURA DA COMANDO");
#endif
            StatoPrecedente = StatoAttuale;
            StatoAttuale = stato_fermo;
            break;

          case stato_chiudi:
#if defined(_DEBUG_)
            Serial.println("STATO FERMO IN CHIUSURA DA COMANDO");
#endif
            StatoPrecedente = StatoAttuale;
            StatoAttuale = stato_fermo;
            break;
        }

        TempoLavoro = currentTime;

      }
      else {
        if (StatoAttuale == stato_apri || StatoAttuale == stato_chiudi) {
          if ((currentTime - TempoLavoro) > (Tempo_Viaggio + Tempo_Battente)) {
#if defined(_DEBUG_)
            Serial.println("STATO FERMO TEMPO");
#endif
            StatoPrecedente = StatoAttuale;
            StatoAttuale = stato_fermo;
          }
        }
      }
    }

    enmStato Precedente() {
      return StatoPrecedente;
    }

    enmStato Attuale() {
      return StatoAttuale;
    }
};

clsStato Stato = clsStato();

class clsTrimmer {
  private:
    int Pin;
    unsigned long Min;
    unsigned long Val;

  public:
    clsTrimmer(int _Pin, int _Min) {
      Pin = _Pin;
      Min = _Min;
      pinMode(Pin, INPUT);
    }

    unsigned long Valore() {
      return Val;
    }

    void Aggiorna(unsigned long Max) {
      Val = constrain(map((unsigned long)analogRead(Pin), 0, 1023, Min, Max), Min, Max);
    }
};

clsTrimmer TempoViaggio = clsTrimmer(TEMPO_VIAGGIO_PIN, TEMPO_VIAGGIO_MIN);
clsTrimmer TempoBattente = clsTrimmer(TEMPO_BATTENTE_PIN, TEMPO_BATTENTE_MIN);

class clsSelettore {
  private:
    int Pin;

  public:
    clsSelettore(int _Pin) {
      Pin = _Pin;
      pinMode(Pin, INPUT_PULLUP);
    }

    bool Stato() {
      return (digitalRead(Pin) == HIGH);
    }

};

clsSelettore Selettore = clsSelettore(SELETTORE_PIN);

class clsMotore {
  private:
    int PinAli;
    int PinDir;
    unsigned long TempoLavoro;
    bool Lavoro;

    unsigned long TempoTotaleApri(unsigned long Tempo_Viaggio, unsigned long Tempo_Battente, bool Primario) {
      unsigned long rtn = Tempo_Viaggio;

      if (Primario) {
        rtn += Tempo_Battente;
      }

      return rtn;
    }

    unsigned long TempoTotaleChiudi(unsigned long Tempo_Viaggio, unsigned long Tempo_Battente, bool Primario) {
      unsigned long rtn = Tempo_Viaggio;

      if (!Primario) {
        rtn += Tempo_Battente;
      }

      return rtn;
    }

    unsigned long TempoBattenteChiudi(unsigned long Tempo_Battente, bool Primario) {
      unsigned long rtn = 0;

      if (!Primario) {
        rtn += Tempo_Battente;
      }

      return rtn;
    }

    unsigned long TempoBattenteApri(unsigned long Tempo_Battente, bool Primario) {
      unsigned long rtn = 0;

      if (Primario) {
        rtn += Tempo_Battente;
      }

      return rtn;
    }

  public:

    clsMotore(int Pin_Ali, int Pin_Dir) {
      PinAli = Pin_Ali;
      PinDir = Pin_Dir;

      pinMode(PinAli, OUTPUT);
      pinMode(PinDir, OUTPUT);

      Fermo();
    }

    void Apri() {
      digitalWrite(PinDir, LOW);
    }

    void Chiudi() {
      digitalWrite(PinDir, HIGH);
    }

    void Fermo() {
      digitalWrite(PinAli, HIGH);
      digitalWrite(PinDir, HIGH);
    }

    void Parti() {
      digitalWrite(PinAli, LOW);
    }

    void Aggiorna(enmStato Stato_Attuale, unsigned long Tempo_Viaggio, unsigned long Tempo_Battente, bool Primario) {
      unsigned long currentTime = millis();

      switch (Stato_Attuale) {
        case stato_fermo:
          Lavoro = false;
          Fermo();
          break;

        case stato_apri:
          if (!Lavoro) {
            Lavoro = true;
            Fermo();
            Apri();
            TempoLavoro = currentTime;
#if defined(_DEBUG_)
            Serial.print("MOTORE AVVIO ");
            Serial.print(PinAli);
            Serial.print(" PER ");
            Serial.print((float)TempoTotaleApri(Tempo_Viaggio, Tempo_Battente, Primario) / 1000);
            Serial.print(" SEC - BATTENTE ");
            Serial.print((float)TempoBattenteApri(Tempo_Battente, Primario) / 1000);
            Serial.print(" SEC - PRIMARIO ");
            Serial.println(Primario);
#endif
          }
          else if ((currentTime - TempoLavoro) > TempoTotaleApri(Tempo_Viaggio, Tempo_Battente, Primario)) {
            Fermo();
          }
          else if ((currentTime - TempoLavoro) > TempoBattenteApri(Tempo_Battente, Primario)) {
            Parti();
          }
          break;

        case stato_chiudi:
          if (!Lavoro) {
            Lavoro = true;
            Fermo();
            Chiudi();
            TempoLavoro = currentTime;
#if defined(_DEBUG_)
            Serial.print("MOTORE AVVIO ");
            Serial.print(PinAli);
            Serial.print(" PER ");
            Serial.print((float)TempoTotaleChiudi(Tempo_Viaggio, Tempo_Battente, Primario) / 1000);
            Serial.print(" SEC - BATTENTE ");
            Serial.print((float)TempoBattenteChiudi(Tempo_Battente, Primario) / 1000);
            Serial.print(" SEC - PRIMARIO ");
            Serial.println(Primario);
#endif
          }
          else if ((currentTime - TempoLavoro) > TempoTotaleChiudi(Tempo_Viaggio, Tempo_Battente, Primario)) {
            Fermo();
          }
          else if ((currentTime - TempoLavoro) > TempoBattenteChiudi(Tempo_Battente, Primario)) {
            Parti();
          }
          break;
      }
    }

};

clsMotore Motore1 = clsMotore(MOTORE1_ALIMENTAZIONE_PIN, MOTORE1_DIREZIONE_PIN);
clsMotore Motore2 = clsMotore(MOTORE2_ALIMENTAZIONE_PIN, MOTORE2_DIREZIONE_PIN);

class clsLampada {
  private:
    int Pin;
    unsigned long TempoLavoro;
    bool Lampeggio;

  public:
    clsLampada(int _Pin) {
      Pin = _Pin;
      pinMode(Pin, OUTPUT);
      Spegni();
      Lampeggio = false;
    }

    void Accendi() {
      digitalWrite(Pin, LOW);
    }

    void Spegni() {
      digitalWrite(Pin, HIGH);
    }

    void Aggiorna(enmStato Stato_Attuale) {
      unsigned long currentTime = millis();

      if (Stato_Attuale == stato_apri || Stato_Attuale == stato_chiudi) {
        if ((currentTime - TempoLavoro) > LAMPADA_FREQUENZA) {
          TempoLavoro = currentTime;
          Lampeggio = !Lampeggio;
#if defined(_DEBUG_)
          if (Lampeggio) {
            Serial.println("LAMPADA LAMPEGGIO");
          }
#endif
        }
        if (Lampeggio) {
          Accendi();
        }
        else {
          Spegni();
        }
      }
      else {
        TempoLavoro = currentTime;
        Lampeggio = false;
        Spegni();
      }

    }

};

clsLampada Lampada = clsLampada(LAMPADA_PIN);

void setup() {
#if defined(_DEBUG_)
  TempoViaggio.Aggiorna(TEMPO_VIAGGIO_MAX);
  TempoBattente.Aggiorna(TempoViaggio.Valore());
  Ricevente.Aggiorna();
  Stato.Aggiorna(Ricevente.Stato(), TempoViaggio.Valore(), TempoBattente.Valore());

  Serial.begin(115200);
  while (!Serial);
  Serial.println("DEBUG - GATE HOME V 1.0");
  Serial.println("-----------------------");
  Serial.print("PRIMARIO MOTORE  "); 
  if (Selettore.Stato()) {
    Serial.println(MOTORE1_ALIMENTAZIONE_PIN);
  } else {
    Serial.println(MOTORE2_ALIMENTAZIONE_PIN);
  }
  Serial.println("-----------------------");
  Serial.print("TEMPO VIAGGIO    "); Serial.print((float)TempoViaggio.Valore() / 1000); Serial.println(" SEC");
  Serial.print("TEMPO BATTENTE   "); Serial.print((float)TempoBattente.Valore() / 1000); Serial.println(" SEC");
  Serial.print("TEMPO TOTALE     "); Serial.print(((float)TempoBattente.Valore() + (float)TempoBattente.Valore()) / 1000); Serial.println(" SEC");
  Serial.println("-----------------------");
  Serial.print("STATO RICEVENTE  "); Serial.println(Ricevente.Stato());
  Serial.print("STATO ATTUALE    "); Serial.println(Stato.Attuale());
  Serial.print("STATO PRECEDENTE "); Serial.println(Stato.Precedente());
  Serial.println("-----------------------");
#endif
}

void loop() {

  TempoViaggio.Aggiorna(TEMPO_VIAGGIO_MAX);
  TempoBattente.Aggiorna(TempoViaggio.Valore());
  Ricevente.Aggiorna();

  Stato.Aggiorna(Ricevente.Stato(), TempoViaggio.Valore(), TempoBattente.Valore());

  Motore1.Aggiorna(Stato.Attuale(), TempoViaggio.Valore(), TempoBattente.Valore(), Selettore.Stato());
  Motore2.Aggiorna(Stato.Attuale(), TempoViaggio.Valore(), TempoBattente.Valore(), !Selettore.Stato());

  Lampada.Aggiorna(Stato.Attuale());

}

 

Galleria :

gatehome_bb.png gh0010.png gh0011.png

gh002.jpg gh003.jpg gh004.jpg

gh005.jpg gh006.jpg gh008.jpg

gh009.jpg

 

Video (in velocità x2):