millis()....maledetto millis()

Lo scippatore

in motorino,sugli autobus,al parco, al supermercato, dipende dalle occasioni e scippo chiunque mi capita a tiro anziani,giovani, bambini,uomini, donne,italiani e stranieri, non guardo in faccia a nessuno, pensa che una volta non sapevo chi scippare hi scippato mia nonno,solo che mi ha riconosciuto ed acasa mi ha dato dietro col badile :astonished:

A parte gli scherzi faccio il manutentore di "Altri Impianti in pratica quelli non identificati"edile di base meccanica di base ed elettrica soprattutto BT e vecchie macchine automatiche, ma ultimamente anche MT per una grossa SPA italiana, quando vedo che un problema arriva da un PLC perche magari ci sono passati mille programmatori o ci sono semplici modifiche da fare, io mi blocco come un somaro.

Una bella esperienza

Io pompe, del gasolio
Prima macchine utensili
Prima robotica di saldatura
Prima distributori automatici
Prima macchine tessili
Prima riviste particolari
Come vedi ampia esperienza anch’io

;D ;D ;D :D 8) :grin: :grinning: :grinning: cè l'ho quasi fatta mi manca solo la macchinetta del caffè ed itempi per il pulsante, come richiesto :kissing: ;D 8) :grin:

Puso: ;D ;D ;D :D 8) :grin: :grinning: :grinning: cè l'ho quasi fatta mi manca solo la macchinetta del caffè ed itempi per il pulsante, come richiesto :kissing: ;D 8) :grin:

insomma ti manca solo il 110 % del lavoro

sei a buon punto

di solito a me ne manca tra il 150 e il 200.............

Non gliel'ho data sù.

Solo che ho dovuto ricominciare tutto da capo(ed un pò mi ha fatto bene) causa sto cavolo di PC nuovo.....ora ho fatto miglioramenti al mio scheck...e sono tornato finalmente a lavorare sul pulsante,appena concludo qualkosa vi stupisco anke col caffè

Puso: sono tornato finalmente a lavorare sul pulsante,appena concludo qualkosa vi stupisco anke col caffè

Considera che la logica di gestione del pulsante prevede cinque diversi "momenti" distinti (stati) in cui può venirsi a trovare, e tre azioni (scritte in rosso) da compiersi solo nel momento in cui nello specifico stato si riscontra la condizione scritta in blu.

|500x360

Ovviamente le "attese" non sono cicli while perché si tornerebbe a bloccare tutto ;)

Ci sono diversi modi per implementare il tutto. Il meno faticoso è una macchinetta a stati fatta con uno switch che ricopi pari pari lo schemino sopra. Un'altra è quella di "catturare" pressioni e rilasci del pulsante e impostare adeguati flag (bandierine / indicatori) in modo da "abilitare" o "disabilitare" l'esecuzione di opportuni if, che alla fine devono realizzare comunque la logica di cui sopra.

Sto impazzendo sul pulsante senza usare lo switch ora mi sorge un nuovo problema(forse mi sto affogando in un bicchier d'acqua)

questa è la parte pulsante

//INVENTO FUNZIONE
//VARIABILI PULSANTE
byte PULSANTE_PREMUTO=0;
byte PRECEDENTE_PRESSIONE=0;
byte PARTENZA=0;
unsigned long TEMPO_PRESSIONE;

void LEGGI_PULSANTE()
{
  Serial.println(PULSANTE_PREMUTO);
  if(digitalRead(pulsante1))
    {
     PULSANTE_PREMUTO=1;
     Serial.println("");
     Serial.println("PULSANTE PREMUTO ");
    }
     else{PULSANTE_PREMUTO=0;}
  
  if((PULSANTE_PREMUTO=1)&&(PRECEDENTE_PRESSIONE==0))
    {
     if(millis()-TEMPO_PRESSIONE>=1000)
      {
       TEMPO_PRESSIONE=millis();
       PULSANTE_PREMUTO=0;
       PRECEDENTE_PRESSIONE++;
      }
    }
  if(PRECEDENTE_PRESSIONE==1){PARTENZA=1;}
  
  if(PRECEDENTE_PRESSIONE>3){PRECEDENTE_PRESSIONE=0;}
          
  Serial.println("");
  Serial.print("PARTENZA ");
  Serial.println(PARTENZA);
}

a parte gli errori che più che altro erano prove il problema l'ho trovato leggendo

Serial.println(PULSANTE_PREMUTO);

in pratica legge lo legge sempre ad 1 anche se non premo il pulsante,ma se lo premo mi dice correttamente che il pulsante è premuto,almeno su tinkercad

Quattro volte che lo leggo e non capisco da cosa possa dipendere il problema

Hai altri dettagli?

Ho fatto altre verifiche ed il problema è sicuramente in LEGGI_PULSANTE ma non capisco dove. Se lancio il LOOP in questa maniera

//LOOP   
void loop()
{
  Serial.println(PULSANTE_PREMUTO);
  LEGGI_PULSANTE();
  VERIFICA_SISTEMA();
  DECIDI_ROTAZIONE();
  COMANDA_PINbob();
}

me lo legge 1 anche se non è premuto

Se invece lo lancio in questo modo

//LOOP   
void loop()
{
  Serial.println(PULSANTE_PREMUTO);
  if(digitalRead(pulsante1))
    {
     PULSANTE_PREMUTO=1;
     Serial.println("");
     Serial.println("PULSANTE PREMUTO ");
    }
     else{PULSANTE_PREMUTO=0;}
  VERIFICA_SISTEMA();
  DECIDI_ROTAZIONE();
  COMANDA_PINbob();
}

lo legge correttamente

Ho fatto ulteriori spostamenti dalla funzione LEGGI_PULSANTE scrivendo direttamente sul Loop, il problema è riapparso quando ho messo questo pezzo

if((PULSANTE_PREMUTO=1)&&(PRECEDENTE_PRESSIONE==0))
    {
     if(millis()-TEMPO_PRESSIONE>=1000)
      {
       TEMPO_PRESSIONE=millis();
       PULSANTE_PREMUTO=0;
       PRECEDENTE_PRESSIONE++;
      }

Quindi immagino che il problema sia qui anche se non capisco dove, e prima che me lo chiedete confermo che queste 4 Variabili sono utilizzate solo nella funzione LEGGI PULSANTE, variabile richiamata in altre funzioni arriverebbe dopo, ma il problema è gia qui

comunque metto lo scketch completo,non è ancora finito la LEGGI_PULSANTE ed un po incasinato il LOOP causa prove a sto piccolo inconvegnente

//DEFINISCO I PIN 
#define pulsante1 2
#define bob1 8
#define bob2 9
#define bob3 10
#define bob4 11
#define sistema_attivo 13

//SETUP
void setup()
{
  pinMode(pulsante1,INPUT);
  pinMode(bob1,OUTPUT);
  pinMode(bob2,OUTPUT);
  pinMode(bob3,OUTPUT);
  pinMode(bob4,OUTPUT);
  pinMode(sistema_attivo,OUTPUT); 
  Serial.begin(9600);
}

//INVENTO FUNZIONE
//VARIABILI PULSANTE
byte PULSANTE_PREMUTO=0;
byte PRECEDENTE_PRESSIONE=0;
byte PARTENZA=0;
unsigned long TEMPO_PRESSIONE;

void LEGGI_PULSANTE()
{
  Serial.println(PULSANTE_PREMUTO);
  if(digitalRead(pulsante1))
    {
     PULSANTE_PREMUTO=1;
     Serial.println("");
     Serial.println("PULSANTE PREMUTO ");
    }
     else{PULSANTE_PREMUTO=0;}
  
  if((PULSANTE_PREMUTO=1)&&(PRECEDENTE_PRESSIONE==0))
    {
     if(millis()-TEMPO_PRESSIONE>=1000)
      {
       TEMPO_PRESSIONE=millis();
       PULSANTE_PREMUTO=0;
       PRECEDENTE_PRESSIONE++;
      }
    }
  
  if(PRECEDENTE_PRESSIONE==1){PARTENZA=1;}
  if(PRECEDENTE_PRESSIONE==2){PARTENZA=2;}
  if(PRECEDENTE_PRESSIONE==3){PARTENZA=3;}
  
  if(PRECEDENTE_PRESSIONE>3){PRECEDENTE_PRESSIONE=0;}
          
  Serial.println("");
  Serial.print("PARTENZA ");
  Serial.println(PARTENZA);
}


//INVENTO FUNZIONE
//VARIABILI VELOCITA',ROTAZIONE e POSIZIONE DI FERMO
int CICLO=0;
int ROTAZIONE=0;
int CONTAPASSI=0;
unsigned long VELOCITA=50;
unsigned long TEMPO=0;

void DECIDI_ROTAZIONE()
{
 Serial.println("");
 Serial.print("MILLIS ");
 Serial.println(millis()); 
 Serial.print("TEMPO ");
 Serial.println(TEMPO); 
  
 if(PARTENZA==1){ROTAZIONE=1;}
 if(PARTENZA==2){ROTAZIONE=2;} 
 if(PARTENZA==3){ROTAZIONE=3;} 
  
 if(ROTAZIONE==1)
   {
    Serial.println("");
    Serial.println("AVANTI ");

    if(millis()-TEMPO>=VELOCITA)
      {
       TEMPO=millis();
       CICLO++;
       CONTAPASSI++;
      if(CICLO>8){CICLO=1;}
      }
    }
   
 if(ROTAZIONE==2)
   {
    Serial.println("");
    Serial.println("INDIETRO ");
   
    if(millis()-TEMPO>=VELOCITA)
      {
       TEMPO=millis();
       CICLO--;
       CONTAPASSI--;
      if(CICLO<1){CICLO=8;}
      }
    }
  
 if(ROTAZIONE==3)
   {
    Serial.println("");
    Serial.println("IN POSIZIONE ");
   
    digitalRead(CICLO);
    digitalRead(CONTAPASSI);
    CICLO=CICLO;
   } 
}

//INVENTO FUNZIONE
// VARIABILI PER VERIFICA SISTEMA
unsigned long LAMPEGGIO=200;
unsigned long TEMPO_LAMPEGGIO;

void VERIFICA_SISTEMA()
{
  if(PARTENZA==0)
    {
     digitalWrite(sistema_attivo,LOW);
     Serial.println("SISTEMA SPENTO");
    }
  
  if(PARTENZA!=0)
    {
     Serial.println("SISTEMA ATTIVO");
    
     digitalWrite(sistema_attivo,HIGH);
     if(millis()-TEMPO_LAMPEGGIO>=LAMPEGGIO)
       {
        TEMPO_LAMPEGGIO=millis();
        digitalWrite(sistema_attivo,LOW);
       }
     if(millis()-TEMPO_LAMPEGGIO>=LAMPEGGIO)
       {
        TEMPO_LAMPEGGIO=millis();
        digitalWrite(sistema_attivo,HIGH);
       }
    }
}  
  
//INVENTO FUNZIONE
// VARIABILI PER COMANDO I PIN
byte BOB1=0;
byte BOB2=0;
byte BOB3=0;
byte BOB4=0;

void COMANDA_PINbob()
{
  Serial.print("CICLO ");
  Serial.println(CICLO);
  Serial.print("BOB ");
  Serial.print(BOB1);
  Serial.print(BOB2);
  Serial.print(BOB3);
  Serial.print(BOB4);
  Serial.println("");
  Serial.print("PASSI ");
  Serial.println(CONTAPASSI);
  
  if(CICLO==0){BOB1=0,BOB2=0;BOB3=0;BOB4=0;}
  if(CICLO==1){BOB1=1,BOB2=0;BOB3=0;BOB4=0;}
  if(CICLO==2){BOB1=1,BOB2=1;BOB3=0;BOB4=0;}
  if(CICLO==3){BOB1=0,BOB2=1;BOB3=0;BOB4=0;}
  if(CICLO==4){BOB1=0,BOB2=1;BOB3=1;BOB4=0;}
  if(CICLO==5){BOB1=0,BOB2=0;BOB3=1;BOB4=0;}
  if(CICLO==6){BOB1=0,BOB2=0;BOB3=1;BOB4=1;}
  if(CICLO==7){BOB1=0,BOB2=0;BOB3=0;BOB4=1;}
  if(CICLO==8){BOB1=1,BOB2=0;BOB3=0;BOB4=1;}
  
  if(BOB1==1){digitalWrite(bob1,HIGH);}else{digitalWrite(bob1,LOW);}
  if(BOB2==1){digitalWrite(bob2,HIGH);}else{digitalWrite(bob2,LOW);}
  if(BOB3==1){digitalWrite(bob3,HIGH);}else{digitalWrite(bob3,LOW);}
  if(BOB4==1){digitalWrite(bob4,HIGH);}else{digitalWrite(bob4,LOW);}
}
   
//LOOP   
void loop()
{
  Serial.println(PULSANTE_PREMUTO);
  if(digitalRead(pulsante1))
    {
     PULSANTE_PREMUTO=1;
     Serial.println("");
     Serial.println("PULSANTE PREMUTO ");
    }
     else{PULSANTE_PREMUTO=0;}
  if((PULSANTE_PREMUTO=1)&&(PRECEDENTE_PRESSIONE==0))
    {
     if(millis()-TEMPO_PRESSIONE>=1000)
      {
       TEMPO_PRESSIONE=millis();
       PULSANTE_PREMUTO=0;
       PRECEDENTE_PRESSIONE++;
      }
    }
  VERIFICA_SISTEMA();
  DECIDI_ROTAZIONE();
  COMANDA_PINbob();
}

Cavolo, era li da vedere, si vede che ero stanco

Pulsante premuto doppio uguale 1 Invece tu hai scritto pulsante premuto uguale 1

Che è un'assegnazione... E come tutte le assegnazioni in C vale quello che è scritto dopo lo uguale, in questo caso vale vero

Errore classico del C

Magari fosse cosi semplice se ci avevo gia provato

 if((PULSANTE_PREMUTO==1)&&(PRECEDENTE_PRESSIONE==0))
    {
     if(millis()-TEMPO_PRESSIONE>=1000)
      {
       TEMPO_PRESSIONE=millis();
       PULSANTE_PREMUTO=0;
       PRECEDENTE_PRESSIONE++;
      }
    }

invece che if((PULSANTE_PREMUTO=1)&& giustamente me lo legge a 0 siccome gliel'ho detto,il problema è che cosi dopo non prosegue...probabilmente il problema è allora da un altra parte,mo ci riguardo con calma che durante le varie prove ho probabilmente incasinato qualkos'altro,

per il momento grazie

Mettila come vuoi

Pulsante premuto è variabile globale. …

Mettere Pulsante premuto uguale 1
METTE uguale a 1 la variabile, che essendo globale, lo rimane
E infatti uguale a uno la trovi
Chissà come mai…

Poi, io più che dirtelo non posso…

si ho notato e me lo avevate gia detto solo che ieri mentre facevo alkune modifiche ho incasinato altro...errori che sto correggendo che li ho gia visti...mo ci arrivo ....e faccio pure il caffè

ECCO FATTO
ho corretto i casini, ora torno a lavorare sulle tempistiche del pulsante…se come clienti va bene propongo cosi:

prima pressione subito parte il led sistema e motore avanti
seconda pressione se maggiore di 700 continua led sistema e motore indietro
terza pressione se maggiore di 700 continua led sistema e motore in posizione
quarta pressione sistema spento e motore spento

in ultimo ci aggiungo il caffè

Praticamente uno schect con utilità zero a parte il mio apprendimento.

::slight_smile: ::slight_smile: ::slight_smile: :smiley: :smiley: :smiley: :smiley: :smiley: :money_mouth_face: :money_mouth_face: :money_mouth_face:

Puso: se come clienti va bene

No :grin:

vabbè mo ci provo cosi....poi se avete contanti ascolto le varie richieste :smiling_imp: :smiling_imp:

comunque a parte gli scherzi mi rendo conto che con piccoli calci nel culo si fanno grandi progressi.... GRAZIE 8) ;) :fearful: :grin:

1) Intanto c'è un certo codice in esubero:

if(PARTENZA==1){ROTAZIONE=1;}
if(PARTENZA==2){ROTAZIONE=2;}
if(PARTENZA==3){ROTAZIONE=3;}

è del tutto uguale a:

ROTAZIONE = PARTENZA;

if(BOB1==1){digitalWrite(bob1,HIGH);}else{digitalWrite(bob1,LOW);}
if(BOB2==1){digitalWrite(bob2,HIGH);}else{digitalWrite(bob2,LOW);}
if(BOB3==1){digitalWrite(bob3,HIGH);}else{digitalWrite(bob3,LOW);}
if(BOB4==1){digitalWrite(bob4,HIGH);}else{digitalWrite(bob4,LOW);}

è del tutto uguale a:

digitalWrite(bob1, BOB1);
digitalWrite(bob2, BOB2);
digitalWrite(bob3, BOB3);
digitalWrite(bob4, BOB4);

2) Convenzioni di scrittura Se non sbaglio in C le convenzioni di scrittura sono opposte a quelle che usi, e questo può creare confusione in chi legge. Si dovrebbe seguire questa tabellina:

NOMI_DI_COSTANTI      maiuscolo + underscore
nomi_di_variabili     minuscolo + undescore
nomiDiFunzioni        iniziali maiuscole tranne la prima e senza underscore

in pratica le define andrebbero maiuscole e le variabili minuscole


3) Indentazione VA BENE! Perfettamente comprensibile, magari tutti i principianti (e anche non) scrivessero con questo ordine.


4) Separazione visiva Per non obbligare l'occhio a cercare, le funzioni sarebbe meglio separarle tra loro da una bella riga di commento:

//-----------------------------------------------------------------------------

e se possibile cercare di tenerle corte. L'inizio e la fine di ogni struttura dovrebbero essere visibili nella stessa schermata, quindi una ventina di righe massimo, ma non sempre è possibile, percio` teniamola come perfezione zen a cui aspirare :sweat_smile:


5) Semplificare la logica Scrivere una sola grossa struttura if che contempli in un colpo solo tutte le possibili condizioni / variazioni / livelli letti dagli ingressi / stati dell'elaborazione, è abbastanza complicato. Meglio scomporre.

Ad esempio il seguente codice legge l'ingresso, con una semplice if scopre se l'ingresso è variato dalla lettura precedente, con una sotto if decide se si tratta di una pressione o di un rilascio e chiama due sottofunzioni. Le due funzioni onP1Press e onP1Release vengono quindi chiamate solo al momento di una pressione e di un rilascio, per cui all'interno di esse non serve più preoccuparsi del pulsante, si sa che in quel momento è stato premuto (o rilasciato) e questo basta.

In quelle due funzioni si scrivono altre if che devono decidere SOLO cosa fare se è la prima pressione o la seconda, o se è un rilascio e non è ancora scaduto il tempo dal momento della prima pressione.

Quindi la complessità del problema si è drasticamente ridotta a: "cosa fare quando rilevo una pressione o un rilascio".

//-----------------------------------------------------------------------------

#define  PULSANTE1   ...           // il pin usato per l'ingresso
#define  PRESS_LEVEL ...           // il livello letto a pulsante premuto

//-----------------------------------------------------------------------------

byte ingresso_prec = !PRESS_LEVEL; // valore iniziale ingresso precedente

//-----------------------------------------------------------------------------

void onP1Press()    // eseguita una volta al momento della pressione
{
}

//-----------------------------------------------------------------------------

void onP1Release()  // eseguita una volta al momento del rilascio
{
}

//-----------------------------------------------------------------------------

void leggiPulsante()
{
  byte ingresso = digitalRead(PULSANTE1); // legge livello ingresso attuale
  if (ingresso != ingresso_prec)                   // se rilevata variazione
     if (ingresso == PRESS_LEVEL)  onP1Press();    // se e` una pressione
     else                          onP1Release();  // se e` un rilascio

  // qui altre eventuali operazioni eseguite sempre

  ingresso_prec = ingresso;    // aggiorna ingressoPrec per prossimo ciclo
}

//-----------------------------------------------------------------------------

void setup()
{
  pinMode(PULSANTE1, INPUT);
}

//-----------------------------------------------------------------------------

void loop()
{
  leggiPulsante();
}

//-----------------------------------------------------------------------------

Nota: le due define iniziali parametrizzano il programma in modo da poter usare pin diversi e collegamento indifferente pull-up/pull-down, semplicemente scrivendo i due valori corretti all'inizio. Nel resto del programma non compaiono mai HIGH/LOW ecc ecc espliciti, questo evita un sacco di errori.

Nota2: si da per scontato che il pulsante sia già adeguatamente filtrato contro i rimbalzi (condensatore di debounce), altrimenti funzionerà tutto male anche con codice giusto. Il seguente schema è un collegamento con resistenza di pull-down e filtro hardware. Il pulsante premuto genera una lettura HIGH.

Claudio_FF: 1) Intanto c'è un certo codice in esubero:

ROTAZIONE = PARTENZA;
digitalWrite(bob1, BOB1);
digitalWrite(bob2, BOB2);
digitalWrite(bob3, BOB3);
digitalWrite(bob4, BOB4);

un po' che lo diciamo....

ok tranne la tabellina di scrittura ho corretto e compreso alkune cose prima facevo avevo un po di confusione,per quello che per comodità mettevo

if(BOB1==1){digitalWrite(bob1,HIGH);}else{digitalWrite(bob1,LOW);}

ora mi sto concentrando sul pulsante che ancora non mi entra nella zucca sto metodo,ci sono vicino a capirlo,ma non mi entra ancora, ci sto lavorando

ovviamente il pulsante era gia filtrato,non cosi preciso,ma filtrato alla vecchia(cavo schermato dedicato con puntazza a terra dedicata e chiusura ad anello).......praticamente una resistenza da 10K sul negativo :confused:

Puso: ovviamente il pulsante era gia filtrato,non cosi preciso,ma filtrato alla vecchia(cavo schermato dedicato con puntazza a terra dedicata e chiusura ad anello)

attenzione, se abiti a meno di 2 sistemi solari da una pila scarica le correnti di terra ti fregano........