millis...lo odio

Sempre allo scopo di studio so cercando di sosituire il delay del codice sottoriportato con la funzionemillis().
Ho letto sia il thread di sukkopera, che quello di Zuccalà e altro tuttavia non sono riuscito a farlo girare.
A livello sintattico sembra andare in quanto l'IDE non mi ha dato errori. Ho definito le variabili nel setup, ripetute nel loop...e inserito il ciclo if dove ora si trova il delay...non gira....dov'è che sbaglio?

/*
  PINOUT:
  RC522 MODULO    Uno/Nano
  SDA             D10
  SCK             D13
  MOSI            D11
  MISO            D12
  IRQ             N/A
  GND             GND
  RST             D9
  3.3V            3.3V
  led verde al Pin 3
  Led rosso al Pin 4
  Relè al Pin 2
*/
#include <SPI.h>
#include <RFID.h>
#include <string.h> // libreria per manipolazione stringhe
/* ========================= Vengono definiti PIN del RFID reader ============ */
#define SDA_DIO 10  // Pin 53 per Arduino Mega
#define RESET_DIO 9
#define delayRead 1000 // Tempo 
#define delayLed 2000
#define ledVerde 3
#define ledRosso 4
#define rele 2
/* ================ Viene creata una istanza della RFID libreria ============= */
RFID RC522(SDA_DIO, RESET_DIO);
char codici[3][11] = {"C5E8165368", "43AA7A25B6", "6FDDAF928B"}; // definizione array char
void setup()
{
  Serial.begin(9600);
  /* ================ Abilita SPI ==================== */
  SPI.begin();
  /* ================ Viene inizilizzato RFID reader =============== */
  RC522.init();
  Serial.println("Setup");
  pinMode(ledVerde, OUTPUT);
  pinMode(ledRosso, OUTPUT);
  pinMode(rele, OUTPUT);
}
void loop()
{
  /* ============== Temporary loop counter ===================== */
  byte i;
  byte d;
  // Se viene letta una tessera
  if (RC522.isCard())
  {
    delay(600);
  // =========== Viene letto il suo codice
    RC522.readCardSerial();
    String codiceLetto = "";
    Serial.println("Codice della tessera letto:");
  // ================ Viene caricato il codice della tessera, all'interno di una Stringa
    for (i = 0; i <= 4; i++)
    {
      codiceLetto += String (RC522.serNum[i], HEX);
      codiceLetto.toUpperCase();
    }
    Serial.println(codiceLetto);
    for (d = 0; d < 30; d++)  // REM dimensione dell'array
    {
  // HAI trovato il codice, esci dal for. L'indice i ti dice quale è il codice trovato
      if (strcmp(codici[d], codiceLetto.c_str()) == 0 ) // sukkopera
      {
        Serial.println("AUTORIZZATA");
        digitalWrite(ledVerde, HIGH);
        digitalWrite(rele, HIGH);
        delay(600);
        digitalWrite(ledVerde, LOW);
        digitalWrite(rele, LOW);
        break;
      }
    }
    if (d == 30)
    {
  // NON HAI trovato il codice e l'indice è arrivato fino a 30 poi sei uscito dal for.
      Serial.println("NON AUTORIZZATA");
      digitalWrite(ledRosso, HIGH);
      digitalWrite(rele, LOW);
      delay(600);
      digitalWrite(ledRosso, LOW);
    }
  }
}

Nel codice postato non ci sono variabili definite per millis ne utilizzo di millis() ma i delay() è un errore di copia incolla? o non ho capito la domanda?

>vince59: spero tu sia conscio che NON è che si può sostitire semplicemente delay() con millis(), ma occorre ristrutturare completamente il codice per gestire la logica non bloccante e l'"evento" temporale indotto da millis().

Io darei di nuovo una bella studiata a quello che trovi prima QUI, poi QUI ed infine anche QUI e QUI ... ::slight_smile:

Guglielmo

Ciao Guglielmo,

sono assolutamente cosciente di ciò che affermi grazie alle indicazioni tue, idi sukkopera e degli altri....ovviamente intendevo sosituire il delay con la funzione millis strutturata come previsto. Definizione variabili, e comparazione dei tempi con relativo azzeramento.

@ fabpolli si è corretto ciò che dici questo è il codice pulito. Il delay che vorrei sosituire ocn la funzione millis (a scopo di studio) è il primo delay all'interno del loop.
Ora provo a ricostruire il codice che avevo scritto con millis e poi mi direte.

..ci sono riuscito...ho cominciato a gestire pure l'odioso millis() :sunglasses:

/*
  PINOUT:
  RC522 MODULO    Uno/Nano
  SDA             D10
  SCK             D13
  MOSI            D11
  MISO            D12
  IRQ             N/A
  GND             GND
  RST             D9
  3.3V            3.3V
  led verde al Pin 3
  Led rosso al Pin 4
  Relè al Pin 2
*/

#include <SPI.h>
#include <RFID.h>
#include <string.h> // libreria per manipolazione stringhe
/* ========================= Vengono definiti PIN del RFID reader ============ */
#define SDA_DIO 10  // Pin 53 per Arduino Mega
#define RESET_DIO 9
#define ledVerde 3
#define ledRosso 4
#define rele 2
/* ================ Viene creata una istanza della RFID libreria ============= */
RFID RC522(SDA_DIO, RESET_DIO);
char codici[3][11] = {"C5E8165368", "43AA7A25B6", "EC40E03480"}; // definizione array char
unsigned long previousMillis = 0; //millis
const long interval = 1000;       // millis
void setup()
{
  Serial.begin(9600);
  /* ================ Abilita SPI ==================== */
  SPI.begin();
  /* ================ Viene inizilizzato RFID reader =============== */
  RC522.init();
  Serial.println("Setup");
  pinMode(ledVerde, OUTPUT);
  pinMode(ledRosso, OUTPUT);
  pinMode(rele, OUTPUT);
}
void loop()
{
  unsigned long currentMillis = millis();   // millis
  /* ============== Temporary loop counter ===================== */
  byte i;
  byte d;
  // Se viene letta una tessera
  if (RC522.isCard())
  {
  // si attende un breve ritardo    
    if (currentMillis - previousMillis >= interval)   // millis
    {                                                 // millis
      previousMillis = currentMillis;                 // millis
  // =========== Viene letto il suo codice
      //delay(600);
      RC522.readCardSerial();
      String codiceLetto = "";
      Serial.println("Codice della tessera letto:");
  // ================ Viene caricato il codice della tessera, all'interno di una Stringa
      for (i = 0; i <= 4; i++)
      {
        codiceLetto += String (RC522.serNum[i], HEX);
        codiceLetto.toUpperCase();
      }
      Serial.println(codiceLetto);
  // ============== Viene verificato se il codice è tra quelli autorizzati o meno
      for (d = 0; d < 3; d++)
      {
  // trovato il codice, esce dal for. L'indice i indica qual'è il codice trovato
        if (strcmp(codici[d], codiceLetto.c_str()) == 0 ) // sukkopera
        {
          Serial.println("AUTORIZZATA");
          digitalWrite(ledVerde, HIGH);
          delay(500);
          digitalWrite(ledVerde, LOW);
          //   digitalWrite(rele, HIGH);
          //   delay(800);
          //   digitalWrite(rele, LOW);
          break;
        }
      }
      if (d == 3)
      {
  // codice NON trovato; l'indice è arrivato fino a 30 ed è uscito dal for.
        Serial.println("NON AUTORIZZATA");
        // delay(500);
        digitalWrite(ledRosso, HIGH);
        delay(500);
        digitalWrite(ledRosso, LOW);
      }
    } // millis
  }
}

Ma perché diavolo sprecate SEMPRE una variabile di ben 4 bytes per "currentMillis" ? ? ? :o

Non sapete usare direttamente la funzione millis() senza metterla in una variabile ? ? ?

if (millis() - previousMillis >= interval) ...
...
previousMillis = millis();

Guglielmo

...azz....pensavo di aver scampato la cazziata!!! rimediato subito!!!

/*
  PINOUT:
  RC522 MODULO    Uno/Nano
  SDA             D10
  SCK             D13
  MOSI            D11
  MISO            D12
  IRQ             N/A
  GND             GND
  RST             D9
  3.3V            3.3V
  led verde al Pin 3
  Led rosso al Pin 4
  Relè al Pin 2
*/

#include <SPI.h>
#include <RFID.h>
#include <string.h> // libreria per manipolazione stringhe
/* ========================= Vengono definiti PIN del RFID reader ============ */
#define SDA_DIO 10  // Pin 53 per Arduino Mega
#define RESET_DIO 9
#define ledVerde 3
#define ledRosso 4
#define rele 2
/* ================ Viene creata una istanza della RFID libreria ============= */
RFID RC522(SDA_DIO, RESET_DIO);
char codici[3][11] = {"C5E8165368", "43AA7A25B6", "EC40E03480"}; // definizione array char
unsigned long previousMillis = 0; //millis
const long interval = 1000;       // millis
void setup()
{
  Serial.begin(9600);
  /* ================ Abilita SPI ==================== */
  SPI.begin();
  /* ================ Viene inizilizzato RFID reader =============== */
  RC522.init();
  Serial.println("Setup");
  pinMode(ledVerde, OUTPUT);
  pinMode(ledRosso, OUTPUT);
  pinMode(rele, OUTPUT);
}
void loop()
{
  //unsigned long currentMillis = millis();   // millis
  /* ============== Temporary loop counter ===================== */
  byte i;
  byte d;
  // Se viene letta una tessera
  if (RC522.isCard())
  {
  // si attende un breve ritardo    
  //  if (currentMillis - previousMillis >= interval)   // millis
  //  {                                                 // millis
  //    previousMillis = currentMillis;                 // millis

   if (millis() - previousMillis >= interval)
   {
     previousMillis = millis();
  // =========== Viene letto il suo codice
      //delay(600);
      RC522.readCardSerial();
      String codiceLetto = "";
      Serial.println("Codice della tessera letto:");
  // ================ Viene caricato il codice della tessera, all'interno di una Stringa
      for (i = 0; i <= 4; i++)
      {
        codiceLetto += String (RC522.serNum[i], HEX);
        codiceLetto.toUpperCase();
      }
      Serial.println(codiceLetto);
  // ============== Viene verificato se il codice è tra quelli autorizzati o meno
      for (d = 0; d < 3; d++)
      {
  // trovato il codice, esce dal for. L'indice i indica qual'è il codice trovato
        if (strcmp(codici[d], codiceLetto.c_str()) == 0 ) // sukkopera
        {
          Serial.println("AUTORIZZATA");
          digitalWrite(ledVerde, HIGH);
          delay(500);
          digitalWrite(ledVerde, LOW);
          //   digitalWrite(rele, HIGH);
          //   delay(800);
          //   digitalWrite(rele, LOW);
          break;
        }
      }
      if (d == 3)
      {
  // codice NON trovato; l'indice è arrivato fino a 30 ed è uscito dal for.
        Serial.println("NON AUTORIZZATA");
        // delay(500);
        digitalWrite(ledRosso, HIGH);
        delay(500);
        digitalWrite(ledRosso, LOW);
      }
    } // millis
  }
}

vince59:
...azz....pensavo di aver scampato la cazziata!!! vedo di provvedere immediatamente

Guglielmo

gpb01:

Guglielmo

inutile che ridi ho già fatto :grin: :blush: :grin:

vince59:
inutile che ridi ho già fatto :grin: :blush: :grin:

OTTIMO !!!

Guglielmo

:grin: 8)

vorrei che il post 9 diventasse uno sticky :-)))))))

vince59:
:grin: 8)

vorrei che il post 9 diventasse uno sticky :-)))))))

... perche' ? ... e' davvero cosi raro che Guglielmo vi faccia un complimento, invece di darvi la solita strigliata con la centogradi col vapore al massimo ? ... (:stuck_out_tongue: :D)

gpb01:
Ma perché diavolo sprecate SEMPRE una variabile di ben 4 bytes per "currentMillis" ? ? ? :o

Non sapete usare direttamente la funzione millis() senza metterla in una variabile ? ? ?

if (millis() - previousMillis >= interval) ...

...
previousMillis = millis();



Guglielmo

Probabilmente quella variabile non finirà nello stack ma il compilatore userà uno o più registri per contenerla, quindi il risultato con la tua forma piu prolissa è praticamente identico.

vbextreme:
probabilmente quella variabile
non finirà nello stack ma il compilatore userà
uno o più registri per contenerla,
quindi il risultato con la tua forma
piu prolissa è praticamente identico.

questa cosa e' aleatoria
dipende da tante considerazioni
potrebbe essere cosi', oppure no

la voce "register" potrebbe aiutare
a forzare l'uso di un registro piuttosto
che locazioni in stack, pero' non e' sicuro
dipende anche da come e' implementata
la machine layer del compilatore C

e varia pure da architettura ad architettura
p.e. sulle softfloat registers, macchine stack based
(core 680x, picoJava) e' altamente improbabile
dato che i softregister sono implementati in ram

vale piu' per le macchine RISC

Però perché se faccio così:

/* Blink without Delay

 Turns on and off a light emitting diode (LED) connected to a digital
 pin, without using the delay() function.  This means that other code
 can run at the same time without being interrupted by the LED code.

 The circuit:
 * LED attached from pin 13 to ground.
 * Note: on most Arduinos, there is already an LED on the board
 that's attached to pin 13, so no hardware is needed for this example.

 created 2005
 by David A. Mellis
 modified 8 Feb 2010
 by Paul Stoffregen
 modified 11 Nov 2013
 by Scott Fitzgerald


 This example code is in the public domain.

 http://www.arduino.cc/en/Tutorial/BlinkWithoutDelay
 */

// constants won't change. Used here to set a pin number :
const int ledPin =  13;      // the number of the LED pin

// Variables will change :
int ledState = LOW;             // ledState used to set the LED

// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long previousMillis = 0;        // will store last time LED was updated

// constants won't change :
const long interval = 1000;           // interval at which to blink (milliseconds)

void setup() {
  // set the digital pin as output:
  pinMode(ledPin, OUTPUT);
}

void loop() {
  // here is where you'd put code that needs to be running all the time.

  // check to see if it's time to blink the LED; that is, if the
  // difference between the current time and last time you blinked
  // the LED is bigger than the interval at which you want to
  // blink the LED.
 // unsigned long currentMillis = millis();

  if (millis() - previousMillis >= interval) {
    // save the last time you blinked the LED
    previousMillis = millis();

    // if the LED is off turn it on and vice-versa:
    if (ledState == LOW) {
      ledState = HIGH;
    } else {
      ledState = LOW;
    }

    // set the LED with the ledState of the variable:
    digitalWrite(ledPin, ledState);
  }
}

Spreco Lo sketch usa 876 byte (2%) dello spazio disponibile per i programmi. Il massimo è 32.256 byte.
Le variabili globali usano 15 byte (0%) di memoria dinamica, lasciando altri 2.033 byte liberi per le variabili locali. Il massimo è 2.048 byte.

/* Blink without Delay

 Turns on and off a light emitting diode (LED) connected to a digital
 pin, without using the delay() function.  This means that other code
 can run at the same time without being interrupted by the LED code.

 The circuit:
 * LED attached from pin 13 to ground.
 * Note: on most Arduinos, there is already an LED on the board
 that's attached to pin 13, so no hardware is needed for this example.

 created 2005
 by David A. Mellis
 modified 8 Feb 2010
 by Paul Stoffregen
 modified 11 Nov 2013
 by Scott Fitzgerald


 This example code is in the public domain.

 http://www.arduino.cc/en/Tutorial/BlinkWithoutDelay
 */

// constants won't change. Used here to set a pin number :
const int ledPin =  13;      // the number of the LED pin

// Variables will change :
int ledState = LOW;             // ledState used to set the LED

// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long previousMillis = 0;        // will store last time LED was updated

// constants won't change :
const long interval = 1000;           // interval at which to blink (milliseconds)

void setup() {
  // set the digital pin as output:
  pinMode(ledPin, OUTPUT);
}

void loop() {
  // here is where you'd put code that needs to be running all the time.

  // check to see if it's time to blink the LED; that is, if the
  // difference between the current time and last time you blinked
  // the LED is bigger than the interval at which you want to
  // blink the LED.
  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;

    // if the LED is off turn it on and vice-versa:
    if (ledState == LOW) {
      ledState = HIGH;
    } else {
      ledState = LOW;
    }

    // set the LED with the ledState of the variable:
    digitalWrite(ledPin, ledState);
  }
}

Così spreco Lo sketch usa 862 byte (2%) dello spazio disponibile per i programmi. Il massimo è 32.256 byte.
Le variabili globali usano 15 byte (0%) di memoria dinamica, lasciando altri 2.033 byte liberi per le variabili locali. Il massimo è 2.048 byte.

50c50
<  // unsigned long currentMillis = millis();
---
>   unsigned long currentMillis = millis();
52c52
<   if (millis() - previousMillis >= interval) {
---
>   if (currentMillis - previousMillis >= interval) {
54c54
<     previousMillis = millis();
---
>     previousMillis = currentMillis;
68a69
>

credo, perche' ha optato per allocare una variabile
uint32_t currentMillis
da 32bit, 4 byte, in stack

"probabilmente" (da verificare) potresti aver
benefici preponendo "register", tipo cosi'
register uint32_t currentMillis;
se il compilatore onora la richiesta, ti ritrovi
currentMillis implementata "a registro"

ora, su macchine a 32bit un registro e' a 32bit
ed e' sufficiente per contenere una variabile uint32_t

su macchine ad 8bit, un registro e' ad 8bit
quindi … questa cosa del voler implementare
una variabile a 32bit su 4 registri ad 8 bit
costa sicuramente dei push & pop e del glue logic
nel mezzo, e potrebbe venire scaratata, sopratutto
se si e' data flag di ottimizzazione per spazio

a sua volta, la chiamata a funzione dentro la
if (millis() … )
schiaffa il suo ret-type (size? 4 byte?) o su stack
o su registro temporaneo, ridotto poi per il calcolo
della conditional branch (se saltare nel ramo true,
o false)

pero' e' spannometria speculativa la mia,
per essere certi di cosa succeda bisognerebbe
sbirciare l'assembly, che racconta cosa ha deciso di fare
il compilatore di turno, caso per caso

provate, io non ho modo di farlo al momento :smiley:

Dato che gli sketch vengono compilati con g++ e dato che il C++ dichiara l'inutilità di usare "register", io per essere coerente non lo uso mai.
Discorso a parte per il C, di cui ha già dato ottime delucidazioni @Y888099.

Come ha notato @As_Needed, più il codice è "semplice" o meglio "chiaro" e più possibilità ha il compilatore di ottimizzare.
Di conseguenza scrivere meno codice in C non significa che il codice sia più performante.