Aiuto x gestione motorizzazione tapparelle

Salve frequentatori di questo forum,
come da oggetto sto cercando di creare uno sketch x gestire 6 tapparelle di un'abitazione, purtroppo x me è il 1° programma che sto realizzando con l'Arduino Mega, e sono anche cosciente che se ne è parlato anche in altri topic di questa esigenza;
il mio problema è che non sono riuscito ancora a creare il blocco della fase di discesa e viceversa,ho provato a seguire diversi topic e soluzioni in rete, ma non sono riuscito ancora a quadrare il tutto.
Chiedo cortesemente il Vostro aiuto, inoltre Vi posto lo sketch su cui stavo lavorando....

unsigned long previousMillis = 0;
unsigned long previousMillis1 = 0;
byte acceso = HIGH;
byte acceso1 = HIGH;

void setup() {
  // set the digital pin as output:
  pinMode(12, OUTPUT);   
  pinMode(11, OUTPUT);  
  pinMode(2, INPUT);
  pinMode(3, INPUT);
  digitalWrite(11, LOW);
  digitalWrite(12, LOW);
}

void loop()
{
  if ((digitalRead(2) == HIGH) && (acceso == LOW)) 
  {
    digitalWrite(11, HIGH);
    digitalWrite(12, LOW);
    acceso = HIGH;
    acceso1 = LOW;
    previousMillis = millis();
  }
  
  else if ((acceso == HIGH) && ((millis()-previousMillis) >= 10000))
  {
    digitalWrite(11, LOW);
    digitalWrite(12, LOW);
    acceso = LOW;
    acceso1 = LOW;    
  }
  
  else if ((digitalRead(3) == HIGH) && (acceso == HIGH) && (acceso1 == LOW) && ((millis()-previousMillis) <= 10000))
  {
    digitalWrite(11, LOW);
    digitalWrite(12, LOW);
    acceso = LOW;
    acceso1 = LOW;
  }


if ((digitalRead(3) == HIGH) && (acceso1 == LOW)) 
  {
    digitalWrite(12, HIGH);
    digitalWrite(11, LOW);
    acceso1 = HIGH;
    acceso = LOW;
    previousMillis1 = millis();
  }

  else if ((acceso1 == HIGH) && ((millis()-previousMillis1) >= 10000))
  {
    digitalWrite(12, LOW);
    digitalWrite(11, LOW);
    acceso1 = LOW;
    acceso = LOW;    
  }
  
  else if ((digitalRead(2) == HIGH) && (acceso1 == HIGH) && ((millis()-previousMillis) <= 10000))
  {
    digitalWrite(12, LOW);
    digitalWrite(11, LOW);
    acceso1 = LOW;
    acceso = LOW;
  }

}

grazie...

Non ho inquadrato bene il tuo programma, non è commentato nelle varie istruzioni quindi resta difficile sapere cosa fanno i pin che hai imposttato, però si evidenzia che su un motore (a 2 direzioni) comandato da 2 bottoni l'else è l'utima cosa da usare.

quello che sembra fai fare al programma è:
se premo il pulsante salita (IF) vai su .... altrimenti vai giù in ogni caso (ELSE), ripeto non si capisce l'abbinamento pin arduino e circuiti di comando/attuatori.

Dovrebbe essere :
IF premo SU vai SU per 10 sec
IF premo GIU' vai GIU' per 10 sec
IF premo niente FAI niente (quindi nessuna istruzione)

Aiuto x gestione
uno sketch x gestire
purtroppo x me

Quelle "x" sono variabili INT, FLOAT o BYTE?

Grazie Pablos per la tua collaborazione,
come dicevo, è il mio primo sketch che sto cercando di tirare giù e quindi sicuramente ci saranno degli errori.
Comunque la logica di funzionamento che vorrei realizzare è appunto :

  1. Se premo Su = sali per il tempo impostato;
  2. Se mentre sta salendo premo Giù = si ferma;

viceversa per l'altro motore....

giucarnic:
...

  1. Se premo Su = sali per il tempo impostato;
  2. Se mentre sta salendo premo Giù = si ferma;
    ...

Quindi devi usare dei flag ... cioe', delle variabili che imposti tu, e che dicono allo sketch cosa sta facendo il motore in questione (dato che lo sketch non lo puo sapere da solo ...

Ad esempio, StatoM1, per il motore 1, lo imposti a 0 se il motore e' fermo (quindi ovviamente anche ogni volta che lo fermi), ad 1 se sta andando su, a 2 se sta andando giu ... poi negli IF di controllo, fai in modo che lo sketch esegua l'operazione giusta in base allo stato del flag ... cioe':

pulsante giu premuto
if (StatoM1 == 0) (cioe' il motore era fermo quando hai premuto giu)
allora accendi il motore in giu e metti il flag a 2
else if (statoM1 == 1) (cioe' stava andando in su quando hai premuto giu)
allora fermi il motore e metti il flag a 0
else if (StatoM1 == 2) (cioe' stava gia andando in giu)
allora non fai nulla

e cosi via, per tutte le condizioni e per tutti i pulsanti ed i motori (ovviamente, serve un diverso flag per ogni motore)

Salve ragazzi, purtroppo sto lavorando a questo sketch quando mi libero da altri impegni ,
in effetti Etemenanki, ti ringrazio per la dritta, ho appena letto il tuo post.
Quindi è come se io dovessi attivare dei feedback di stato per ogni motore di tapparella,
e di conseguenza dirgli all'Arduino attiva ad esempio uscita Su o Giù( che io ovviamente vado a designare nel Setup ) per effetto del comando HIGH corrispondente dell'ingresso "x".
Scusate, ma dovrò creare delle variabili di stato delle uscite e quelle degli ingressi (cioè dei pulsanti)
per ogni tapparella, e cioè per 6 ?
Inoltre dovrò creare anche delle variabili da collegare ai "millis()" per ognuna di esse da poter gestire
i tempi di azionamento dei motori, giusto?
Continuo rimodulare lo sketch poi magari Ve lo ri-posto per una vostra verifica,

grazie.....

Ciao,

a mio avviso, il modo migliore per realizzare questo sketch è un automa a stati finiti. Ne stiamo parlando qui. Trovi un po' di chiarimenti ed un esempio di codice.

Nel tuo caso avresti un automa con tre stati:

  • stato ATTESA: il motore è fermo in attesa di comando. In questo stato se premo il tasto SU viene attivata l'uscita SU, resettato il contatore del tempo trascorso e si passa nello stato SU; se viene premuto il tasto GIU viene attivata l'uscita GIU, resettato il contatore del tempo trascorso e si passa nello stato GIU.

  • stato GIU: in questo stato se premo il tasto GIU oppure se il contatore del tempo trascorso raggiunge il tempo massimo, disattivo l'uscita GIU (fermo il motore) e torno nello stato ATTESA.

  • stato SU: in questo stato se premo il tasto SU oppure se il contatore del tempo trascorso raggiunge il tempo massimo, disattivo l'uscita SU (fermo il motore) e torno nello stato ATTESA.

Un'altra cosa: per la gestione del singolo motore, chiuderei tutto il codice in una classe. In questo modo, per gestire i 6 motori dovrò istanziare 6 volte la classe inizializzando ciascuna di istanza con i valori dei piedini di input e output della relativa tapparella.

Mi rendo conto che in questo momento ti complico la vita ma in realtà credo che il tutto si semplifichi. Infatti avrai tutto il codice scritto una sola volta. Ogni singola modifica riguarderà contemporaneamente tutti i 6 motori. Se invece scrivi il codice 6 volte all'interno della loop correrai il rischio di apportare una modifica soltanto in alcuni punti ottenendo alcuni motori che funzionano correttamente ed altri no.

Spero di essere stato utile. Mi farà comunque piacere discutere ulteriormente la cosa.

Ciao.
Vittorio.

Ciao Vittorio, e grazie per la condivisione delle tue conoscenze in merito,
è ovvio che semplificare il codice vuol dire ridurre le possibilità di errore,
in effetti ci stavo ragionando su come ottimizzare il tutto per gestire queste utenze.

In merito alla creazione di "class" avevo già data un'occhiata su di un altro sketch
trovato in rete, ma comprendi che essendo all'inizio nello studio di questo fantastico
Arduino e del linguaggio " C ", stavo procedendo per step nel capire le Variabili, Costanti,
Funzioni, ecc.ecc..

Comunque devo dire, non essendo proprio a digiuno del mondo delle automazioni, che già
qualcosina l'ho inquadrata, ovviamente con il Vostro aiuto, sicuramente mi perfezionerò.

Di seguito posto qualcosa che penso abbia a che fare con le "class" ...

//-------------------------- TapparellaIF Class -------------------------------------------------
class TapparellaIF {
int pinAPRI;
int pinCHIUDI;
public:
TapparellaIF(int pinApri, int pinChiudi);
~TapparellaIF();
void putInOpenState();
void putInCloseState();
void putInIdleState();
void putInLowState();
void putInHighState();
};
TapparellaIF::TapparellaIF(int pinapri, int pinchiudi){
pinAPRI = pinapri;
pinCHIUDI = pinchiudi;
digitalWrite(pinCHIUDI, HIGH); //set the pin HIGH and thus turn LED on
digitalWrite(pinAPRI, HIGH); //set the pin HIGH and thus turn LED on
pinMode(pinAPRI, OUTPUT); //make that pin an OUTPUT
pinMode(pinCHIUDI, OUTPUT); //make that pin an OUTPUT
digitalWrite(pinCHIUDI, HIGH); //set the pin HIGH and thus turn LED on
digitalWrite(pinAPRI, HIGH); //set the pin HIGH and thus turn LED on
}
TapparellaIF::~TapparellaIF(){/nothing to destruct/}
void TapparellaIF::putInOpenState(){
digitalWrite(pinCHIUDI, HIGH); //set the pin HIGH and thus turn LED on
digitalWrite(pinAPRI, 0); //set the pin HIGH and thus turn LED on
}
void TapparellaIF::putInCloseState(){
digitalWrite(pinCHIUDI, LOW); //set the pin HIGH and thus turn LED on
digitalWrite(pinAPRI, HIGH); //set the pin HIGH and thus turn LED on
}
void TapparellaIF::putInIdleState(){
digitalWrite(pinCHIUDI, HIGH); //set the pin HIGH and thus turn LED on
digitalWrite(pinAPRI, HIGH); //set the pin HIGH and thus turn LED on
}
void TapparellaIF::putInLowState(){
digitalWrite(pinCHIUDI, LOW); //set the pin HIGH and thus turn LED on
digitalWrite(pinAPRI, LOW); //set the pin HIGH and thus turn LED on
}
void TapparellaIF::putInHighState(){
digitalWrite(pinCHIUDI, HIGH); //set the pin HIGH and thus turn LED on
digitalWrite(pinAPRI, HIGH); //set the pin HIGH and thus turn LED on
}

TapparellaIF tapparella1 = TapparellaIF(PIN_TAPPAR1_APRI , PIN_TAPPAR1_CHIUDI);
TapparellaIF tapparella2 = TapparellaIF(PIN_TAPPAR2_APRI , PIN_TAPPAR2_CHIUDI);
TapparellaIF tapparella3 = TapparellaIF(PIN_TAPPAR3_APRI , PIN_TAPPAR3_CHIUDI);
TapparellaIF tapparella4 = TapparellaIF(PIN_TAPPAR4_APRI , PIN_TAPPAR4_CHIUDI);
TapparellaIF tapparella5 = TapparellaIF(PIN_TAPPAR5_APRI , PIN_TAPPAR5_CHIUDI);

void putAllInOpeningState(){
tapparella1.putInOpenState();
tapparella2.putInOpenState();
tapparella3.putInOpenState();
tapparella4.putInOpenState();
tapparella5.putInOpenState();
digitalWrite(openLedPin, HIGH); //set the pin HIGH and thus turn LED on
digitalWrite(closeLedPin, LOW); //set the pin LOW and thus turn LED off
}
void putAllInClosingState(){
tapparella1.putInCloseState();
tapparella2.putInCloseState();
tapparella3.putInCloseState();
tapparella4.putInCloseState();
tapparella5.putInCloseState();
digitalWrite(openLedPin, LOW);
digitalWrite(closeLedPin, HIGH);
}
void putAllInIdleState(){
tapparella1.putInIdleState();
tapparella2.putInIdleState();
tapparella3.putInIdleState();
tapparella4.putInIdleState();
tapparella5.putInIdleState();
digitalWrite(openLedPin, LOW);
digitalWrite(closeLedPin, LOW);
}
void putAllInLowState(){
tapparella1.putInLowState();
tapparella2.putInLowState();
tapparella3.putInLowState();
tapparella4.putInLowState();
tapparella5.putInLowState();
digitalWrite(openLedPin, LOW);
digitalWrite(closeLedPin, LOW);
}
void putAllInHighState(){
tapparella1.putInHighState();
tapparella2.putInHighState();
tapparella3.putInHighState();
tapparella4.putInHighState();
tapparella5.putInHighState();
digitalWrite(openLedPin, HIGH);
digitalWrite(closeLedPin, HIGH);
}

potrebbe essere utile per il mio progetto ?

Ciao, Giuseppe

grosso modo si... il concetto è questo (non ho controllato la sintassi né tantomeno il codice...).

Però hai capito perfettamente quello che intendevo... il codice è tutto nella classe e ne usi 6 istanze diverse.

Non vedo però nella classe la gestione dei piedini di input dei pulsanti di comando. Ed inoltre dovresti ovviamente aggiungere la gestione delle temporizzazioni.

Ti consiglierei di provarci da solo perché è il modo migliore per imparare. Poi magari ne parliamo insieme.

Ciao.
Vittorio.

Ok grazie, ci studio sù...

Salve ragazzi,
sto continuando nel creare questo sketch, ma forse mi sono perso nel creare quest'automa a stati
come suggerito da Vittorio.
Credo abbia ancora bisogno del Vs supporto , Vi posto quello su cui stavo lavorando per un consiglio,
nella verifica mi da' anche degli errori che non riesco a venirne a capo...
// definizione stati
#define ATTESA
#define GIU
#define SU

const byte OUT_GIU = 11;
const byte OUT_SU = 12;
const byte IN_GIU = 2;
const byte IN_SU = 3;
byte stato_IN_GIU;
byte stato_IN_SU;
byte stato_OUT_GIU;
byte stato_OUT_SU;

unsigned long Tnow_GIU;
unsigned long T0_GIU;
unsigned long Tnow_SU;
unsigned long T0_SU;
unsigned long tON = 10000;

int stato;

void setup()
{
pinMode(OUT_GIU, OUTPUT);
pinMode(OUT_SU, OUTPUT);
pinMode(IN_GIU, INPUT);
pinMode(IN_SU, INPUT);
// condizioni iniziali

stato_OUT_GIU = LOW;
stato_OUT_SU = LOW;
T0_GIU = millis();
T0_SU = millis();
}

void loop()
{
Tnow_GIU = millis();
Tnow_SU = millis();
stato_IN_GIU = digitalRead(IN_GIU); // Legge ingresso IN_GIU
stato_IN_SU = digitalRead(IN_SU); // Legge ingresso IN_SU

// definizione stati
switch (stato)
{

case ATTESA:
if((stato_OUT_GIU = LOW) && (stato_OUT_SU = LOW))
{
if stato_IN_GIU = HIGH;
{
stato = GIU; // PASSA ALLA FASE DISCESA
T0_GIU = Tnow_GIU; // Azzera il contatore
}
else if stato_IN_SU = HIGH;
{
stato = SU; // PASSA ALLA FASE SALITA
T0_SU = Tnow_SU; // Azzera il contatore
}
else
{
stato = ATTESA ;
}
}
break;

case GIU:
if(stato_IN_GIU == HIGH)
{
stato_OUT_GIU = LOW;
stato = ATTESA;
}
else
{
if (Tnow_GIU - T0_GIU >= tON)
{
T0_GIU = Tnow_GIU; // Azzera contatore
stato = ATTESA;
}
else
{
stato_OUT_GIU = LOW;
}
}

break;

case SU:
if(stato_IN_SU == HIGH)
{
stato_OUT_SU = LOW;
stato = ATTESA;
}
else
{
if (Tnow_SU - Tnow_SU >= tON)
{
T0_SU = Tnow_SU; // Azzera contatore
stato = ATTESA;
}
else
{
stato_OUT_GIU = LOW;
}
}

break;

default:
break;

} // End switch

digitalWrite(OUT_GIU, stato_OUT_GIU);
digitalWrite(OUT_SU, stato__OUT_GIU);

} // End loop

Aiuto mi sono bloccato !!
Sto andando nel pallone con lo switch ..... :confused: