nathanvi l'aveva detto...

ciao a tutti,

ho compilato il mio 2° semplice sketch che spero, con grossa soddisfazione dei principianti, di farlo vedere sul forum al più presto funzionante anche meccanicamente. lo sketch è ok a parte dei particolari.

si tratta di un arm su 2 assi + una pinza il tutto pilotato attraverso un joystik. quando la pinza afferra un oggetto e lo solleva il peso viene misurato da un sensore (force sensor) ho previsto che in base al peso si accendano dei led dapprima verdi poi gialli ed infine rossi per avvertire che siamo vicino al punto critico.

quando volevo che il led rosso lampeggiasse per attirare l'attenzione ho usato il delay come sempre. sorpresa. ovviamente mi temporizza anche la corsa dei servi.

quindi bisogna usare il mills come mi aveva consigliato tempo fa l'amico NATHANVI.

ho scaricato questo codice:

unsigned long time;
byte mem=0;

void setup(){
...
time=millis();
....
}

void loop(){

 if(millis>time+1000){
  digitalWrite(PIN,!mem);
}

fai altro nel frattempo...

non riesco a capire, al posto del "HIGH" c'è "!mem"

c'è qualche anima buona che me lo spiega??

ringrazio in anticipo

la variabile mem è inizializzata a zero. l'operatore ! è l'operatore booleano NOT cioè fa la negazione. Quindi !mem equivale a NOT(0) cioè 1. Non se pero' se arduino veda l'uno come un HIGH... non ci ho mai provato

grazie Uccio,

per far lampeggiare un led io ho imparato che:

digitalWrite(pin, HIGH) per un tot tempo delay poi spegni digitalWrite(pin,LOW)

se non posso usare il delay perchè ferma il prog, ma invece il mills(che lo fa proseguire) questa funzione dovrà essere impostata oltre come comando HIGH/LOW anche come tempo di intermittenza????

continuo a non capire...

nel loop ci dovra essere qualcosa del genere:

if (millis() - previousMillis > interval) {

    previousMillis = millis();   

    if (ledState == LOW)
      ledState = HIGH;
    else
      ledState = LOW;

digitalWrite(ledPin, ledState);

il significato dell'if iniziale è: fino a quando non sia passato un tempo pari ad interval dall'ultima volta che hai acceso o spento il led (cioè pari a previousMillis) non fare niente. se invece è passato commuta lo stato del led.

Aggiungo una cosa ad integrazione di quello che ha detto uccio. Il pezzo di codice in oggetto è:

 if(millis>time+1000){
  digitalWrite(PIN,!mem);
}

Come ha detto uccio, l'IF (che secondo me richiede un millis() e non solo millis) vuol dire che se è passato un secondo fa quello che c'è nelle quadre.

Il !mem usa, sempre come ha detto uccio, l'operatore "punto esclamativo" che significa NOT ovvero il contrario del valore di "mem" Puoi usare la formula che ha scritto con l'IF annidato oppure io preferisco in questo modo:

 if(millis>time+1000){
  mem= !mem
  digitalWrite(PIN,mem);
}

Fa la stessa cosa che fa uccio con gli IF ma la trovo più compatta. In altre parole dice: "se è passato un secondo dai a mem il suo valore contrario (quindi se era high assegna low e viceversa) e poi dai un digitalWrite con il valore di mem..." Spero sia chiaro.

giusto nathanvi

 if(millis()>time+1000){
  digitalWrite(PIN,!mem);
}

questo non avrebbe mai funzionato perchè mancava la commutazione di stato

mem=!mem;

perfetto ho capito tutto, sono molto contento di poter usare questa nuova funz che è una vera figata. la provo appena posso e vi dirò se funziona nel mio programmino.

grazie a tutti due gli amici, senza il vostro aiuto non andrei lontano.

riccardo

ho creato un sketch solo per studiare la funzione:

mi da errore nella riga " if(millis>time+1000){ " con la dicitura:

In function 'void loop()': error: ISO C++ forbids comparison between pointer and integer

ti invio il codice con dei commenti a lato che sono quello che dovrebbero fare le funzioni secondo me ditemi se sono conclusioni giuste, se non vi ho ancora rotto con le mie richieste.

ciao e grazie

// TEST MILLS

unsigned long time;       // definisce time come valore senza segno intero lungo
byte mem=0;               //   gli dice che mem può essere  o 0/1
int ledpin=13;          // ouput  pin 13

void setup(){
  
time=millis();        // time è uguale a dei millisecondi che partono quando arriva a questa funzione
pinMode(ledpin,OUTPUT);  // solita zuppa
}

void loop(){

 if(millis>time+1000){    // se è passato un secondo da quando parte a contare (se scrivessi 500 sarebbe mezzo secondo) fai...
   mem=!mem                 //  inverte il valore di mem se 0 passa a 1 

  digitalWrite(ledpin,!mem);   // manda al pin 13 il valore di mem quindi lo fa lampeggiare per un secondo facendo 
//andare avanti il loop che ovviamente in un secondo ci passa su questa funzione un paio di milioni di volte.
  
}

prova cosi

// TEST MILLS

unsigned long time;       // definisce time come valore senza segno intero lungo
byte mem=0;               //   gli dice che mem può essere  o 0/1
int ledpin=13;          // ouput  pin 13

void setup(){
  
time=millis();        // time è uguale a dei millisecondi che partono quando arriva a questa funzione
pinMode(ledpin,OUTPUT);  // solita zuppa
}

void loop(){

 if (millis() > time+1000){    // se è passato un secondo da quando parte a contare (se scrivessi 500 sarebbe mezzo secondo) fai...
   mem=!mem;             //  inverte il valore di mem se 0 passa a 1

  digitalWrite(ledpin,mem);   // manda al pin 13 il valore di mem quindi lo fa lampeggiare per un secondo facendo
//andare avanti il loop che ovviamente in un secondo ci passa su questa funzione un paio di milioni di volte.
  
}

hai dimenticato le parentesi affianco a millis:

if(millis()>time+1000)

mi sono spremuto tutta la sera e qualche ora questa mattina ma non riesco a capire la funzione al 100%.

ho controllato ogni passaggio: appena si lancia lo sketch lo carica , fa rimanere spento il led 13 per un secondo (quindi la stringa "if" funziona perfettamente) poi come deve essere passa in HIGH e si accende e rimane sempre acceso. in teoria dovrebbe nella ripetizione del loop trovare il mem con valore 1 e riconvertirlo in 0 quindi spegnere il led , il tutto con l'intermittenza di un secondo.

PS ho inserito un led pin 12 solo per verificare che il programmo fili liscio senza interferire

// TEST MILLIS

unsigned long time;        // definisce time come valore senza segno intero lungo
byte mem=0;               //   gli dice che mem può essere  o 0/1
int ledpin=13;           //   pin 13
int ledpin12=12;        // pin 12

void setup(){

   
time=millis();                      // time è uguale a dei millisecondi che partono quando arriva a questa funzione
pinMode(ledpin,OUTPUT);            // solita zuppa
pinMode(ledpin12,OUTPUT);         // solita zuppa
}

void loop(){
  {digitalWrite(ledpin12,HIGH);          // led test per vedere che il prog continui senza temporizzazioni
  }

  {
 if (millis() > time+1000){           //dal tempo mills qualsiasi numenro sia, che uguale a time +1000 quindi l'if e valido solo
                                     //dopo che è trascorso un secondo.
   mem=!mem;                        //inverte il mem da 0 a 1 o l'opposto
   
  digitalWrite(ledpin,mem);       // dato che lo stato all'inizio del loop il pin 13 è 0 lo porta a 1 e accende il led dopo 1 secondo
  
}
}
}

qualche consiglio??

riccardo :)

paverik, vedi quello che ti scrivevo tempo fa? (e da qui il titolo del tuo topic) Procedendo per piccoli passi si comprendono molte cose. Il problema sta nel time=millis() inserito in setup. In questo modo tu lo inizializzi all'inizio dello sketc e quando gli vai a dire:

if(millis() > time+1000)

essendo time inizializzato nel setup, l'if sarà sempre vero e quindi il LED sempre acceso! Prova anche ad inserire una valorizzazione nel time tipo questa:

if (millis() > time+1000){  
   mem=!mem;                  
  digitalWrite(ledpin,mem);
  time = millis();
}

ovvero ogni volta che cambi stato del led fai anche un "refresh della variabile time".

Aggiungo anche un'altra cosa. Al posto di

mem=!mem;

ho trovato da un codice di AlphaBeta (un utente del forum) che è veramente in gamba, una alternativa che "stilisticamente" mi è piaciuta molto perchè assomiglia al perl:

  mem ? mem=false : mem=true;

E' una sorta di if che recita come segue:

Che valore ha mem? Se vero fallo diventare falso, viceversa fallo diventare vero.

Carino no?

e' ovvio quando entri nel blocco if non aggiorni time.

nathanvi mi hai anticipato

grazie per i consigli,

l'ho subito provato e funziona perfettamente.

ovvio io pensavo che il mills tornasse a zero quando passava per il loop.

Nathanvi, ho seguito al 100% il tuo consiglio, mi sono divertito a far lampeggiare led , variare con PWM lintensità, attaccare sensori vari, pilotare servi con difficoltà ma con grande divertimento e soddisfazione.Il tutto non copiando con il copia incolla gli esempi ma cercando di capire ogni singola stringa.

mi stò anche documentando, anche se devo dire che l'argomento non è difficile (perchè il linguaggio è logico) ma è difficilissimo ed estremamente raro trovare un testo che te lo spiega con semplicità e in modo pragmatico come fate VOI amici esperti del forum.

Vi faccio un esempio pratico: nel prog che sto eleborando funziona tutto perfettamente ma dato che devo pilotare 3 servi attraverso 3 input differenti in scioltezza ho previsto le porte pin 9-10-11 in PWM. sorpresa. la porta 11 non va. comincio a spremermi dopo varie prove determino che non è un proplema sintattico. cerco di documentarmi e scopro che le porte hanno un "controlled by timer" diverso (infatti la 9 e 10 funzionano timer 1) . ma dove trovo chi mi spiega cosè questo parametro e soprattutto come si setta??? vi assicuro non è facile.

lungi da me la voglia di passare per uno che vuol fare il passo più lungo della gamba. anche se nelle idee che mi frullano nella testa ci sono obiettivi che probabilmente non raggiungerò, ma sognare non costa nulla.

grazie ancora alla prossima (ci sarà di sicuro)