X4-Life RGB ledszalag távoli vezérlése

X4-Life RGB ledszalagot szerettem volna távolról irányítani, ezért első körben a távirányítóját akartam módosítani. Az volt az alap ötlet, hogy a távirányító áramkörére ahol a gomb benyomásával rövidre zárjuk az áramkört, oda kis tüskéket forrasztottam, amit majd tranzisztorral akartam kapcsolgatni. Szerencsére hamar meggondoltam magam, így valami sokkal szofisztikáltabb megoldást választottam. Szerencsére a neten rengeteg cikk található arról, hogyan tudjuk kiolvasni az IR távirányítóból érkező jelet.

Erről a LED szalagról lenne szó

Dekorációs fény, X4-LIFE 701473

Első körben kössük be a TSOP 31238 38kHz-es IR vevőt az alábbi módon. A képen TSOP31236 szerepel, de a bekötése ugyanaz. A különbség a kettő között a vivőfrekvencia, ami az egyiknél 36Khz a másiknál, amit mi használunk 38kHz.

IR vevő

Ezután töltsük fel az Arduino-ra a következő kódot, vagy töltsük le a legfrissebb változatot a github-ról és használjuk azt.

//#include <ircodes.h>

/* Raw IR decoder sketch!
This sketch/program uses the Arduno and a PNA4602 to
decode IR received. This can be used to make a IR receiver
(by looking for a particular code)
or transmitter (by pulsing an IR LED at ~38KHz for the
durations detected
Code is public domain, check out www.ladyada.net and adafruit.com
for more tutorials!
*/

// We need to use the 'raw' pin reading methods
// because timing is very important here and the digitalRead()
// procedure is slower!
//uint8_t IRpin = 2;
// Digital pin #2 is the same as Pin D2 see
// http://arduino.cc/en/Hacking/PinMapping168 for the 'raw' pin mapping
#define IRpin_PIN PIND
#define IRpin 2
// for MEGA use these!
//#define IRpin_PIN PINE
//#define IRpin 4

// the maximum pulse we'll listen for - 65 milliseconds is a long time
#define MAXPULSE 65000

// what our timing resolution should be, larger is better
// as its more 'precise' - but too large and you wont get
// accurate timing
#define RESOLUTION 20

// we will store up to 100 pulse pairs (this is -a lot-)
uint16_t pulses[100][2]; // pair is high and low pulse
uint8_t currentpulse = 0; // index for pulses we're storing

void setup(void) {
  Serial.begin(9600);
  Serial.println("Ready to decode IR!");
}

void loop(void) {
  uint16_t highpulse, lowpulse; // temporary storage timing
  highpulse = lowpulse = 0; // start out with no pulse length
  
  
// while (digitalRead(IRpin)) { // this is too slow!
    while (IRpin_PIN & (1 << IRpin)) {
     // pin is still HIGH

     // count off another few microseconds
     highpulse++;
     delayMicroseconds(RESOLUTION);

     // If the pulse is too long, we 'timed out' - either nothing
     // was received or the code is finished, so print what
     // we've grabbed so far, and then reset
     if ((highpulse >= MAXPULSE) && (currentpulse != 0)) {
       printpulses();
       currentpulse=0;
       return;
     }
  }
  // we didn't time out so lets stash the reading
  pulses[currentpulse][0] = highpulse;
  
  // same as above
  while (! (IRpin_PIN & _BV(IRpin))) {
     // pin is still LOW
     lowpulse++;
     delayMicroseconds(RESOLUTION);
     if ((lowpulse >= MAXPULSE) && (currentpulse != 0)) {
       printpulses();
       currentpulse=0;
       return;
     }
  }
  pulses[currentpulse][1] = lowpulse;

  // we read one high-low pulse successfully, continue!
  currentpulse++;
}

void printpulses(void) {
  Serial.println("\n\r\n\rReceived: \n\rOFF \tON");
  for (uint8_t i = 0; i < currentpulse; i++) {
    Serial.print(pulses[i][0] * RESOLUTION, DEC);
    Serial.print(" usec, ");
    Serial.print(pulses[i][1] * RESOLUTION, DEC);
    Serial.println(" usec");
  }
 
  // print it in a 'array' format
  Serial.println("int IRsignal[] = {");
  Serial.println("// ON, OFF (in 10's of microseconds)");
  for (uint8_t i = 0; i < currentpulse-1; i++) {
    Serial.print("\t"); // tab
    Serial.print(pulses[i][1] * RESOLUTION / 10, DEC);
    Serial.print(", ");
    Serial.print(pulses[i+1][0] * RESOLUTION / 10, DEC);
    Serial.println(",");
  }
  Serial.print("\t"); // tab
  Serial.print(pulses[currentpulse-1][1] * RESOLUTION / 10, DEC);
  Serial.print(", 0};");
}

Az ON gomb megnyomása után a soros porton a következő adathalmazt kapjuk majd, ez lényegében egy négyszögjel magas és alacsony állapotát jelenti (Received: OFF ON). A jobb oldalon ugyanaz tömbbe rendezve.

 

Nyers adatok Tömbbe rendezett adatok
Received:
OFF ON
47040 usec, 8760 usec
4360 usec, 540 usec
540 usec, 560 usec
520 usec, 580 usec
520 usec, 540 usec
560 usec, 540 usec
520 usec, 580 usec
520 usec, 560 usec
540 usec, 560 usec
520 usec, 580 usec
1620 usec, 540 usec
1620 usec, 560 usec
1620 usec, 580 usec
1620 usec, 560 usec
1600 usec, 560 usec
1620 usec, 580 usec
1620 usec, 560 usec
1620 usec, 540 usec
1620 usec, 580 usec
520 usec, 560 usec
1620 usec, 580 usec
1620 usec, 540 usec
520 usec, 580 usec
520 usec, 560 usec
540 usec, 540 usec
540 usec, 580 usec
500 usec, 560 usec
1620 usec, 580 usec
520 usec, 560 usec
540 usec, 540 usec
1640 usec, 540 usec
1620 usec, 580 usec
1620 usec, 560 usec
1620 usec, 540 usec
38800 usec, 8780 usec
2160 usec, 540 usec
27884 usec, 8740 usec
2200 usec, 540 usec
int IRsignal[] = {
// ON, OFF (in 10’s of microseconds)
876, 436,
54, 54,
56, 52,
58, 52,
54, 56,
54, 52,
58, 52,
56, 54,
56, 52,
58, 162,
54, 162,
56, 162,
58, 162,
56, 160,
56, 162,
58, 162,
56, 162,
54, 162,
58, 52,
56, 162,
58, 162,
54, 52,
58, 52,
56, 54,
54, 54,
58, 50,
56, 162,
58, 52,
56, 54,
54, 164,
54, 162,
58, 162,
56, 162,
54, 3880,
878, 216,
54, 2788,
874, 220,
54, 0};

 

Ezután  a kapott IR szignált egy másik kódban felhasználjuk, ez lesz  majd az új távirányítónk. Az Arduino 8-12 pinjei bemenetre vannak állítva, így ha egy külső jellel 5V-ra felhúzzuk, azzal lefuttatunk egy függvényt. Pl. a 12-es bemenetre 5V-os jelet adunk azzal lefuttatjuk a x4on függvényt.

 if (onPin == HIGH){
    X4on();
    delay(100);
    }

A 13-as pin kimenetre van állítva, a x4on függvényben tárolt jelalak itt fog “távozni”.  Ehhez a pinhez egy infra LED-et kapcsolunk ami az elektromos szignált elektromágneses sugárzássá alakítja, ami a levegőben terjedve végül eléri az IR detektorunkat, ahol elektromos jellé alakul ismét, majd a megfelelő áramkör értelmezi a jelet, végül a LED szalag bekapcsol.

// This sketch will send out a Nikon D50 trigger signal (probably works with most Nikons)
// See the full tutorial at http://www.ladyada.net/learn/sensors/ir.html
// this code is public domain, please enjoy!
//Modified by acetylcholin 
// This sketch will send out a X4-LIFE RGB LED on/off/red/green/blue signals
int IRledPin =  13;    // LED connected to digital pin 13
int onPin = 12;
int offPin = 11;
int redPin = 10;
int greenPin = 9;
int bluePin = 8;
// The setup() method runs once, when the sketch starts
 
void setup()   {                
  // initialize the IR digital pin as an output:
  pinMode(IRledPin, OUTPUT);      
  Serial.begin(9600);
  pinMode(onPin, INPUT);
  pinMode(offPin, INPUT);
  pinMode(redPin, INPUT);
  pinMode(greenPin, INPUT);
  pinMode(bluePin, INPUT);
}
 
void loop()                     
{
 onPin = digitalRead(12);
 offPin = digitalRead(11);
 redPin = digitalRead(10);
 greenPin = digitalRead(9);
 bluePin = digitalRead(8);
  if (onPin == HIGH){
    X4on();
    delay(100);
    }
   
  if (offPin == HIGH){
    X4off();
    delay(100);
    }
  if (redPin == HIGH){
    X4red();
    delay(100);
    } 
    if (greenPin == HIGH){
    X4green();
    delay(100);
    }

if (bluePin == HIGH){
    X4blue();
    delay(100);
    }
}
 
// This procedure sends a 38KHz pulse to the IRledPin 
// for a certain # of microseconds. We'll use this whenever we need to send codes
void pulseIR(long microsecs) {
  // we'll count down from the number of microseconds we are told to wait
 
  cli();  // this turns off any background interrupts
 
  while (microsecs > 0) {
    // 38 kHz is about 13 microseconds high and 13 microseconds low
   digitalWrite(IRledPin, HIGH);  // this takes about 3 microseconds to happen
   delayMicroseconds(10);         // hang out for 10 microseconds, you can also change this to 9 if its not working
   digitalWrite(IRledPin, LOW);   // this also takes about 3 microseconds
   delayMicroseconds(10);         // hang out for 10 microseconds, you can also change this to 9 if its not working
 
   // so 26 microseconds altogether
   microsecs -= 26;
  }
 
  sei();  // this turns them back on
}
 
void X4on() {
  
 
  pulseIR(8760);
  delayMicroseconds(4360);
   pulseIR(560);
  delayMicroseconds(540);
   pulseIR(540);
  delayMicroseconds(540);
   pulseIR(560);
  delayMicroseconds(540);
   pulseIR(540);
  delayMicroseconds(540);
   pulseIR(560);
  delayMicroseconds(520);
   pulseIR(580);
  delayMicroseconds(520);
   pulseIR(560);
  delayMicroseconds(520);
   pulseIR(560);
  delayMicroseconds(520);
   pulseIR(580);
  delayMicroseconds(1620);
   pulseIR(540);
  delayMicroseconds(1640);
   pulseIR(540);
  delayMicroseconds(1620);
   pulseIR(580);
  delayMicroseconds(1620);
   pulseIR(560);
  delayMicroseconds(1620);
   pulseIR(540);
  delayMicroseconds(1620);
   pulseIR(580);
  delayMicroseconds(1620);
   pulseIR(560);
  delayMicroseconds(1620);
   pulseIR(560);
  delayMicroseconds(1600);
   pulseIR(600);
  delayMicroseconds(500);
   pulseIR(560);
  delayMicroseconds(1620);
   pulseIR(580);
  delayMicroseconds(1620);
   pulseIR(540);
  delayMicroseconds(520);
   pulseIR(580);
  delayMicroseconds(520);
   pulseIR(560);
  delayMicroseconds(540);
   pulseIR(560);
  delayMicroseconds(520);
   pulseIR(560);
  delayMicroseconds(540);
   pulseIR(540);
  delayMicroseconds(1620);
   pulseIR(580);
  delayMicroseconds(520);
   pulseIR(560);
  delayMicroseconds(540);
   pulseIR(540);
  delayMicroseconds(1620);
   pulseIR(560);
  delayMicroseconds(1620);
   pulseIR(580);
  delayMicroseconds(1620);
   pulseIR(560);
  delayMicroseconds(1600);
   pulseIR(560);
  delayMicroseconds(38780);
   pulseIR(8780);
  delayMicroseconds(2160);
   pulseIR(540);
  delayMicroseconds(27864);
   pulseIR(8760);
  delayMicroseconds(2180);
   pulseIR(560);
  delayMicroseconds(27844);
   pulseIR(8760);
  delayMicroseconds(2180);
   pulseIR(560);
 
}

void X4off() {
  
  pulseIR(8780);
  delayMicroseconds(4360);
  pulseIR(560);
  delayMicroseconds(540);
  pulseIR(560);
  delayMicroseconds(520);
  pulseIR(560);
  delayMicroseconds(520);
  pulseIR(560);
  delayMicroseconds(540);
  pulseIR(560);
  delayMicroseconds(520);
  pulseIR(580);
  delayMicroseconds(520);
  pulseIR(540);
  delayMicroseconds(560);
  pulseIR(540);
  delayMicroseconds(520);
  pulseIR(580);
  delayMicroseconds(1620);
  pulseIR(560);
  delayMicroseconds(1620);
  pulseIR(560);
  delayMicroseconds(1620);
  pulseIR(580);
  delayMicroseconds(1620);
  pulseIR(540);
  delayMicroseconds(1620);
  pulseIR(560);
  delayMicroseconds(1620);
  pulseIR(580);
  delayMicroseconds(1620);
  pulseIR(560);
  delayMicroseconds(1620);
  pulseIR(560);
  delayMicroseconds(1600);
  pulseIR(600);
  delayMicroseconds(1600);
  pulseIR(560);
  delayMicroseconds(1620);
  pulseIR(560);
  delayMicroseconds(1620);
  pulseIR(580);
  delayMicroseconds(1620);
  pulseIR(540);
  delayMicroseconds(520);
  pulseIR(580);
  delayMicroseconds(520);
  pulseIR(560);
  delayMicroseconds(540);
  pulseIR(560);
  delayMicroseconds(520);
  pulseIR(560);
  delayMicroseconds(540);
  pulseIR(540);
  delayMicroseconds(560);
  pulseIR(540);
  delayMicroseconds(520);
  pulseIR(580);
  delayMicroseconds(520);
  pulseIR(560);
  delayMicroseconds(1620);
  pulseIR(580);
  delayMicroseconds(1620);
  pulseIR(560);
  delayMicroseconds(1620);
  pulseIR(540);
  delayMicroseconds(38780);
  pulseIR(8780);
  delayMicroseconds(2180);
  pulseIR(560);
  delayMicroseconds(27864);
  pulseIR(8760);
  delayMicroseconds(2200);
  pulseIR(560);
  delayMicroseconds(27864);
  pulseIR(8760);
  delayMicroseconds(2200);
  pulseIR(540);
  delayMicroseconds(27864);
  pulseIR(8780);
  delayMicroseconds(2180);
  pulseIR(560);
 
  
  }

void X4red() {
  
  pulseIR(8760);
  delayMicroseconds(4360);
  pulseIR(540);
  delayMicroseconds(560);
  pulseIR(560);
  delayMicroseconds(540);
  pulseIR(540);
  delayMicroseconds(560);
  pulseIR(520);
  delayMicroseconds(560);
  pulseIR(540);
  delayMicroseconds(520);
  pulseIR(580);
  delayMicroseconds(520);
  pulseIR(540);
  delayMicroseconds(540);
  pulseIR(560);
  delayMicroseconds(520);
  pulseIR(580);
  delayMicroseconds(1620);
  pulseIR(540);
  delayMicroseconds(1620);
  pulseIR(540);
  delayMicroseconds(1620);
  pulseIR(580);
  delayMicroseconds(1620);
  pulseIR(560);
  delayMicroseconds(1620);
  pulseIR(540);
  delayMicroseconds(1620);
  pulseIR(580);
  delayMicroseconds(1620);
  pulseIR(560);
  delayMicroseconds(1620);
  pulseIR(540);
  delayMicroseconds(1640);
  pulseIR(560);
  delayMicroseconds(560);
  pulseIR(520);
  delayMicroseconds(580);
  pulseIR(500);
  delayMicroseconds(1640);
  pulseIR(540);
  delayMicroseconds(1640);
  pulseIR(560);
  delayMicroseconds(540);
  pulseIR(540);
  delayMicroseconds(560);
  pulseIR(540);
  delayMicroseconds(540);
  pulseIR(560);
  delayMicroseconds(540);
  pulseIR(540);
  delayMicroseconds(1600);
  pulseIR(600);
  delayMicroseconds(1600);
  pulseIR(560);
  delayMicroseconds(540);
  pulseIR(540);
  delayMicroseconds(560);
  pulseIR(520);
  delayMicroseconds(1620);
  pulseIR(580);
  delayMicroseconds(1620);
  pulseIR(560);
  delayMicroseconds(1620);
  pulseIR(560);
  delayMicroseconds(38760);
  pulseIR(8760);
  delayMicroseconds(2180);
  pulseIR(560);
  delayMicroseconds(27844);
  pulseIR(8760);
  delayMicroseconds(2180);
  pulseIR(560);
  delayMicroseconds(27844);
  pulseIR(8760);
  delayMicroseconds(2180);
  pulseIR(560);
  delayMicroseconds(27844);
  pulseIR(8760);
  delayMicroseconds(2180);
  pulseIR(560);
  delayMicroseconds(27844);
  pulseIR(8760);
  delayMicroseconds(2180);
  pulseIR(560);
  
  }

void X4green() {
  
  pulseIR(8780);
  delayMicroseconds(4340);
  pulseIR(560);
  delayMicroseconds(580);
  pulseIR(520);
  delayMicroseconds(520);
  pulseIR(580);
  delayMicroseconds(520);
  pulseIR(540);
  delayMicroseconds(560);
  pulseIR(540);
  delayMicroseconds(520);
  pulseIR(580);
  delayMicroseconds(520);
  pulseIR(560);
  delayMicroseconds(560);
  pulseIR(540);
  delayMicroseconds(540);
  pulseIR(560);
  delayMicroseconds(1620);
  pulseIR(560);
  delayMicroseconds(1600);
  pulseIR(560);
  delayMicroseconds(1620);
  pulseIR(580);
  delayMicroseconds(1620);
  pulseIR(540);
  delayMicroseconds(1620);
  pulseIR(560);
  delayMicroseconds(1620);
  pulseIR(580);
  delayMicroseconds(1620);
  pulseIR(540);
  delayMicroseconds(1640);
  pulseIR(540);
  delayMicroseconds(1640);
  pulseIR(560);
  delayMicroseconds(1620);
  pulseIR(560);
  delayMicroseconds(540);
  pulseIR(560);
  delayMicroseconds(1620);
  pulseIR(560);
  delayMicroseconds(1620);
  pulseIR(540);
  delayMicroseconds(580);
  pulseIR(520);
  delayMicroseconds(560);
  pulseIR(540);
  delayMicroseconds(560);
  pulseIR(520);
  delayMicroseconds(560);
  pulseIR(520);
  delayMicroseconds(560);
  pulseIR(540);
  delayMicroseconds(1620);
  pulseIR(560);
  delayMicroseconds(540);
  pulseIR(560);
  delayMicroseconds(540);
  pulseIR(540);
  delayMicroseconds(1620);
  pulseIR(560);
  delayMicroseconds(1640);
  pulseIR(540);
  delayMicroseconds(1620);
  pulseIR(560);
  delayMicroseconds(38780);
  pulseIR(8760);
  delayMicroseconds(2180);
  pulseIR(560);
  delayMicroseconds(27844);
  pulseIR(5780);
  delayMicroseconds(2180);
  pulseIR(560);
  
 

}

void X4blue() {

   pulseIR(8760);
  delayMicroseconds(4360);
  pulseIR(560);
  delayMicroseconds(540);
  pulseIR(560);
  delayMicroseconds(520);
  pulseIR(580);
  delayMicroseconds(520);
  pulseIR(540);
  delayMicroseconds(560);
  pulseIR(540);
  delayMicroseconds(520);
  pulseIR(580);
  delayMicroseconds(520);
  pulseIR(540);
  delayMicroseconds(560);
  pulseIR(560);
  delayMicroseconds(520);
  pulseIR(560);
  delayMicroseconds(1640);
  pulseIR(540);
  delayMicroseconds(1620);
  pulseIR(560);
  delayMicroseconds(1620);
   pulseIR(580);
  delayMicroseconds(1620);
  pulseIR(540);
  delayMicroseconds(1620);
  pulseIR(560);
  delayMicroseconds(1620);
  pulseIR(580);
  delayMicroseconds(1620);
  pulseIR(540);
  delayMicroseconds(1620);
  pulseIR(560);
  delayMicroseconds(1620);
  pulseIR(580);
  delayMicroseconds(520);
  pulseIR(560);
  delayMicroseconds(540);
  pulseIR(540);
  delayMicroseconds(540);
  pulseIR(560);
  delayMicroseconds(1620);
  pulseIR(560);
  delayMicroseconds(520);
  pulseIR(580);
  delayMicroseconds(520);
   pulseIR(560);
  delayMicroseconds(540);
  pulseIR(540);
  delayMicroseconds(520);
  pulseIR(580);
  delayMicroseconds(1620);
  pulseIR(560);
  delayMicroseconds(1620);
  pulseIR(540);
  delayMicroseconds(1620);
  pulseIR(580);
  delayMicroseconds(520);
  pulseIR(560);
  delayMicroseconds(1620);
  pulseIR(580);
  delayMicroseconds(1620);
  pulseIR(560);
  delayMicroseconds(1620);
  pulseIR(540);
  delayMicroseconds(38780);
  pulseIR(8800);
  delayMicroseconds(2160);
  pulseIR(540);
  delayMicroseconds(27884);
   pulseIR(8760);
  delayMicroseconds(2180);
  pulseIR(540);
  delayMicroseconds(27884);
  pulseIR(8760);
  delayMicroseconds(2200);
  pulseIR(540);
  delayMicroseconds(27864);
  pulseIR(8760);
  delayMicroseconds(2180);
  pulseIR(560);
  
}

A LED bekötés egyszerű, a 13-as pinre rákötjük a LED pozitív lábát, a negatív láb meg megy a földre egy 220Ω-os ellenálláson keresztül.

IR LED

A feladat könnyebbik részével meg is volnánk. Teszteljük az áramkörünket, 1kΩ ellenálláson keresztül a 12-es pint 5V-ra kötjük, ha mindent jól csináltunk, akkor a LED szalag világít. Most kössük a 11-es pinre, a LED szalag kialszik.

 

A távoli vezérlés

Ezt javascipt-el fogjuk megoldani, méghozzá nem is akármilyen módon. 2017. január elsején fog debütálni a jDesktop.com. Ez egy olyan vizuális javascipt szerkesztő alkalmazás amivel könnyedén építhetünk webes alkalmazásokat, távoli vezérlést valósíthatunk meg, vagy szenzorokból származó jeleket valós időben grafikonon jeleníthetünk meg. Az alkalmazás raspberry pi-re optimalizált, így a telepítési útmutatót használva néhány perc alatt megvan. Ez a rész természetesen egy minimális LINUX ismeretet megkövetel. Az ajánlott operációs  rendszer a raspberry-re innen letölthető:

Raspbian

Tehát 2017. január elsejétől a következő linken megtalálod a telepítési útmutatót:

http://jdesktop.com/documentation/installation/

A fejlesztő környezet még erősen béta, de a fő funkciók kifogástalanul működnek. Természetesen az egész rendszer folyamatos fejlesztés alatt áll, így bármilyen építő jellegű kritika szívesen fogadott.

A példa alkalmazást (jLED) innen tudod letölteni:

jLED

Ezt kicsomagolás után a /var/www/html könyvtárba kell másolni, ezután a fejlesztő környezetben meg tudod majd nyitni.

A raspberry és az Arduino közötti összeköttetés 

Közös földre kötjük őket.

Raspberry pi Model B+ Arduino UNO
7 (GPIO4) 12
29 (GPIO5) 11
31 (GPIO6) 10
26 (GPIO7) 9
27 (GPIO8) 8

 

A kezelőfelület

kezelofelulet

A raspberry lokális IP címét használva elérhető bármelyik böngészőből: (kivéve IE, ennek használata nem ajánlott) 192.168.0.15/jLED/

Ügyelj a formátumra 192.168.0.15/jLED/ a törtvonal (/) használata a jLED után elengedhetetlen, elhagyva a szerver leállását okozza. Természetesen ez nemsokára orvosolva lesz.

 

Néhány kép a LED világításról

 

Alkatrészek 

• TSOP31238 38kHz IR vevő (Hestore.hu)

• IR led, ellenállás

• Arduino Uno

• Rapberry

• Néhány jumper wire

 

Videó

Felhasznált irodalom

http://www.build-electronic-circuits.com/arduino-remote-control/

Lezione 1 Arduino Progetto Come fare trasmettitore o ricevitore IR

Ajánlott irodalom

Share This:

 
Loading Facebook Comments ...

Leave a Comment