Pressione prolungata IR

Salve volevo sapere un modo per gestire (via software) la pressione prolungata di pulsanti di un telecomando infrarossi. Per esempio, tengo premuto il tasto 1 e si accende la lampadina blu, lascio il tasto 1 e si spegne. Tengo premuto il tasto 2 e si accende la lampadina rossa, lascio il tasto 2 e la lampadina si spegne.
Sono riuscito da solo a gestire con un semplice codice la gestione di un solo output, con due o più la cosa mi diventa difficile. Come posso fare?

Per primo devi verificare se il telecomando trasmette di continuo il codice. Alcuni modelli con certi tipi di code-protocolli mandano il codice solo poche volte nonostante il pulsante sia premuto di continuo.

Ciao Uwe

Credo che invii di continuo visto che se premo per esempio un pulsante (senza tenerlo premuto), stampando a video il suo codice mi viene 3445678 per esempio, mentre se tengo premuto qualsiasi pulsante mi esce sempre lo stesso codice 4657879 (i codici sono inventati)

Up

Adesso che sai che continui ad inviare il segnale dove sta il problema? Basta che duplichi il codice che hai fatto per usare solo uno ma cambiandio il codice ir

simonenascivera:
Adesso che sai che continui ad inviare il segnale dove sta il problema? Basta che duplichi il codice che hai fatto per usare solo uno ma cambiandio il codice ir

Ci ho già provato e non ci sono riuscito. Se mi faresti un esempio di codice di un programma che gestisce 2 led te ne sarei grato

Sei tu che dovresti mettere il pezzo di codice che hai fatto e che va modificato, non è corretto mettere in condizione un utente a fare ricerche e tirare giù uno sketch, collegare compononenti per provarlo ecc ecc
Non pensi sia più semplice per tutti postare il codice che hai? O magari non hai nessun codice?

pablos:
Sei tu che dovresti mettere il pezzo di codice che hai fatto e che va modificato, non è corretto mettere in condizione un utente a fare ricerche e tirare giù uno sketch, collegare compononenti per provarlo ecc ecc
Non pensi sia più semplice per tutti postare il codice che hai? O magari non hai nessun codice?

Sante parole.

Serve del codice per gestire due led con due bottoni?

int led1=3;
int led2=5;
int button1=2;
int button2=4;

void setup() {
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
pinMode(button1, INPUT);
pinMode(button2, INPUT);
}
void loop() {
    if (button1==HIGH) {
        digitalWrite(led1, HIGH);
    } else {
        digitalWrite(led1, LOW);
    }
    if (button2==HIGH) {
        digitalWrite(led2, HIGH);
    } else {
        digitalWrite(led2, LOW);
    }
}

Ok, questo è il mio codice che non funziona, è solo un tentativo non andato bene.
In pratica il mio telecomando IR, quando viene premuto un pulsante, prima invia un codice unico differente ad ogni pulsante, poi se si continua a tenere premuto invia sempre lo stesso codice, 4294967295.
In poche parole, il seguente tentativo di programma non funziona in quanto se si tiene premuto il pulsante non succede niente (luce spenta), mentre se il pulsante lo si preme solamente senza tenerlo, fa accendere la lampadina per 300ms.

#include <IRremote.h>

int RECV_PIN = 11;
IRrecv irrecv(RECV_PIN);
decode_results results;

int lampadina=10;
int pulsante=0;

void setup()
{
  pinMode(lampadina, OUTPUT);
  Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver
}

void loop() {
  if (irrecv.decode(&results)) {
    Serial.println(results.value);
    
    if(results.value == 2534850111){
      pulsante=1;
      digitalWrite(lampadina,HIGH);
      delay(300);
      digitalWrite(lampadina,LOW);
    }
    if(results.value == 4294967295){
      if (pulsante==1){
        digitalWrite(lampadina,HIGH);
      } 
    }
  }
  else{
    digitalWrite(lampadina,LOW);
  }
    irrecv.resume(); // Receive the next value
    pulsante=0;
    
    delay(200);
}

L errore penso che derivi da come hai impostato la cosa prova al posto dell if che hai quando lo premi per lungo tempo metti un while

simonenascivera:
L errore penso che derivi da come hai impostato la cosa prova al posto dell if che hai quando lo premi per lungo tempo metti un while

Al posto di questo if?
"if(results.value == 4294967295)"

Si

simonenascivera:
Si

Così facendo va in loop una volta aver ricevuto il codice 4294967295 in quanto non c'è modo di uscirne

Usa while (results.value == 4294967295)

Esce dal while appena il codice differisce da 4294967295.

Brado:
Usa while (results.value == 4294967295)

Esce dal while appena il codice differisce da 4294967295.

Ho fatto così e va in loop, il fatto è che il codice non può mai differire da 4294967295 in quanto il codice non viene riletto all'interno del while e per farlo rileggere non so come fare.

Dal tuo codice:
irrecv.resume(); // Receive the next value

Brado:
Dal tuo codice:
irrecv.resume(); // Receive the next value

Ho provato ad implementarlo nel while e non va comunque. Come fanno per esempio le tv? Con che tipo di algoritmo?

Ciao, forse questo codice portrebbe esserti utile:

#include <IRremote.h>

int receiver = 11;

IRrecv irrecv(receiver);
IRsend irsend;
decode_results results;
long last_value;
 
void setup() {
  irrecv.enableIRIn();
}

unsigned int volumeUp[25]={2400,550,650,550,1200,550,650,550,600,550,1250,550,600,550,650,550,1200,550,650,550,600,550,650,550,650};
unsigned int volumeDown[25]={2400,550,1200,600,1200,550,650,550,600,550,1250,550,600,600,600,550,1250,550,600,550,650,550,600,550,650};

void loop() {
  if (irrecv.decode(&results)){
    irrecv.resume();
    delay(50);

    if (results.value != 4294967295) {
      delay(50);
      last_value = results.value;
    }

    if (last_value == 16754775 || results.value == 16754775) {
      irsend.sendRaw(volumeUp, 25, 40);
    } else if (last_value == 16769055 || results.value == 16769055) {
      irsend.sendRaw(volumeDown, 25, 40);
    }

    delay(50);
    irrecv.enableIRIn();
  }
}

Il codice permette di alzare ed abbassare il volume di un televisore sony con un telecomando nec, anche tenendo premuto il pulsante. E' diverso da quello che vuoi fare tu, ma sostituendo l'invio del segnare ir con l'accensione del led, dovrebbe andare.
Il valore "4294967295" sarebbe il codice che invia il telecomando tenendo premuto un qualsiasi pulsante.

Grazie mille mi sei stato veramente d'aiuto. Questo è il codice che ho rielaborato per ciò che devo fare. Mi è rimasto un ultimo sottile problema, siccome devo far girare una ventola il tempo che tengo premuto un pulsante, con questo codice, la ventola si aziona per 1200ms e si spegne per un po' (non so quali sono i tempi di arduino senza delay), non si potrebbe fare che non si spegne per niente?
Ti ringrazio ancora, il codice che mi hai fornito va bene lo stesso anche perchè si spegne per pochissimo e non cambierebbe molto.
Grazie mille :smiley: :smiley:

#include <IRremote.h>
#include <Servo.h>

Servo myservo;

int receiver = 11;

int ventola = 8;

IRrecv irrecv(receiver);
IRsend irsend;
decode_results results;
long last_value;

int pos = 90;

void setup() {
irrecv.enableIRIn();
pinMode(ventola,OUTPUT);
myservo.attach(7);
myservo.write(pos);
}

void loop() {
if (irrecv.decode(&results)){
irrecv.resume();
// delay(10);

if (results.value != 4294967295) {
last_value = results.value;
}

if (last_value == 3855596927 || results.value == 3855596927) {
digitalWrite(ventola,HIGH);
delay(1200);
} else if (last_value == 553536955 || results.value == 553536955) {
pos=pos+5;
myservo.write(pos);
} else if (last_value == 3622325019 || results.value == 3622325019) {
pos=pos-5;
myservo.write(pos);
} else if (last_value == 2538093563 || results.value == 2538093563) {
pos=90;
myservo.write(pos);
}

irrecv.enableIRIn();
}
else{
digitalWrite(ventola,LOW);
}
}