Sari la conținut
ELFORUM - Forumul electronistilor

Telecomanda IR cu arduino LED-uri


gabitzu2006

Postări Recomandate

Salutare! Sunt incepator in ale programarii, asa ca va cer ajutorul. Vreau sa fac un montaj cu arduino prin care sa comand 5 leduri/relee si un motor de cc printr-o punte H. Dar sa o luam pe rand. vreau ca fiecare din cele 5 leduri sa fie pornite/oprite cu o apasare a unui anume buton de pe telecomanda. De exemplu: apas 1 pe telecomanda, se aprinde led-ul 1 si ramane aprins, apas butonul 2, se stinge 1 si se aprinde 2 si ramane aprins, etc. Pana acum am reusit sa fac asta cu 4 leduri, sunt sigur ca ma descurc si cu al 5-lea led. Mai vreau ca folosind tastele up si down de pe telecomanda sa aprind pe rand cate un rand din cele 5, iar daca e aprins led-ul 3 sa zicem, apasand up sa se aprinda pe rand, la cate o apasare, led-ul 4, apoi sa se stinga led 4 si sa se aprinda 5, apoi se stinge 5 si se aprinde 1..etc. Aici m-am impotmolit, am inceract eu putin de inginerie inversa dar nu mi-a iesit.

Pentru comanda puntii H cred ca trebuie sa folosesc inca 2 iesiri digitale care la apasarea cate unui buton pe telecomanda sa ramane activate atata timp cat e apasat butonul respectiv. Asta inca nu stiu cum sa o fac, dar zic sa le luam pe rand. Intr-un final, as vrea sa pot comanda led-urile si motorul folosind 3 butoane: unul pentru a ”rula” prin cele 5 leduri, si doua pentru a comanda motorul intr-un sens sau celalalt. Atasez sketchul. Eu zic sa luam problemele pe rand, deci daca se poate, ajutor cu prima problema va rog, sa pot rula prin leduri. Multumesc!

#include <IRremote.h>
int RECV_PIN = 2; // the pin where you connect the output pin of sensor
int relay1 = 4;
int relay2 = 5;
int relay3 = 6;
int relay4 = 7;
int relayPins[] = {4, 5, 6, 7};  //array with all the relays' pins
int relayStates[] = {0,0,0,0,0}; //the initial state of relays
int i=0;  //relay index for the arrays

#define code1 16753245    // code received from button no. 1
#define code2 16736925    // code received from button no. 2
#define code3 16769565    // code received from button no. 3
#define code4 16720605    // code received from button no. 4
#define code5 16718055    // cod pt up
#define code6 16730805    // cod pt down

IRrecv irrecv(RECV_PIN);
decode_results results;

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


void loop() {
if (irrecv.decode(&results)) {
unsigned int value = results.value;
switch(value) {
case code1:
if(relayStates[1] == 0) { // if first relay is on then
digitalWrite(relay1, HIGH);
digitalWrite(relay2,LOW);
digitalWrite(relay3,LOW);
digitalWrite(relay4,LOW);// turn it off when button is pressed
relayStates[1] = 1; // and set its state as off
} else { // else if first led is off
digitalWrite(relay1, LOW); // turn it on when the button is pressed
relayStates[1] = 0; // and set its state as on
}
break;
case code2:
if(relayStates[2] == 0) {
digitalWrite(relay2, HIGH);
digitalWrite(relay3,LOW);
digitalWrite(relay4,LOW);
digitalWrite(relay1,LOW);
relayStates[2] = 1;
} else {
digitalWrite(relay2, LOW);
relayStates[2] = 0;
}
break;
case code3:
if(relayStates[3] == 0) {
digitalWrite(relay3, HIGH);
digitalWrite(relay2,LOW);
digitalWrite(relay1,LOW);
digitalWrite(relay4,LOW);
relayStates[3] = 1;
} else {
digitalWrite(relay3, LOW);
relayStates[3] = 0;
}
break;
case code4:
if(relayStates[4] == 0) {
digitalWrite(relay4, HIGH);
digitalWrite(relay2,LOW);
digitalWrite(relay3,LOW);
digitalWrite(relay1,LOW);;
relayStates[4] = 1;
} else {
digitalWrite(relay4, LOW);
relayStates[4] = 0;
}
break;
case code5: //when you press the Forward button
       //this if/else statement makes sure that relay is ON or OFF before move to the next relay
       if(relayStates[i]==0)
          digitalWrite(relayPins[i], LOW);
       else
          digitalWrite(relayPins[i], HIGH);
          Serial.println("Next relay");
       //makes sure that when we reach the last relay it goes to the first relay again
       if(i>=3)
          i=-1;
       i+=1;             
       break;

      case code6: //when you press the Reverse button
        //this if/else statement makes sure that relay is ON or OFF before move to the previous relayLED
        if(relayStates[i]==0)
          digitalWrite(relayPins[i], LOW);
        else
          digitalWrite(relayPins[i], HIGH);
        Serial.println("Previous relay");
        //makes sure that when we reach the first relay it goes to the last relay
        if(i<=0)
          i=4;
        i-=1;
        break;
}
irrecv.resume(); // Receive the next value
}

}

 

Link spre comentariu
  • Răspunsuri 58
  • Creat
  • Ultimul Răspuns

Top autori în acest subiect

Mie-mi iese ceva ca mai jos. Intreaba ce nu intelegi.

 #include <IRremote.h>
int RECV_PIN = 2; // the pin where you connect the output pin of sensor
int relay1 = 4;
int relay2 = 5;
int relay3 = 6;
int relay4 = 7;
int relayPins[] = {relay1, relay2, relay3, relay4};  //array with all the relays' pins
int relayStates[] = {0,0,0,0}; //the initial state of relays
int i=0;  //relay index for the arrays

#define code1 16753245    // code received from button no. 1
#define code2 16736925    // code received from button no. 2
#define code3 16769565    // code received from button no. 3
#define code4 16720605    // code received from button no. 4
#define code5 16718055    // cod pt up
#define code6 16730805    // cod pt down

IRrecv irrecv(RECV_PIN);
decode_results results;

void setup() {
  Serial.begin(115200);
  irrecv.enableIRIn(); // Start the receiver  
  for(int i = 0; i < 4; i++){
     pinMode(relayPins[i], OUTPUT);
  }
}


void loop() {
  static int idx = -1; //index iesire

  if (irrecv.decode(&results)) {
    unsigned int value = results.value;
    switch(value) {
       case code1: 
              idx = 0; //prima iesire, 
              relayStates[idx] ^= 1; //inverseaza starea
           break;
       case code2: 
              idx = 1; 
              relayStates[idx] ^= 1; 
           break;
       case code3: 
              idx = 2; 
              relayStates[idx] ^= 1; 
           break;
       case code4: 
              idx = 3; 
              relayStates[idx] ^= 1; 
           break;
       case code5: //up 
              idx++; // selecteaza urmatoarea iesire
              idx %=4; //daca e 4, ia-o de la capat
              relayStates[idx] = 1; //fa iesirea 1
           break;
       case code6: //down
              idx--; //selecteaza iesirea precedenta
              if(idx < 0){ //daca e negativa, iao pe cea mai mare
                idx=3;
              }
              relayStates[idx] = 1; //fa iesirea 1
           break;
       default : idx = -1;
    }


    for(int i = 0; i < 4; i++){ // modifica iesirea in functie de testele anterioare.
      if(i == idx){
        digitalWrite(relayPins[i], relayStates[i]);
      } else {
        digitalWrite(relayPins[i], LOW);
      }
    }

    irrecv.resume(); // Receive the next value
  } //if (irrecv.decode(&results))

} //loop()

 

Link spre comentariu

@Liviu M am testat sketchul tau si face asa: apas 1, 2, 3 sau 4 si fiecare led e aprins pt scurt timp si apoi se stinge. apas up se aprinde led1 tot pentru scurt timp, apas down se aprinde led4.

de ce era nevoie ca la declararea relayPins sa fie relay1, etc si nu mergea cum am zis eu, numerele pinilor? doar intreb... poate are legatura cu iterarea idx? oricum, nu vrea sa mearga. pe terminal nu imi mai apare nimic, evident pt ca nu mai am nicio linie serial.println. nu sufar de asta, dar mai ajuta la debug.

Editat de gabitzu2006
update
Link spre comentariu

super! acum merge, dupa ce am comentat linia aia. mai lasa-ma sa mai studiez, ca sa inteleg ce ai facut.   :) va merge daca mai adaug un code5 intre actualul code4 si code5? si vreau sa mai adaug un alt buton, care sa comande un alt led, dar care sa nu faca parte din bucla celor 5 leduri. incerc eu sa scriu si daca nu merge revin. Multumesc de ajutor! Sigur voi mai avea nevoie de ajutor, dar mai incerc si eu

Link spre comentariu

Ai adaugat mai sus niste intrebari, raspund aici.

Am inlocuit numerele cu nume pentru ca tot le ai si e pacat de ele sa ramana nefolosite. Mergea si cu numere, da' parca e mai frumos asa. Plus ca e mai sigur. Daca te razgandesti si vrei sa modifici pinii, nu ai de modificat decat intr-un loc, nu in doua.

N-ar trebui sa aibe treaba cu functionarea, drept dovada ca se aprind cum trebuie cand apesi butoanele.

Pe terminal nu mai apare nimic ca n-am fost atent cand am sters codul in plus. Poti adauga ce mesaje vrei si unde vrei. Vezi c-am modificat viteza de comunicatie (115200), trebuie s-o modifici si in monitorul lui Arduino.

Link spre comentariu
#include <IRremote.h>
int RECV_PIN = 2; // the pin where you connect the output pin of sensor
int relay1 = 4;
int relay2 = 5;
int relay3 = 6;
int relay4 = 7;
int relay5 = 8;
int relayPins[] = {relay1, relay2, relay3, relay4, relay5};  //array with all the relays' pins
int relayStates[] = {0,0,0,0,0}; //the initial state of relays
int i=0;  //relay index for the arrays

#define code1 16753245    // code received from button no. 1
#define code2 16736925    // code received from button no. 2
#define code3 16769565    // code received from button no. 3
#define code4 16720605    // code received from button no. 4
#define code5 16712445    // code pt 5
#define code6 16718055    // cod pt up
#define code7 16730805    // cod pt down

IRrecv irrecv(RECV_PIN);
decode_results results;

void setup() {
  Serial.begin(115200);
  irrecv.enableIRIn(); // Start the receiver  
  for(int i = 0; i < 5; i++){
     pinMode(relayPins[i], OUTPUT);
  }
}


void loop() {
  static int idx = -1; //index iesire

  if (irrecv.decode(&results)) {
    unsigned int value = results.value;
    switch(value) {
       case code1: 
              idx = 0; //prima iesire, 
              relayStates[idx] ^= 1; //inverseaza starea
           break;
       case code2: 
              idx = 1; 
              relayStates[idx] ^= 1; 
           break;
       case code3: 
              idx = 2; 
              relayStates[idx] ^= 1; 
           break;
       case code4: 
              idx = 3; 
              relayStates[idx] ^= 1; 
           break;
       case code5: 
              idx = 4; 
              relayStates[idx] ^= 1; 
           break;
       case code6: //up 
              idx++; // selecteaza urmatoarea iesire
              idx %=5; //daca e 5, ia-o de la capat
              relayStates[idx] = 1; //fa iesirea 1
           break;
       case code7: //down
              idx--; //selecteaza iesirea precedenta
              if(idx < 0){ //daca e negativa, iao pe cea mai mare
                idx=4;
              }
              relayStates[idx] = 1; //fa iesirea 1
           break;
       //default : idx = -1;
    }


    for(int i = 0; i < 5; i++){ // modifica iesirea in functie de testele anterioare.
      if(i == idx){
        digitalWrite(relayPins[i], relayStates[i]);
      } else {
        digitalWrite(relayPins[i], LOW);
      }
    }

    irrecv.resume(); // Receive the next value
  } //if (irrecv.decode(&results))

} //loop()

Am reusit! Acum vreau sa adaug un Led care sa fie comandat independent de celelalte. Cred ca ar merge un case8 urmat de digitalwrite simplu, corect? va fi afectat de codul de pana acum? hai ca incerc.

am vazut ca ai modificat viteza, mersi de avertizare.

cum fac, eventual cu case9 si case10, ca ledurile comandate de aceste butoane sa fie actionate doar cat timp sunt apasate butoanele?

Editat de gabitzu2006
update
Link spre comentariu

nu stiu. am incercat cum am zis eu, nu merge...adica daca apas tasta pt led6, acesta se aprinde (dar lumineaza f slab) si nu il mai pot stinge.  :)

#include <IRremote.h>
int RECV_PIN = 2; // the pin where you connect the output pin of sensor
int relay1 = 4;
int relay2 = 5;
int relay3 = 6;
int relay4 = 7;
int relay5 = 8;
int relay6 = 3;
int relayPins[] = {relay1, relay2, relay3, relay4, relay5, relay6};  //array with all the relays' pins
int relayStates[] = {0,0,0,0,0,0}; //the initial state of relays
int i=0;  //relay index for the arrays

#define code1 16753245    // code received from button no. 1
#define code2 16736925    // code received from button no. 2
#define code3 16769565    // code received from button no. 3
#define code4 16720605    // code received from button no. 4
#define code5 16712445    // code pt 5
#define code6 16718055    // cod pt up
#define code7 16730805    // cod pt down
#define code8 16726215    // cod pt on/off

IRrecv irrecv(RECV_PIN);
decode_results results;

void setup() {
  Serial.begin(115200);
  irrecv.enableIRIn(); // Start the receiver  
  for(int i = 0; i < 5; i++){
     pinMode(relayPins[i], OUTPUT);
  }
}


void loop() {
  static int idx = -1; //index iesire

  if (irrecv.decode(&results)) {
    unsigned int value = results.value;
    switch(value) {
       case code1: 
              idx = 0; //prima iesire, 
              relayStates[idx] ^= 1; //inverseaza starea
           break;
       case code2: 
              idx = 1; 
              relayStates[idx] ^= 1; 
           break;
       case code3: 
              idx = 2; 
              relayStates[idx] ^= 1; 
           break;
       case code4: 
              idx = 3; 
              relayStates[idx] ^= 1; 
           break;
       case code5: 
              idx = 4; 
              relayStates[idx] ^= 1; 
           break;
       case code6: //up 
              idx++; // selecteaza urmatoarea iesire
              idx %=5; //daca e 5, ia-o de la capat
              relayStates[idx] = 1; //fa iesirea 1
           break;
       case code7: //down
              idx--; //selecteaza iesirea precedenta
              if(idx < 0){ //daca e negativa, iao pe cea mai mare
                idx=4;
              }
              relayStates[idx] = 1; //fa iesirea 1
           break;
       case code8:
       digitalWrite(relay6, HIGH);
       break;
       //default : idx = -1;
    }


    for(int i = 0; i < 5; i++){ // modifica iesirea in functie de testele anterioare.
      if(i == idx){
        digitalWrite(relayPins[i], relayStates[i]);
      } else {
        digitalWrite(relayPins[i], LOW);
      }
    }

    irrecv.resume(); // Receive the next value
  } //if (irrecv.decode(&results))

} //loop()

nu stiu cum sa fac ca, apasand pe butonul de la telecomanda, o data sa se aprinda ledul si sa ramana aprins, iar cand mai apasa o data sa se stinga ledul si sa ramana stins, etc. ma refer la relay6, in sketchul meu.

acum am mai observat ceva: daca sa zicem, led2 e aprins, apas butonul pt led3, acum se stinge led2 si nu mai e aprins niciun led. mai apas o data acelasi buton, pt led3 si abia acum led3 se aprinde. cand rulez printre ele, cu up si down, nu se intampla fenomenul asta. nu este foarte deranjant, cred ca poate ramane asa, daca nu e mare bataie de cap corectarea.

 

 

in legatura cu intrebarea: cum stii cand se termina de apasat butonul, am observat in terminal asta: cand apas butonul, telecomanda emite codul butonului o singura data, de exemplu 16716015, apoi emite cat timp tin apasat butonul codul 4294967295. probabil ca se poate considera ca butonul nu mai este apasat daca intre doua coduri din astea de final (429...) e un interval de timp intre 5us si 20us (am dat niste valori aiurea, nu stiu cum pot determina distanta temporala intre doua coduri succesive. poate din specificatiile NEC).

 

Editat de gabitzu2006
informatii noi
Link spre comentariu

Poti testa codul de mai jos? Trebuie sa fie echivalent (ca functionare) cu cel pe care l-am pus initial, dupa ce ai comentat defaultul din switch. Daca merge, poate reusim sa detectam opritul apasatului.

 #include <IRremote.h>

#define NR_IESIRI 4
int RECV_PIN = 2; // the pin where you connect the output pin of sensor
int relay1 = 4;
int relay2 = 5;
int relay3 = 6;
int relay4 = 7;
int relayPins[] = {relay1, relay2, relay3, relay4};  //array with all the relays' pins
int relayStates[] = {0,0,0,0}; //the initial state of relays
int i=0;  //relay index for the arrays

#define code1 16753245    // code received from button no. 1
#define code2 16736925    // code received from button no. 2
#define code3 16769565    // code received from button no. 3
#define code4 16720605    // code received from button no. 4
#define code5 16718055    // cod pt up
#define code6 16730805    // cod pt down

IRrecv irrecv(RECV_PIN);
decode_results results;

void setup() {
  Serial.begin(115200);
  irrecv.enableIRIn(); // Start the receiver  
  for(int i = 0; i < NR_IESIRI; i++){
     pinMode(relayPins[i], OUTPUT);
  }
}


void loop() {
  static int idx = -1; //index iesire

  if (irrecv.available())
  {
    if (irrecv.decode(&results)) {
      unsigned int value = results.value;
      switch(value) {
         case code1: 
                idx = 0; //prima iesire, 
                relayStates[idx] ^= 1; //inverseaza starea
             break;
         case code2: 
                idx = 1; 
                relayStates[idx] ^= 1; 
             break;
         case code3: 
                idx = 2; 
                relayStates[idx] ^= 1; 
             break;
         case code4: 
                idx = 3; 
                relayStates[idx] ^= 1; 
             break;
         case code5: //up 
                idx++; // selecteaza urmatoarea iesire
                idx %= NR_IESIRI; //daca e 4, ia-o de la capat
                relayStates[idx] = 1; //fa iesirea 1
             break;
         case code6: //down
                idx--; //selecteaza iesirea precedenta
                if(idx < 0){ //daca e negativa, ia-o pe cea mai mare
                  idx = NR_IESIRI - 1;
                }
                relayStates[idx] = 1; //fa iesirea 1
             break;
         default : idx = -1;
      } //switch
  
  
      for(int i = 0; i < NR_IESIRI; i++){ // modifica iesirea in functie de testele anterioare.
        if(i == idx){
          digitalWrite(relayPins[i], relayStates[i]);
        } else {
          digitalWrite(relayPins[i], LOW);
        }
      }
    } //if (irrecv.decode(&results))
    
    irrecv.resume(); // Receive the next value
  } //if (irrecv.available())  

} //loop()

 

Link spre comentariu

acum merge cu ledul 6! insa lumineaza slab. am schimbat si pinul digital la care l-am conectat, am schimbat si LED-ul...tot asa. ce sa aiba oare? am schimbat si rezistorul...doar sa il fi schimbat cu un rezistor de aceeasi valoare.

Arduino: 1.8.12 (Windows 10), Placă"Arduino Uno"

C:\Users\gabri\Desktop\comanda IR 4 relee\get_dec\get_dec.ino: In function 'void loop()':

get_dec:35:14: error: 'class IRrecv' has no member named 'available'

   if (irrecv.available())

              ^~~~~~~~~

exit status 1
'class IRrecv' has no member named 'available'

asta imi da cand il compilez

 

Link spre comentariu

Presupun ca if(irrecv.decode()) e parcursa tot timpul, cu ultimul cod, asa ca iesirea relay6 isi schimba starea foarte repede si ce vezi tu e o mediere.

Pune un delay(200); inainte de } //loop, ar trebui sa-l vezi cum palpaie.

Se pare ca folosim biblioteci diferite. Ce biblioteca ai pentru IRremote?

Editat de Liviu M
Link spre comentariu

am incercat si cu delay 4000 dar nu pot spune ca palpaie. merge sa-i mai bag un switch cu un case, separat? sau cum sa fac?

nu stiu. daca vrei o postez aici. am pornit de la un sketch de pe un site unde era oferita si biblioteca, pt ca am fost disperat sa incerc diferite sketchuri, eu folosind ultima versiune de biblioteca IRremote. pana la urma am luat biblioteca de acolo si a mers. Hai ca incerc sa o pun aici.

IRremote.zip

ma gandesc ca as putea rezolva problema ledului 6 integrand semnalul livrat si amplificandu-l putin. asta asa, ca workaround hardware   :)

Editat de gabitzu2006
idee 9
Link spre comentariu

Creează un cont sau autentifică-te pentru a adăuga comentariu

Trebuie să fi un membru pentru a putea lăsa un comentariu.

Creează un cont

Înregistrează-te pentru un nou cont în comunitatea nostră. Este simplu!

Înregistrează un nou cont

Autentificare

Ai deja un cont? Autentifică-te aici.

Autentifică-te acum



×
×
  • Creează nouă...

Informații Importante

Am plasat cookie-uri pe dispozitivul tău pentru a îmbunătății navigarea pe acest site. Poți modifica setările cookie, altfel considerăm că ești de acord să continui.Termeni de Utilizare si Ghidări