Go Down

Topic: millis()....maledetto millis() (Read 10998 times) previous topic - next topic

Claudio_FF

#30
Sep 16, 2017, 01:52 pm Last Edit: Sep 16, 2017, 02:00 pm by Claudio_FF
Questa parte l'ho utilizzata per dare più o meno velocità al motore
Code: [Select]
unsigned velocita=50;
unsigned tempo=0;

Ho capito a cosa servono, è la dichiarazione del tipo che non è corretta (quindi funziona per pura fortuna).


Quote
Qui invece ho voluto il motore fermo in una posizione qualsiasi con le bobine attive in modo che l'albero mantenga quella posizione e non sia libero di girare per inerzia, in più ho voluto ricordare in quale posizione "PASSO" si trova per poterlo sfruttare come un encoder
Code: [Select]
else
    {
     digitalRead(ciclo);
     digitalRead(conteggiopassi);
     ciclo=ciclo;
    }
}    

Quelle istruzioni vengono eseguite per qualsiasi condizione diversa da 2 (quindi anche mentre il motore gira con condizione == 1), e (per il momento) non fanno assolutamente niente.

Quote
cosi provo di capire la differenza con if(millis() - tempo >= velocita)
Se ne sta parlando anche qui.
********* IF e SWITCH non sono cicli ! *********
**** Una domanda ben posta è già mezza risposta ****
*** La corrente si misura in mA, la quantità di carica in mAh ***

Puso

 :smiley-eek-blue: mi hai fregato con quel led, è più complicato del previsto per me, ci metto un pò ma ci riuscirò

docsavage

#32
Sep 16, 2017, 02:44 pm Last Edit: Sep 16, 2017, 02:51 pm by docsavage
La dichiarazione di queste due variabili mi sembra un po' strana
se ne è parlato nel post 7, rara ma non errata.
Comunque potrebbe indurre in confusione

E certo vale come indizio di non chiarezza nel modo di programmare
E' stato bello... ma appunto: è stato
Ocio, che adesso c'è qualcuno che dice le stesse cose per le quali mi martellavate... Il tempo è galantuomo

Puso

ecco fatto
ho tolto il reset e conteggiato il millis() in maniera corretta, poi ho aggiunto e modificato questo
Code: [Select]
//VARIABILI PER I COMANDI MOTORE
int ciclo=0;
int rotazione=0;
int partenza=0;

//VARIABILE PER I COMANDI LAMPEGGIO SISTEMA
int lampeggio=0;

//VARIABILI PER LA VELOCITA LAMPEGGIO SISTEMA
unsigned long lampeggio_sistema=500;
unsigned long tempo_sistema=0;

//VARIABILI PER LA VELOCITA DEL MOTORE
unsigned long velocita=50;
unsigned long tempo=0;

//VARIABILE PER EVENTUALE RESET DI MILLIS()
extern unsigned long timer0_millis;


poi ho fatto una Funzione apposita
Code: [Select]
//INVENTO FUNZIONE DA RICHIAMARE NEL LOOP()
void VERIFICA_SISTEMA()
{
  if(lampeggio==0){digitalWrite(led_sistema,LOW);}
  if(lampeggio==1){digitalWrite(led_sistema,HIGH);}

 
  if(ciclo!=0)
    {
     digitalRead(lampeggio);
   
     if(millis()-tempo_sistema>=lampeggio_sistema)
       {
        lampeggio++;
        tempo_sistema=millis();
       }
     if(lampeggio>1){lampeggio = 0;}
     }
}



e l'ho richiamata nel LOOP togliendo i Reset Millis
Code: [Select]
//SCRIVO IL LOOP()
void loop()
{
 LEGGI_MONITOR();
 LEGGI_PULSANTE();
 VERIFICA_SISTEMA();
 DECIDI_ROTAZIONE();
 ISTRUISCI_BOBINE();
 COMANDA_BOBINE();
 }


Ora funziona anche il Led

se come clienti avete altre richieste chiedete pure che a me fa solo bene per esercitarmi,ovviamente il prezzo aumenta ;D  8)  :smiley-lol:

Puso

Prossimo passo

Ripasso le variabili.
Evito le righe inutili(anche se le metto per mia più facile comprensione)
Vi uso come"Comittenti" fatemi pure richieste aggiuntive sul mio progetto cosi mi alleno.

Prossimo progetto appena mi sento pronto usare un joystick al posto del pulsante,anche se non lo trovo sul simulatore di tinkercad ,se no ci avevo gia fatto prove, proverò col potenziometro.

Ma per ora mi devo esercitare quindi fate pure richieste e corregetemi se sbaglio.

Etemenanki

Intanto, come suggerimento generico, puoi risparmiare variabili (e memoria) evitando di usare delle unsigned long per metterci dentro solo il valore dei ritardi ed altra roba simile ... anzi, a meno che il tuo programma poi in fase di funzionamento non debba modificare quei valori, puoi proprio evitare di usare delle variabili, e scrivere semplicemente quei valori nello sketch ... memoria risparmiata e meno complicazioni ;)
"Sopravvivere" e' attualmente l'unico lusso che la maggior parte dei Cittadini italiani,
sia pure a costo di enormi sacrifici, riesce ancora a permettersi.

Puso

Grazie per il suggerimento,ma data la mia poca esperienza le ho messe apposta in attesa di "clienti" che mi chiedano modifiche all'ultimo momento,,,,,,diciamo che l'ho pensato come un progetto modificabile velocemente per ogni esigenza senza dover rivedere tutto,comunque ho capito il tuo concetto e ti ringrazio.

Claudio_FF

#37
Sep 16, 2017, 09:35 pm Last Edit: Sep 16, 2017, 09:51 pm by Claudio_FF
Quote from: Puso
Code: [Select]
digitalRead(lampeggio);
Un grosso dubbio... cosa dovrebbe fare per te questa istruzione che hai scritto? (considera anche i valori che può assumere la variabile lampeggio)

Quote
se come clienti avete altre richieste chiedete pure
Il cliente è parzialmente soddisfatto... voleva un LED che lampeggiasse sempre costantemente in ogni momento, invece si è accorto che se tiene premuto a lungo il pulsante, per tutto il tempo della pressione il LED non lampeggia più  ;)

Quote
l'ho pensato come un progetto modificabile velocemente per ogni esigenza senza dover rivedere tutto
È cosa buona e giusta parametrizzare il programma, in modo da non dover modificare ogni volta qui e la con il rischio di dimenticare qualcosa o sbagliare, però per non consumare memoria andrebbe appunto fatto con costanti e/o define.
********* IF e SWITCH non sono cicli ! *********
**** Una domanda ben posta è già mezza risposta ****
*** La corrente si misura in mA, la quantità di carica in mAh ***

Puso

scusate il ritardo nel rispondere ho un po di problemi col PC

Il digitalRead lo avevo messo per sapere in stato fosse il led sicuramente ora è inutile,ma lo tengo perche magari potrebbe tornarmi comodo durante le richieste della clientela pignola

Ho notato la richiesta del led che si blocca mentre il pulsante è premuto,,,,,,,,ci sto ragionando,pensavo fosse una cosa da poco,ma prima o poi ci salto fuori, appena riesco a non litigare col PC che in sto periodo mi fa innervosire

Per le variabili ammetto di avere ancora grosse lacune,,,,,le devo risccrivere alla lavagna :smiley-eek-blue:  :'(

appena risolvo il piccolo problema con il led di sistema lo posto

Puso

 >:( ummmm dopo vari tentativi falliti ho aggiunto questo al precedente
Code: [Select]
//VARIABILE PER I COMANDI LAMPEGGIO SISTEMA
byte lampeggio=0;
byte lampeggio_attivo=0;

 poi l'ho richiamato metto lo sketch completo
Code: [Select]
//VARIABILI PER RICORDARE I PIN
byte pulsante=2;
byte bobina1=8;
byte bobina2=9;
byte bobina3=10;
byte bobina4=11;
byte led_sistema=13;

//VARIABILI PER COMANDARE I PIN
byte bob1=0;
byte bob2=0;
byte bob3=0;
byte bob4=0;
byte sistema_attivo=0;

//VARIABILI PER RICORDARE LA POSIZIONE MOTORE
int conteggiopassi=0;
int girocompleto=512;

//VARIABILI PER I COMANDI MOTORE
byte ciclo=0;
byte rotazione=0;
byte partenza=0;

//VARIABILE PER I COMANDI LAMPEGGIO SISTEMA
byte lampeggio=0;
byte lampeggio_attivo=0;

//VARIABILI PER LA VELOCITA LAMPEGGIO SISTEMA
unsigned long lampeggio_sistema=500;
unsigned long tempo_sistema=0;

//VARIABILI PER LA VELOCITA DEL MOTORE
unsigned long velocita=50;
unsigned long tempo=0;

//VARIABILE PER EVENTUALE RESET DI MILLIS()
extern unsigned long timer0_millis;

void setup()
{
 //ASSEGNO TIPO DI PIN
 pinMode(pulsante,INPUT); 
 pinMode(bobina1,OUTPUT);
 pinMode(bobina2,OUTPUT);
 pinMode(bobina3,OUTPUT);
 pinMode(bobina4,OUTPUT);
 pinMode(led_sistema,OUTPUT);
 
 //ASSEGNO VELOCITA SERIAL MONITOR
 Serial.begin(9600);
}


//INVENTO FUNZIONE DA RICHIAMARE NEL LOOP()
void  LEGGI_MONITOR()
{
 Serial.print("MILLIS ");
 Serial.println(millis());
 
 Serial.print("LAMPEGGIO ");
 Serial.print(lampeggio_attivo);
 Serial.println(lampeggio);
 
 Serial.print("TEMPO ");
 Serial.println(tempo);
 
 Serial.print("CICLO  ");
 Serial.println(ciclo);
 Serial.print(bob1);
 Serial.print(bob2);
 Serial.print(bob3);
 Serial.print(bob4);
 Serial.println("");
 
 if(rotazione==0)
   {
    Serial.println("");
    Serial.println("FERMO");
   }
 if(rotazione==1)
   {
    Serial.println("");
    Serial.println("AVANTI");
   }
 if(rotazione==2)
   {
    Serial.println("");
    Serial.println("INDIETRO");
   }
 Serial.print("PASSI  ");
 Serial.println(conteggiopassi);
}


//INVENTO FUNZIONE DA RICHIAMARE NEL LOOP()
void LEGGI_PULSANTE()
{   
 if((digitalRead(pulsante))&&(rotazione==0))//Dice Avanti
   {
    while(digitalRead(pulsante)){lampeggio_attivo=1;}
    rotazione=1;
    lampeggio_attivo=1;
   }
 
  if((digitalRead(pulsante))&&(rotazione==1))//Dice Indietro
   {
    while(digitalRead(pulsante)){lampeggio_attivo=1;}
    rotazione=2;
    lampeggio_attivo=1;
   }
 
  if((digitalRead(pulsante))&&(rotazione==2))//Dice Stop
   {
    while(digitalRead(pulsante)){lampeggio_attivo=1;}
    rotazione=0;
    lampeggio_attivo=1;
   }
}

//INVENTO FUNZIONE DA RICHIAMARE NEL LOOP()
void DECIDI_ROTAZIONE()
{
 //COMANDA AVANTI
 if(rotazione==1)
   {
    if(millis()-tempo>=velocita)
      {
       conteggiopassi++;
       ciclo++;
       tempo=millis();
      }
    if(ciclo>8){ciclo=1;}
   }
 
 //COMANDA INDIETRO
 if(rotazione==2)
   {
    if(millis()-tempo>=velocita)
      {
       conteggiopassi--;
       ciclo--;
       tempo=millis();
      }
    if(ciclo<1){ciclo=8;}
   }
 
 //COMANDA STOP
 //MANTIENE LA POSIZIONE
 //RICORDA LA POSIZIONE
 else
    {
     digitalRead(ciclo);
     digitalRead(conteggiopassi);
     ciclo=ciclo;
    }
}     

//INVENTO FUNZIONE DA RICHIAMARE NEL LOOP()
void ISTRUISCI_BOBINE()
{
 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;}
}

//INVENTO FUNZIONE DA RICHIAMARE NEL LOOP()
void COMANDA_BOBINE()
{
 if(bob1==1){digitalWrite(bobina1,HIGH);}else{digitalWrite(bobina1,LOW);}
 if(bob2==1){digitalWrite(bobina2,HIGH);}else{digitalWrite(bobina2,LOW);}
 if(bob3==1){digitalWrite(bobina3,HIGH);}else{digitalWrite(bobina3,LOW);}
 if(bob4==1){digitalWrite(bobina4,HIGH);}else{digitalWrite(bobina4,LOW);}
}

//INVENTO FUNZIONE DA RICHIAMARE eventualmente NEL LOOP()
void RESETTA_MILLIS()
{
  timer0_millis=0;
  tempo=millis();
  tempo_sistema=millis();
}

//INVENTO FUNZIONE DA RICHIAMARE NEL LOOP()
void VERIFICA_SISTEMA()
{
 if(lampeggio_attivo=1)
    {
     digitalRead(lampeggio);
     if(millis()-tempo_sistema>=lampeggio_sistema)
       {
        lampeggio++;
        tempo_sistema=millis();
       }
     if(lampeggio>1){lampeggio = 0;}
     }
  if(lampeggio==0){digitalWrite(led_sistema,LOW);}
  if(lampeggio==1){digitalWrite(led_sistema,HIGH);}
 
}


//SCRIVO IL LOOP()
void loop()
{
 
 LEGGI_MONITOR();
 VERIFICA_SISTEMA();
 LEGGI_PULSANTE();
 DECIDI_ROTAZIONE();
 ISTRUISCI_BOBINE();
 COMANDA_BOBINE();
 
}


credo che il problema sia qui
Code: [Select]
//INVENTO FUNZIONE DA RICHIAMARE NEL LOOP()
void LEGGI_PULSANTE()
{   
 if((digitalRead(pulsante))&&(rotazione==0))//Dice Avanti
   {
    while(digitalRead(pulsante)){lampeggio_attivo=1;}
    rotazione=1;
    lampeggio_attivo=1;
   }
 
  if((digitalRead(pulsante))&&(rotazione==1))//Dice Indietro
   {
    while(digitalRead(pulsante)){lampeggio_attivo=1;}
    rotazione=2;
    lampeggio_attivo=1;
   }
 
  if((digitalRead(pulsante))&&(rotazione==2))//Dice Stop
   {
    while(digitalRead(pulsante)){lampeggio_attivo=1;}
    rotazione=0;
    lampeggio_attivo=1;
   }
}


in pratica legge legge il lampeggio_attivo=1,ma se tengo premuto il pulsante se ne frega,,,,,,mi sono arenato nuovamente,,,, >:(  >:(

Claudio_FF

#40
Sep 17, 2017, 05:31 pm Last Edit: Sep 17, 2017, 05:44 pm by Claudio_FF
Quote from: Puso
Il digitalRead lo avevo messo per sapere in stato fosse il led
Per sapere in che stato si trova il LED leggi i pin di trasmissione/ricezione della porta seriale? (peraltro senza assegnare il risultato della lettura a nulla)

Ridomando: secondo te che operazione viene svolta dall'istruzione:
Code: [Select]
digitalRead(0);??


Code: [Select]
Per le variabili ammetto di avere ancora grosse lacune
Sono semplicemente le scatole (con capienza 8, 16 e 32 fagioli) in cui mettere i dati di lavoro che servono (codificati con la combinazione di fagioli opportuna).

Quando sono scritte a destra dell' uguale di assegnamento allora nel punto in cui sono scritte se ne considera il loro valore, quando sono scritte a sinistra dell'uguale allora è un'assegnazione di un valore a quella variabile.

Per tutti gli altri valori scritti nel programma che non variano mai non servono scatole, bastano etichette (costanti e/o define).


Quote
Code: [Select]
while(digitalRead(pulsante)){lampeggio_attivo=1;}
E lo sapevo che provavi a mettere qualcosa li dentro  ;)

Non è la soluzione giusta, per vari motivi, tra cui il fatto che quella funzione dovrebbe occuparsi solo del proprio lavoro specifico e non anche di cosa devono fare altre funzioni di processi indipendenti (possiamo considerare il lampeggio del LED un processo a sè stante indipendente da quello del controllo motore).

Si è fatto tanto per eliminare i delay bloccanti usando millis, ma quei while sono esattamente come dei delay, l'esecuzione si pianta la dentro fintantoché la condizione di guardia del ciclo continua a restare vera.

È comunque giusto lavorare su quella singola funzione, le altre vanno già bene, quindi è solo da quella che bisogna rimuovere cicli bloccanti.

Come esempio questo codice inverte lo stato del LED 13 ogni volta che viene premuto il pulsante... ma non sta ad attendere che venga anche rilasciato. Il principio è identificare l'istante di cambiamento dell'ingresso confrontandolo con lo stato letto nel ciclo precedente.
Code: [Select]
#define OBD_LED      13
#define PIN_INGRESSO ...
#define PRESS_STATE  ...


byte inPrec = !PRESS_STATE;


void setup()
{
    pinMode(OBD_LED, OUTPUT);
    pinMode(PIN_INGRESSO, INPUT);
}


void loop()
{
    byte in = digitalRead(PIN_INGRESSO);

    if (in != inPrec  &&  in == PRESS_STATE)
        digitalWrite(OBD_LED, !digitalRead(OBD_LED));

    inPrec = in;
}
********* IF e SWITCH non sono cicli ! *********
**** Una domanda ben posta è già mezza risposta ****
*** La corrente si misura in mA, la quantità di carica in mAh ***

Etemenanki

... in attesa di "clienti" che mi chiedano modifiche ...
... il caffe' lo fa ? ...

(scusa, non ho resistito :D)
"Sopravvivere" e' attualmente l'unico lusso che la maggior parte dei Cittadini italiani,
sia pure a costo di enormi sacrifici, riesce ancora a permettersi.

docsavage

beh, se vuoi una cosa da fare, che potrebbe essere interessante...

prova a far seguire un encoder

ruoti l'encoder e si gira l'albero dello stepper, di un passo per ogni impulso dell'encoder

e aggiungi un controllo sulla massima coppia e massima accelerazione dello stepper,
quindi se il movimento dell'encoder supera le capacità dello stepper, riduci la velocità dello stepper, ma prolunghi il movimento, fino a fargli raggiungere comunque la posizione voluta, pur se con un minimo ritardo

naturalmente in questo caso accendi DUE led di segnalazione

uno immediato, che si spegne subito appena la condizione passa (ovvero la differenza tra albero d'ingresso ed albero di uscita scende sotto un valore accettabile)

ed un secondo led che memorizza l'allarme, che si può resettare solo premendo l'apposito pulsante

non sarebbe male far lampeggiare il led che adesso lampeggia sempre, secondo un ben preciso codice

del tipo un decimo di secondo on un decimo off tutto OK
un secondo di pausa, 1 impulso da un decimo: sovravelocità in senso orario
e via così


naturalmante occorre prevedere il caso che siano intervenuti DUE o PIU' differenti allarmi, e fare lampeggi alternati per indicare tutti gli allarmi intervenuti


occhio che non sto scherzando, cose del genere sono abbastanza comuni
E' stato bello... ma appunto: è stato
Ocio, che adesso c'è qualcuno che dice le stesse cose per le quali mi martellavate... Il tempo è galantuomo

Puso

Giusto Giusto

immaginavo che il problema fosse il zona pulsante,in sti giorni ci lavoro sù. >:(

Un passo alla volta prima correggo le variabili che adesso ho compreso un po meglio,poi mi invento qualkosa sulla zona pulsante, :smiley-cry:
poi ci metto la macchinetta del caffè, :smiley-mr-green:
poi.........rileggo quello che ha scritto Docsavage di cui apprezzo il fatto che lo vedo molto speranzoso sui miei progressi e per farlo contento ne voglio mettere 2 di encoder di cui1 dice all'altro cosa fare. :smiley-eek-blue:

A parte gli scherzi appena riaggiungo un po di padronanza con le cose semplici di base,potrebbe essere un esercizio interessate per me per fare il passo sucessivo.

Ok mi do da fare appena riesco lo posto per il momento ancora grazie.

docsavage

Interessante la cosa dei due encoder

hai ragione, ne vanno due, uno sull'albero d'ingresso e l'altro su uno dei due alberi di uscita di un differenziale, per controllare la velocità dell'altro albero di uscita e trasformarlo in un cambio epicicloidale
nemmeno questo è uno scherzo, mai sentito parlare di toyota prius?


ma, sempre senza scherzare, hai chiesto tu di proporti delle cose nuove da fare
io ti ho solo soddisfatto................
E' stato bello... ma appunto: è stato
Ocio, che adesso c'è qualcuno che dice le stesse cose per le quali mi martellavate... Il tempo è galantuomo

Go Up