problema doppio controllo pin

ciao a tutti, ho un problema che sembra semplice ma mi sta complicando un po.
ho un progetto creato con sensore a tasteggio (quelli gialli in vendita appositamente x arduino)
devo fare in modo che (in questa sequenza):

il sensore rileva l'oggetto
passano 20 secondi e rifa' un altro controllo
in quel caso se il sensore è sempre "attivo" fa uscire un segnale di output
attende tot secondi che gli imposto (esempio 3 secondi)
rimanda lo stesso segnale di output e cosi via sempre ogni 3 secondi

se invece
il sensore rileva l'oggetto
e dopo 10 secondi l'oggetto si sposta lui non fa nulla

dato che arduino fa costantemente il loop del programma...è possibile farlo?

Ciao, puoi usare un automa a stati finiti (non ti preoccupare... sembra una parolaccia ma è piuttosto semplice).

Ne abbiamo parlato qui qualche giorno fa. Prova a leggere il thread e se hai bisogno di chiarimenti chiedi pure.

si all'incirca il concetto l'ho capito ..ma nn riesco a capire come possa funzionare nel mio caso :roll_eyes:

ti allego come l'ho fatto io.
funziona nel senso che se passo la mano davanti al sensore e la tolgo non succede nulla, se la tengo fissa sul sensore lui fa passare 20 secondi, attiva l'uscita.... poi attende tot secondi esempio 5 secondi (funzione stato_inc / stato_dec) e poi riattende i 20 secondi...riattiva l'uscita e cosi via.
in pratica fa all'inizio solo 20.....poi dopo sempre 20 + 5
invece a me serve che se passo la mano attende 20 secondi , attiva...poi attende tot secondi impostati (esempio 5secondi) riattiva...poi altri tot secondi ..riattiva e cosi via.

void loop() {

  //INIZIO FUNZIONE *********************************************************************************

  while (digitalRead(FOTOCELLULA_PIN) == LOW) //riceve il segnale della fotocellula
  {
    delay(20000);   //tempo di attesa di 20 secondi dopo la rilevazione della fotocellula


    mode = ACTIVE;


    if (digitalRead(FOTOCELLULA_PIN) == LOW)

     digitalWrite(FOTOCAMERA_PIN, HIGH);   // da il contatto del 4N25 
     digitalWrite(LED_PIN, HIGH); // accende il led notifica
     delay(500);  //mantiene per 0.5 secondi
     digitalWrite(FOTOCAMERA_PIN, LOW);   // toglie contatto del 4N25 

     delay(tempo * 1000); //ritardo in millisecondi = 1 secondo
     digitalWrite(LED_PIN, LOW); // spegne il led notifica
  }


  stato_inc = digitalRead(pulsante_inc); //
  if (stato_inc != last_stato_inc) {
    if (stato_inc == LOW) {
      tempo = tempo + 1; // incrementa di 1 secondo
    }
  }
  last_stato_inc = stato_inc;

  stato_dec = digitalRead(pulsante_dec); //
  if (stato_dec != last_stato_dec) {
    if (stato_dec == LOW) {
      tempo = tempo - 1; // decrementa di 1 secondo
      if ( tempo <= 1 ) {
        tempo = 1 ;
      }
    }
  }
  last_stato_dec = stato_dec ;

  if ((mode == ACTIVE) && (digitalRead(FOTOCELLULA_PIN) == LOW))
  {
    digitalWrite(FOTOCAMERA_PIN, LOW);   // toglie il contatto del 4N25 
    digitalWrite(LED_PIN, LOW);
    mode = STANDBY;
  }



  // FUNZIONE AUMENTO DECREMENTO PULSANTI (stato_inc / stato_dec ) *********************************************************************************
  lcd.setCursor(7, 1);
  lcd.print(tempo);
  lcd.print(" ");
  lcd.setCursor(10, 1);
  lcd.print("Sec.");
  lcd.setCursor(15, 1);
  lcd.write(2);



}

Manca tutta la parte di inizializzazione di variabili. Il codice così non può compilare per cui non è possibile testarlo, almeno nella sintassi.
Hai messo un while con un delay di 20 secondi. E' eccessivo. Devi usare la funzione millis() in modo da non bloccare il programma per un tempo così lungo.
C'è un IF senza parentesi graffe. E' voluto?

Il resto della logica non l'ho controllato.

vi allego tutto il codice cosi potete testarlo

#include <LiquidCrystal_I2C.h>
#include <Wire.h>




#define FOTOCELLULA_PIN 10   //pin a cui è collegata la fotocellula
#define FOTOCAMERA_PIN 12   //pin a cui è collegato l'opto 4N25
#define LED_PIN 13  //pin led di notifica

#define STANDBY 0
#define ACTIVE 1
byte pulsante_inc = 2 ; // Pulsante incrementa i secondi
byte pulsante_dec = 3 ; // Pulsante decrementa i secondi
int tempo = 1 ; // ritardo di scatto di default  all'accensione

byte last_stato_inc = HIGH ;
byte last_stato_dec = HIGH ;
byte stato_inc = HIGH ;
byte stato_dec = HIGH ;

int mode = STANDBY;

//*********************crea disegno frecce

byte frecce[8] = {
  B00100,
  B01110,
  B11111,
  B00000,
  B00000,
  B11111,
  B01110,
  B00100
};





LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // indirizzo 0x27 seriale del i2c


void setup() {
  pinMode(pulsante_inc, INPUT_PULLUP);   //imput digitale pulsante +
  pinMode(pulsante_dec, INPUT_PULLUP);   //imput digitale pulsante -
  pinMode(FOTOCELLULA_PIN, INPUT);   //imput digitale fotocellula
  pinMode(FOTOCAMERA_PIN, OUTPUT);   //output digitale scatto foto
  pinMode(LED_PIN, OUTPUT); //output led notifica


  Wire.begin();
  lcd.begin(16, 2);
  lcd.createChar(2, frecce);  //CARATTERE FRECCE

  lcd.setCursor(0, 0);
  lcd.print("avvio sistema..");
  lcd.setCursor(0, 1);
  lcd.print("by Luca V.");
  delay(4000);
  lcd.clear();

  lcd.setCursor(0, 0);
  lcd.print("Controllo scatto");

  lcd.setCursor(0, 1);
  lcd.print("attesa");

}


void loop() {

  //INIZIO FUNZIONE *********************************************************************************

 while (digitalRead(FOTOCELLULA_PIN) == LOW) //riceve il segnale della fotocellula
  {
    delay(20000);   //tempo di attesa di 20 secondi 


    mode = ACTIVE;


    if (digitalRead(FOTOCELLULA_PIN) == LOW)

      digitalWrite(FOTOCAMERA_PIN, HIGH);   // da il contatto del 4N25 
    digitalWrite(LED_PIN, HIGH); // accende il led notifica
    delay(500);  //mantiene per 0.5 secondi
    digitalWrite(FOTOCAMERA_PIN, LOW);   // toglie contatto del 4N25

    delay(tempo * 1000); //ritardo in millisecondi = 1 secondo
    digitalWrite(LED_PIN, LOW); // spegne il led notifica
  }


  stato_inc = digitalRead(pulsante_inc); //
  if (stato_inc != last_stato_inc) {
    if (stato_inc == LOW) {
      tempo = tempo + 1; // incrementa di 1 secondo
    }
  }
  last_stato_inc = stato_inc;

  stato_dec = digitalRead(pulsante_dec); //
  if (stato_dec != last_stato_dec) {
    if (stato_dec == LOW) {
      tempo = tempo - 1; // decrementa di 1 secondo
      if ( tempo <= 1 ) {
        tempo = 1 ;
      }
    }
  }
  last_stato_dec = stato_dec ;

  if ((mode == ACTIVE) && (digitalRead(FOTOCELLULA_PIN) == LOW))
  {
    digitalWrite(FOTOCAMERA_PIN, LOW);   // toglie il contatto del 4N25 
    digitalWrite(LED_PIN, LOW);
    mode = STANDBY;
  }



  // FUNZIONE AUMENTO DECREMENTO PULSANTI *********************************************************************************
  lcd.setCursor(7, 1);
  lcd.print(tempo);
  lcd.print(" ");
  lcd.setCursor(10, 1);
  lcd.print("Sec.");
  lcd.setCursor(15, 1);
  lcd.write(2);



}

l'if mi sa che l'ho dimenticato ma la funzione gira lo stesso..
per quanto riguardo il while ho provato a leggere un po ma mi vado ad incasinare :frowning:

EDIT

adesso ho risolto impostando solo il tempo iniziale coi pulsanti.
in pratica imposto 20 secondi...se passo la mano sopra x 15 secondi e la tolgo non accade nulla
se la lascio per piu di 20 secondi attiva l'uscita 1 vola...e poi la riattiva dopo altri 20 secondi e cosi via
cosi va gia bene...

Vedi così
--> codebender

Ho modificato mode in avvia_sequenza.
Il for permette il controllo dell'oggetto ogni decimo di secondo e non solo dopo 20.

perfetto! cosi in pratica attende i 20 secondi iniziali...e poi se il sensore è sempre "attivo" attente il tempo che gli viene impostato tramite pulsanti.
è ottimo grazie!!!
ora devo solo vedere se riesco a creare uno spazio per altri due tasti (o mettere uno switch utilizzando i 2 tasti come fossero 4) e impostare entrambi i tempi di attesa

Ti consiglio di aggiungere un pulsante di STOP forzato da verificare all'interno dei due cicli.
E' probabile che tu voglia interrompere la procedura se qualcosa non va bene.