Start programma, stop e memoria posizione

Rileggi tutto perché ti sfuggono troppe cose.

  1. La pausa è un "algo safety", non può essere realizzata tagliando l'alimentazione.
  2. L'utente è principiante, per cui millis è ancora un mistero, mentre delay è intuitivo e ha dimostrato di saperlo usare. Per questo motivo non posso dirgli di usare puntatori, alias, struct, array e in genere tutte le armi che un programmatore C/C++ usa per implementare gli algoritmi.
  3. Posta tu un esempio di codice adatto ad un principiante.

PS: ma a me cosa importa della pegou, citro e della crys, per le chiacchiere c'è lo spambar.

Ciao.

il fungo quindi rimane, almeno una cosa è assodata

adesso parliamo del ciclo di lavoro
per lo OP:
cosa deve fare , descritto bene, non mettere un video,
perchè a programmare devi imparare tu, io sono capace
quindi cominci col passo 1:descrizione ed analisi del problema

ovvero?
spiega per quelli meni istruiti di te, grazie

Concordo. Alla pressione del fungo deve essere eseguito più o meno il seguente algoritmo:

PinAct safetyAlgo[] = {
    {.pin = PIN_EV_OLIO, .state = LOW, .pause = 0}
  , {.pin = PIN_EV_VACUM, .state = LOW, .pause = 0}
  , {.pin = PIN_VACUM_PUMP, .state = LOW, .pause = 0}
  , {.pin = PIN_EV_ARIA, .state = HIGH, .pause = 3000}
  , {.pin = PIN_EV_ARIA, .state = LOW, .pause = 0}
//              ^__pin      stato_^      ^__pause dopo la digitalWrite(.state)
  , { 0 }
};

Trattandosi di un comando di emergenza deve essere eseguito immediatamente.

L'algoritmo principale viene messo in pausa e l'algoritmo di sicurezza viene eseguito in modo bloccante. Terminato l'algoritmo di sicurezza il pulsante play avvia l'algoritmo principale, ripetendo il ciclo in cui era stato interrotto. Il contatore di ripetizioni dell'algoritmo principale non si azzera dopo avere premuto il fungo.

L'algoritmo principale è quasi descritto al post:Start programma, stop e memoria posizione - #7 by saettajhones
Ma sarebbe bene dare un nome a pin più specifico che portvac che ad esempio ho dato per scontato sia un elettrovalvola per cui gli ho assegnato il nome PIN_EV_VACUM, ma non so se è corretto.

Per cui @saettajhones se dai un nome più significativo tutto in maiuscolo che non sia troppo lungo, puoi a seguire riepilogare cosa deve fare l'algoritmo principale.

Ciao.

Ok che sia un fungo o un pulsante per me è uguale basta che non tolga corrente a tutto altrimenti sarebbe sufficente il pulsante on off che uso per alimentare arduino, come ben dicevi tu prima lui deve memorizzare da dove era rimasto alla PAUSA e se togli corrente non penso sia un bel lavoro, o sbaglio?

Prima di proseguire in questa direzione faccio una domanda sempre da principiante, a stò punto può essere più facile per iniziare a programmare una soluzione diversa? Per il mio scopo può funzionare comunque ma magari è meno incasinata come programmazione, chiedo da ignorante ovviamente, se è un opzione del cavolo la chiudo subito lì e continuo come prima.
Per quanto riguarda alcuni post vedrò di studiarmi un pò di cose ma comincio ad avere un pò di confusione in testa.

Alternativa 2

Componenti
display lcd
-Benvenuto
-scritta CICLI N°1
2 pulsanti tipo freccette SU e GIU che ti permettono di aumentari o diminuire i cicli
1 pulsante START per avviare il nostro ciclo a 9 fasi che verrà ripetuto per X volte come impostato
1 PULSANTE STOP

/ASPIRAZIONE

1 apertura maniglia di aspirazione    // PORTVAC
2  accensione pompa del vuoto          // VACUUM
3 chiusura maniglia di aspirazione 
4 spegnimento pompa 

//SCARICO ARIA

5 apertura maniglia scarico aria     //AIROUT
6 chiusura maniglia scarico aria

//RIEMPIMENTO

7 apertura maniglia riempimento olio   // FILLING
8 chiusura maniglia riempimento olio

//SCARICO ARIA

5 apertura maniglia scarico aria     //AIROUT
6 chiusura maniglia scarico aria

//FINE 


PULSANTE STOP

Riempimento. // FILLING  CHIUSA
aspirazione  // PORTVAC CHIUSA
pompa  vuoto    //VACUUM  CHIUSA

Valvola scarco aria      APERTA
tempo 3 secondi
Valvola  scarico aria.  CHIUSA

In questo caso non sarà necessario memorizzare il numero di cicli svolti perchè sarò io ad impostare nuovamente quanti cicli dovrà rifare.

Può essere una soluzione meno complessa per il mio progetto da principiante rispetto alla precedente o peggioriamo la situazione ?

Scommessa vinta

Il futuro prevediamo io e mio fratello... il futuro :grinning:

A questo punto è inutile proseguire
Andrà bene tutto, purché lo faccia qualcun altro

Devo dire che anche a me lo OP ha molto deluso

Gli ho spiegato cosa doveva fare ed ero pronto a dargli il mio aiuto
Ma non ha fatto nulla di quello che gli è stato chiesto
Dice cose che si contraddicono tra loro e continua a dar ragione a tutti
Io direi tipico di chi ha poca voglia

Bah, io smetto di seguire

Scusami ma tu sei diventato programmatore in 1 settimana ?
Io nel mio lavoro se una cosa è troppo complessa per chi inizia cerco di fargli fare qualcosa di più idoneo al suo livello sennò giustamente va in confusione e gli passa la voglia.

Se ci sono vie meno complesse per fare il progetto in modo da divertirmi anche perchè no?
Non ci vedo niente di strano nel cercare qualcosa di meno complesso per arrivare ad un risultato simile, poi se il post non interessa o non si ha pazienza coi principianti nessuno obbliga a seguirlo.

Stessa cosa vale per chi si diverte a criticare e fare scommessine,può guardare altro che a me poco interessa di quello. che scrive.

1 Like

no, io no
ma se mi si chiedeva cosa volevo far lo sapevo, e lo sapevo descrivere, e stavo portando te a riuscirci
non te lo ho detto solo io che serve di essere chiari con la descrizione di quello che serve, anzi io sono l'ultimo che lo ha fatto
anzi, sono io quello che ha "spezzato una lancia" in tua difesa per evitare che troppe indicazioni complesse e inutili ti mettessero in confusione

secondo te cosa significa questa frase?

questo significa:
non stavano aiutando te
stavano cercando di capire loro quanto avresti capito tu delle loro parole

non è questo l'aiuto del quale avevi bisogno, e lo ammettono anche

ma al di la di quello che ho fatto io
parliamo di quello che non hai fatto tu:
hai dato una descrizione chiara?
no
e allora come pensi di poter scrivere un programma

e così facendo credi veramente che qualunque cosa ti dicano potrebbe aiutarti a risolvere un problema che TU per primo non sai descrivere? figurati gli altri...

di meno complesso di cosa?
perchè adesso mi stai dicendo che tu hai capito il livello di complessità di quello che ti scrivevano?

comunque la tua scelta la hai fatta

scusa, ma cosa c'è di troppo complesso che esprimersi chiaramente?
sarebbe bastato che tu rispondessi a qualche domanda, per sciogliere qualche dubbio e poter mettere qualcosa di solido sotto la tastiera
non lo hai mai fatto tu, anzi tu per primo hai continuamente cambiato idea
comunque non mi diverto a fare scommessine
la mia frase serviva per segnalarti che dovevi starci attento, a questo
non sei stato attento, e hai sparigliato di nuovo un problema che non sai capire
tanto per intenderci il problema è il tuo, non il nostro
e' semmai a me che non interessa, non a te, a te dovrebbe interessare, perchè nella palude dove sei adesso avresti bisogno di aiuto serio, ma ...

Mah ... il problema è sempre lo stesso ed è generalizzato ...

... "Con Arduino puoi fare tutto, non serve sapere nulla, basta fare copia/incolla, in un attimo fai quello che vuoi, ecc. ecc." ... la rete è piena di queste IDIOZIE e tutti credono che basta prendere un Arduino, andare su Internet, copiare un pezzo di programma, sperare che qualcuno faccia il lavoro di assemblaggio/correzione dei vari pezzi ed avere quello che si vuole. :roll_eyes:

NO, NON FUNZIONA COSÌ ... così al limite si fa lampeggiare un LED, ma per fare qualsiasi cosa un po' più complessa, TOCCA STUDIARE ed anche TANTO ... leggersi libri, studiarsi i reference, magari imparare a fare i diagrammi di flusso (che ormai nessuno usa più), fare un'infinità di piccoli programma di prova, cercare la soluzione pezzetto per pezzeto e ... dedicarci un'infinità di tempo ...

Ma tant'è che ... finisce sempre allo stesso modo ... :confused:

Guglielmo

1 Like

DUCEMBARR
Prova a lavorare in ospedale se vuoi vedere delle paludi vere, qui si gioca con i codici , lì la faccenda è molto seria.

Sull essere poco chiari ti do ragione, non è semplice nemmeno per me, inziare a programmare crea un casino enorme in testa anche quando cerchi poi di spiegarti.
Non voglio giustificarmi, certo se faccio domande banali o confuse cercate di capire che non è così facile, è un mondo nuovo, forse per per voi è intuitivo per me non lo è neanche un pò.

E per la cronaca se non avessi avuto voglia pagavo un programmatore ed ero a posto, non vedo il problema, non è che voglio farlo io perchè più economico, era solo per soddisfazione personale.

Ciao Guglielmo si me ne stò rendendo conto, i dettagli sono molto importanti e cominci a capirlo strada facendo.
Continuerò a studiare piano piano come stò facendo, i risultati arriveranno. grazie

Buone feste

Si potrebbe essere più semplice per il principiante, ma l'ostacolo è sempre
il delay. Ho risolto in parte i problemi legati all'uso di delay e in sua sostituzione ho creato una funzione dly() che fa quasi la stessa cosa di delay. Durante il dly(2000), viene chiamata la funzione process() la quale intercetta la pressione del pulsante verde.

L'algoritmo funziona (sembra) ma non vado affatto orgoglioso del codice.
Non è semplice da capire, ma qualche commento che ho inserito dovrebbe aiutarti. L'unico vero vantaggio di questo algoritmo è che puoi usare dly().

Al post trovi il link, che ti porta direttamente al simulatore online wokwi. Premi play sotto la scritta "simulation". Osserva cosa viene stampato sul monitor seriale. Premi il pulsante verde accanto a quello blu. Per passare da RUN a PAUSE e viceversa premi lo stesso pulsante.

Dovrebbe fare 10 ripetizioni.

PS: non chiedere come fare tutto il resto perché non ho idea se si possa fare con questa implementazione.

PS1: Avessero mai sputato per errore un pezzo di codice, con tutto quel ciarlare lo avrebbero realizzato molto meglio di quello che ho fatto io.

Ciao.

Grazie Mauro sembra funzionare proprio come volevo io, lo stò guardando proprio ora, cerco di studiarmelo un pò per capirne il funzionamento.

Grazie ancora :wink:

Certo che anche "menare il can per l'aia" come qualcuno sta facendo non è bello

Adesso siamo ai delay interrommpibili...

Seriamente, ma non ti sembra che si stia esagerando ?

Una sequenza con "delay interrompibili" più KISS di questa non riesco a pensarla: https://wokwi.com/projects/384209310516219905

Contatto di stop di tipo normalmente chiuso per sicurezza.

Riepilogo
#define START   A0    // pull-down normalmente 0 (contatto NO)
#define STOP    A1    // pull-down normalmente 1 (contatto NC)

byte   fase = 0;
byte   ripetizioni = 0;

//==============================================

// delay interrompibile, dt in secondi
bool dly(int dt) {
    for (int n=0; n<(dt*100); n++) {
        delay(10);
        if (1==fase  &&  digitalRead(STOP)==0) {
           fase = 2;
           return 1;
        }
    }
    return 0;
}

//==============================================

void setup() {
    Serial.begin(115200);
    pinMode(START, INPUT);
    pinMode(STOP,  INPUT);
}


void loop() {

    switch(fase) {

      case 0:  // attesa avvio
          if (digitalRead(START)==1) {
             Serial.println("Avvio sequenza");
             if (0 == ripetizioni) ripetizioni = 5; 
             fase = 1;
          }
      break;

      case 1:  // esecuzione sequenze
          Serial.println("------------------------");
          Serial.print("Inizio ciclo: -");
          Serial.println(ripetizioni);
          Serial.println("------------------------");
          Serial.println("ASPIRAZIONE");
          Serial.println("   Apri valvola aspirazione");
          if (dly(1)) break;
          Serial.println("   Accendi pompa vuoto");
          if (dly(1)) break;
          Serial.println("   Chiudi valvola aspirazione");
          if (dly(1)) break;
          Serial.println("   Spegni pompa vuoto");
          if (dly(1)) break;
          Serial.println("SCARICO ARIA");
          Serial.println("   Apri valvola scarico aria");
          if (dly(1)) break;
          Serial.println("   Chiudi valvola scarico aria");
          if (dly(1)) break;
          Serial.println("RIEMPIMENTO");
          Serial.println("   Apri valvola carico olio");
          if (dly(1)) break;
          Serial.println("   Chiudi valvola carico olio");
          if (dly(1)) break;
          Serial.println("SCARICO ARIA");
          Serial.println("   Apri valvola scarico aria");
          if (dly(1)) break;
          Serial.println("   Chiudi valvola scarico aria");
          if (dly(1)) break;
          ripetizioni--;
          if (ripetizioni == 0) { 
              Serial.println("Finito cicli.");
              fase = 0;
          }
      break;

      case 2:  // fase di stop
          Serial.println("------------------------");
          Serial.println("Interruzione ciclo...");
          Serial.println("------------------------");
          Serial.println("Chiudi valvola carico olio");
          Serial.println("Chiudi valvola aspirazione");
          Serial.println("Spegni pompa vuoto");
          Serial.println("Apri valvola scarico aria");
          dly(1);
          Serial.println("Chiudi valvola scarico aria");
          Serial.println("Finito stop.");
          Serial.println("------------------------");
          fase = 0;
      break;
    }

}
3 Likes

Ok, buono a sapersi. Non ti perdere quello di @Claudio_FF, anzi direi che come buon esercizio gli aggiungi le digitalWrite, così vediamo anche come dichiari i nomi dei pin. Facci caso:

// @Claudio_FF
#define PIN_BTN_1  A0    // start pull-down normalmente 0 (contatto NO)
#define PIN_BTN_2  A1    // stop pull-down normalmente 1 (contatto NC)

mentre,

// Maurotec
const byte PIN_BTN_1 = A0;
const byte PIN_BTN_2 = A1;

Puoi scegliere al momento a piacere, dal punto di vista funzionale non c'è differenza.

Nota anche che non usa alcuna libreria per la gestione dei pulsanti.
Nel codice non ci sono comandi complicati e sta sfruttando poche ed essenziali caratteristiche del linguaggio:

  • dly funzione che prende un argomento e restituisce un valore.
  • ciclo for usato nella funzione dly().
  • switch case, standard che contiene dei break condizionati.

Nonostante ciò il programma fa quello che ci si aspetta e per i motivi sopra elencati è proprio indicato per il principiante.

Ciao.

1 Like

Da vedere cosi sembra piu semplice, anche se qualcosa mi dice che nn sarà scontato, faccio qualche prova e vediamo cosa ci salta fuori grazie di nuovo

Be, si fai tutte le prove, ma non capita mai che il principiante abbia un codice di riferimento che sia semplice ed essenziale come quello, quindi anche se non ti dovesse riuscire ad aggiungere le digitalWrite sappi che quel codice lo devi usare come riferimento per apprendere.

Esiste il codice esplorativo, si tratta di pezzi di programma che cercano di evidenziare pregi e difetti di una soluzione software che non si è mai sperimentata prima. Il codice esplorativo non è mai una perdita di tempo anche se si dovesse rivelare apparentemente un fallimento. Quello che ho scritto io nasce proprio da codice esplorativo.

Ciao.

come ho già detto anni fa: mai sfidarmi a scrivere codice

ecco, senza dare la pappa fatta, ma un buon scheletro per partire

/*

   By C1P8, continuo a non essere rotto

   Per fare? Un timer ciclico ripetibile ed interrompibile

*/

#define START 2 // pin del pulsante di start
#define PAUSA 3 // pin del pulsante di pausa
#define cicli 4 // uso la minuscola perchè diverrà in futuro una variabile



byte pin[] = {4, 5, 6}; // i pin usati per le uscite: pompa, aria, olio
byte Pin = sizeof pin / sizeof pin[0];
unsigned long int tempi[] = {1000, 2000, 4000, 300}; // i tempi in millisecondi tra uno stato e il successivo
byte Stati = sizeof tempi / sizeof tempi[0];
char * uscite[] = {"001", "010", "110", "100", "000"}; // la configurazione di uscita da tenere,una in più rispetto ai tempi, per la configurazione di stop definitivo
// si potrebbero anche usare campi di bit, ma non esageriamo
// primo carattere prima uscita, secondo carattere seconda uscite, etc etc
// carattere 0 uscita spenta, carattere diverso da zero uscita accesa



void setup(void)
{
   for (byte i = 0; i < Pin; i++)
   {
      pinMode(pin[i], OUTPUT);
   }

   pinMode(START, INPUT);
   pinMode(PAUSA, INPUT);
}

void loop(void)
{
   while (!digitalRead(START)); // aspetta che venga premuto start

   //mesegue i cicli richiesti
   for (byte i = 0; i < cicli; i++)
   {
      // eseguo un ciclo
      ciclo();
   }
}

void ciclo(void)
{
   // esegue un singolo ciclo della sequenza richiesta
   unsigned long int inizio = millis();
   int  stato = 0;
   uscita(uscite[stato]);

   while (1) // ciclo continuo
   {
      if (!digitalRead(PAUSA))
      {
         // qui si spegne il led di pausa
         if (millis() - inizio > tempi[stato])
         {
            stato++;
            inizio = millis();

            if (stato > Stati)
            {
               uscita(uscite[stato]);
               break;
            }
         }
      }
      else
      {
         // qui si accende il led di pausa;
      }
   }
}


void uscita(char * uscite)
{
   for (byte i = 0; i < Pin; i++)
   {
      digitalWrite(pin[i], (uscite[i] - '0'));
   }
}

per maurotec:
lo hofatto esattamente come dicevo io: copiando da timer ciclici trovati qui sul forum
uno addirittura in una discussione iniziata da te

non ci sono puntatori a funzioni, callback, macchine a stati virtuali, classi o altri ammeniccoli

puro buon codice C vecchia maniera

il funzionamento è semplicissimo

oppure no?

forse è meno semplice di quello che si crede, se qualcuno non conosce il C
e allora siamo al punto dove ero io:
si parte dalle basi
descrivere il problema

e poi,
pseudocidice
e poi traduzione in C
etc etc

questo è semplice
non altr
e questo volevo far fare allo OP

e secondo me questa è e rimane l'unica soluzione al problema

PS
rimane da trovare come far scecliere il numero di cicli da ripetere e come visualizzarlo con/senza un display
e se lo OP non ci dice cosa ha e cosa sa fare e' inutile proseguire

PPS
per la cronaca, stamattina ci ho messo poco meno di un'ora a scriverlo
compresa la ricerca dei timer
mentre aspettavo che portassero l'ossigeno per mamma
consegnato, torno a fare il mio