I am using the Shirriff library IRremote.h on a Nano to send IR codes to an IR LED pointing at an IR spotlamp. ( I used the same library and IR receiver to grab the codes from the hand remote control for the lamp.) My purpose is to send a sequence of IR codes to the lamp without me sitting in the garden with the remote control. Cracking the lamp open to get at its controller directly is not an option.
I am using verion 2.6.0 of the library because I found the more recent versions too difficult to use. It does exactly what I want and works well.
I now want to add another IR device using the same Nano board simultaneously. That also sort of works when running the two senders off the same output pin in parallel. The drawback with using a single pin is that the two devices share codes which in some cases do different things so ideally I want to use separate pins for each output device. Actually the bigger problem is that the lamps share the same on and off codes.
The output pin is hard coded in the library as pin 3 (timer 2) or alternatively pin 9 (timer 1) depending on which is commented in or out. I have not tried activating both because there is no way of specifying the pin(s) when creating an instance of the IR sender class.
I wondered if anyone has already solved this problem.
Assuming it would work*, I'm not sure to understand how having two pins would solve that issue.
Your IR "message" radiates through space and will reach both devices. So if there is a shared code between the two devices, they will both see it...
* the doc states this
Multiple IR receiver and sender instances
This library supports only one IR receiver and one IR sender object (IRrecv and IRsend) per CPU.
However since sending is a serial task, you can use setSendPin() to switch the pin to send, thus emulating multiple sender.
The receiver uses a special timer triggered function, which reads the digital IR signal value from one pin every 50 µs.
So multiple IR receivers can only be used by connecting the output pins of several IR receivers together. The IR receiver modules internally use an NPN transistor as output device with just a 30k resistor to VCC. This is basically an "open collector" and allows multiple output pins to be connected to one Arduino input pin.
However, keep in mind that any weak / disturbed signal from one of the receivers will also interfere with a good signal from another receiver.
I agree with @J-M-L that if the devices have identical address and command codes, then having separate transmitters won't accomplish anything. Does the same remote controller work with both devices? If not, then they have different addresses, and it should all work with a single transmitter.
Thanks for this. The lamps/IR Leds will be about 20m apart and the IR Leds have a fairly small view angle. I have tested with the hand remotes using a couple of codes which are unique and providing there isn't a reflective surface I can operate them independently. I expect that to be better outside than in. The issue is with the majority of codes which are not unique.
The note you found is for the 4.4 version and is absent in the 2.6.0 version I have been using so far. I spent a couple of hours wading through the code for the newer version without getting any of the examples to work, so far. Disappointing since the 2.6.0 version took 5 minutes to get going both receiving and sending. It's also unfortunate because the note about emulating multiple sender looks exactly what I am looking for. However I cannot find the method setSendPin() in any of the V4.4 library files and my stabs in the dark about how to use it have not been successful. I feel a sub-optimal workaround coming on.
A few of the codes do the same thing on both lamps; some of them operate both lamps but with different functionality and a couple of them are unique to each lamp. So if I send the message 0xFF10EF to both in parallel I get Red from one lamp and Green from the other. If I separate the pins and send the appropriate (and different) code for Red to each separately I don't understand why that wouldn't accomplish anything. I have already established that I can signal the lamps independently with the hand control if the IR Leds point away from each other - even in the dark. I just want to do the same thing with Arduino.
There is an example of how to convert from 2.x to 4.x here
I was stuck on 2.x for a while too. My stuff worked and I didn't want to spend effort on modifying my code to use 4.x. I finally upgraded because I found a bug in 2.x, the code worked fine built with Arduino, but built with VS Code + PlatformIO it didn't work. When I spoke to the author of the library he told me to upgrade if I wanted support.
I assume each lamp came with its own remote controller. If so, using one of the remotes, do you get a response from both lamps when you press a button? You seem to be saying you do. If so, then they use the same address, and optical isolation would be the only option. In the past I have use soda straws to really narrow the angle of transmission and reception.
In v4.4.1 of IRremote, I find code related to the IR_SEND_PIN in IRremoteInt.h beginning at line 459, and in IRSend.hpp beginning at line 56. It appears the send pin is part of the begin() function, but it's mostly over my head. And I can't tell whether the send pin is fixed at the time of compile, or it's something you can set in your code.
the library's author suggest to use IrSender.setSendPin(); but looking at the code it does not make much of a difference
May be this works for you, no need for the PinDefinitionsAndMore.h stuff (assuming you run on a UNO for example)
#define DISABLE_CODE_FOR_RECEIVER // Disables static receiver code like receive timer ISR handler and static IRReceiver and irparams data. Saves 450 bytes program memory and 269 bytes RAM if receiving functions are not required.
#define EXCLUDE_EXOTIC_PROTOCOLS // Saves around 240 bytes program memory if IrSender.write is used
#define NO_LED_FEEDBACK_CODE // Saves 566 bytes program memory
#undef IR_SEND_PIN // neeeded if you need to set send pin programmatically
#include <IRremote.hpp>
const uint8_t sendPin1 = 3;
uint16_t address1 = 0x0102;
uint8_t command1 = 0x34;
const uint8_t sendPin2 = 5;
uint16_t address2 = 0x203;
uint8_t command2 = 0x45;
void setup() {
Serial.begin(115200);
while (!Serial) yield();
Serial.println(F("START " __FILE__ " from " __DATE__ "\r\nUsing library version " VERSION_IRREMOTE));
IrSender.begin(sendPin1); // Specify send pin but you can change it later with IrSender.setSendPin();
IrSender.enableIROut(38);
}
void loop() {
IrSender.setSendPin(sendPin1);
Serial.print(F("Send IR signals at pin "));
Serial.println(sendPin1);
Serial.flush();
IrSender.sendNEC(address1 & 0xFF, command1, 0);
delay(1000); // delay must be greater than 5 ms (RECORD_GAP_MICROS), otherwise the receiver sees it as one long signal
IrSender.setSendPin(sendPin2);
Serial.print(F("Send IR signals at pin "));
Serial.println(sendPin2);
Serial.flush();
IrSender.sendNEC(address2 & 0xFF, command2, 0);
delay(1000); // delay must be greater than 5 ms (RECORD_GAP_MICROS), otherwise the receiver sees it as one long signal
}
However, v4 uses bit banging for the output, not a timer unless you specify that. v2 only uses a timer as I remember, and I don't know how you would switch from one timer to the other. I mean, you'd need both ISRs and such.
Thanks for the replies everyone. I got it working quite easily once I committed the day to reading the library code and the notes. (RTFM!) All I needed to do was disable the pin define macro and substitute a global variable and invoke the IrSender.setSendPin() function, a few lines of code to direct the incoming command sequence to the desired pin and it works fine. I didn't explain properly in my OP that the only reason I am using IR is because that's what the lamps have. My sender leds are not remote, they are very local to the devices but far apart from each other so shielding from cross talk is not an issue. I have it set up and it works well. I'm calling this one solved with thanks.