Aiuto per Progetto Cancello scorrevole comandato da arduino

Buona sera a tutti,
vi vorrei chiede aiuto per un problema mentre creavo il mio programma.
L'elenco dei componenti è:
2 fine corsa
2 relè
1 fotocellula
1 ricevitore ir.
mentre creavo il programma di prova per simulare con due led l' inversione di marcia,
se dovevo accendere il led con il telecomando tutto ok
ma quando nel programma inserivo la riga che diceva che quando il fine corsa era in HIGH si doveva spegnere il led per poi passati tot secondi si doveva accendersi l'altro led.
il problema sta che il 1° led si accendeva da solo e poi non riconosceva il segnale del fine corsa.

Benvenuto. :slight_smile:
Ti invitiamo a presentarti qui: Re: Presentazioni nuovi iscritti, fatevi conoscere da tutti! - Generale - Arduino Forum
e a leggere il regolamento: [REGOLAMENTO] Come usare questa sezione del forum - Italiano - Arduino Forum

Personalmente io non ho capito nulla della tua domanda. Poi comunque senza vedere il codice (sketch) è dura darti qualche consiglio.

Ciao nid69ita, sto progettando un cancello scorrevole automatico in scala da portare agli esami di qualifica regionali.
Dovrei programmare Arduino per svolgere queste azioni:

  1. premo un tasto del telecomando tv
  2. il cancello si avvia
  3. il cancello tocca il finecorsa
  4. rimane fermo per tot secondi
  5. marcia indietro
  6. tocca il secondo finecorsa
  7. si spegne tutto
    (dal 2 al 6 un led giallo deve lampeggiare)

Ora è più chiaro, ma il problema sarà nel tuo sketch, e senza vederlo viene difficile darti delle dritte.
Comunque parli di 2 led, 1 giallo e l'altro?

Per il led che lampeggia, così tanto per dire, esistono dei led che alimentati lampeggiano, senza dover accenderli/spegnerli e che perciò semplificherebbero.

Di solito per quei programmi che si basano su uno STATO si consigli di usare una macchina di stati:
http://www.lucadentella.it/2013/04/30/macchina-a-stati-finiti-e-arduino/
Il tuo ciclo loop() per prima cosa legge gli input come telecomando e finecorsa, poi verifica con una istruzione switch() in quale stato sei e in base agli input modifica lo stato.
Per il led il lampeggiare deve farlo sono quando lo stato è in alcuni valori. Inoltre non puoi usare la delay() che è bloccante, soprattutto per il telecomando.

Posta il tuo sketch. (per vedere come fare guarda il punto 7 del Regolamento)

Ecco lo sketch che mi da problemi:

#include <IRremote.h> 
int receiver = 11; 
IRrecv irrecv(receiver); 
decode_results results;
int finecorsa;
void setup()
{
  Serial.begin(9600); 
  irrecv.enableIRIn(); 
  pinMode(8, OUTPUT);
  pinMode(2, INPUT);
  pinMode(6,OUTPUT);
 
}
void loop()
{
  finecorsa=digitalRead(2);
  
  if (irrecv.decode(&results))
  {
    Serial.println(results.value, HEX); 
    irrecv.resume();
  }
     if ( results.value == 5||results.value == 805 ){ 
    digitalWrite(8, HIGH); 
  } 
 if ( results.value == 2||results.value == 802 ){ 
    digitalWrite(8, LOW); 
  }  
if (finecorsa==HIGH);{
digitalWrite(8, LOW);
}
}

-Sull’ultimo if hai messo un ; di troppo :astonished:

  • la verifica del valore di ritorno del IR devi farla solo se ricevi un comando dal telecomando, perciò i due if results devono stare dentro il primo if
if (irrecv.decode(&results))
  { Serial.println(results.value, HEX); 
    irrecv.resume();
    if ( results.value == 5 || results.value == 805 )
    { digitalWrite(8, HIGH); 
    } 
    if ( results.value == 2 || results.value == 802 ) 
    { digitalWrite(8, LOW); 
    }  
  }
  if (finecorsa==HIGH)
  { digitalWrite(8, LOW);
  }

Il finecorsa, da solo lo hai provato? Sei sicuro che quando si attiva ritorna HIGH ?

Consigli:

  1. aggiungi un pò di commenti
  2. dichiara con delle #define quei numeri di pulsanti con dei nomi significativi (805 non è molto intuitivo)
  3. dichiara i pin con delle const byte pinXXX=numero; in modo da rendere più chiaro il codice e poi leggere ovunque 8 non è molto leggibile
  4. hai testato i singoli sensori da soli ? se no, provali da soli e con uno sketch minimale per verificare come li hai collegati

Devi effettuare ancora qualche modifica credo

#include <IRremote.h>
const int receiver = 11;
IRrecv irrecv(receiver);
decode_results results;

int finecorsa = LOW;
int iniziocorsa = LOW;
const int Led1 = 8;
const int Led2 = 6;
const int Button = 2;

void setup() {
  Serial.begin(9600);
  irrecv.enableIRIn();
  pinMode(Led1, OUTPUT);
  pinMode(Button, INPUT);
  pinMode(Led2, OUTPUT);

}


void loop() {
  finecorsa = digitalRead(Button);
  // iniziocorsa = digitalRead(xxxxxxxx);

  if (irrecv.decode(&results))
  {
    Serial.println(results.value, HEX);
    irrecv.resume();
  }

  if ( results.value == 5 || results.value == 805 ) {
    digitalWrite(Led1, HIGH);
    digitalWrite(Led2, LOW);
    // azionamento relè avanti
  }
  if ( results.value == 2 || results.value == 802 ) {
    digitalWrite(Led1, LOW);
    digitalWrite(Led2, HIGH);
    // azionamento relè indietro
  }

  if (finecorsa == HIGH)  {
    // stop motore
    digitalWrite(Led1, LOW);
    digitalWrite(Led2, HIGH);
    // azionamento relè indietro
  }

  if (iniziocorsa == HIGH)  {
    // stop motore
    digitalWrite(Led1, LOW);
    digitalWrite(Led2, LOW);
  }

} // End Loop

Occhio, @PaoloP, ti sei portato dietro l'errore del ; sull'if()

ho provato con il tuo sketch.
ci sono due problemi il led rosso sta sempre acceso e il ricevitore è lento

nid69 invece il tuo funziona
ora mi serve il lampeggio

Il led rosso sarebbe 8 ? Vedi che senza dichiararlo in cima diventa un casino capirlo

const byte pinRed=8;

e poi usi ovunque pinRed invece di 8

Comunque, sei sicuro dei tasti del telecomando? I miei che ho provato (ben 4) di solito mi danno dei valori esadecimali tipo questo: 0xFFD02F

il mio telecomando da questi segnali, infatti funziona.

ferrif97:
nid69 invece il tuo funziona
ora mi serve il lampeggio

Quando accendi il led rosso, vorrebbe dire che hai attivato il rele per il cancello giusto?
Quindi dichara una variabile tipo

#define K_FERMO 0 
#define K_APRE 1
#define K_CHIUDE 2
byte CancelloStato=K_FERMO;

Quando accendi il led rosso metterai CancelloStato=K_APRE e quando lo spegni a K_FERMO .
Questa variabile ti fa sapere che il cancello è in movimento.

Al fondo della loop() dopo tutti gli if dovrai metter un altro if che si chiede se il cancello è in movimento:

if(CancelloStato==K_APRE || CancelloStato=K_CHIUDE)
{
}
else  // K_FERMO
{ digitalWrite(pinGiallo,LOW);  
}

Dentro quell'if bisogna accendere/spegnere il led giallo usando però la millis() e seguendo un pò quello che è l'esempio della BlinkWithoutDelay (uno degli esempi forniti con l'IDE)
Dovresti guardarti quell'esempio ed adattartelo. Non vorrei dirti di più. Vorrei tu ci arrivassi da solo (non è semplice, lo sò)

come lo imposto nel mio sketch?

#include <IRremote.h> // use the library

int receiver = 12; // pin 1 of IR receiver to Arduino digital pin 11
IRrecv irrecv(receiver); // create instance of 'irrecv'
decode_results results;
int finecorsa;
void setup()
{
  Serial.begin(9600); // for serial monitor output
  irrecv.enableIRIn(); // Start the receiver
  pinMode(8, OUTPUT);
  pinMode(2, INPUT);
  pinMode(6,OUTPUT);
 
}
void loop()
{
finecorsa=digitalRead(2);
  
  if (irrecv.decode(&results))
  { Serial.println(results.value, HEX); 
    irrecv.resume();
    if ( results.value == 5 || results.value == 805 )
    { digitalWrite(8, HIGH); 
    } 
    if ( results.value == 2 || results.value == 802 ) 
    { digitalWrite(6, LOW); 
    }  
  }
  if (finecorsa==HIGH)
  { digitalWrite(8, LOW);
  delay(5000);
  digitalWrite(6, HIGH);
  }

    
}

Prima leggi questo, per favore:
http://www.leonardomiliani.com/2013/programmiamo-i-compiti-con-millis/

Quello che ti viene spiegato in quel tutorial tu lo devi fare nel tuo sketch ma solo dentro la nuova if che ti ho indicato

const byte actPin = 6;  // action pin
const byte ledPin = 7;  // led pin blinking when in action
const byte btnPin = 8;  // comando avvio
const byte finPin = 9;  // fine corsa

enum stato_tipo { K_FERMO=0, K_APRI=1, K_CHIUDI=2 };
stato_tipo   Stato=K_FERMO;

int ledStato = 0; // ledState used to set the LED
unsigned long prevMillis = 0;
#define K_INTERVALLO 500UL 

void setup() 
{ delay(1000);
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT); 
  pinMode(actPin, OUTPUT); 
  pinMode(btnPin, INPUT); 
  pinMode(finPin, INPUT); 
  digitalWrite(actPin,LOW);
  digitalWrite(ledPin,LOW);
}

void loop() 
{ unsigned long currMillis = millis();
  Serial.println(Stato);
  switch(Stato)
  { case K_FERMO:
      if( digitalRead(btnPin)== HIGH)      
      { Stato=K_APRI; 
        digitalWrite(actPin,HIGH);
      }
      break;
    case K_APRI:
      if(currMillis - prevMillis > K_INTERVALLO) 
      { prevMillis = currMillis; //save the last time you blinked the LED
        ledStato = ! ledStato;
        digitalWrite(ledPin, ledStato);
      }    
      if( digitalRead(finPin)== HIGH )
      { Stato=K_FERMO; 
        digitalWrite(actPin,LOW);
        digitalWrite(ledPin,LOW);
      }
      break;
    case K_CHIUDI:
      break;
  }
}

ciao nid69 con l’ultimo sketch tuo il led lampeggia sempre.
ti vorrei chiedere perché il finecorsa2 quando viene azionato non spegne tutto come da sketch (o meglio lo devo premere 2 o 3 volte per spegnere tutto il circuito)?

#include <IRremote.h> // use the library

int receiver = 12; // pin 1 of IR receiver to Arduino digital pin 11
IRrecv irrecv(receiver); // create instance of 'irrecv'
decode_results results;
int finecorsa;
int finecorsa2;
void setup()
{
  Serial.begin(9600); // for serial monitor output
  irrecv.enableIRIn(); // Start the receiver
  pinMode(8, OUTPUT);
  pinMode(2,  INPUT);
  pinMode(6, OUTPUT);
  pinMode(9,  INPUT);
  pinMode(7,OUTPUT);
 
}
void loop()
{
finecorsa=digitalRead(2);
finecorsa2=digitalRead(9);
  
  if (irrecv.decode(&results))
  { Serial.println(results.value, HEX); 
    irrecv.resume();
    if ( results.value == 5 || results.value == 805 )
    { digitalWrite(8, HIGH); 
    
    } 
    if ( results.value == 2 || results.value == 802 ) 
    { digitalWrite(6, LOW); 
    }  
  }
  if (finecorsa==HIGH)
  { digitalWrite(8, LOW);
  delay(5000);
  digitalWrite(6, HIGH);
  }
if (finecorsa2==HIGH){
  digitalWrite(6,LOW);
  digitalWrite(8,LOW);
}  

}

Lo sketch l'ho corretto, partiva nella setup() con i due led a high. Io per le prove ho una board con pulsanti e led ma che lavorano in logica negativa, HIGH li spengo, LOW li accendo. Per il resto quello sketch mi funziona. :grin:

Per il tuo sketch, non saprei.

  1. potrebbe essere che la irrecv.decode() rallenta tutto
  2. potrebbe essere il finecorsa che è ancora high e hai un delay(5000) -> azzz 5 secondi di blocco di Arduino
  3. potrebbe essere un problema Hardware, il collegamento non è perfetto e perciò non sente HIGH quando lo premi.
    Aggiungi la stampa dei due finecorsa:
void loop()
{ finecorsa=digitalRead(2);
  finecorsa2=digitalRead(9);
  Serial.print("finecorsa="); Serial.print(finecorsa);
  Serial.print("   finecorsa2="); Serial.println(finecorsa2);

Con il serial Print ho scoperto dove stava il problema.
non funzionava perchè c'era il delay, infatti dopo che aspettavi 5 sec dopo l'accensione del led il finecorsa funziona.
ora manca solo il problema del lampeggiante