Clone IR Remote for Arduino Projects (IRlib2) - Page 1
Forum section: electronics / projects

author: Joshsstuff
author_rank: Contributor
timestamp: July 01, 2017, 12:18:32 pm
content: Hello Gang!I am trying to clone the IR signal of consumer electronics to give IR control to my Arduino.(I wish to give the Arduino the ability to turn on and off a TV)This seems simple enough, and there are several tutorials online, so, easy, right?I've found several examples of how to copy the IR signal into the Serial Monitor my problem is re-transmitting them with my IR Led from my arduino.Demo Hardware:My breadboard example:I'm using an detector to collect the IR signals, and a 940nm IR LED to transmit.Most of the tutorials I find on the internet are based on outdated IR Libraries.(I don't mind this, as long as I can get them to work)After failing to transmit the captured codes from my IR Led I tired the examples from the new IRlib2 library.I've tried the "rawRecv" example sketch and successfully captured the timing data.Code:/* rawR&cv.ino Example sketch for IRLib2* Illustrate how to capture raw timing values for an unknow protocol.* You will capture a signal using this sketch. It will output data the* serial monitor that you can cut and paste into the "rawSend.ino"* sketch.*/// Recommend only use IRLibRecvPCI or IRLibRecvLoop for best results#include <IRLibRecvPCI.h>IRrecvPCI myReceiver(2);//pin number for the receivervoid setup() {Serial.begin(9600);delay(2000); while (!Serial); //delay for LeonardomyReceiver.enableIRIn(); // Start the receiverSerial.println(F("Ready to receive IR signals"));}void loop() {//Continue looping until you get a complete signal receivedif (myReceiver.getResults()) {Serial.println(F("Do a cut-and-paste of the following lines into the "));Serial.println(F("designated location in rawSend.ino"));Serial.print(F("\n#define RAW_DATA_LEN "));Serial.println(recvGlobal.recvLength,DEC);Serial.print(F("uint16_t rawData={\n\t"));for(bufIndex_t i=1;i<recvGlobal.recvLength;i++) {Serial.print(recvGlobal.recvBuffer,DEC);Serial.print(F(", "));if( (i % 8)==0) Serial.print(F("\n\t"));}Serial.println(F("1000};"));//Add arbitrary trailing spacemyReceiver.enableIRIn(); //Restart receiverI get this code from my samsung remote:Code:Do a cut-and-paste of the following lines into thedesignated location in rawSend.ino#define RAW_DATA_LEN 68uint16_t rawData={4530, 4514, 562, 1686, 562, 1682, 566, 1682,562, 590, 534, 590, 534, 590, 534, 590,534, 590, 534, 1686, 558, 1686, 562, 1686,562, 590, 534, 590, 534, 590, 530, 594,530, 594, 530, 590, 534, 1686, 562, 590,534, 590, 534, 590, 534, 590, 534, 594,526, 594, 530, 1686, 562, 590, 534, 1690,558, 1682, 562, 1686, 562, 1686, 562, 1686,562, 1682, 562, 1000};Here is the 'rawSend' example sketch:Code:/* rawSend.ino Example sketch for IRLib2* Illustrates how to send a code Using raw timings which were captured* from the "rawRecv.ino" sample sketch. Load that sketch and* capture the values. They will print in the serial monitor. Then you* cut and paste that output into the appropriate section below.*/#include <IRLibSendBase.h> //We need the base code#include <IRLib_HashRaw.h> //Only use raw senderIRsendRaw mySender;void setup() {Serial.begin(9600);delay(2000); while (!Serial); //delay for LeonardoSerial.println(F("Every time you press a key is a serial monitor we will send."));}/* Cut and paste the output from "rawRecv.ino" below here. It will* consist of a #define RAW_DATA_LEN statement and an array definition* beginning with "uint16_t rawData= {…" and concludes* with "…,1000};"*//** Cut-and-paste into the area above.*/void loop() {if (Serial.read() != -1) {//send a code every time a character is received from the// serial port. You could modify this sketch to send when you// push a button connected to an digital input pin.mySender.send(rawData,RAW_DATA_LEN,36);//Pass the buffer,length, optionally frequencySerial.println(F("Sent signal."));}}HardwareI'm using a 940nm IR LED driven by a 2222a BJT.I used the diagram from a tutorial that used a 4.6K resistor on the base.(should I have a current limiter for the IR LED?)Here is my question:After I paste the timing code into "rawSend" How do I code the LED to turn on and off with the appropriate timing?I've tried many tutorials I found online, but perhaps because they use a different library, I'm not having success.I've tried examples like these:http://howtomechatronics.com/tutorials/arduino/control-any-electronics-with-a-tv-remote-arduino-ir-tutorial/]http://howtomechatronics.com/tutorials/arduino/control-any-electronics-with-a-tv-remote-arduino-ir-tutorial/http://www.instructables.com/id/Arduino-Infrared-Remote-tutorial/Using IR commands to control consumer electronics is something I'd like to use a lot once I figure it out.Any tips would be greatly appreciated!Thanks!

author: senso
author_rank: Frequent Contributor
timestamp: July 01, 2017, 12:31:58 pm
content: You use a timer, search for IRToy for Dangerous Prototypes.And maybe you will be better off ditching the arduino crap code and start doing it, with one timer and a couple interrupts its pretty easy to do the 38Khz carrier plus modulation of the typical RC5 IR code/signal.

author: madires
author_rank: Super Contributor
timestamp: July 01, 2017, 01:24:08 pm
content: Samsung RCs use the NEC protocol (mostly the extended format). Please seehttp://www.sbprojects.com/knowledge/ir/nec.phpfor the protocol andhttp://irdb.tk/for codes.

author: Joshsstuff
author_rank: Contributor
timestamp: July 01, 2017, 04:22:17 pm
content: Quote from: madires on July 01, 2017, 01:24:08 pmThank you for the link madires!That is helpful to know.I realize after I posted this question that there are SEVERAL ways to accomplish the task of sending IR signals to a device.(I found this out after I started researching it!)So I am going to be more clear about what my objectives are, that should distil the options down to what my needs are specifically.Objectives:1) Arduino hardware:As stated in the topic description, I wish to use this in my Arduino projects.(I have one started that I'm stuck on, but also I will need this ability for future Arduino projects)2) Protocol agnostic:Since I wish to use this method with all sorts of IR devices, I like the idea of collecting "raw" data from the remote pointed at the IR receiver and simply recording the pulse data.This should work with any remote!I'm aware that reverse engineering manufacturer protocols has it's benefits, especially if I wish to send multiple signals.However, to just turn on a power button here or there this seems overkill, and will complicate my sketch.3) Simple is best!(for now)If I can get away with a string of 'High' and 'Low' timings instead of evoking serial communication, or extra libraries, I'm all for it!Is there a simple way to just record the "ON" and "OFF" times and blink the LED with direct code?(this would require a different capture technique or some translation it seems?)Once I am confident, and get this up and running, I am willing to try more complex methods to learn.Quote from: senso on July 01, 2017, 12:31:58 pmThank you senso!I found a link to the IR_Toy:http://dangerousprototypes.com/docs/USB_IR_Toy_v2Given my objective to use this in my Arduino projects, will this be helpful to me?Quote from: senso on July 01, 2017, 12:31:58 pmEasy is Awesome!I'm a noob, so I need easy lol.Can you give an example of how I could start working on that if it is an easy way to do it?Correct me if I'm wrong, but essentally just trying to 'blink an LED' hereOnce I have the pulse code, my only challenge is to use some protocol to pulse the IR LED.That is my simplified view of this problem, but I'm open to any suggestions on how I could simplify this further.(I'll settle for anything that works! lol)Thank you for your help.

author: Buriedcode
author_rank: Super Contributor
timestamp: July 01, 2017, 08:24:16 pm
content: I'm sure some Arduino libraries are great, but because many lack documentation, or try to do too much, they can be difficult to use - and sometimes have dependencies.I'm sure that library can capture the bit periods just fine - IR remotes generally use pulse position modulation, but some can use a form of PWM. Googling the basics will be helpful.Your IR detector/reciever has active circuitry built in, it isn't just a photodiode. This will amplify and demodulate the carrier (usually 38kHz but can be between 36 and 40kHz) meaning it will output one state fo recieving the 38kHz carrier, and another state when not receiving any carrier.https://internetofhomethings.com/homethings/wp-content/uploads/2015/09/demodulation.jpgSo your Arduino is looking at the timing of the waveform in "IR detect". But to control your appliance, you must use this waveform to modulate the carrier. How you do this is up to you, and I am unsure if that library will do it for you. If it doesn't you can easily set up a timer or PWM for 38kHz, 50% duty, and use this to drive a transistor, or, just for testing, have the PWM driving the LED's cathode, and your IR remote data on the anode (via resistor of course).Whilst I'm sure you can make it somewhat protocol agnostic - you will still have to make some assumptions. Also, different appliances use different frequency carriers. Very often between 36 and 40kHz, so 38kHz will almost always work for most things, but some might not.

author: Joshsstuff
author_rank: Contributor
timestamp: July 01, 2017, 11:40:35 pm
content: Quote from: Buriedcode on July 01, 2017, 08:24:16 pmYou make some good points Buriedcode.Thank you for the picture. I watched Daves Arduino project already 2X all the way through and your pic now makes sense.EEVblog #506 - IR Remote Control Arduino Protocol TutorialI have a scope, so in theory I have the tools to reverse engineer this just as Dave does.But it's a little intimidating, even though the video was very enjoyable to watch Dave do it.I'm not advanced enough to figure this all out on my own, I was hoping to get a grasp on one of the tutorials as opposed to 'inventing my own wheel"(although this would be a good learning experience, I already have a project halted until I can clear this hurdle)Perhaps a little help in debugging this example sketch would help below?Desperate to follow all of the tutorials published with the older libraries, I decide to loadthe library based on the work of Ken Shirriff.I've passed on this before in favor of the newer IRLib2, however, since I'm not finding tutorials on this new library, I decided to go ahead and install the "Arduino-IRremote-master library"I am not trying out the capture example, and immediately the IDE encounters an error in compiling "IRrercevDump".Undeterred, I try the seemingly updated "IRrecevDumpV2" = same error:'class decode_results' has no member named 'address'Here is the complete sketches in case you do not have the library installed with examples.ERrecevDump Example sketchCode:/** IRremote: IRrecvDump - dump details of IR codes with IRrecv* An IR detector/demodulator must be connected to the input RECV_PIN.* Version 0.1 July, 2009* Copyright 2009 Ken Shirriff* http://arcfn.com* JVC and Panasonic protocol added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post)* LG added by Darryl Smith (based on the JVC protocol)*/#include <IRremote.h>/** Default is Arduino pin D11.* You can change this to another available Arduino Pin.* Your IR receiver should be connected to the pin defined here*/int RECV_PIN = 11;IRrecv irrecv(RECV_PIN);decode_results results;void setup(){Serial.begin(9600);irrecv.enableIRIn(); // Start the receiver}void dump(decode_results *results) {// Dumps out the decode_results structure.// Call this after IRrecv::decode()int count = results->rawlen;if (results->decode_type == UNKNOWN) {Serial.print("Unknown encoding: ");}else if (results->decode_type == NEC) {Serial.print("Decoded NEC: ");}else if (results->decode_type == SONY) {Serial.print("Decoded SONY: ");}else if (results->decode_type == RC5) {Serial.print("Decoded RC5: ");}else if (results->decode_type == RC6) {Serial.print("Decoded RC6: ");}else if (results->decode_type == PANASONIC) {Serial.print("Decoded PANASONIC - Address: ");Serial.print(results->address, HEX);Serial.print(" Value: ");}else if (results->decode_type == LG) {Serial.print("Decoded LG: ");}else if (results->decode_type == JVC) {Serial.print("Decoded JVC: ");}else if (results->decode_type == AIWA_RC_T501) {Serial.print("Decoded AIWA RC T501: ");}else if (results->decode_type == WHYNTER) {Serial.print("Decoded Whynter: ");}Serial.print(results->value, HEX);Serial.print(" (");Serial.print(results->bits, DEC);Serial.println(" bits)");Serial.print("Raw (");Serial.print(count, DEC);Serial.print("): ");for (int i = 1; i < count; i++) {if (i & 1) {Serial.print(results->rawbuf*USECPERTICK, DEC);}else {Serial.write('-');Serial.print((unsigned long) results->rawbuf*USECPERTICK, DEC);}Serial.print(" ");}Serial.println();}void loop() {if (irrecv.decode(&results)) {Serial.println(results.value, HEX);dump(&results);irrecv.resume(); // Receive the next value}}IRrecevDumpV2 example sketch:Code://------------------------------------------------------------------------------// Include the IRremote library header//#include <IRremote.h>//------------------------------------------------------------------------------// Tell IRremote which Arduino pin is connected to the IR Receiver (TSOP4838)//int recvPin = 11;IRrecv irrecv(recvPin);//+=============================================================================// Configure the Arduino//void setup ( ){Serial.begin(9600); // Status message will be sent to PC at 9600 baudirrecv.enableIRIn(); // Start the receiver}//+=============================================================================// Display IR code//void ircode (decode_results *results){// Panasonic has an Addressif (results->decode_type == PANASONIC) {Serial.print(results->address, HEX);Serial.print(":");}// Print CodeSerial.print(results->value, HEX);}//+=============================================================================// Display encoding type//void encoding (decode_results *results){switch (results->decode_type) {default:case UNKNOWN: Serial.print("UNKNOWN"); break ;case NEC: Serial.print("NEC"); break ;case SONY: Serial.print("SONY"); break ;case RC5: Serial.print("RC5"); break ;case RC6: Serial.print("RC6"); break ;case DISH: Serial.print("DISH"); break ;case SHARP: Serial.print("SHARP"); break ;case JVC: Serial.print("JVC"); break ;case SANYO: Serial.print("SANYO"); break ;case MITSUBISHI: Serial.print("MITSUBISHI"); break ;case SAMSUNG: Serial.print("SAMSUNG"); break ;case LG: Serial.print("LG"); break ;case WHYNTER: Serial.print("WHYNTER"); break ;case AIWA_RC_T501: Serial.print("AIWA_RC_T501"); break ;case PANASONIC: Serial.print("PANASONIC"); break ;case DENON: Serial.print("Denon"); break ;}}//+=============================================================================// Dump out the decode_results structure.//void dumpInfo (decode_results *results){// Check if the buffer overflowedif (results->overflow) {Serial.println("IR code too long. Edit IRremoteInt.h and increase RAWBUF");return;}// Show Encoding standardSerial.print("Encoding : ");encoding(results);Serial.println("");// Show Code & lengthSerial.print("Code : ");ircode(results);Serial.print(" (");Serial.print(results->bits, DEC);Serial.println(" bits)");}//+=============================================================================// Dump out the decode_results structure.//void dumpRaw (decode_results *results){// Print Raw dataSerial.print("Timing[");Serial.print(results->rawlen-1, DEC);Serial.println("]: ");for (int i = 1; i < results->rawlen; i++) {unsigned long x = results->rawbuf * USECPERTICK;if (!(i & 1)) { // evenSerial.print("-");if (x < 1000) Serial.print(" ") ;if (x < 100) Serial.print(" ") ;Serial.print(x, DEC);} else { // oddSerial.print(" ");Serial.print("+");if (x < 1000) Serial.print(" ") ;if (x < 100) Serial.print(" ") ;Serial.print(x, DEC);if (i < results->rawlen-1) Serial.print(", "); //',' not needed for last one}if (!(i % 8)) Serial.println("");}Serial.println(""); // Newline}//+=============================================================================// Dump out the decode_results structure.//void dumpCode (decode_results *results){// Start declarationSerial.print("unsigned int "); // variable typeSerial.print("rawData["); // array nameSerial.print(results->rawlen - 1, DEC); // array sizeSerial.print("] = {"); // Start declaration// Dump datafor (int i = 1; i < results->rawlen; i++) {Serial.print(results->rawbuf * USECPERTICK, DEC);if ( i < results->rawlen-1 ) Serial.print(","); // ',' not needed on last oneif (!(i & 1)) Serial.print(" ");}// End declarationSerial.print("};"); //// CommentSerial.print(" // ");encoding(results);Serial.print(" ");ircode(results);// NewlineSerial.println("");// Now dump "known" codesif (results->decode_type != UNKNOWN) {// Some protocols have an addressif (results->decode_type == PANASONIC) {Serial.print("unsigned int addr = 0x");Serial.print(results->address, HEX);Serial.println(";");}// All protocols have dataSerial.print("unsigned int data = 0x");Serial.print(results->value, HEX);Serial.println(";");}}//+=============================================================================// The repeating section of the code//void loop ( ){decode_results results; // Somewhere to store the resultsif (irrecv.decode(&results)) { // Grab an IR codedumpInfo(&results); // Output the resultsdumpRaw(&results); // Output the results in RAW formatdumpCode(&results); // Output the results as source codeSerial.println(""); // Blank line between entriesirrecv.resume(); // Prepare for the next value}}Any advice on how to get arround this?Thanks!

author: JoeO
author_rank: Frequent Contributor
timestamp: July 02, 2017, 12:29:09 am
content: Is your nano an 8 MHz version or a 16MHz version?Where did you get the circuit you are using to drive the IR LED?Why didn't you use the one out of Sherriff's webpage?http://www.righto.com/2009/08/multi-protocol-infrared-remote-library.html?commentPage=5Your "4.6K" ohm resistor is really a 4.7K ohm resistor.

author: Joshsstuff
author_rank: Contributor
timestamp: July 02, 2017, 03:13:05 am
content: Quote from: JoeO on July 02, 2017, 12:29:09 am

author: JoeO
author_rank: Frequent Contributor
timestamp: July 03, 2017, 02:10:37 am
content: I have used all of Sheriff's hardware and c-code. It all works.

author: Joshsstuff
author_rank: Contributor
timestamp: July 03, 2017, 03:59:12 am
content: Quote from: JoeO on July 03, 2017, 02:10:37 amThat's Great!Have you posted a sample of it anywhere?I've had no trouble with capturing the IR code, my question is how to transmit it . . .what technique did you use if you tried it?I found an awesome video that explains every step!The only catch is that he is using a computer to send the IR pulse codes through the Com of the Arduino.I'm going to copy his project, if it works, I'll modify it to send from the Arduino.His code: (for both capture and send)Code:#include <IRremote.h>IRrecv receiver(2); // receiver is connected to pin2IRsend sender;decode_results results;long repetitions;long count;unsigned int durations;void (*reset)(void) = 0;void setup() {Serial.begin(9600);receiver.enableIRIn(); // start receiving signals}void loop() {// check for text from the PC// the PC sends a string containing "r,n,a,b,c,d,e,..." where r is how many times to repeat the command,// n is the number of durations, and a/b/c/d/e/... are the durations.// the durations are how long each mark and space period of an infrared command should last, in microseconds.if(Serial.available()) {// parse the textrepetitions = Serial.parseInt();count = Serial.parseInt();for(int i = 0; i < count; i++)durations = Serial.parseInt();// send the command using 40kHz PWMfor(int i = 0; i < repetitions; i++) {sender.sendRaw(durations, count, 40);delay(50);}// for a bit of fault tolerance, reset the arduino after receiving any commandreset();}// check if a decoded infrared signal is availableif(receiver.decode(&results)) {Serial.println(results.value, HEX);Serial.print(results.rawlen - 1);for(int i = 1; i < results.rawlen; i++) {unsigned int number = results.rawbuf * USECPERTICK;Serial.print(",");Serial.print(number);}Serial.println("");receiver.resume();}}