Remote control controlled via Internet

This is a kinda complex tutorial, although Iíll try to make it as easy to understand for a wide amount of programmers.

Before proceeding, keep in mind that youíll need at least one Altair.

Step 1: ?Theory

Remote control controlled via Internet
Remote control controlled via Internet

First of all, we should know that the infrared light is simply light with an specific colour out of the bounds of the colours we can see with the naked eye.

In fact, the infrared wave length goes from 750 nanometers (ms), which is a little beyond of the wave length we canít perceive. Bigger wave lengths are different things, suchs as microwaves, for instance.

As a small experiment in order to see infrared light from a remote control, you could point at a controller using your phoneís camera (or any other camera) while itís on, then press a button. You should see something like on the picture number of this step.

*IR blinking remote*

The problem is that everything that surrounds us emit infrared light, with different wave length but still infrared (thatís why, when you see through a camera you donít see everything shining; cameras only perceive certain wave length, which allow us to see the remote control IR light). Keeping in mind, a method in order to send information using IR light regardless of all the IR light "noise" is needed.

Step 2: The Solution

Remote control controlled via Internet

Something similar to morse code was developed in order to solve this issue.

Modulation is in fact, the name that it has, and basically is making a IR LED blink @ 35kHz (although it may vary among manufacturers).

In fact sending a command, comes out as a blinks with spaces between them (measured in microseconds), in order to "attract the attention" of the receiver. The receiver, only measures the time the set of blinks lasted. Between block and block the space seems close to nonexistent to us, although on the IR context is more than enough.

To make it clearer, take a look to the gif on the page.

Keep in mind that the receiver is always returning "1", while the sender is not sending anything.

Step 3: ?Practice

Remote control controlled via Internet

The theory was explained, now it remains to put into practice all the new knowledge.

Before making a controller with Altair, the first task is learning how to read the information emitted by any Remote Control; from a TV, for instance.

For warming up, Iíd like to you to make this little test. (Instead of batteries you could use directly the Altair, plugging the wires to 3.3v and to GND).

This experiment will blink every time the IR receiver receives something from a remote control. Cool, huh?

Step 4: The receiver

Remote control controlled via Internet

Alright, now.. with this code youíll make the Altair to read whatever a controller transmits.

Check the embedded CODE (Had too many format troubles editing code here)

Assistance links:

http://www.arduino.cc/en/pmwiki.php?n=Reference/P... (PIND)

http://www.arduino.cc/en/pmwiki.php?n=Reference/P.... ( _BV(2) explanation)

http://www.arduino.cc/en/pmwiki.php?n=Reference/P.... (Bits mask)

Here I show you how to connect the Altair in order to work as a receiver.

ALWAYS check on the DATASHEET of your receiver (avoid burning it, like it happened to me while doing this tutorial).

Remote control controlled via Internet
CODE1.ino4 KB

Step 5: The emissor (and receiver)

Remote control controlled via Internet

Now, the explanation in order to make that the receiver you just did also emits. The connection of the Altair, the components with the protoboard will be shown after the code. Likewise, the assistance links will be immediately after the code, although the code will be commented the best way possible. Any doubt with any part of the code, donít hesitate to comment it on the section below, no one is born knowing, specially with all this which is pretty complex if you are not familiarized with low level programming.

The next code has one or more modification to the last code, itís recommended to have it as a different file.

Check the embedded code!

Assistance Links

http://www.fiz-ix.com/2012/01/how-to-configure-ard... (Inner timers)

http://www.fiz-ix.com/2012/01/how-to-configure-ard... (PWM)

Remote control controlled via Internet
CODE2.ino6 KB

Step 6: Embedded Aquila Action

Having all this implemented, the received code could be simply copied form the Serial Monitor, and paste it as a new matrix in the code. Then, adding the Aquila action functions in order to call that (or those) matrix and have a Remote Control even better through the Aquila platform (the advantage of this is that you wonít need to buy more push buttons and that youíll be able to automate as I will mention now).

See this as a "simple" application for the Altair, imagine configuring it so at N time of the day your TV would turn on and start recording your favorite show.

Now, we will add a few more lines to implement the Aquila platform. Iím including a matrix with a lot of numbers; this are the ones the remote control that I used sends to the TV I used (that in fact I extracted directly from the Serial Monitor). Youíll have to change those numbers for the ones your Serial Monitor returns

Although, I left them there so you could see a matrix structure.

//Because the timing is very important, we wonít be using digitalRead //for itís very slow compared with what weíll be using. //Check the reference link after the code; back on the tutorial. //This (PIND) thing means that form pin 0 to 7 will be READ ONLY #define IRpin_PIN PIND #include #include #include

#define MASK 2 //This will be taken as a binary number (00000010) #define Boton 33 //Built-in Altair Button (It has inverted logif! LOW = Pressed, HIGH = NOT pressed) #define Boton2 10 //Extern button, normal logic! HIGH = Pressed, LOW = Not pressed! #define IR 9 //The longest pulse that will be read is going to be 65ms (when the code applies, itíll be a microseconds function //So it will NOT be taken as 65000ms (being this 65 seconds); in fact 65 ms is A LOT in this environment. #define MAXPULSE 65000 //Nuestra resolución de tiempo, entre más grande es el valor mejor, //Our time resolution, the bigger the value the better, for itís more precise //but it takes longer to process it //And we would be losing the precision we won not using digitalRead #define RESOLUTION 20 //El pulso que se recibirá será en pares, 100 pares en ste ámbito es muchísimo //The received pulse will be in pairs, 100 pairs is actually a LOT. uint16_t pulses[100][2]; // Remember that a "value" consist in an ON and OFF from the LED, so in the matrix is stored in pairs. uint8_t currentpulse = 0; // Itíll be used to know how many pairs from ON and OFF have being received. bool full = false;

uint16_t turnON [120][2]={{46264,1100},{540,1160},{480,1960},{540,1080},{520,1120},{520,1120},{520,1100},{540,1080},{560,1060},{1420,1040},{600,1800},{720,920},{20324,980},{640,980},{660,1780},{740,880},{760,860},{760,880},{760,880},{760,880},{760,860},{1600,900},{760,1700},{760,880},{20384,940},{700,920},{700,1740},{760,880},{760,860},{780,860},{760,880},{760,900},{720,900},{1600,880},{740,1740},{760,860}}; //This is an example of how a code for turning ON a TV looks like, It may be different to yours, so youíll have to modify the matrix in the next functions (also this one) :)

uint16_t vUP[120][2]={0}; uint16_t vDWN[120][2]={0}; uint16_t cUP[120][2]={0}; uint16_t cDWN[120][2]={0}; uint16_t inp[120][2]={0};

bool encender (uint8_t param, bool gotParam) { Enviar (turnON); delay(500); }

bool volumenUP (uint8_t param, bool gotParam) { Enviar(vUP); delay(500); }

bool volumenDWN (uint8_t param, bool gotParam) { Enviar(vDWN); delay(500); }

bool canalUP (uint8_t param, bool gotParam) { Enviar(cUP); delay(500); }

bool canalDWN (uint8_t param, bool gotParam) { Enviar(cDWN); delay(500); }

bool input (uint8_t param, bool gotParam) { Enviar(inp); delay(500); } void setup(void) _BV(COM2B1)

void IRcarrier (unsigned int matrix) { if (matrix != 0) { TCCR2A ^= _BV(COM2A1); //Changes the 8íth bit. Turns the LED ON. delayMicroseconds(matrix); //Waits matrix-microseconds with the LED turned ON. TCCR2A ^= _BV(COM2A1); //Turns the LED off. } }

void Enviar(uint16_t pulse[120][2]) { digitalWrite(15, LOW); for (int i = 0; i < 120; i++) { if (pulse[i][0] == 0) //If a matrix slot is empty, it leaves the loop. { break; } delayMicroseconds(pulse[i][0]); //Waits n microseconds wi the IR LED off. IRcarrier(pulse[i][1]); //Enters the función sending the delay that takes the ON from the IR } digitalWrite(15, HIGH); }

//The only thing this función does is printing everything received after the pulse is over. void printpulses() { Serial.println("\n\r\n\rReceived: \n\rOFF\t|\tON"); Serial.print("{"); for (uint8_t i = 0; i < currentpulse; i++) { Serial.print("{"); Serial.print(pulses[i][0], DEC); //DEC

Mesh.loop(); Aquila.loop();

digitalWrite(15, HIGH); //Built-in LEDs, inverted logic. digitalWrite(14, HIGH); //Both begin off.

if (digitalRead(Boton2) == HIGH || (currentpulse != 0)) { if (digitalRead(Boton2) == HIGH) { Serial.println("Leyendo!"); digitalWrite(14, LOW); //GREEN LED ON! full = false; } uint16_t highpulse, lowpulse; // The pulse will be temporary stored on this variables. highpulse = lowpulse = 0; //This process will be splitter in to steps, when the LED is ON; HighPulse and when itís off; LowPulse. //All this Ďwhileí function is for when the pulse is on High (the LED ON) // --- Complex Explanation --- // //We will apply what is on the pin 0-7 a "mask" and we take whatever is on the position 00000100 // If we order the pins this way -> 76543210 we an see in a clearer way that the 00000100 is on the antepenultimate position, same as (xxxxx2xx) //The '&' operator generates a truth table between 00000100 and what is connected to the pins (the micro controller will ignore whatever is not on the pin 2, basically). //So, if thereís anything connected to the PIN 2, it will work. while (IRpin_PIN & (1 = MAXPULSE) && (currentpulse != 0)) { printpulses(); currentpulse=0; return; } } pulses[currentpulse][1] = lowpulse * RESOLUTION; // A ON-OFF pulse has been read // the whole process will be repeated until some command exceeds the length of a ON or a OFF (and enters to the Ďif loopí). currentpulse++; }

if (digitalRead(Boton) == LOW && full == true) { Enviar(pulses); delay(500); } digitalWrite(14,HIGH); }

Remote control controlled via Internet
CODE3.ino8 KB
 
 

Tag cloud

make build easy simple arduino making homemade solar laser printed portable cheap mini building custom cardboard wooden create super lego turn paracord chocolate your paper light intel