Problema pulsanti led millis

buona sera a tutti, chiedo un enorme aiuto in quanto sono ad una settimana che ci provo ma non mi esce il risultato che voglio.
in poche parole ho creato un dispositivo avente un arduino nano, un sensore a ultrasuoni hc-sr04, 2 sensori e18-d80nk e 5 led.
3 led sono dedicati al sensore di cui misura la distanza di pellet che ho nella cassa.. gli altri 2 sono collegati ai sensori che ho predisposto a metà e fine cassa.
il mio intento è
sensore 1 HIGH && sensore 2 LOW -> led1 spento, led 2 acceso lampeggiante
sensore 2 HIGH -> sensore 2 HIGH -> led 1 acceso - led 2 spento
sensore 1 LOW && sensore 2 LOW -> led 1 spento - led 2 spento

//programma lettura pellet nel silos

#define TRIG_PIN 15 // ingresso A1 di arduino nano utilizzato come ingresso digitale
#define ECHO_PIN 14 // ingresso A0 di arduino nano utilizzato come ingresso digitale
#include <SR04.h>
SR04 sr04 = SR04(ECHO_PIN, TRIG_PIN); //inseriamo un oggetto di tipo SRO4, lo chiamiamo sr04 e gli diamo come parametri i pin utilizzati per TRIG ed ECHO


#include "SevSegShift.h"

#define SHIFT_PIN_SHCP 4
#define SHIFT_PIN_STCP 5
#define SHIFT_PIN_DS   6

SevSegShift sevseg(SHIFT_PIN_DS, SHIFT_PIN_SHCP, SHIFT_PIN_STCP);

#define ledGreen 9
#define ledYellow 8
#define ledRed 7

#define LedYellowSens 10
#define LedRedSens 11
#define SensMezzo 2
#define SensFine  3


int pellet;

void setup() {
  pinMode (ledGreen, OUTPUT);
  pinMode (ledYellow, OUTPUT);
  pinMode (ledRed, OUTPUT);
  pinMode (LedYellowSens, OUTPUT);
  pinMode (LedRedSens, OUTPUT);
  pinMode (SensMezzo, INPUT);
  pinMode (SensFine, INPUT);
  



  // impostiamo la libreia sevseg con i relativi parametri.
    byte numDigits = 4;
  byte digitPins[] = {1, 2, 3, 4}; // of ShiftRegister(s) | 8+x (2nd Register)
  byte segmentPins[] = {8 + 0, 8 + 1, 8 + 2, 8 + 3, 8 + 4, 8 + 5, 8 + 6, 8 + 7}; // of Shiftregister(s) | 8+x (2nd Register)
  bool resistorsOnSegments = false; // 'false' means resistors are on digit pins
  byte hardwareConfig = COMMON_CATHODE; // See README.md for options
  bool updateWithDelays = false; // Default 'false' is Recommended
  bool leadingZeros = false; // Use 'true' if you'd like to keep the leading zeros
  bool disableDecPoint = true; // Use 'true' if your decimal point doesn't exist or isn't connected

  sevseg.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments,
               updateWithDelays, leadingZeros, disableDecPoint);
  sevseg.setBrightness(90);
  Serial.begin(9600);

}


void loop() {


  static unsigned long timer = millis();

  if (millis() - timer >= 1000) { //sfruttando la funzione millis facciamo in modo che ogni 1000 ms dal reset della scheda
    timer += 1000; //(o dall'avvio) avvenga una lettura del sensore di distanza
    pellet = sr04.Distance();
  }
  sevseg.setNumber(pellet);
  Serial.print(pellet);
  Serial.println("cm");

  sevseg.refreshDisplay();


  if (pellet < 40) { // accendiamo il primo led se la misura è sotto i 50 cm
    digitalWrite (ledGreen, HIGH);
    digitalWrite (ledYellow, LOW);
    digitalWrite (ledRed, LOW);
  }
  
  else if (pellet <= 41 && pellet >= 64) { // tra i 50 e i 95 cm facciamo accendere il secondo led
    digitalWrite (ledGreen, LOW);
    digitalWrite (ledYellow, HIGH);
    digitalWrite (ledRed, LOW);
  }
  
  else if (pellet > 65) { //dopo i 100 cm facciamo accendere il terzo led
    digitalWrite (ledGreen, LOW);
    digitalWrite (ledYellow, LOW);
    digitalWrite (ledRed, HIGH);

  }
  if ( digitalRead(SensMezzo) == LOW ) {

    digitalWrite (LedYellowSens, HIGH);




  } else {
    digitalWrite (LedYellowSens, LOW );




  }


  if ( digitalRead(SensFine) == LOW) {

    digitalWrite (LedRedSens, HIGH);



  } else {
    digitalWrite (LedRedSens, LOW );




  }

}

fin qui ci sono arrivato e mo non riesco ad andare più avanti.
grazie in anticipo

Forse è più semplice se implementi una piccola macchina a stati finiti.

Giusto.

Si potrebbe anche seguire questo schema logico

LEGGI sensore1
SE sensore1 == HIGH
  LEGGI sensore2
  SE sensore2 == HIGH
    Led1ONLed2OFF()
  ELSE
    Led1OFFLed2Blink()
ELSE
  LEGGI sensore 2
  SE sensore2 == LOW
    Led1OFFLed2OFF()
  ELSE
    NonPrevisto()

Led1ONLed2OFF()
  Led1 = ON
  Led2 = OFF

Led1OFFLed2Blink()
  Led1 = OFF
  SE millis() >= intervallo
    reset millis()
    cambia stato Led2
  ELSE
    return

Led1OFFLed2OFF()
  Led1 = OFF
  Led2 = OFF

Ciao,
P.

Grazie mille dell'aiuto solo una cosa non ho capito.. C'è scritto non previsto.. Cosa intendi?

Con una combinazione di due ingressi hai 4 possibili stati, ma tu ne hai descritto solo 3.

E perché il 4 sarebbe tutti e 2 led accesi non mi servono.. Per questo ne ho scritto solo 3

Se non chiedo tanto.. Mi fareste capire come ragionereste voi con il mio problema? Cioè un esempio l'ho visto.. Ma vorrei capire come riuscire a creare una struttura non solo con questo esempio ma altri.. Per poi applicarli su altri progetti.. Se non chiedo tanto

La "struttura" come la chiami tu è una struttura logica deterministica, cioè un insieme di azioni che, nel caso di Arduino, si ripetono ciclicamente.

PRIMA DI PENSARE AL "PROGRAMMA" occorre descrivere IN ITALIANO il comportamento che si vuole ottenere dal sistema che si vuole implementare.
POI si cerca di suddividere il comportamento in parti più semplici e possibilmente indipendenti l'una dall'altra.

A questo punto occorre cercare di descrivere il funzionamento di ciascuna parte in termini di logica di programmazione. E qui occorre conoscere le istruzioni che hai a disposizione secondo quello che vuoi usare. Le prime strutture semplici sono quelle condizionali (SE ... ALLORA ... ALTRIMENTI ...) comuni a tutti i sistemi, e con queste già puoi fare molto. L'esempio che ti ho descritto usa solo quelle.

Quando una struttura condizionale diventa complicata, o impossibile da descrivere logicamente, ci sono altre strutture, come quella suggerita da cotestatnt. Qui trovi una descrizione.

Ciao,
P.

Ci sono diversi approcci, quello indicato da pgiagno è il più generale con cui affronti qualsiasi problema che richieda diverse fasi di funzionamento (o diversi processi in "parallelo").

In un caso come questo si può anche ragionare a livello più basso, abbiamo una tabella:

 s1  s2 | l1  l2
-----------------
  0   0 |  0   0
  1   0 |  0  blk
  1   1 |  1   0

da cui si vede che il LED1 è comandato semplicemente dall'and di s1 e s2:

digitalWrite(PIN_LED1, s1 && s2);

e abbiamo una condizione di lampeggio:

cond = s1 & !s2;

dopo di che serve un blinker comandato da questa condizione. Se è falsa uscita blinker 0 e blinker disattivo:

if (!cond) {  q = 0;   act = 0;  }

se vera possiamo essere alla prima attivazione, e quindi impostiamo uscita 'q' alta, blinker attivo, e ci salviamo il tempo di sistema per la temporizzazione:

else if (!act) {  q = 1;   act = 1;   t = millis();  }

oppure possiamo essere già in conteggio, e allora ad ogni timeout invertiamo l'uscita (e "ricarichiamo il tempo di sistema):

else if (millis()-t >= 500) {  q ^= 1;  t = millis();  }

Il blinker si comporta quindi in questo modo:

545675456

non resta che comandare il LED2 con l'uscita del blinker:

digitalWrite(PIN_LED2, q);

Wow.. Grazie mille per le diritte. Ora incomincio a capirci qualcosa.. Ho letto tanto e visto tanti video. Ma purtroppo non ho mai capito bene come strutturare uno sketch.. Fino a mo ho sempre copiato e incollato tutto un po' a destra un po' a sinistra allora sono riuscito.. Questo è il mio primo progetto che sto facendo da zero solo con quello che so. Vi ringrazio ancora.. Ps se era per me avevo risolto alla vecchia maniera con integrati, resistenze e condensatori .. Ma era troppo facile ahhah

Quando qualcuno mi chiede che progetto affrontare, dopo quelli elementari con led e sensori, io suggerisco di implementare un semaforo stradale.

La prima realizzazione consiste nel far alternare correttamente la successione delle luci con le temporizzazioni prestabilite, e fino a qui in genere non ci sono difficoltà, ma il mio consiglio è di utilizzare da subito la funzione millis() per i passi successivi.

Il secondo passo consiste nell'introdurre un pulsante che consenta di far passare il semaforo da "funzionante" a "luci gialle lampeggianti" e viceversa, tenendo conto che il passaggio da "luci gialle lampeggianti" a "funzionante" deve avvenire correttamente: 1)luci gialle fisse, 2)verde da un lato e rosso dall'altro, 3)funzionamento normale.

Il terzo passo consiste nel rendere "intelligente" il semaforo. Simulando sensori stradali, si verifica la presenza di veicoli in entrambe le direzioni di marcia. Se in una certa direzione non ci sono veicoli, quando dovrebbe scattare il verde per quella direzione, la temporizzazione viene prolungata (ad esempio: raddoppiata) a meno che non sopraggiunga in quel periodo un veicolo; nel qual caso il semaforo provvede alla successione delle luci per dargli subito via libera, ritornando alle temporizzazioni precedentemente impostate.

Il quarto passo consiste nella predisposizione al passaggio pedonale. Se un pedone preme il pulsante di prenotazione, in funzionamento normale non succede niente, nel senso che le luci si alternano con le temporizzazioni normali, Nel funzionamento "intelligente" occorre predisporre la precedenza al pedone.

Se qualcuno lo ha implementato fino al quarto stadio non me l'ha MAI detto.

Ciao,
P.

È un'applicazione classica ma sempre validissima!

Bisognerebbe preparare uno starter kit didattico con tanto di plastico e macchinine!
Sarebbe un bel progetto da portare nelle scuole.

Grazie cotestatnt, penso che sia valido perché ad ogni passo fornisce una realizzazione funzionante, e questo è necessario per gratificare il progettista e spingerlo a continuare.

Ciao,
P.

Più semplicemente, l1=s2.

//programma lettura pellet nel silos
#include "SevSegShift.h"

#define TRIG_PIN 14 // ingresso A0 di arduino nano utilizzato come ingresso digitale
#define ECHO_PIN 15 // ingresso A1 di arduino nano utilizzato come ingresso digitale
#include <SR04.h>
SR04 sr04 = SR04(ECHO_PIN, TRIG_PIN); //inseriamo un oggetto di tipo SRO4, lo chiamiamo sr04 e gli diamo come parametri i pin utilizzati per TRIG ed ECHO




#define SHIFT_PIN_SHCP 4 // va collegato al 4 di arduino e al 14 del 74HC595
#define SHIFT_PIN_STCP 5 // va collegato al 5 di arduino e al 12 del 74HC595
#define SHIFT_PIN_DS   6 // va collegato al 6 di arduino e al 11 del 74HC595

SevSegShift sevseg(SHIFT_PIN_DS, SHIFT_PIN_SHCP, SHIFT_PIN_STCP);

//led di controllo sensore ultrasuoni
#define ledGreen 7
#define ledYellow 8
#define ledRed 9

//led sensori IR E18-D80NK
#define LedYellowSens 10
#define LedRedSens 11

// Ingresso sensori IR E18-D80NK
#define SensMezzo 2
#define SensFine  3

// variabili Debounce

long t = 0;
long debounce_delay = 2000;

int stato = 1;

// variabili lampeggio led
unsigned long ritardo;
int led = 0;

int pellet;

void setup() {
  pinMode (ledGreen, OUTPUT);
  pinMode (ledYellow, OUTPUT);
  pinMode (ledRed, OUTPUT);
  pinMode (LedYellowSens, OUTPUT);
  pinMode (LedRedSens, OUTPUT);
  pinMode (SensMezzo, INPUT);
  pinMode (SensFine, INPUT);




  // impostiamo la libreia sevseg con i relativi parametri.
  byte numDigits = 4;
  byte digitPins[] = {1, 2, 3, 4}; // of ShiftRegister(s) | 8+x (2nd Register)
  byte segmentPins[] = {8 + 0, 8 + 1, 8 + 2, 8 + 3, 8 + 4, 8 + 5, 8 + 6, 8 + 7 }; // of Shiftregister(s) | 8+x (2nd Register)
  bool resistorsOnSegments = false; // 'false' means resistors are on digit pins
  byte hardwareConfig = COMMON_CATHODE; // See README.md for options
  bool updateWithDelays = false; // Default 'false' is Recommended
  bool leadingZeros = false; // Use 'true' if you'd like to keep the leading zeros
  bool disableDecPoint = true; // Use 'true' if your decimal point doesn't exist or isn't connected

  sevseg.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments,
               updateWithDelays, leadingZeros, disableDecPoint);
  sevseg.setBrightness(90);
  Serial.begin(9600);

}


void loop() {

  static unsigned long timer = millis();

  if (millis() - timer >= 1000) { //sfruttando la funzione millis facciamo in modo che ogni 1000 ms dal reset della scheda
    timer += 1000; //(o dall'avvio) avvenga una lettura del sensore di distanza
    pellet = sr04.Distance();
  }
  sevseg.setNumber(pellet); //  stampiamo la lettura del sensore a ultrasuoni sul display
  Serial.print(pellet); // stampiamo la lettura del sensore ad ultrasuoni sul pannello di arduino
  Serial.println("cm");

  sevseg.refreshDisplay();

// queste misure possono essere cambiate sostituendo i numeri e metterli a vostro piacere
  if (pellet < 40) { // accendiamo il primo led se la misura è sotto i 40 cm
    digitalWrite (ledGreen, LOW);
    digitalWrite (ledYellow, HIGH);
    digitalWrite (ledRed, HIGH);
  }

  else if (pellet <= 41 && pellet >= 64) { // tra i 41 e i 64 cm facciamo accendere il secondo led
    digitalWrite (ledGreen, HIGH);
    digitalWrite (ledYellow, LOW);
    digitalWrite (ledRed, HIGH);
  }

  else if (pellet > 65) { //dopo i 65 cm facciamo accendere il terzo led
    digitalWrite (ledGreen, HIGH);
    digitalWrite (ledYellow, HIGH);
    digitalWrite (ledRed, LOW);

  }

  if ((millis() - t) > debounce_delay) { // ritardo lettura sensori 
    int sens1 = digitalRead(SensMezzo); //sensore a ultrasuoni posto a metà della cassa del pellet
    int sens2 = digitalRead(SensFine);  //sensore a ultrasuoni posto alla fine della cassa del pellet
    t = millis();


    switch (stato) { // se i sensori sono tutti e 2 attivi i led sono spenti
      case 1:
        digitalWrite(LedYellowSens, HIGH);
        digitalWrite(LedRedSens, HIGH );
        //cambio di stato se:
        if (sens1 && !sens2) stato = 2; // se il primo sens1 e spento e il sens2 e attivo si sposta allo stato 2
        break;

      case 2: // il led giallo e attivo e il led rosso è spento
        digitalWrite(LedYellowSens, LOW);
        digitalWrite(LedRedSens, HIGH);
        //cambio di stato se:
        if (sens1 && sens2) stato = 3;    // se i sensori sono tutti e 2 spenti si passa allo stato 3
        if (!sens2 && !sens1) stato = 1;  // se i sensori sono tutti e 2 attivi i led sono spenti e si ritorna allo stato 1
        break;

      case 3: // il led giallo e spento e il led rosso e acceso lampeggiante
        digitalWrite(LedYellowSens, HIGH);
        if (millis() - ritardo > 500) {
          led = !led; // il valore stato cambia ogni volta che l'if è vero
          ritardo = millis(); // azzero il valvore di ritardo
        }

        digitalWrite(LedRedSens, led); // accendo e spengo il led in funzionae di "stato"

        if (sens1 && !sens2) stato = 2; se il primo sens1 e spento e il sens2 e attivo si sposta allo stato 2

        break;
    }
  }
}

ragazzi grazie mille di tutto.. ora finalmente sono arrivato dove volevo.
L'unica cosa e che il lampeggio del led cammina insiene al debaunce, non mi da fastidio ma vorrei capire il perche e dove ho sbagliato e se ci sono modifiche da fare vi sarei grato di illuminarmi.. grazie ancora

Hai messo lo switch dentro l'if del debounce.

  sevseg.setNumber(pellet); //  stampiamo la lettura del sensore a ultrasuoni sul display
  Serial.print(pellet); // stampiamo la lettura del sensore ad ultrasuoni sul pannello di arduino
  Serial.println("cm");

  sevseg.refreshDisplay();

// queste misure possono essere cambiate sostituendo i numeri e metterli a vostro piacere
  if (pellet < 40) { // accendiamo il primo led se la misura è sotto i 40 cm
    digitalWrite (ledGreen, LOW);
    digitalWrite (ledYellow, HIGH);
    digitalWrite (ledRed, HIGH);
  }

  else if (pellet <= 41 && pellet >= 64) { // tra i 41 e i 64 cm facciamo accendere il secondo led
    digitalWrite (ledGreen, HIGH);
    digitalWrite (ledYellow, LOW);
    digitalWrite (ledRed, HIGH);
  }

  else if (pellet > 65) { //dopo i 65 cm facciamo accendere il terzo led
    digitalWrite (ledGreen, HIGH);
    digitalWrite (ledYellow, HIGH);
    digitalWrite (ledRed, LOW);

  }

Tutta la porzione di codice precedente andrebbe all'interno della prima

if (millis() - timer >= 1000) 

Per migliorare la legibilità e snellire il contenuto del loop potresti creare una funzione ad es di nome updateDisplay() da richiamare dentro la prima if dopo la lettura del sensore.

Scritto così se il valore pellet è 40 non si accenderà nessun led. Aggiungi un <=.

E non si può fare? Come sarebbe la giusta?

Ho provato a includere la tutto nella prima ma mi da errore il refresh..