PULSANTE START E PAUSA PROGRAMMA

Ciao a tutti , ho fatto un semplice programma per muovere 4 motori in continua con Arduino uno ; ho questo problema :

-Vorrei far partire il programma con un pulsante e non alimentando arduino , non direttamente quando do tensione

  • Vorrei mettere un pulsante per stoppare il programma in qualsiasi momento( tipo stop emergenza ) e poi premendo di nuovo riprendere da dove si è interrotto il programma .

Vi ringrazio in anticipo per l'aiuto
Grazie a tutti
Paolo

Allego mio programma

#include <AFMotor.h>

AF_DCMotor motor1(1); 

AF_DCMotor motor2(2); 

AF_DCMotor motor3(3); 

AF_DCMotor motor4(4); 
 
void setup()
{
  motor1.setSpeed(100); 
  motor2.setSpeed(100); 
  motor3.setSpeed(100); 
  motor4.setSpeed(100); 
}
 
void loop()
{
  
  motor1.run(BACKWARD); 
  delay(4000);
  motor1.run(FORWARD); 
  delay(3000);
  motor1.run(RELEASE);
  
  motor2.run(FORWARD); 
  delay(4000);
  motor2.run(BACKWARD);
  delay(3000);
  motor2.run(RELEASE); 
  
  motor3.run(BACKWARD); 
  delay(4000);
  motor3.run(FORWARD); 
  delay(3000);
  motor3.run(RELEASE); 
  
  motor4.run(FORWARD); 
  delay(4000);
  motor4.run(BACKWARD); 
  delay(3000);
  motor4.run(RELEASE); 

  motor1.run(BACKWARD);
  motor2.run(FORWARD);
  delay(4000);
  motor1.run(FORWARD);
  motor2.run(BACKWARD);
  delay(3000);
  motor1.run(RELEASE);
  motor2.run(RELEASE); 

  motor3.run(BACKWARD);
  motor4.run(FORWARD);
  delay(4000);
  motor3.run(FORWARD);
  motor4.run(BACKWARD);
  delay(3000);
  motor3.run(RELEASE);
  motor4.run(RELEASE); 

  motor2.run(FORWARD);
  motor3.run(BACKWARD);
  delay(4000);
  motor2.run(BACKWARD);
  motor3.run(FORWARD);
  delay(3000);
  motor2.run(RELEASE);
  motor3.run(RELEASE);

  motor1.run(BACKWARD);
  motor4.run(FORWARD);
  delay(4000);
  motor1.run(FORWARD);
  motor4.run(BACKWARD);
  delay(3000);

  motor1.run(RELEASE);
  motor4.run(RELEASE); 
  motor1.run(RELEASE); 
  motor2.run(RELEASE); 
  motor3.run(RELEASE);  
  motor4.run(RELEASE); 

  delay(10000);

  exit(0);
}

programma prototipo senza stop.txt (1.54 KB)

Leggi il regolamento e posta il codoce in modo corretto, modificando il post precedente

Psocks: Come ti è già stato fatto notare, 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).

In pratica, tutto il tuo codice dovrà trovarsi racchiuso tra due tag: [code] _il _tuo_ codice_ [/code] così da non venire interpretato e non dare adito alla formazione di caratteri indesiderati o cattiva formattazione del testo. Grazie.

Guglielmo

Ho dato uno sguardo, prima quando era leggibile, pur se male.
Il problema è un uso improprio di delay
Purtroppo il programma va riscritto, ripensato in funzione di una macchina a stati, stati determinati da una variabile che tenga traccia del tempo
In parole povere? Cerca tra i mille mila post che parlano di millis al posto di delay

>Psocks: Ti sembra di aver messo il programma in una forma leggibile? Pensi che qualcuno riesca a capirlo e quindi aiutarti? Ma li rileggete i vostri post dopo averli scritti/modificati ? ? ? :o :o :o

Prendi il tuo programma con l'IDE di Arduino, usa la funzione di indentatura automatica (Strumenti -> Formattazione Automatica) elimina le inutili righe vuote e, quando finalmente sarà in una forma leggibile, rimettilo al suo posto, tra i tag code. Grazie.

Guglielmo

Standardoil:
Purtroppo il programma va riscritto...

Quoto, se non si è notato :wink:

Devi eliminare tutti i delay e ripensare il tutto temporizzando in modo differente usando millis.

Con millis, più che un orologio, hai un cronometro che misura il tempo da quando hai dato il via e tu devi dire, quando sono passati 10s avvia il motore 1, quando sono passati 13s spegnilo e accendi il 2, quando sono passati 15s spegnilo e accendi il 3 ecc.

Premesso che il codice non è un gran che vista la sequenza assolutamente fissa e l'uso di tanti delay() (sarebbe da rivedere, come ti hanno suggerito, ma se per te per ora va bene così come prototipo almeno ok ma studiati la funzione millis()), direi che per fare quello che chiedi una soluzione sia questa sotto. Non è neanche la mia una soluzione ottimale né particolarmente elegante, ma è quella con "minimo impatto" sul tuo codice.
(vedi cosa ho cambiato e cerca di capire perché, poi se proprio non ne vieni a capo puoi sempre chiedere qui)

#include <AFMotor.h>

AF_DCMotor motor1(1); 
AF_DCMotor motor2(2); 
AF_DCMotor motor3(3); 
AF_DCMotor motor4(4); 

// Pin del pulsante (con AF Motor hai solo il pin 2)
#define PLAYPAUSE 2
// Flag
volatile bool play = false;

void setup()
{
  motor1.setSpeed(100); 
  motor2.setSpeed(100); 
  motor3.setSpeed(100); 
  motor4.setSpeed(100); 
  // Se possibile mettere un debounce hardware
  attachInterrupt(digitalPinToInterrupt(PLAYPAUSE), button, RISING);
}
 
void loop()
{
  waitRun()
  motor1.run(BACKWARD); 
  delay(4000);
  motor1.run(FORWARD); 
  delay(3000);
  motor1.run(RELEASE);
  waitRun()
  motor2.run(FORWARD); 
  delay(4000);
  motor2.run(BACKWARD);
  delay(3000);
  motor2.run(RELEASE); 
  waitRun()
  motor3.run(BACKWARD); 
  delay(4000);
  motor3.run(FORWARD); 
  delay(3000);
  motor3.run(RELEASE); 
  waitRun()
  motor4.run(FORWARD); 
  delay(4000);
  motor4.run(BACKWARD); 
  delay(3000);
  motor4.run(RELEASE); 
  waitRun()
  motor1.run(BACKWARD);
  motor2.run(FORWARD);
  delay(4000);
  motor1.run(FORWARD);
  motor2.run(BACKWARD);
  delay(3000);
  motor1.run(RELEASE);
  motor2.run(RELEASE); 
  waitRun()
  motor3.run(BACKWARD);
  motor4.run(FORWARD);
  delay(4000);
  motor3.run(FORWARD);
  motor4.run(BACKWARD);
  delay(3000);
  motor3.run(RELEASE);
  motor4.run(RELEASE); 
  waitRun()
  motor2.run(FORWARD);
  motor3.run(BACKWARD);
  delay(4000);
  motor2.run(BACKWARD);
  motor3.run(FORWARD);
  delay(3000);
  motor2.run(RELEASE);
  motor3.run(RELEASE);
  waitRun()
  motor1.run(BACKWARD);
  motor4.run(FORWARD);
  delay(4000);
  motor1.run(FORWARD);
  motor4.run(BACKWARD);
  delay(3000);
  waitRun()
  motor1.run(RELEASE);
  motor4.run(RELEASE); 
  motor1.run(RELEASE); 
  motor2.run(RELEASE); 
  motor3.run(RELEASE);  
  motor4.run(RELEASE); 
  waitRun()
  delay(10000);
}

void button()
{
  play = !play;
}

void waitRun()
{
  while ( !play ) { };
}

Ciao DocDoc , hai ragione ma purtroppo sono un principiante di Arduino e il mio programma base è molto semplice e con errori.
Ti chiedo ho notato la funzione wait run () tra i movimenti dei motori , questo comporta che devo premere il pulsante dopo ogni movimento oppure serve come punto di restart quando vado a stoppare ?
Intanti Grazie mille cmq

Provo a spiegarti come funziona, mettendoti anche i link al reference del linguaggio.

Ho introdotto la variabile "play", booleana, la quale dice al programma se debba eseguire le istruzioni (quando vale "true") o meno (quando vale "false").

La waitRun() come puoi vedere ha solo una istruzione:

while ( !play ) { };

questo significa che esce di lì solamente quando la variabile "play" diventa "true" ("!" è l'operatore NOT, quindi leggila come "not play" ovvero "play == false")

Dato che quella variabile cambia di stato (da false a true e viceversa) ad ogni pressione di tasto grazie alla attachInterrupt la quale dice che ad ogni pressione (RISING ossia cambio di stato da LOW a HIGH) viene eseguita tramite la funzione button() nella quale se la variabile "play" è "false" diventa "true" e viceversa.

Quindi dovunque tu metti la waitRun() sarà un punto di "pausa" ossia se lo stato attuale è "true", uscirà subito quindi eseguirà le istruzioni successive, mentre se è "false" non prosegue. Messa tra uno "step" di movimento ed il successivo, consente quindi di "fermare" l'esecuzione, e riprenderla esattamente da dove si era fermato.

Ripeto, non è la soluzione più elegante ma quella più "indolore" per il tuo codice attuale, ne ho approfittato per introdurti alla attachInterrupt() che è sempre utile conoscere. Per future estensioni o rivisitazioni ti conviene usare la millis() ed una macchina a stati finiti, tutte cose che penso attualmente siano superiori alle tue conoscenze, ma piano piano ti conviene avvicinartici. E come dico sempre, non buttarti a capofitto con troppe cose "nuove", affrontale sempre una alla volta, studia quello che hai visto di "novità" e procedi

Grazie ancora dei preziosissimi consigli DocDoc!!ti aggiornerò sui progressi!!se ne faccio!!hahaha!!!ciao e alla prossima !!!ps grazie anche agli altri!!! :slight_smile:

Ciao DocDoc ho provato con il tuo programma ma mi da erroe : Arduino:1.8.8 (Windows 7), Scheda:"Arduino/Genuino Uno"

  In function 'void loop()':

sketch_mar12a:26:1: error: expected ';' before 'motor1'

motor1.run(BACKWARD); 

^

sketch_mar12a:32:3: error: expected ';' before 'motor2'

  motor2.run(FORWARD); 

  ^

sketch_mar12a:38:2: error: expected ';' before 'motor3'

 motor3.run(BACKWARD); 

 ^

sketch_mar12a:44:3: error: expected ';' before 'motor4'

  motor4.run(FORWARD); 

  ^

sketch_mar12a:59:3: error: expected ';' before 'motor3'

  motor3.run(BACKWARD);

  ^

sketch_mar12a:68:3: error: expected ';' before 'motor2'

  motor2.run(FORWARD);

  ^

sketch_mar12a:77:3: error: expected ';' before 'motor1'

  motor1.run(BACKWARD);

  ^

sketch_mar12a:84:3: error: expected ';' before 'motor1'

  motor1.run(RELEASE);

  ^

sketch_mar12a:91:3: error: expected ';' before 'delay'

  delay(10000);

  ^

exit status 1
expected ';' before 'motor1'

Mancano i ; dopo ogni waitRun()

ho posizionato ; corretti ma non funziona.....collegando pin 2 non bolcca nulla e appena do alimentazione parte il programma nn aspetta un mio start da pulsante. :confused:

Magari delleresistenza di pull-down sul pulsante?
la butto li', senza aver ben guardato, ma ho l'impressione che siano molto utili......

Psocks:
collegando pin 2 non bolcca nulla e appena do alimentazione parte il programma nn aspetta un mio start da pulsante. :confused:

Se leggi il programma il pulsante è normalmente LOW e si considera premuto quando diventa HIGH. Quindi devi collegare una resistenza di pull-down dal pin a GND, e dal pin il pulsante a Vcc. Tu come hai collegato il pulsante?

Però lasciami dire una cosa: il ";" finale è stata una mia svista, ma se non sai che i comandi finiscono sempre con ";" (altrimenti te ne saresti accorto da solo quando hai letto quell'errore) e non hai compreso come funziona quella istruzione attachInterrupt nonostante te l'abbia descritta ("RISING ossia cambio di stato da LOW a HIGH") e quindi capire che il pulsante deve avere una resistenza di pull-down, temo che dovresti impegnarti un poco di più e non "buttare a massa nel forum" qualsiasi piccolo intoppo che riscontri, non ti pare? Prova, cerca in rete, sbattiti un attimo prima di rinunciare e chiedere aiuto, altrimenti impari poco...

Concordo in pieno