Vai al contenuto
PLC Forum


automazione bloccata


Francesco Querin

Messaggi consigliati

Francesco Querin

devo automatizzare una sequenza e fin qui va tutto bene ho i codici gia fatti, il problema che mi blocca e questo

if (condizione) codice e metto un if (condizione)codice

fin qui va tutto bene, premo il motore gira premo il secondo pulsante il servo ruota ora

if (condizione) codice e metto un if (condizione)codice ci aggiungo if (condizione) codice

si blocca dopo la ruotazione del servo, premo pulsante 1 parte il motore premo pulsante 2 si blocca il motore ruota il servo premo il pulsante 3 non si accende il rele.

 

secondo problema

 
int pongo;
int variabile=0;
int gelato;
if(digitalRead(buttonA)==HIGH){ variabile=1;}
if(variabile=(1)){ delay(1000); pongo=LOW;}
if(digitalRead(buttonA)==HIGH and pongo==LOW){ delay(1000); gelato=HIGH;}
if(gelato==HIGH and digitalRead(buttonA)==HIGH){ variabile=2;}
 
 switch(variabile){
  case 1:
  a();
  break;
  case 2:
  e();
  break ;
 
risultato 1 non funziona, rusultato 2 va diretto ai rele, risultato 3 parte il caso 1 senza comando, ce qualche programma simile al caso mio da studiare e capirci qualcosa, ho pulsante di avvio, pulsante di stop, servomotore, sensore di livello.
devo premere il pulsante, far partire il motore, fermarsi al  pulsante di stop, ruotare il servo che inserisce il sensore, attivare le elettrovalvole, raggiunto la soglia spegnere le elettrovalvole, ruotare il servo estraendo il sensore, parte il motore in senso inverso e si ferma al pulsante di stop.
 
uso la funzione void a () {codice} per evitare sequenze fuori fase penso di usare la fine di un istruzione come inizio di un altra istruzione.
non so più che fare
Link al commento
Condividi su altri siti


Se vuoi avere un aiuto, descrivi esattamente in italiano standard le operazioni che vorresti compiere nelle loro esatta sequenza.

 

Esempio:

Se l'ingresso 1 è vero attivo l'uscita 3.

Se luscita 3 è vera e l'ingresso 2 è vero apro l'uscita 3 e attivo l'uscita 2 per 5".

Se.......

Link al commento
Condividi su altri siti

Francesco Querin

premo il pulsante bevanda 1 e il nastro con il bicchiere si sposta al distributore.

arriva al sensore di presenza e si ferma, il sensore comanda il servomotore.

il servomotore ruota, al servo e attaccato il sensore di livello, ruotando il servo inserisce il sensore.

finita la rotazione del servo le elettrovalvole si aprono.

finito di riempire il sensore chiude le elettrovalvole.

il sensore fa ruotare il servo che toglie il sensore di livello.

il sensore fa partire il nastro con il bicchiere verso di me fino al secondo sensore di presenza che ferma il nastro.

 

ripetuto per il pulsante di bevanda 2 e per il pulsante di bevanda 3

il nastro e comandato da dei motori passo passo, le elettrovalvole sono comandate da una scheda rele a logica negativa, ho un driver semplicissimo e ho fatto tutta la sequenza avanti/indietro su arduino

Link al commento
Condividi su altri siti

Bene definita la sequnza che devi realizzare che cosa non funziona?

Mi sembra semplicissima.

 

Ne metti a punto una, poi le altre due sono uguali, devi solo cambiare il parametro relativo alla bevanda da erogare.

Link al commento
Condividi su altri siti

Francesco Querin

metto dei pulsanti per simulare i sensori

if (pulsante premuto 1)

{codice motore andata

if (pulsante premuto 2) sensore di stop motore e avvio servo

{servo in posizione 180

fin qui tutto bene e funzionante

if (pulsante premuto 3)  simulo le elettrovalvole con i rele accesi, ma non funziona e cosi il resto del codice

{codice rele }}}

 

2 versione con case

if (pulsante premuto){variabile=1}

if (variabile=1){aspetta 1 secondo e variabile 2 =basso}

if ( pulsante premuto e variabile 2= basso) { aspetta 1 secondo e variabile 3 = alto}

if (pulsante premuto e variabile 3 = alto) { variabile=2}

non funziona, ho parte subito, ho parte direttamente a 2 appena premo il pulsante.

 

Link al commento
Condividi su altri siti

Ma il programma legge lo stato del pulsante 3? fatti un debug buttanto lo stato sulla seriale così lo leggi da PC mentre il programma gira.

Link al commento
Condividi su altri siti

Francesco Querin

in teoria si perché faccendo dei piccoli programma come premo pulsante accendo il rele ho testato praticamente tutto l'hardware che mi serve, ho testato il sensore di levello, il sensore di presenza , il servo,il motore , il rele e i pulsanti, tutto funziona provero il debug

Link al commento
Condividi su altri siti

Se poi magari scrivessi i programmi in modo più ordinato e secondo la consuetudine, sarebbe più facile anche per te capire gli eventuali errori.

int pongo;
int variabile=0;
int gelato;
if(digitalRead(buttonA)==HIGH){ variabile=1;}
if(variabile=(1)){ delay(1000); pongo=LOW;}
if(digitalRead(buttonA)==HIGH and pongo==LOW){ delay(1000); gelato=HIGH;}
if(gelato==HIGH and digitalRead(buttonA)==HIGH){ variabile=2;} 

   //Diventa   
      
  int pongo;
  int variabile=0;
  int gelato;
  if(digitalRead(buttonA)==HIGH)
     { 
        variabile=1;
      }
   if(variabile=(1))
      { delay(1000); 
         pongo=LOW;
       }
   if((digitalRead(buttonA)==HIGH and pongo==LOW))
      { 
          delay(1000); 
          gelato=HIGH;
      }
   if((gelato==HIGH) and (digitalRead(buttonA)==HIGH))
      {
         variabile=2;
      } 

 

Link al commento
Condividi su altri siti

Francesco Querin
non ho idee, se faccio if condizione variabile = 1 e case 1 funziona se metto più case o l'intero programma niente non ho idee per risolvere sto problema. forse dovrei pulire il segnale ma non so dove pulirlo.
Link al commento
Condividi su altri siti

Ti do un consiglio, cerca di non usare i cicli while, perchè se non stai bene attento non esci più dal ciclo ed il programma si blocca li.

 

La tua automazione è una semplice sequenza di operazioni che saranno eseguite secondo le condizioni dei segnali in ingresso.

 

Quando si devono acquisire segnali digitali da contatti, si usa acquisirli a tempi fissi di, ad esempio, 10 ms, così si confrontano gli stati della lettura attuale con quelli della precedente e, se i due stati sono identici si copia lo stato in un registro che verrà usato per le elaborazioni del programma. In questo modo si effettua un filtro di debouncing (antirimbalzo).

Io solitamente uso il timer1 per avere un interrupt ogni 10ms e nella routin di servizio leggo gli ingressi ed aggiorno la tabella attuale e precedente.

 

Poi in macchine come la tua si fa la scelta dell'operazione tramite "case"; nel ciclo di case la prima condizione vera richiama la funzione legata a quel comando.

 

Lì puoi fare un ciclo di while, ma devi assicurarti bene che il programma ne possa uscire una volta che il ciclo è concluso.

 

Per debuggare il software fai quello che ti dicevo in precedenza.

Comincia a far eseguire una funzione alla volta.

Per essere sicuro che il programma esegua i cicli come previsto metti delle variabili di memoria che vengono azzerate ad ogni inizio ciclo e poi vengono alzate nei punti strategici. Ogni volta che il programma passa in uno di questi punti, dopo aver scritto la variabile scrivila con un Serial.println(...); così la puoi visualizzare in tempo reale sull'uscita della seriale (Ctrl+Shif+m).

 

Link al commento
Condividi su altri siti

Francesco Querin
https://pastebin.com/TdkA1Bvz nel link ho scritto anche i problemi, pensavo di fare qualche sorta di debouncing che se legge un istruzione ignori completamente le altre 2 fino a rest del programma con qualcosa del tipo come negli esempi qua fatti https://github.com/thomasfredericks/Bounce2
qualcosa di simile. oppure qualcosa del tipo
#define buttonA != buttonB and buttonC 
buttonA=digitalRead(pin assegnato)
if (buttonA==HIGH) {codice}
 
 
Link al commento
Condividi su altri siti

Il problema con arduino è che, essendoci valanghe di librerie se software pronto in circolazione sulla rete, molti si cimentano in lavori che sono al disopra delle loro conoscenze.

Se il alvoro bene o male funziona, non hanno imparato molto; altrimenti si trovano di fronte a difficoltà insormontabili.

 

Dopo questo cappello, vediamo il tuo problema.

 

E' dall'inizio che cerco di spiegarti la metodologia di lavoro.

Il software è un problema di logica e metodo.

Bisogna fare i passi della giusta lunghezza, in proporzione alle conoscenze personali.

 

Tu vuoi realizzare una macchina che esegue 3 funzioni differenti, anche se simili tra loro.

 

La funzione base, se non ho capito male è:

  • Riconosco la pressione di un pulsante
  • Se ho premuto il pulsante muovo un motore in una determinata posizione.
  • Al termine del movimento un sensore riconosce la presenza di un oggetto (bicchiere), se loggetto è presente eseguo un riemimento.
  • Al termine del riempimento riposiziono l'oggetto al punto di partenza
  • Quando l'oggetto è ritornato al punto di partenza la macchina è pronta per un nuovo ciclo.

Ora io ti consiglio di accantonare tutto quello che hai fatto e ripartire da zero.

Comincia con scrivere le operazioni elementari seguendo una traccia simile a quela che ho scritto. Verifica l'esatto funzionamento della prima funzione; solo quando hai verificato che tutto funziona regolarmente passi al secondo passo.

In questo modo ti costruisci una serie di mattoncini di base e li colleghi uno dopo l'altro lasciandoti alle spalle solo un qualche cosa di perfettamente funzionante.

 

Scrivere tutto assieme e poi provare, non è mai un buon metodo anche quando si è più esperti.

Link al commento
Condividi su altri siti

Francesco Querin
l'ho fatto, ho testato
if ( digitalRead(buttonA)==HIGH)
{
variabile=1;
alpha=HIGH;
}
e funziona cambio con
if ( digitalRead(buttonA)==HIGH)
{
variabile=1;
beta=HIGH;
}
vedendo che il codice funziona, infatti azziono pompa ed elettrovalvola selezionata arrivo a scrivere
if ( digitalRead(buttonA)==HIGH)
{
variabile=1;
alpha=HIGH;
}
if ( digitalRead(buttonA)==HIGH)
{
variabile=1;
beta=HIGH;
}
if ( digitalRead(buttonA)==HIGH)
{
variabile=1;
gamma=HIGH;
}
e qui non funziona più la chiamata e parte automaticamente la parte in cima nel case 2, penso sia un problema di sovraposizione.
Link al commento
Condividi su altri siti

A me sembra che non esca mai dal while(memoria==HIGH) .

Traccia quando entra nel case 2 e tracciane il percorso e le relative variabili.

Link al commento
Condividi su altri siti

ciao, non mi sono messo a guardare nei dettagli il programma per noia... ma sei sicuro che il problema non capiti quando vanno in funzione le elettrovalvole che disturbano arduino?

Link al commento
Condividi su altri siti

Francesco Querin

le elettrovalvole sono collegate ai rele e sto testando su altri rele non collegati a nulla, i rele semplicemente sono per gestire un carico a tensione superiore a quella di arduino, uso rele comandati a 5V  per carico a 24V.

non credo sia HW il problema

Link al commento
Condividi su altri siti

Francesco Querin

https://pastebin.com/LZwP878x

praticamente gli if che dovrebbero selezionare il codice dentro il while non funzionano, cioe se premo il pulsante nel while non si mette il codice dell'if corrispondente.

mi sono dimenticato i rele sono una scheda a logica negativa quindi i rele sono LOW per accesi e HIGH per spenti ho coretto ma nel file sono in HIGH invece di LOW.

if/else lo spostato al di fuori del while e non ho risolto nulla adesso nel file aggiornato e al di fuori del while mentre il break rimane all'interno del ciclo while

Link al commento
Condividi su altri siti

Non è che la spiegazione sia chiarissima.

 while(memoria==HIGH)
  {
   
  if(alpha==HIGH)
  {
     digitalWrite(rele1, HIGH);
     digitalWrite(rele2, HIGH);
  }

Stai forse dicendo che, ad esempio, questo if non funziona?

Hai provato a verificare con:

 while(memoria==HIGH)
  {
   Serial.println(alpha);
   if(alpha==HIGH)
  {  
     digitalWrite(rele1, HIGH);
     digitalWrite(rele2, HIGH);
	 Serial.println(rele1);
	 Serial.println(rele2);
  }

 

Link al commento
Condividi su altri siti

Francesco Querin

ai raggione e mi scuso per la poca chiarezza della risposto. Ho provato come ai detto tu ma non funziona il monitor seriale del ide di arduino e bianco, ho messo Serial.println(cocacola); sul pulsante 1 sotto Alpha ma ho visto solo 0, cosi ho metto Serial.println(5); sotto Alpha e premendo vedevo comparire i 5 provato anche su beta e gamma con 3 e 9, e tutti e 3 funzionano.

Link al commento
Condividi su altri siti

Francesco Querin
if(digitalRead(buttonC)==HIGH)
{
  gamma=HIGH;
  memoria=HIGH;
}
 
  while(memoria=HIGH)
 
non funziona ma
 

if(digitalRead(buttonC)==HIGH)
{
  gamma=HIGH;
}
 
  while(alpha==HIGH or beta==HIGH or gamma==HIGH)
 
cosi funziona, apparte lo stop del ciclo, la variabile  memoria non funziona, come se Alpha andasse in HIGH e LOW mentre memoria non aquisisce stato quindi non essendo in HIGH non fa iniziare il ciclo.
 
 
Link al commento
Condividi su altri siti

Scusa se " gamma==HIGH; " e "memoria==LOW;" significa che o hai un problema nella dichiarazione della variabile memoria, oppure che c'è qualche istruzione che l'azzera.

 

Fantasmi dispettosi che fanno impazzire i programmatori, non esistono, esistono solo stupidate di programamzione difficili da scoprire.:)

 

Debaggare un programma è un compito che richiede metodo e molta pazienza, specialmente quando si è alle prime armi.

per questo motivo è meglio spezzare il problema in tanti mattori elementari che si mettono a punto uno alla volta.

Link al commento
Condividi su altri siti

Francesco Querin
come al solito dopo un po mi viene in mente un altro modo di vedere le cose e cosi funziona, solo non capisco perché non posso fare bevanda=rele1 bevanda =rele2, pero ho testato e ritestato e funziona, tra l'altro e piu semplice.
 
ora metto nel programma completo e non funziona, metto serial.print per vedere quando e nel case 2 se funziona appunto sul monitor seriale. questo non accade non vedo scritto case 2 sulla seriale.
Link al commento
Condividi su altri siti

Se non lo leggi è perchè non entra in case 2.

Prima di entrare in switch metti un serial.println(varaiabile) così vedi il valore assegnato.

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...