Motore avanti/indietro

Buongiorno,
vi scrivo perché ho qualche problema con lo sviluppo del software, spero possiate aiutarmi.
Ho un piccolo scorrevole con motore 12VDC, 2 finecorsa normalmente chiusi, uno per stop avanti e l’altro per stop indietro, una scheda a 3 relè che permette di regolare la marcia, se avanti (k1) o indietro (k2), mentre il terzo relè (k3) serve per selezionare la velocità motore, ovvero scambia 12V con 9V per ottenere un rallentamento prima di sbattere contro il finecorsa con troppa forza/inerzia (con k3 a riposo il motore funziona con 9V). Tutto questo devo farlo funzionare con un unico pulsante normalmente aperto. Se premo il pulsante deve aprirsi, se lo premo prima che arrivi al finecorsa fermo il motore, se lo ripremo deve chiudersi, se lo ripremo prima del finecorsa si ferma e via così. Stesso identico funzionamento di un qualsiasi cancello automatico.

Ho già buttato giù qualche sketch, qualcosa funziona, ma si verificano delle problematiche fuori da ogni schema. Se premo il pulsante la prima volta tutto ok, se aspetto il finecorsa a volte il motore rimane in trazione anche se solitamente va tutto ok. se da tutto aperto premo il pulsante per chiudere il cancello e aspetto il finecorsa tutto ok, anche se a volte il motore rimane in trazione a finecorsa premuto. Comunque sia in queste casistiche il cancello si apre e si chiude per quasi tutte le volte.
Se invece premo il pulsante per fermare il cancello, che si stia aprendo o chiudendo fa poca differenza, mi si blocca il programma e non si muove più nulla. Rare volte capita che il cancello si muove solo in lento e solo quando il pulsante è mantenuto premuto, quindi al rilascio si ferma.

Di seguito allego qualche sketch:
Scorrevole rele è quello che funziona meglio, le altre prove sono un disperato tentativo di riscrivere il programma in maniera differente, ma niente da fare.
Purtroppo le mie conoscenze sono limitate dal lato programmazione.

Sperando in un vostro aiuto Vi ringrazio.

Buona giornata

Michael

sketck.zip (3.76 KB)

Hai controllato se puoi farlo ? ... a livello legale, intendo ... perche' le normative sull'automazione e sui cancelli automatici sono abbastanza restrittive, se si trattasse di un prototipo o di un modello niente da dire, ma nel momento in cui applichi una cosa del genere (autocostruita) ad un cancello scorrevole reale, potrebbero crearti casini ...

ciao Mikebs,

lo so che la tentazione di farsi le cose da se è forte ma ti ricordo che dal regolamento :

15.4 Modifica ad altri "impianti e/o macchinari"

Così come per il punto 15.3, richieste relative alla modifica di "impianti e/o macchinari", come ad esempio la modifica di macchine presenti in officine, cancelli elettrici di casa, ecc. ecc., essendo anche esse soggette a normativa (difatti le modifiche possono essere fatte solo da personale qualificato ed autorizzato, in grado di rilasciare/modificare i necessari "fascicoli tecnici", "dichiarazioni di conformità" e qunt'altro richiesto dalla legge) non saranno ammesse ed i relativi post/thread, chiusi e cancellati.

quindi ti consiglio di chiarire bene che ruolo avrà arduino in questo progetto.

... il fatto che usasse un motore a 12VDC e che per rallentare lo mandasse a 9VDC, mi aveva dato l'idea (... forse errata) che si trattasse di un modellino.

Se mi dite però che anche nella realtà ci sono cancelli elettrici che lavorano con queste tensioni ... beh aspetto la risposta di Mikebs prima di decidere se chiudere o meno. ::)

Guglielmo

Grazie per le risposte, intanto preciso che questa automazione è solo un prototipo, non è installata in un luogo pubblico o in luoghi accessibili a persone o animali, infatti non sono previsti lampeggianti, allarmi, fotocellule (solo prove a banco su struttura autocostruita, quindi nessuna modifica a nulla di pre-esistente) ed è una cosa personale. Se dubitate di me a livello lavorativo posso dirvi che sono un elettricista industriale, in azienda facciamo quadri per presse, linee robotizzate, interventi su CN, programmazione PLC, ecc... Purtroppo tra il gestire dei PLC Siemens e una schedina Arduino Uno c'è l'abisso, per questo speravo di chiedere aiuto a voi per debuggare il programma, perché tutto funziona ma non perfettamente. Comunque sia, mi assumo TUTTE le responsabilità di quel che farò con questo progetto, e preciso di nuovo, è tutto un prototipo, non c'è bisogno di chiudere, per cortesia. Preciso altra cosa, se lo dovessi fare per un cliente comprerei una scheda universale per cancelli automatici con tanto di telecomando e via, ma è bello complicarsi la vita imparando a fare cose nuove... ;) Poi questo progetto è già stato intrapreso in modi differenti da altre persone per gli Esami di Stato, non vedo i problemi legali che vedete voi per il mio caso.

comunque, facendo ulteriori prove ed inserendo dei condensatori di debounce su finecorsa e pulsante ora lo sketch "scheda_rele" funziona abbastanza bene. Inoltre, sto pensando di implementare dei finecorsa a molla sulla struttura da me costruita.

Non è un vero cancello automatico, anche se il funzionamento è quello praticamente. Spero di poter ragionare con voi su questo progetto. Per piacere non serve chiuidere, chiedo venia!

A presto

Michael

Il probloema NON è la TUA esperienza (... che non metto in dubbio), il problema è l'inesperienza degli ALTRI che vengono qui, leggono il progetto e si mettono a rifarlo senza avere le dovute conoscenze !!!

Terrò d'occhio il thread e se riscontrerò (... o mi verrà segnalata) qualche cosa che riterrò NON adatta ad un pubblico meno esperto ... mi vedrò comunque costretto a chiudere.

Dura Lex, sed Lex.

Guglielmo

ciao mikebs,

iniziamo con una discussione teorica...

il mio programma deve funzionare in modo "fluido" o voglio che in certi punti si blocchi diventando "sordo" a quello che succede all'esterno (segnali in ingresso)?....molto probabilmente la risposta che ti darai sarà: deve essere fluido e stare sempre attento a quello che succede...quindi i delay() vanno sostituiti con altro metodo (leggasi millis()).

essendo un prototipo di cancello scorrevole quanto importante è rilevare l'intervento dei finecorsa nell'immediato!?...direi abbastanza....quindi bisogna creare e legare delle ISR ad essi...e qui si deve valutare la scheda arduino in tuo possesso...in quanto non hanno lo stesso numero di pin utilizzabili per gli interrupts...vado a memoria...la UNO ne ha 2 la MEGA ne ha 6...le altre non ricordo.

Mikebs: Poi questo progetto è già stato intrapreso in modi differenti da altre persone per gli Esami di Stato, non vedo i problemi legali che vedete voi per il mio caso.

Il problema c'è, bello grosso, nel momento in cui vuoi installare un Arduino su un prodotto che va installato da qualche parte, non importa se è un cancello o un semplice pannello luminoso, questo perché Arduino non ha nessuna omologazione/certificazione per l'uso industriale/civile. Detto in altro modo, con Arduino puoi fare tutte le prove e i test che vuoi sul banco del laboratorio, però se decidi di trasformare la cosa in un prodotto, anche se in singolo esemplare, non puoi usare nessuna scheda Arduino, devi progettare una tua scheda Arduino Like che sia in regola con le omologazioni/certificazioni richieste dalla applicazione, oppure usi un PLC Arduino Like, che ovviamente non costa solo 20 E, già in regola con le disposizioni di legge.

Grazie per l'opportunità, vedrò di rispettare la Legge in tutti i punti anche nel rispetto del Forum.

Per il PLC Arduino non ne ero a conoscenza, ma quindi utilizzando questo sarebbe lecito utilizzarlo in un'automazione?

Per millis e delay non ne conosco la differenza, provo ad approfondire meglio il discorso. Comunque, più fluido è il programma e meglio è come hai ben capito, e ovviamente i finecorsa sono molto importanti, il loro intervento deve essere il più rapido possibile, anche se non pretendo il millisecondo, succede nulla se il motore spinge mezzo secondo in più (meglio evitare), c'è pure un finecorsa meccanico come ultima spiaggia quindi se va in battuta non scappa nulla.

Per il discorso del numero di pin utilizzabili come interrupt non mi son capito molto penso. Intendi dire che anche se ho più 10 pin digitali liberi posso utilizzarne solo 2 come interrupt? e se aggungo il terzo? Perchè non si può? Intendo, in questo caso ho 3 interrupt tra i finecorsa elettrici e il pulsante, giusto?

Grazie a tutti e buona serata ;)

il delay() forza in pausa il programma per il tempo stabilito e fino al suo scadere, c'è qualche eccezione, il programma non verifica lo stato degli ingressi ne cambia lo stato delle uscite...ne fa calcoli di vario genere.

con millis() e come se mettessi un "promemoria"...da quando viene "chiamato" (memorizzazione del tempo attuale ed impostazione della quantità di tempo da attendere) il programma continua a girare e a fare tutto quello che deve fare...allo scadere del tempo di "promemoria" esegue, se possibille, quello per cui è stato impostato il promemoria...

per fare mio un esempio scritto da altri puoi considerare :

delay() = alle 15.00 c'è la partita...io mi siedo sul divano alle 14.30...nei 30 minuti di differanza non faccio nulla...sono in delay()

millis() = alle 15.00 c'è la partita sono le 14.00...metto la sveglia e continuo a riordinare casa...alle 15.00 suona la sveglia...mi metto a vedere la partita.

interrupt = in entrambe gli esempi tua moglie ti dice di portare fuori la spazzatura...tu abbandoni quello che stavi o non stavi facendo e porti fuori la spazzatura.

se guardi nella pagina delle reference di arduino QUI trovi descritto l'interrupt ed i pin utilizzabili perchè non tutti hanno questa possibilità; QUI un accenno a millis().

io direi che provi a modificare lo sketch con queste nuove nozioni e poi diamo un'occhiata...se non ti sarà chiaro come gestire queste nuove cose facci sapere e vedremmo di chiarire.

in ultimo...non penso che per il pulsante sia necessario un interrupt...per i fine corsa si.

io, senza entrare nel merito del si puo' non si puo' fare, do per scontato si tratti di modellino a 12 v

dicevo io vedrei bene una coppia di fine corsa con DUE contatti, uno va ad arduino, e fa quello che deve fare via software (anche non interrupt, poco serve)

l'altro contatto interviene in hardware, a tagliare l'alimentazione del relè di marcia corrispondente NON, ripeto non mi fiderei di solo fine corsa ad intervento software

anche per l'inversione d marcia, metterei i due rele di marcia a vanti e indietro interbloccati (io userei anche teleruttore doppio interbloccato meccanicamente, ma non esageriamo)

così gli interrupt diventano non necessari

ah, eliminerei i goto..................

se vuoi domani sera ne parliamo..

quindi da quanto ho capito ci sono dei PIN specifici da utilizzare come Interrupt, nel mio caso il 2 e il 3, giusto?

Son sincero, non mi è entrato bene in testa il discorso della funzione millis, o meglio, come sfruttarla nel mio sketch, devo studiarla per bene e fare qualche prova/esempio.

Comunque ho provato a fare qualche modifica che mi è venuta in mente mantenendo i delay, ora funziona meglio, anche se a volte si blocca il conteggio.

int dir1PinA = 2;
int dir2PinA = 3;
int speedPinA = 8;
int puls = 7;
int FcAv = 6;
int FcInd = 5;

int fcAv,fcInd,antiRip,count,velocita = 0;
int pulsante;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(dir1PinA,OUTPUT);
  digitalWrite(dir1PinA, LOW);
  pinMode(dir2PinA,OUTPUT);
  digitalWrite(dir2PinA, LOW);
  pinMode(speedPinA,OUTPUT);
  digitalWrite(speedPinA, LOW);
  pinMode(puls,INPUT);
  pinMode(FcAv,INPUT);
  pinMode(FcInd,INPUT);
  count=0;
  pulsante=1;
}

void loop() {
  Serial.println("pulsante=");
  Serial.println(pulsante);
  digitalWrite(dir1PinA, LOW);
  digitalWrite(dir2PinA, LOW);
  digitalWrite(speedPinA, LOW);
  pulsante = digitalRead(puls);
  fcAv = digitalRead(FcAv);
  fcInd = digitalRead(FcInd);
  Serial.println("pulsante=");
  Serial.println(pulsante);
  delay (200);
  
   pressione:
  if ((pulsante == 0 )&&(antiRip == 0 )){
    count++;
    Serial.print(count);
    if (count > 4)count = 1;
    antiRip = 1;
    if (count < 0)count = 1; 
    antiRip = 1;
    Serial.print("conteggio =");
    Serial.print(count);
    Serial.println(" ");
  }
  if (pulsante == 1 ){
    antiRip = 0;
  }


  // avanti  
  if ((pulsante == LOW )&&(count == 1 )){
        Serial.println("Motor 1 Forward");
        while (pulsante == LOW ) pulsante = digitalRead(puls);
        delay (100);
        
        for (int i = 160 ; (i > 0)&&(fcAv == LOW) ; i-- ){    // i = tempo in decimi di secondo
          Serial.println("For Forward");
          fcAv = digitalRead(FcAv);
          pulsante = digitalRead(puls);
          antiRip = 0;
          
          if ( pulsante == LOW ){
            digitalWrite(speedPinA, 0);
            digitalWrite(dir2PinA, 0);
            goto pressione;
          }
          
          if ((i <= 160) && (i > 150))
          {
            velocita = 0;   // velocità partenza
            digitalWrite(speedPinA, velocita);
            digitalWrite(dir1PinA, LOW);
            digitalWrite(dir2PinA, HIGH);
            Serial.print(i);
          }
          if (( i <= 150 ) && (i > 110))  //134
          {
            velocita = 1;  // velocità massima
            digitalWrite(speedPinA, velocita);
            digitalWrite(dir1PinA, LOW);
            digitalWrite(dir2PinA, HIGH);
            Serial.print(i);
          }
          if ((i <= 110) && (i > 0))
          {
            velocita = 0;   // velocità rallentamento
            digitalWrite(speedPinA, velocita);
            digitalWrite(dir1PinA, LOW);
            digitalWrite(dir2PinA, HIGH);
            Serial.print(i);
          }
          delay (100);
        }
        
        digitalWrite(speedPinA, 0);
        digitalWrite(dir2PinA, 0);
        count++;
        Serial.println(count);
        Serial.println(antiRip);
   }

   // indietro
   if ((pulsante == LOW )&&(count == 3 )){
        Serial.println("Motor 1 Backward");
        while (pulsante == LOW ) pulsante = digitalRead(puls);
        delay (100);
        
        
        for (int x = 200 ; (x > 0)&&(fcInd == LOW) ; x-- ){
          Serial.println("For Backward");
          fcInd = digitalRead(FcInd);
          pulsante = digitalRead(puls);
          antiRip = 0;
          
          if ( pulsante == LOW ){
            digitalWrite(speedPinA, 0);
            digitalWrite(dir1PinA, 0);
           goto pressione;
          }

          if ((x <= 200) && (x > 190))
          {
            velocita = 0;   // velocità partenza
            digitalWrite(speedPinA, velocita);
            digitalWrite(dir1PinA, HIGH);
            digitalWrite(dir2PinA, LOW);
            Serial.print(x);
          }
          if ((x <= 190) && (x > 140))
          {
            velocita = 1;   // velocità massima
            digitalWrite(speedPinA, velocita);
            digitalWrite(dir1PinA, HIGH);
            digitalWrite(dir2PinA, LOW);
            Serial.print(x);
          }
          if ((x <= 140) && (x > 0))
          {
            velocita = 0;   // velocità rallentamento
            digitalWrite(speedPinA, velocita);
            digitalWrite(dir1PinA, HIGH);
            digitalWrite(dir2PinA, LOW);
            Serial.print(x);
          }
          delay (100);
        }
        digitalWrite(speedPinA, 0);
        digitalWrite(dir1PinA, 0);
        count++;
        Serial.println(count);
        Serial.println(antiRip);
   }

}
1
pulsante=
0
3conteggio =3 
Motor 1 Backward
For Backward
200For Backward
199For Backward
198For Backward
197For Backward
196For Backward
195For Backward
194For Backward
193For Backward
192For Backward
191For Backward
190For Backward
189For Backward
188For Backward
187For Backward
186For Backward
185For Backward
184For Backward
183For Backward
182For Backward
181For Backward
180For Backward
179For Backward
178For Backward
177For Backward
176For Backward
175For Backward
174For Backward
173For Backward
172For Backward
171For Backward
170For Backward
169For Backward
168For Backward
167For Backward
166For Backward
165For Backward
164For Backward
163For Backward
162For Backward
161For Backward
160For Backward
159For Backward
158For Backward
157For Backward
156For Backward
155For Backward
154For Backward
153For Backward
152For Backward
151For Backward
150For Backward
149For Backward
148For Backward
147For Backward
146For Backward
145For Backward
144For Backward
143For Backward
142For Backward
141Fo⸮

come notate quando è arrivato a 141 il conteggio si è bloccato tutto in maniera strana. Può essere d’aiuto?

per il discorso di pensare ad un’esclusione elettromeccanica dei relè sarebbe buona cosa visto che nei quadri industriali si fa per questioni di sicurezza. Devo provare ad inserire anche questo, solo che pensavo di sviluppare per bene il software prima di aggiungere componenti o incrementare la difficoltà dello schema.

Mi metto a studiare nel frattempo…

Grazie a tutti

Prima di tutto, in conformità al regolamento, punto 7, devi editare il tuo post (quindi NON scrivendo un nuovo post, ma utilizzando il bottone More → Modify che si trova in basso a destra del tuo post) e racchiudere il codice all’interno dei tag CODE (… sono quelli che in edit inserisce il bottone con icona fatta così: </>, tutto a sinistra) e NON nei tag che hai usato tu …

… dopo che lo avrai fatto, ti consiglio di studiarti come si usa la millis(), prima QUI, poi QUI ed infine leggi anche QUI e QUI … vedrai che ti sarà tutto più chiaro :wink:

Guglielmo