Vai al contenuto
PLC Forum


arduino automa a stati o...


LorenzoBS

Messaggi consigliati

da una settimana mi sto dedicando ad arduino, ho gia' fatto i schemi piu semplici e seguito i programmi base compreso if ed else,

ora nella stragrande maggioranza di tutorial e progetti didattici,  vengono implementati nelle lezioni sensori aggiuntivi quali: infrarossi, temperatura,ecc.

al momento vorrei proseguire con l utilizzo di attuatori e sensori, piu' precisamente motore e microswitch,   ho fatto diverse prove con if ed else. ma sulla board poi non funzionavano. allora ho cercato di approfondire  automi a stati finiti. ed oltre al mal di testa ed aver cancellato tutto per andare a dormire non ho fatto nulla.

sono alla ricerca di lezioni, o sketch per riuscire a capire, come effettuare un ciclo di movimenti ad uno o più  attuatori, utilizzando diversi finecorsa.

Insomma... vorrei muovere qualcosa da un punto A ad un punto B ;-)

per ora.....

 

Link al commento
Condividi su altri siti


2 ore fa, LorenzoBS ha scritto:

Insomma... vorrei muovere qualcosa da un punto A ad un punto B 😉

 

A parte il fatto che oltre ai costrutti "if ... else ..." dovresti studiarti tante altre cose, prima di procedere con le macchine a stati, per realizzare quello che hai indicato hai comunque bisogno di alcuni trasduttori.

Il metodo più semplice è quello di avere 2 microswitches posizionati in A e B più un conmando di start ed uno di stop- Come uscite devi averne 2 una comanda il moto avanti e l'altro indietro.

Selezioni 4 pins di arduino come ingressi e metti 4 resistori da 4k7 (il valore non è molto importante) verso gnd.Poi battezzi gli ingressi coma A, B, marcia e stop.

Selezioni 2 pins come uscite e le battezzi come Avanti e Indietro, poi ti procuri 2 relè con doppi contatto di scambio e realizzi una configurazione ad "H" per comadare il motore.

Colleghi i 2 micro  switches tra +5V e gli ingressiA e B; colleghi i 2 pulsanti tra +5v e gli ingressi Marcia e Stop

 

Ora non ti resta che scrivere il programma di comando.

Devi Leggere gli ingressi marcia e stop; se, e solo se, il solo ingresso "marcia" è vero (alto) comandi la marcia.

Per scegliere se avanti o indietro leggi gli ingressi A e B; se tutti e 2 sono Falsi (bassi), allora comandi avanti per definizione, altrimenti comandi la marcia in modo che il tuo motore si muova verso il microswitch non impegnato (basso).

Poi leggi sempre lo stato dei micro switches e quello dell'ingresso di stop, ogni volta che un micro è impegnato (Vero o alto) inverti il senso di marcia.

Se l'ingresso di Stop è Vero (alto) togli la marcia.

 

Questo programma può essere successivamente migliorato, ma questo lo devi poi pensare tu vedendo le varie condizioni di lavoro.

Link al commento
Condividi su altri siti

Ieri sera purtroppo, non sono riuscito a metterci le mani, comunque riguardo lo studiare, ci sto provando. al momento sto ripartendo da zero, solo con if

con queste due righe voglio accendere un pin con un bottone, e spegnerlo con un altro. (fine corsa)

 

 

 

#define LED 13                // LED collegato al pin digitale 13
#define BUTTON 7              // pin di input dove è collegato il pulsante avvio
#define FINC 6              // pin di input dove è collegato il fine corsa
int val = 0;                  // si userà val per conservare lo stato dei pin di input
int stato = 0;                // ricorda lo stato in cui si trova il led, stato = 0 led spento, stato = 1 led acceso
 
void setup() {
  pinMode(LED, OUTPUT);       // imposta il pin digitale come output
  pinMode(BUTTON, INPUT);     // imposta il pin digitale come input
  pinMode (FINC, INPUT);      // imposta il pin digitale come input
}
 
void loop() {
  val = digitalRead(BUTTON);// legge iL valore dell'input e lo conserva
 
  // controlla che l'input sia HIGH (pulsante premuto)
  // e cambia lo stato del led
  if (val == HIGH) {
    stato = 1 - stato;
  } 
 
  if (stato == 1) {
    digitalWrite(LED, HIGH);   // accende il led

  val = digitalRead (FINC);     //legge valore fine corsa
    if (val == HIGH);
    digitalWrite(LED, LOW);    //spegne il led
  }
  
  }

non ho provato nulla sulla board, se riesco tento stasera.

sono in attesa anche di altri componenti acquistati online, per velocizzare la cosa.

grazie per l'aiuto.

Link al commento
Condividi su altri siti

del_user_97632

Bene, verifica che funzioni. Quando funziona il tuo metodo a if-then-else, ti do una traccia per migliorare.

 

Puoi provare come esercizio a utilizzare una semplcie macchina a stati.

 

/* define stupidi ma giusto per mostrare
 * come nominare gli stati */
#define STATO_0		0
#define STATO_1		1

static void init()
{
	/* inizializzazioni varie */
}

static linline int tasto_premuto()
{
	/* restituiosci 1 se il tasto e' premuto */

	return /* il tuo codice */ ? 1 : 0;
}

int main() {
	int stato = STATO_0;

	for (;;) {
		switch (stato) {
		case STATO_0:
			init();
			stato++;
			break;
		case STATO_1:
			/* qui cattura il tasto premuto */
			if (tasto_premuto())
				stato++;
			break;
		/* etc etc, altri stati, lascio a te completare */
		
		default:
			/* qui si entra nel caso in cui lo stato vada ad 
			 * un valore non contemplato sopra */
			break;
		}
	}
}

 

Specie nelle mcu poco potenti, lo switch case e' piu' performante di un catena di "if then elseif else".

La cpu non verifica tutte le condizioni if-then-else, che puo essere una lunga catena di costose assembly "cmp"  (compare, e spesso dunque jmp), ma semplicemente fa un unico "jmp" allo stato attuale, un paio di cicli di clock sempre e comunque.

 

 

Modificato: da _angelo_
Link al commento
Condividi su altri siti

3 ore fa, _angelo_ ha scritto:

Specie nelle mcu poco potenti, lo switch case e' piu' performante di un catena di "if then elseif else".

 

Non è detto, dipende dal compilatore. 

Ad esempio con il compilatore della CCS che ho sempre usato per i pic, se usano comparazioni booleane la sequeza if then else è più breve e veloce di quella "switch".

Questo lo so per certo perchè avendo avuto problemi di velocità su di un sitema di regolazione, ho dovuto limare al micron tutto, in alcuni caso ho inserito righe di asm proprio per "stressare" al limite la velocità.

Parafrasando un noto banchiere oramai defunto: le istruzioni non si contano, si pesano. Poi su alcune MCU di architettura RISC unb'istruzione vale l'altra in termini di cicli macchina.

 

Per mio conto entrambe le soluzioni semprano complicare un poco il semplicissimo problema; mentre manca un controllo fondamentale: l'antirimbalzo sul riconoscimento dello stato del pulsante.

Modificato: da Livio Orsini
Link al commento
Condividi su altri siti

del_user_97632
1 ora fa, Livio Orsini ha scritto:

Ad esempio con il compilatore della CCS che ho sempre usato per i pic, se usano comparazioni booleane la sequeza if then else è più breve e veloce di quella "switch".

 

Io parlo di   if elseif elseif elseif else   in C , si traduce in  

 

cmp

branch if not equal

cmp

branch if not equal

cmp

branch if not equal 

 

ripetuto per tutti gli else if, se il tuo caso si verifica all'ultimo, lo switch case e' piu veloce.

 

lo switch e' in ogni caso solo un jmp calcolato sommando l'offset legato allo stato, una somma e in salto in runtime.

 

1 ora fa, Livio Orsini ha scritto:

Poi su alcune MCU di architettura RISC unb'istruzione vale l'altra in termini di cicli macchina.

s-ni

Una nota frase che piace a molti e' che un RISC prende un ciclo di clock per istruzione. Come se lo fosse per definizione, beh circa, non e' proprio cosi, diciamo "spesso in un solo ciclo di clock", dipende dalla cpu.  Editato: si hai detto certe cpu dunque diciamo la stessa cosa.

 

Antirimbalzo sicuro da aggiungere :)

 

 

 

Modificato: da _angelo_
Link al commento
Condividi su altri siti

2 ore fa, _angelo_ ha scritto:

 

ripetuto per tutti gli else if, se il tuo caso si verifica all'ultimo, lo switch case e' piu veloce.

 

mentre se si verifica al primo è più lento:smile:

 

Quando si tratta di stressare al limite per la velocità allora si fa un'alisi statisca delle probabilità che un'evento accada, oppure qaule evento sicuramente accade più frequentemente  e si sceglie la strategia più adatta.

Ma queste sono considerazioni per analisti molto specializzati e, sopratutto, esperti in determiante applicazioni.

 

Qui stiamo cercando di aiutare un principiante, che sta imparando da autodidatta. Io ritengo si non solo inutile, ma anche dannoso, confondergli le idea con tentativi di ottimizzazioni che coinvolgono conoscenze a livello di traduzione del compilatore.

Se leggi un buon manuale, fatto da un buon didattico, per imparare a programmare arduino, segue proprio lastrada intrapresa da LorenzoBS (Brescia?). Si comincia ad usare eda capire il blocco decisionale If ... then ... else poi quando si domina bene questo costrutto si comincia a verificare altre strade.

Io tengo sempre a portata di mano la "bibbia" del "C" di Ritchie & Kerningham (ho scritto i nomi a memoria ma credo tu abbia capito che parlo del "ritcie"): Anche in quel manuale la strada è sempre quella: il primo blocco decisionale che si affronta è "if ... then .. else".

Se torno indietro di 50 anni, e più, e ripenso all'insegnamento di "calcolo automatico" , del corso di fisica ad indirizzo elettronico-informatico, quando si iniziava a studiare un linguaggio (allora il primo passo avveniva con il Fortran iv) la strada era sempre quella: il primo blocco decisionale si avvaleva del costrutto "if ... then ... else.

 

Io credo che prima di iniziare a pensa a come ottimizzare il tempo macchina sia più importante imparare ad ottimizzare la strategia di risoluzione di un problema.; non  a caso terminavo il mio intervento con:

Il 1/12/2019 alle 11:30 , Livio Orsini ha scritto:

 

Questo programma può essere successivamente migliorato, ma questo lo devi poi pensare tu vedendo le varie condizioni di lavoro.

 

Inoltre io son contrario, perchè lo ritengo poco didattico, fornire un codice sviluppato.

Ritengo sia meglio spiegare la logica con cui si deve affrontare il problema. Se la logica è corretta lòa codifica è praticamente automatica.

Link al commento
Condividi su altri siti

del_user_97632

 

27 minuti fa, Livio Orsini ha scritto:

mentre se si verifica al primo è più lento:smile:

 

Quando si tratta di stressare al limite per la velocità allora si fa un'alisi statisca delle probabilità che un'evento accada, oppure qaule evento sicuramente accade più frequentemente  e si sceglie la strategia più adatta.

Ma queste sono considerazioni per analisti molto specializzati e, sopratutto, esperti in determiante applicazioni.

hehehe  :) potrai darmi atto che forse il primo compare su 10 puo essre piu veloce di un add + jmp. Dal secondo al  10* no. In una lunga sequenza di if -elseif - elseif- xxxx - else poi ...  Nei piccoli micro non c'e' alcuna "branch-prediction", come nelle moderne cpu quindi e' bene sapere quel che e' piu performante. 

 

37 minuti fa, Livio Orsini ha scritto:

Qui stiamo cercando di aiutare un principiante, che sta imparando da autodidatta. Io ritengo si non solo inutile, ma anche dannoso, confondergli le idea con tentativi di ottimizzazioni che coinvolgono conoscenze a livello di traduzione del compilatore.

Se leggi un buon manuale, fatto da un buon didattico, per imparare a programmare arduino, segue proprio lastrada intrapresa da LorenzoBS (Brescia?). Si comincia ad usare eda capire il blocco decisionale If ... then ... else poi quando si domina bene questo costrutto si comincia a verificare altre strade.

Ma hai ragione che puo essre un passo piu avanzato. Tuttavia Lorenzo qui sta gia sbrigandosela bene con gli if then else, prossimo passo a mio avviso certamente capire una semplice macchina di stati (sono basi).
 

Nota che Il mio switch case e' poco piu di uno pseudo-code, non compila, apposta.

 

 

 

Link al commento
Condividi su altri siti

17 minuti fa, _angelo_ ha scritto:

atto che forse il primo compare su 10 puo essre piu veloce di un add + jmp.

 

Infatti io ho scritto: " mentre se si verifica al primo è più lento ", ovviamente è lo switch il più lento.

Poi, ti ripeto, queste cose si fanno quando si cerca di limirare il tempo macchina al picosecondo.

Quando faccio giochetti con arduino non sto certo a curare nemmeno il microsecondo, cerco solo la strada più sempliceal momento.

 

Forse tu andavi ancora alle elementari quando programmavo microelaboratori basati su 8085 con a disposizione 4 kbytes di EPROM e 256 bytes di RAM, eppure ci ho realizzato delle belle automazioni su macchine niente affatto semplici. Questo per farti comprendere che ho una certa pratica nell'ottimizzare e minimizzare il tutto, nello spremere dalla macchina il possibile e qualche cosa in più. Oggi dove i mega bytes si sprecano lavoro in tutto relax.:smile:

Link al commento
Condividi su altri siti

del_user_97632

Non capisco come il tuo CCM possa dare un risutlato piu performante. Il compilatore puo' ottimizzare al punto tale di darti lo stesso codice risultante di uno switch case, questo si, (e da vedere poi quali altri compilatori 8 bit lo fanno). Ma non capisco some possa essere piu veloce.

 

Gli if / elseif / else restano comodi e comunque inevitabili se usi variabili , ad esempio if (a == b). Una macchina a stati comunque spesso aiuta la leggibilita' del codice rispetto a piu lunghi serpenti di if / elseif / else.

 

Scusa se non espongo le cose in maniera piu accademica, non ne sono capace.


Tornando a Lorenzo, spero di non averti confuso, io ho suggerito lo switch / case come prossimo passo, visto che nessuno replicava, e visto che la macchina a stati in C la trovi tre le basi.

 

 

 

Link al commento
Condividi su altri siti

10 ore fa, _angelo_ ha scritto:

Non capisco come il tuo CCM possa dare un risutlato piu performante

 

Io uso PICC dell CCS, una vecchia versione per gli 8 bits; confronti e salti o non salti. Se salti sono 2 cicli, se non salti è un solo ciclo.

Questo avviene sia sul costrutto switch che sul costrutto if.

Dipende dal numero dei test che deve eseguire.Se i testi sono in numero eguale non c'è differenza.

I PIC appartengono a quei processori RISC in cui tutte le istruzioni impiegano un ciclo macchina, un ciclo non un clock.

Link al commento
Condividi su altri siti

sono qua...non mi son fatto spaventare dai tecnicismi descritti sopra 😂 

non sono riuscito a far funzionare il codice che avevo scritto inizialmente,

ho iniziato a scriverli su tinkercad per evitare di star li a infilare pin, con un bimbo piccolo a casa che la sera vuol giocare.

poi ho tentato anche con stati, qui ho fatto un casino, nonostante ho compreso in linea teorica la creazione degli stati, condizioni. non riesco a scrivere il codice.

ogni lettura affrontata mi lasciava qualche dubbio, ogni video che guardavo, affrontava lo stesso argomento in maniera differente. e peggiorava la situazione.

ora nel w.e. non mi rimane che cominciare da zero con un corso.  so bene che e' cosi' che si comincia, e non si deve andar di fretta, saltando capitoli,

ma non essendo interessato a pwm e tutte le parti dei sensori ecc.

sarei riuscito a trasferire il mio diagramma in testo. purtroppo mi rendo conto, che in quelle lezioni, forse avrei imparato  ulteriormente il funzionamento dell'IDE

Io invece, essendo interessato solo a comandare elettrovalvole e rele,  ho pensato che tutte le lezioni spese in sensori di umidita / temperatura/ infrarossi ecc. mi avessero soloconfuso il percorso.

magari sara veramente cosi... speriamo di no. ho scelto arduino  credendo di potermi avvicinare alla programmazione in maniera piu' easy di un plc.

staremo a vedere..

Link al commento
Condividi su altri siti

Ciao, non ho letto tutti i post precedenti, ma ti posso dire che per imparare a far funzionare qualcosa con arduino non è easy, ma bisogna capire bene cosa si sta facendo e cosa si vuole fare.

la cosa più semplice è comandare dei motori DC piccolini, i classici motorini che utilizzano le macchinine o vari giochini dei bambini per muoversi, funzionante anche con i 5V di arduino  cosi non hai bisogno di alimentatori esterni e li comandi direttamente dai pin di arduino.

Ci sono anche librerie da scaricare che aiutano nella programmazione per svariate cose, nel senso che nella libreria ci sono già scritti le varie funzioni che deve fare ad esempio il motore, e dal programma richiami semplicemente alcune funzioni.

Sinceramente a me non piace questo sistema perchè non si comprende appieno tutte le fasi.

Su youtube trovi molti video di assi lineari creati con arduino, alcuni molto ben fatti con spiegazioni passo passo.

Anche io qualche anno fa ho realizzato una cosa del genere, e mi sono costruito questo. Non è stato facile per me perchè non avevo mai visto il linguaggio di programmazione, essendo un progettista meccanico e come te ho trovato molto materiale tutto diverso e alla fine mi sono realizzato il programma quasi da zero, ci ho messo parecchio anche se di poche righe, ma ho capito molto.

Nei link del mio video di youtube trovi il link per github dove trovi il programma e il link di grabcad dove puoi scaricare il progettino in 3D per ricavarti i vari pezzi.

Io ho utilizzato quasi tutto da recupero, tranne le cinghia e il driver. 

Ora sono passato da arduino a Nodemcu ESP8266 che ritengo un prodotto ottimo in rapporto qualità prezzo e sto portando avanti questo progetto

 

Link al commento
Condividi su altri siti

  • 1 month later...

cambiato automazione, questa volta un imbottigliatrice. comunque questo e' il meglio che son riuscito a capire con il poco tempo impiegato per studiare.

(mia moglie mi ha regalato un abbonamento a netfix)..

so che ho fatto diversi errori, bacchettatemi pure, ma fatemi capire.

 

// automazione riempitrice e tappatrice bottiglie pneumatica.
//la meccanica richiede un cilindro pneumatico alimentato da elettrovalvola per il riempimento
//un cilindro pneumatico per la tappatrice 
//un piatto girevole per posizionare le bottiglie su stazione
// finecorsa induttivo per centraggio posizione del piatto
int stato = 1;
#define piatto 13;  // motore che ruota il piatto per posizionare le bottiglie sotto le stazioni
#define tapp  12;   // comanda elettrovalvola tappatrice
#define filling 11; // comanda elettrovalvola per il riempimento
#define pos 10;      // legge la posizione del piatto
#define start 9;     //avvia il ciclo
#define pieno 8;     //segnala la bottiglia piena

void setup() {
  pinMode (piatto , OUTPUT);
  pinMode (tapp , OUTPUT);
  pinMode (filling , OUTPUT);
  pinMode (pos , INPUT);
  pinMode (start , INPUT);
  pinMode (pieno , INPUT);
  // put your setup code here, to run once:

}

void loop() {
  // put your main code here, to run repeatedly:
  switch (stato)
    case 1;
        digitalWrite (piatto, HIGH);
        if digitalRead (pos == HIGH) stato = 2;
    break;
    case 2;
        digitalWrite (piatto, LOW);
        delay (500);
        digitalWrite (filling, HIGH);
        digitalWrite (tapp, HIGH);
        delay (3000);
        digitalWrite (tapp, LOW);
        if digitalRead (pieno == HIGH) stato = 3;
    break;
    case 3;
        digitalWrite (filling, LOW);
        delay (500);
        digitalWrite (piatto,HIGH);
        if digitalRead (pos == HIGH) stato = 2
    break;
 

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