problema IR remote, relè bistabile...aiutooo!!

ciao a tutti, ho un piccolo problema

uso regolarmente arduino con un telecomando, ora dovrei eccitare un relè bistabile, ma
non riesco a scrivere il programma che riesce a fare questo.
Dovrei alzare (HIGH) una porta digitale per qualche millesimo di secondo, quando premo un tasto del
telecomando, e poi dovrebbe abbassarsi dinuovo (LOW), automaticamente....
ho provato questo codice:
.....

void loop() {

......
.......
...

if (results.value == ZERO){
digitalWrite(5,HIGH);
delay(200);
digitalWrite (5,LOW);
delay (200);

}

ma non funziona, non come dico io.
attendo un vostro aiuto,
grazie

DARIO :slight_smile:

Non capisco una cosa, ZERO l'hai assegnato al codice del tasto del telecomando?
Se si, ZERO l'hai inizializzato come Float?

Perché sennò dovresti scrivere "results.value==0x codice tasto in esadec."

Ma io per i codici dei tasti uso gli int e non ho problemi..
Comunque forse l'hai dato per scontato nel codice ma hai messo "irrecv.resume()" alla fine di ogni ricezione?

Cosa non funziona esattamente del codice? Non entra nell'if oppure il relè non si eccita?

questo è il codice completo,
i tasti uno , due , tre, funzionano perfettamente come voglio io,

invece il tasto zero voglio che mi svolga questa funzione cioè
lo premo e mi si alza la porta 5 (HIGH) e dopo un delay(200) si spegne sola senza che io debba ripremere alcun tasto.
è possibile?

non capisco, cosa significa quel "irrecv.resume()" alla fine di ogni ricezione?
deo metterlo?
ecco il codice:

#include <IRremote.h>
#include <IRremoteInt.h>

#define UNO 0x687CBF0
#define DUE 0x687CBC8
#define TRE 0x687CBE8
#define ZERO 0x687CBFC
#define POWER 0x687CBC0

int RECV_PIN = 4; //riceve segnale ricevitore IR

IRrecv irrecv(RECV_PIN);

decode_results results;

void setup()
{
pinMode (2, OUTPUT); //attiva relè A , salita serranda
pinMode (3, OUTPUT); //attiva relè B, discesa serranda
pinMode (5, OUTPUT); //attiva relè bistabile, luce balcone
pinMode (7,INPUT);

irrecv.enableIRIn();
Serial.begin (9600);
}
void loop() {

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

if (results.value == UNO){
digitalWrite (2, HIGH);
digitalWrite (3, LOW);
delay(100);
}
if (results.value == DUE){
digitalWrite (2,LOW);
digitalWrite (3,LOW);
delay(100);

}
if (results.value == TRE){
digitalWrite(2, LOW);
digitalWrite (3,HIGH);
delay(100);
}

if (results.value == ZERO){
digitalWrite(5,HIGH);
delay(200);
digitalWrite (5,LOW);
delay (200);
}

if(results.value == POWER){
digitalWrite(2, LOW);
digitalWrite(3, LOW);
digitalWrite(5, LOW);
}

}

Io modificherei così, ma magari no è questo il punto:

#include <IRremote.h>
#include <IRremoteInt.h>

#define UNO    0x687CBF0
#define DUE   0x687CBC8
#define TRE    0x687CBE8
#define ZERO  0x687CBFC  
#define POWER    0x687CBC0



int RECV_PIN = 4;  //riceve segnale ricevitore IR



IRrecv irrecv(RECV_PIN);

decode_results results;

void setup()
{
pinMode (2, OUTPUT); //attiva relè A , salita serranda
pinMode (3, OUTPUT); //attiva relè B, discesa serranda
pinMode (5, OUTPUT); //attiva relè bistabile, luce balcone
pinMode (7,INPUT);

irrecv.enableIRIn();
  Serial.begin (9600);
}
void loop() {

  
 if (irrecv.decode(&results)) {
   
   Serial.println(results.value, HEX);
   
   if (results.value == UNO){
    digitalWrite (2, HIGH);
    digitalWrite (3, LOW);
    delay(100);
   }

   if (results.value == DUE){
    digitalWrite (2,LOW);
    digitalWrite (3,LOW);
    delay(100);
   }

   if (results.value == TRE){
    digitalWrite(2, LOW);
    digitalWrite (3,HIGH);
    delay(100);
   }
  
   if (results.value == ZERO){
    digitalWrite(5,HIGH);
    delay(200);
    digitalWrite (5,LOW);
    delay (200);
   } 
  
  
   if(results.value == POWER){
    digitalWrite(2, LOW);
    digitalWrite(3, LOW);
    digitalWrite(5, LOW); 
   }

   irrecv.resume(); 
 }
   
   
}

Sciorty mi ha preceduto, anche io avrei detto così.

Sicuramente è irrecv.resume();

Io però l'avrei spostato sotto la graffa di chiusura del primo IF.

Così:

void loop() {

if (irrecv.decode(&results)) {

Serial.println(results.value, HEX);

if (results.value == UNO){
digitalWrite (2, HIGH);
digitalWrite (3, LOW);
delay(100);
}

if (results.value == DUE){
digitalWrite (2,LOW);
digitalWrite (3,LOW);
delay(100);
}

if (results.value == TRE){
digitalWrite(2, LOW);
digitalWrite (3,HIGH);
delay(100);
}

if (results.value == ZERO){
digitalWrite(5,HIGH);
delay(200);
digitalWrite (5,LOW);
delay (200);
}

if(results.value == POWER){
digitalWrite(2, LOW);
digitalWrite(3, LOW);
digitalWrite(5, LOW);
}

//irrecv.resume();
}

irrecv.resume();
}

Comunque prova tutti e due i modi.

Facci sapere! :smiley:

ragazzi, non va... :frowning:
però quella terza parentesi graffa che leggo nel vostro codice, io non me la trovo1!!
perchè l'avete aggiunta?

cmq l'ho modificato cosi:

if (results.value == ZERO){
digitalWrite(5,HIGH);
delay(200);
digitalWrite (5,LOW);
delay (200);

}

if(results.value == POWER){
digitalWrite(2, LOW);
digitalWrite(3, LOW);
digitalWrite(5, LOW);
}

irrecv.resume();

}

Prova così:

#include <IRremote.h>

// const pin
#define ReleA     2
#define ReleB     3
#define ReleC     5
#define RECV_PIN  4
// const code
#define UNO    0x687CBF0
#define DUE    0x687CBC8
#define TRE    0x687CBE8
#define ZERO   0x687CBFC 
#define POWER  0x687CBC0

// var
decode_results results;
unsigned long last_time;

IRrecv irrecv(RECV_PIN);

void setup()
{
  Serial.begin (9600);
  
  pinMode (ReleA, OUTPUT); //attiva relè A , salita serranda
  pinMode (ReleB, OUTPUT); //attiva relè B, discesa serranda
  pinMode (ReleC, OUTPUT); //attiva relè bistabile, luce balcone
  
  // pinMode (7,INPUT); // ???
  
  irrecv.enableIRIn(); // Start the receiver
  irrecv.blink13(true);
  last_time = millis();
}

void ReleOnOff(byte _1, byte _2, byte _3, byte stato1, byte stato2, byte stato3, boolean _zero)
{
  if (_zero)
  {
    digitalWrite(_1, HIGH);
    delay(stato1);
    digitalWrite (_1, LOW);
    delay (stato1);
    return;
  }
  
  if (_1 > 0)
    digitalWrite (_1, stato1);
  if (_2 > 0)
    digitalWrite (_2, stato2);
  if (_3 > 0)
    digitalWrite (_3, stato3);    
//  delay(100); 
}

void loop()
{
  if (irrecv.decode(&results))
  {
    if ((millis() - last_time) > 1000)
    {
      // Conta solo le letture con almeno 1 sec. di distanza
      last_time = millis();
      Serial.println(results.value, HEX);
    
      switch(results.value)
      {
         case UNO:
                   ReleOnOff(ReleA, ReleB, 0, HIGH, LOW, 0, false);
                   break;
         case DUE:
                   ReleOnOff(ReleA, ReleB, 0, LOW, LOW, 0, false);
                    break;
         case TRE:
                   ReleOnOff(ReleA, ReleB, 0, LOW, HIGH, 0, false);
                   break;
         case ZERO:
                   ReleOnOff(ReleC, 0, 0, 200, 0, 0, true);
                   break;  
         case POWER:
                     ReleOnOff(ReleA, ReleB, ReleC, LOW, LOW, LOW, false);
                     break;
         }
    }
  irrecv.resume(); 
 }   
}

ps. controlla se ho messo i pin giusti :sweat_smile:

"faccina" sei un genio.. ti ringrazio,
funziona perfettamente, resto sempre di piu meravigliato davanti alle potenzialita di arduino, ce l'ho da solo un mese ma già
mi ha incantato..

comunque "faccina "

non era possibile scrivere il programma come stavo facendo io?
sai perchè te lo chiedo,
perchè so che di giorno in giorno io lo modificherò. omeglio dovrò aggiungere altre funzioni, quindi
ho paura che non ci riuscirò, perchè leggendo il codice, vedevo cose che ancora non ho imparato!!

grazie ancora

dario9:
"faccina" sei un genio.. ti ringrazio,

:blush: XD

dario9:
non era possibile scrivere il programma come stavo facendo io?
sai perchè te lo chiedo,
perchè so che di giorno in giorno io lo modificherò. omeglio dovrò aggiungere altre funzioni, quindi
ho paura che non ci riuscirò, perchè leggendo il codice, vedevo cose che ancora non ho imparato!!

grazie ancora

Si ma come l'ho scritto io dovrebbe essere più facile da leggere/modificare.
Qui Arduino - Home puoi trovare tutto quello che serve per leggere/scrivere il codice.
Comunque lo commento un po' cosi capisci come modificarlo:
I pin dell'arduino e i codici del telecomando puoi impostarli usando #define perchè sono costanti #define - Arduino Reference

irrecv.blink13(true);

Questo serve per far lampeggiare il led sull'arduino (collegato al pin 13) quando riceve un segnale dal telecomando, se usi il pin per qualcos'altro o non ti serve non lo usare.

last_time = millis();
.
.
.
if (irrecv.decode(&results)) // controlla se arriva il segnale dal telecomando
  {
    if ((millis() - last_time) > 1000) // c'è un segnale, ora controlla se è passato poù di un secondo dal'ultimo
    {
      last_time = millis(); // è passato più di un secondo, ora aggiorna la variabile con il tempo attuale

Spiegato rozzamente:
Se non lo usi: premi il tasto del telecomando e spara un casino di volte il codice, l'arduino lo legge ed esegue il codice ogni volta senza pause
Se lo usi: imposti all'inizio una variabile che conteggia il tempo, poi quando l'arduino legge il codice controlla anche che sia passato più di un secondo (puoi cambiare con più o meno tempo ma un secondo di solito va bene) dall'ultima volta, quindi esegue il codice 1 volta ogni secondo anche se tieni il dito premuto sul tasto.

switch(results.value)
      {
         case UNO:
                   ReleOnOff(ReleA, ReleB, 0, HIGH, LOW, 0, false);
                   break;

Questo è tipo l'if ma è molto più comodo da usare e leggibile quando hai tanti controlli da fare sul valore della stessa variabile, ricordati di mettere break; alla fine di ogni case

void ReleOnOff(byte _1, byte _2, byte _3, byte stato1, byte stato2, byte stato3, boolean _zero)

Questa funzione l'ho fatta per evitare di riscrivere lo stesso codice per ogni case (o if)