Davide Rosa Hack
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 :
Video (in velocità x2):