A simple way to debug would be to use an oscilloscpe to compare the difference between the real remote and your Arduino signal.
Either use an IR receiver and scope the results of both Arduino and remote with the same data sent. Or open the remote and scope the lines directly and compare with the Arduino data driving lines. Then adjust your code to make the two identical. As @mpflaga says, the timing between sends is a likely suspect.
In my experience when decoding IR signals it is almost always better to be very pedantic about the signal timings. For example, just accumulating the HIGH times in an array will work most of the time, but will not cope with the occasional noise burst. You need to validate each HIGH and each LOW period.
As another example of the need to be careful with timings, for the "start" signal, you only detect that the initial LOW period (i.e. 38 kHz IR burst) is longer than the minimum (2200)...but what if it is way longer due to a noise burst? And what if the quite time immediately after that is too long or too short? You'll trigger falsely, and then continue to try to make sense of the possibly still noisy signal that follows and get an unreliable result.
What I would suggest is that you use your scope and timing figures to get a feel for the correct timings (which you have largely done), and write your code to detect whether each individual bit is valid (that is, both LOW and HIGH times are within tolerance) and, if an invalid bit is encountered, ignore all further transitions for say 100 ms before listening again for a "start" sequence. The aim is to never attempt to process a command unless it is known to be parsed completely.
Also (probably less important) the 16 bits that seem to be always the same may not always be that way. You may just not have seen the cases where they are significant. Maybe they are for a device address and/or flags (such has "key pressed and held"). In some protocols, the signal sequence changes significantly when a remote key is pressed and held, and others toggle a bit in the "command" field as each command is issued.
I think a good way to rigorously parse an IR signal is by using a finite state machine (FSM). For an example you can see my open source project at http://sourceforge.net/projects/irk-usb/ ...it's not for arduino, but it should be helpful nonetheless.
Best Answer
As the question does not state which digital IR Transmitter and Receiver modules are in use, this answer explains how infrared data communication can be achieved using simply a generic IR LED, and a modulated IR receiver such as Vishay's TSOP17xx or other similar parts.
Assumptions:
Receiving:
This is the easy part. Simply connect the OUT pin of the sensor to the serial RX pin of your Arduino (digital Pin 0). If your Arduino is one of the basic (older) models, use
Serial.read()
inloop()
:For the Arduino Mega or Due, you can also use Serial1, Serial2 or Serial3, depending on which RX pin you use.
For additional reference, see the Arduino Serial reference.
N.B. Power the sensor with the same voltage as your Arduino actually runs its microcontroller at, either 3.3 or 5 Volts depending on Arduino model. Each Arduino board has a suitable voltage output pin you can use for this. Do not use the external supply (7 to 12 Volts typically) provided to the Arduino board.
Transmitting:
You have two options: (1) Arduino, LED and passive components, or (2) using an additional logic gate component. The first option is good for low-current IR LEDs (20-30 mA tops):
55,944 Hz
). An overflow value of 421 will deliver38,005 Hz
instead, if needed.Connect a suitable current limiting resistor (120 to 150 Ohms on a 5 Volt Arduino = approximately 18 mA to 23 mA limit), a small signal diode, and the LED in series as shown below:
simulate this circuit – Schematic created using CircuitLab
For driving a higher current LED, an additional logic component, a quad AND gate such as SN74AS1008 can be used. This part sources or sinks up to 48 mA per gate, and multiple gates can be paralleled for higher current drive.
simulate this circuit
Now simply use
Serial.write()
in your Arduinoloop()
code, to transmit any serial data, which will be received by theSerial.read()
at the other end, as described previously.