Vai al contenuto
PLC Forum


automazione di sequenza


Francesco Querin

Messaggi consigliati

Francesco Querin
devo fare un automazione premendo il pulsante mi deve eseguire a,b,c,d,e,f, dove ognuna a sua volta comandano una serie di informazioni, a e b il motore destra sinistra c e d il servo destra sinistra ecc
ecco il programma intero cosi si puo capire meglio la sequenza, il progetto prevede un automazione in cui il bicchiere va al dispensatore viene riempito e poi ritorna, ho motori passo passo servo motore sensori di stop sensore di liquido elettrovaltole rele questa e la parte manuale sto facendo una parte automatica per questo dispensatore

ecco il programma


#include <Servo.h>
int buttonA = 9; // sequenza bevanda 1
int buttonB = 10; // sequenza bevanda 2
int buttonC = 11; // segnale di stop
int buttonD = 12; // sequenza bevanda 3
int a; // verso il distributore
int b; // dal distributore
int c; // servo avanti
int d; // servo indietro
int e; // bevanda 1
int f; // bevanda 2
int g; // bevanda 3
int a1;
int fase0 = 0;
int fase1 = 1;
int fase2 = 2;
int fase3 = 3;
int rele2 = 4;
int rele3 = 5;
int rele4 = 6;
int rele1 = 7;
int tempo = 10;
int tempo2 = 200;
int pos;
Servo myservo;
void setup() {
  myservo.attach(8);
  pinMode(buttonA, INPUT);
  pinMode(buttonB, INPUT);
  pinMode(buttonC, INPUT);
  pinMode(buttonD, INPUT);
  pinMode(fase0, OUTPUT);
  pinMode(fase1, OUTPUT);
  pinMode(fase2, OUTPUT);
  pinMode(fase3, OUTPUT);
  pinMode(rele2, OUTPUT);
  pinMode(rele3, OUTPUT);
  pinMode(rele4, OUTPUT);
  pinMode(rele1, OUTPUT);
 
 
}
void loop() {
  if(a=HIGH) for(int marcia; marcia=digitalRead(buttonC)==LOW;)
  {
    digitalWrite(fase0, HIGH);
    digitalWrite(fase3, LOW);
    delay(tempo);
    digitalWrite(fase0, LOW);
    digitalWrite(fase1, HIGH);
    delay(tempo);
    digitalWrite(fase1, LOW);
    digitalWrite(fase2, HIGH);
    delay(tempo);
    digitalWrite(fase2, LOW);
    digitalWrite(fase3, HIGH);
    delay(tempo);
  }
  if(b=HIGH) for(int marcia; marcia=digitalRead(buttonC)==LOW;)
  {
    digitalWrite(fase3, HIGH);
    digitalWrite(fase0, LOW);
    delay(tempo);
    digitalWrite(fase3, LOW);
    digitalWrite(fase2, HIGH);
    delay(tempo);
    digitalWrite(fase2, LOW);
    digitalWrite(fase1, HIGH);
    delay(tempo);
    digitalWrite(fase1, LOW);
    digitalWrite(fase0, HIGH);
    delay(tempo);
  }
  if (c=HIGH) for (pos = 0; pos <= 180; pos += 1) { myservo.write(pos); delay(15); }
  if (d=HIGH) for (pos = 180; pos >= 0; pos -= 1) { myservo.write(pos); delay(15); }
  if (e=HIGH) for (int marcia; marcia=analogRead(A0)<290;) { digitalWrite(rele1, LOW); digitalWrite(rele2, LOW); }
  if (f=HIGH) for (int marcia; marcia=analogRead(A0)<290;) { digitalWrite(rele1, LOW); digitalWrite(rele3, LOW); }
  if (g=HIGH) for (int marcia; marcia=analogRead(A0)<290;) { digitalWrite(rele1, LOW); digitalWrite(rele4, LOW); }
  
    digitalWrite(rele1, HIGH);
    digitalWrite(rele4, HIGH);
    digitalWrite(rele3, HIGH);
    digitalWrite(rele2, HIGH);
 
 if (digitalRead(buttonA)==HIGH)
 { a==HIGH; }
 delay(tempo2);
 while(digitalRead(buttonC)==HIGH)
 { c==HIGH; pos=180; pos=e; e==HIGH; }
  delay(tempo2);
  analogRead(A0)>290==a1;
 while(a1==HIGH)
 { d==HIGH; pos=0; pos=b; b==HIGH; }
 
}
 
lautomazione della sequenza non funziona
Link al commento
Condividi su altri siti


Come ti ho già spiegato in un'altra discussione, devi dividere il programma in più sottoprogrammi.

Nel programma nain (loop) metterai le condizioni di richiamo dei vari sotto programmi.

Analizzare un programma fatto da un altro è già una cosa non facile, se pi il programma è un unico listone passa la voglia ancora prima di leggerlo.

 

Fatti una bella descrizione delle operazioni o con un diagramma di flusso o con una descrizione dettagliata, verificando bene la strategia per eseguire l'automazione; poi codifichi le varie fasi.

 

Avrai una funzione che riconosce i comandi, un'altra che effettua gli spostamenti ed almeno una terza per i riempimenti.

 

Suddivdi il tuo programma e poi verifica se funziona o quale funzione non funziona.

Ad esempio, per prima cosa verifica il riconoscimento dei comandi; una volta che questo è consolidato e funzionante, verifica gli spostamenti.

 

Fare automazione non è un lavoro semplice dove basta butttar giù qualche istruzione. Prima di arrivare alle istruzioni c'è tutto un lavoro di analisi e di progettazione della strategia.

La tua è un'automazione abbastanza semplice, ma anche la tua esperienza è molto limitata. Cerca di partire con il piede giusto, altrimenti rischi di fare la fine di certi pseudo programmatori che buttan giùprogrammi che basta un nulla per mandarli a rotoli.

Link al commento
Condividi su altri siti

Francesco Querin

dei consigli sto facendo una prova ecco il programma non so come dirgli a ha queste funzioni

int a;
int b;
int c;
void setup()
{
pinMode(2, INPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);

 
}
void loop()
{
digitalWrite(3, HIGH);// da solo spegne il rele
digitalWrite(4, HIGH);
digitalWrite(5, HIGH);
while(digitalRead(2)==HIGH){ a; }
a(digitalWrite(3, LOW); delay(500); digitalWrite(3, HIGH); delay(500);)
 
Link al commento
Condividi su altri siti

Francesco Querin

voglio dire a arduino che a sono le istruzioni per far blinkare il led a 500 milisecondi b sono le istruzioni per far blinkare il led a 1 secondo e c sono le istruzioni per far blinkare il led a 3 secondi e che il pulsante fa partire a dopo 1 sencondo parte b dopo 1 secondo parte c

 

 

niente da fare non ci riesco


while(digitalRead(2)==HIGH){delay(1000); a; delay(1000); b; delay(1000); c;}
if(a){digitalWrite(3, LOW); delay(500); digitalWrite(3, HIGH); delay(500);}
if(b){digitalWrite(4, LOW); delay(1000); digitalWrite(4, HIGH); delay(1000);}
if(c){digitalWrite(5, LOW); delay(2000); digitalWrite(5, HIGH); delay(2000);}
 
in poche parole al posto di entrare in funzione quando e specificato nel while entrano finito il ciclo a poi finito il ciclo b cioe non blinkano tutti e tre ma a blinka poi b blinka poi c blinka invece di a blinka b blinka e c blinka aiuto,ho provato tutte le combinazioni usando if e while, ,ne aprofitto per chiedere meglio come funzionano if e while perché a volte while condizione codice while condizione codice non funziona e while condizione codice if condizione codice funziona o viceversa
Link al commento
Condividi su altri siti

Francesco Querin

se non riesco a risolvere questo non posso associare delle istruzioni a qualcosa e fare un codice che in automatico mi richiama quelle istruzioni ce per caso qualche comando che non conosco che invece dovrei usare ?

 
Link al commento
Condividi su altri siti

ELSE , fino a che riesci di nuovo a respirare , secondo me , (da un certo punto ti invidio ) ,sei un pochino affrettato :thumb_yello:

Ho seguito attentamente il video (tutto ) , e riflette quel che ho detto ; purtroppo , per il programa , non sono in grado di aiutarti :(

Link al commento
Condividi su altri siti

Francesco Querin

grazie sto cercando qualcosa di questo tipo

int funzione(a,b;)

{ c=a+b;

somma=return c}

 n1=5

n2=5

somma=n1+n2;

return somma

 

scusatemi se ho scritto male qualcosa vedendola stanco da allenamento comunque e una funzione ed e richiamata solo che quel che cerco dovrebbe essere

a=int funzione(a,b;)

{ c=a+b;

somma=return c}

cosi da creare un automatismo che richiami le funzioni in tal modo premendo un pulsante richiamo una sequenza di funzioni che fanno muovere il motore il servo versare il liquido e riportare il bicchiere. Continuo a cercare in rete se avete qualcosa che mi puo essere di esempio

Link al commento
Condividi su altri siti

Allora devi definire il perido di blinking come una variabile, ad esempio

int blink_time = 500; // parti con tempo di blinking di 0.5"

Poi definisci un'altra variabile per misurare il tempo, ad esempio

in time = 1000;

 

Quando riconosci il pulsante inizi a far lampeggiare il LED e, contemporaneamente con l'istruzione mills() leggi il tempo elo memorizzi.

Fai un loop di attesa sino a quando il tempo letto non è maggiore di time, allora passi a blink_time il nuovo valore.

 

Tanto per darti un'idea, prova qualche cosa di simile.

   tempo=millis();
   if ((tempo - prec_tempo) >=300)
     {
       flgacq = HIGH;
       prec_tempo = tempo;
       icnttim--;
       if (icnttim == 0)
          {
            icnttim = 3;
            flgacqan = HIGH;
          }
     } 

E' solo un esempio per farti vedere come si può contare il tempo e far accadere un evento ad intervalli precisi. In questo caso c'è un evento ogni 300 ms ed un'altro ogni 900ms, conteggiando 3 volte i 300ms. I due tempi servono per acquisire 2 periferiche differenti.

Link al commento
Condividi su altri siti

Francesco Querin

grazie mi studiero questo esempio adesso devo fermarmi per via di un esame devo studiare ma attendo il prima possibile di riprendere nel frattempo me lo studiero

Link al commento
Condividi su altri siti

Francesco Querin

non ho capito 2 cose del tuo programma icnttim = 3; prec_tempo = tempo; precisamente perché sono in quella posizione e non in altre posizioni, esempio perché icnttim e dentro il secondo if e non dentro al primo if? e perché prec_tempo e uguale a tempo dove il conteggio dei tempi? cercando in giro

void  a() { digitalWrite(3,LOW); delay(tempo1); digitalWrite(3, HIGH); delay(tempo1);}
void b(){ digitalWrite(4,LOW); delay(tempo2); digitalWrite(4, HIGH); delay(tempo2);}
void c(){ digitalWrite(5,LOW); delay(tempo3); digitalWrite(5, HIGH); delay(tempo3);}
void loop()
{digitalWrite(3, HIGH);digitalWrite(4, HIGH);digitalWrite(5, HIGH);
if(digitalRead(2)==HIGH){ delay(tempo4);  a();  delay(tempo4);  b();  delay(tempo4);  c();}
}
funziona perfettamente apparte il blinkaggio cioe in teoria dovrebbe partire ma non finire pero finisce dopo un solo ciclo di HIGH e LOW
Link al commento
Condividi su altri siti

Perchè la variabile  icnttim viene decrementata se, e solo se, è scaduto il primo intervallo di tempo.

Parti con tempo = 0; e prec_tempo = 0; mills() ti da i ms trascorsi dall'inizio del programma. Ad ogni giro di programma tempo avrà un valore crescente; quando (tempo - prec_tempo) >= 300 significa che son trascorsi 300ms o più, ovvero il mio temporizzatore è scaduto. A questo punto egauglio prec_tempo a tempo e riparto per un secondo ciclo.

 

Questo è un metodo per non usare interrupts a tempo e non usare temporizzatori bloccanti come delay(x). Ogni volta che c'è un'istruzione delay(x) il programma si blocca in attesa che sia trascorso il tempo impostato.

Link al commento
Condividi su altri siti

Francesco Querin

capito dopo un tot tempo parte il primo if e parte il secondo if il primo si spegne, e poi dopo tot tempo riparte il 2 giro dopo 3 giri il 2 if riparte. Giusto ?? buon esempio puo essere utile, tornando a noi

digitalWrite(3,LOW); delay(tempo1); digitalWrite(3, HIGH); delay(tempo1);

cosi lampeggia

void  a() { digitalWrite(3,LOW); delay(tempo1); digitalWrite(3, HIGH); delay(tempo1);}

if(digitalRead(2)==HIGH){ a();} cosi lampeggia

if(digitalRead(2)==HIGH){ a();delay(1000); b();} parte a fa un ciclo aspetta parte b fa un ciclo

 

ho sbaglio nel richiamare le funzioni o sbaglio nelle funzioni perché a quanto pare devo inserire qualcosa altrimenti il normale codice per lampeggiare non funziona, non riesco a venirne a capo. Cercando in giro ho visto che uno in un forum usava una funzione senza ritorno quindi una funzione void e che posso usare i comandi scrivendoli blink,setup,loop, ma non so come usarli

 

Link al commento
Condividi su altri siti

Il primo codice, dei 2, è corretto, infatti lampeggia.


 

Quote

 

Cercando in giro ho visto che uno in un forum usava una funzione senza ritorno quindi una funzione void e che posso usare i comandi scrivendoli blink,setup,loop, ma non so come usarli


 

 

Scusa ma non riesco a capire quello che vuoi fare. Se intendi eseguire un lampeggio senza delay il mio esempio è quellom che ti serve

Link al commento
Condividi su altri siti

Francesco Querin

io voglio usare quel lampeggio dentro una funzione e poi richiamarla in un automazione, esempio pratico

funzione 1 codice

funzione 2 codice

funzione 3 codice

funzione n codice

 

if(condizione)  richiamo funzione 1 richiamo funzione 2 richiamo funzione 3

 

per ora testo dei lampeggi poi il codice dentro le funzioni sara quello del progetto vero e proprio

Link al commento
Condividi su altri siti

Usa l'istruzione "case".

leggi questo tutorial.

 

Ma non ti è mai venuta l'idea di leggere uno dei tanti tutorial che insegnao a fare i primi passi con arduino, imparando la progammazione passo passo, un modo organico?

Link al commento
Condividi su altri siti

Francesco Querin

si praticamente ho imparato dai tutorial solo che i tutorial che ho visto mi hanno spiegato quello non tutto arduino, linguaggio c e c++ dovrei cercare altri canali e vedere i tutorial che hanno per capire qualcosa di piu

Link al commento
Condividi su altri siti

Francesco Querin

letto ci sono cose che non capisco se non voglio cambiare ma voglio che si aggiunga cioe acendo lampeggio led 1 poi accendo lampeggio led 2 ecc ? const int  buttonPin = 2;   const int ledPin = 13;  perché const int ?

 StatoPulsante = digitalRead(BUTTON);              // legge il valore dell'input e lo conserva  

  1.   if (StatoPulsante != StatoPulsantePrecedente) {   // compara lo stato del pulsante attuale con il precedente  
  2.     if (StatoPulsante == HIGH) {                    // se lo stato è cambiato incrementa il contatore  
  3.       // se lo stato corrente è alto, il pulsante è passato da off a on  
  4.       ContatorePulsantePremuto++;  

poi dentro il if  usa altri if, if dentro if pero a me non funzionano usati per inserimento di codice come nell'immagine che ho disegnato (male scusate per questo)

infine non capisco bene questo, cioe come fa a collegare n ai 4 led e a fare la sequenza

  1. for (int x=0; x<5; x++) {                                // ciclo di accensione e spegnimento led  
  2.       for (int n=10; n<14; n++) {                            // ciclo sui diodi da accendere e spegnere  
  3.         digitalWrite(n, HIGH);     

 

anche usando gli if fuori dal primo if non cambia la situazione

qqwww.png

Link al commento
Condividi su altri siti

Francesco Querin

comunque mi e stato utile come idea per risolvere il problema, vorrei scrivere un programma che usi i case solo che come azionamento swicth usi il fine ciclo della funzione, cioe il pulsante di stop variabile pos =180 variabile pos = 0 analogRead>290 cioe il fine ciclo delle direzioni del motore del finecorsa e del sensore che regola la quantità di liquido, comandato da 3 pulsanti che decidono anche a un certo punto del programma a b o c ovvero bevanda 1 bevanda 2 bevanda 3 pulsante 1 e collegato a a pulsate 2 e collegato a b ecc.

Link al commento
Condividi su altri siti

Scusa Francesco ma io non riesco a capire molto bene quello che vuoi fare e quello che scrivi.

Non riesci a scrivere in italiano standard?:)

A scuola non ti hanno spiegato che per essere comprensibili bisogna far uso della punteggiatura e, possibilmente, usare periodi brevi?

 

Prova a descrivere il tuo problema con una descrizione dettagliata delle operazioni, serve anche come specifica per codificare il programma.

Una cosa che molti aspiranti ignorano è che una deswcrizione dettaglaita e chiara del problema, è praticamente la risoluzione del problema. La codifca diventa poi quasi automatica.

 

Vediamo se ho interpretato bene quello che vorresti fare.

 

Hai un pulsante.

Ogni volta che premi il pulsante incrementi un contatore.

Se il contatore vale zero non fai nessuna operazione.

Se il contatore assume un valore tra 1 e 6 compresi, esegui determinate operazioni.

Se il contatore raggiunge un valore >6 lo azzeri.

 

Questo potrebbe esser un modo.

 int icnt = 0;

........

 if icnt > 0
   {
     switch(icnt)
       {
		 case 1:
			funzione_a ();
		 break;
		 case 2:
			funzione_b ();
		 break;
		 case 3:
			funzione_c ();
		 break;
		 case 4:
			funzione_d ();
		 break;
		 case 5:
			funzione_e ();
		 break;
		 case 6:
			funzione_f ();
		 break;
     }
   }

Come puoi notare la descrizione ha praticamente definito il codice, è stata necessaria solo un'operazione di traduzione semplice.

TI rimangono da fare le due funzioni per interpretare il fronte di salita del pulsante e per movimentare il contatore.

Per verificare se il tutto punziona realizza le 6 gunzioni che fanno accendere ciascuna un solo LED differente (uno di 6).

Nota anche un particolare che sembra trascurabile.

Quando dichiaro il contatore come intero assegno un nome che inizia per "i", se fosse una variabile carattere sarebbe iniziata con "c"; mentre una lettera iniziale "b" indica una variabile booleana e "f" sta per flag.

Sembra una pignoleria fine a se stessa, ma quando dopo mesi rileggi un programma, magari molto lungo, capisci al volo che tipo di variabile stai usando

Link al commento
Condividi su altri siti

Francesco Querin

ci provo anche se non sono mai stato bravo in grammatica,

premo il pulsante 1

richiamo funzione 1, il motore va da me al distributore

il pulsante di stop finisce la corsa del motore e richiama la funzione 2

il servomotore ruota e inserisce il sensore di livello, che richiama funzione 3

il distributore versa il liquido il sensore ferma il distributore e richiama la funzione 4

il servo ruota ed estrae il sensore richiama la funzione 5

il motore va verso di me e il pulsante di stop ferma il motore

 

ricopiato per altre 2 volte, vorrei poi fare in modo di scrivere un solo programma che rileva quale dei pulsanti ho premuto. come in foto solo che oltre a far partire il programma il pulsante 1 determina che vera richiamata funzione 1 pulsante 2 funzione 2, in altre parole pulsante coca cola fara partire e versare la coca cola e il pulsante aranciata fara versare l'aranciataIMG_20170602_104650.thumb.jpg.4a1449a18f17ea293f1e5c6da34f43ed.jpg

Link al commento
Condividi su altri siti

Come sempre, pr prima cosa il programma va diviso in fasi elementari.

Per prima cosa devi fare una funzion che riconosca lo stato dei pulsanti, verifichi che lo stato sia stabile (antirimbalzo o debouncing) ed alzi il flags corrispondente.

Un tempo di antirimbalzo corretto è pari a 20ms.

void setup()
{
------------

 
  noInterrupts();
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1 = 6491;
  TCCR1B |= (1<<CS12);
  TIMSK1 |= (1<<TOIE1);
  iccz = 0;
  interrupts();
}
ISR (TIMER1_OVF_vect)
 {
   TCNT1 = 64911; //ricarica timer
   It_cntd--;
   if (It_cntd == 0)
    {
      It_cntd = 2;
      old_Run = b5;
      old_Down = b4;
      old_Up = b3;
      old_Men = b2;
      old_Ent = b1;
      b1 = digitalRead(2);
      b2 = digitalRead(3);
      b3 = digitalRead(4);
      b4 = digitalRead(5);
      b5 = digitalRead(7);
      comandi();
    }
}

L'esempio usa un interrupt a 10ms, sul timer1, come clok di macchina.

Ogni 20ms (decontggio di It_cntd) salva il precedente stato di 4 ingressi ed acquisisce il nuovo stato, richiama la funzione comandi, che nl caso dell'esempio è piuttosto complessa.

Tu potresti fare il test direttamente nella routine di servizio interrupt ed alzare i flags di strat e stop. Flag che saranno abbassati quando la funzione che ssi scatenano sarà iniziata.

Una volta che hai messo a punto i comadi comincia a scrivere una funzione alla volta ed a verificarla.

 

Link al commento
Condividi su altri siti

Francesco Querin

ok ci lavorero su, tre domande

prima domanda, attualmente nel mio programma ho il codice if(condizione) for(condizione) codice, dovrei creare una funzione in cui ce solo il codice cosi quando nel programma arrivo a richiamarla devo fare istruzione for(condizione) richiamo funzione.

seconda domanda ho pensato a qualcosa del tipo int bevanda1= digitalRead(buttonA), bevanda1=drest, cosi drst mi attiva il ciclo e arrivato a un punto swicth drest=case1, ripetuto per il pulsante 2 e per il pulsante 3.

terza domanda, ho trovato in giro la funzione void ho pensato di usare questa funzione e coretto.

cosa mi consigliate

 

Link al commento
Condividi su altri siti

Senti se non ti spieghi in modo comprensibile, con un minimo di punteggiatura e di frasi compiute, io mi rifiuto di cercare di interpretare quello che scivi.

Link al commento
Condividi su altri siti

Crea un account o accedi per commentare

Devi essere un utente per poter lasciare un commento

Crea un account

Registrati per un nuovo account nella nostra comunità. è facile!

Registra un nuovo account

Accedi

Hai già un account? Accedi qui.

Accedi ora
×
×
  • Crea nuovo/a...