IRSND - english – Mikrocontroller.net (original) (raw)

By Frank M. (ukw)

This is the English translation of the German ISRND documentation.

IRSND - Infrared Multi Protocol Encoder

Waveform of an NEC-format remote control signal

IRSND is the counterpart to IRMP. IRSND encodes and transmits IR frames.

Introduction

A simple IR transmitter connected to a microcontroller.

IRSND is the counterpart to IRMP: it reproduces the original IR frame from data received by IRMP, which can then be transmitted over an IR emitter.

Supported MCUs

IRSND runs on numerous MCU families:

AVR

XMega

PIC (C18 Compiler)

STM32

TEENSY 3.0

Supported Protocols

IRSND supports the following IR protocols:

IRSND does NOT yet support the following protocols:

Download

Version 3.2.6, Date: 2021-01-27

Download stable version: Irsnd.zip

IRMP & IRSND is also available by SVN: IRMP in SVN

You can see the history of the software changes here: Software History

Source Code

The source code can be easily compiled for AVR MCUs by loading the project file irsnd.aps in AVR Studio 4.

For other development environments it is simple to create a project or makefile. The source includes:

IMPORTANT:

Include only irsnd.h in your application source code:

All other include files are included within irsnd.h. See also the sample application irsnd-main-avr.c.

IRSND encodes all protocols listed above in an interrupt service routine (ISR), see also irsnd.c.

Settings in irsndconfig.h

F_INTERRUPTS

Number of interrupts per second. The value can be set to a value between 10000 and 20000.

Default value:

#define F_INTERRUPTS 15000 // interrupts per second

IRSND_SUPPORT_xxx_PROTOCOL

Here you can select which protocols to enable in IRSND. Common protocols are emabled by default. To enable additional protocols or disable others to save memory, set the corresponding values in irsndconfig.h.

// typical protocols, disable here! Enable Remarks F_INTERRUPTS Program Space #define IRSND_SUPPORT_SIRCS_PROTOCOL 1 // Sony SIRCS >= 10000 ~200 bytes #define IRSND_SUPPORT_NEC_PROTOCOL 1 // NEC + APPLE >= 10000 ~100 bytes #define IRSND_SUPPORT_SAMSUNG_PROTOCOL 1 // Samsung + Samsung32 >= 10000 ~300 bytes #define IRSND_SUPPORT_MATSUSHITA_PROTOCOL 1 // Matsushita >= 10000 ~200 bytes #define IRSND_SUPPORT_KASEIKYO_PROTOCOL 1 // Kaseikyo >= 10000 ~300 bytes

// more protocols, enable here! Enable Remarks F_INTERRUPTS Program Space #define IRSND_SUPPORT_DENON_PROTOCOL 0 // DENON, Sharp >= 10000 ~200 bytes #define IRSND_SUPPORT_RC5_PROTOCOL 0 // RC5 >= 10000 ~150 bytes #define IRSND_SUPPORT_RC6_PROTOCOL 0 // RC6 >= 10000 ~250 bytes #define IRSND_SUPPORT_RC6A_PROTOCOL 0 // RC6A >= 10000 ~250 bytes #define IRSND_SUPPORT_JVC_PROTOCOL 0 // JVC >= 10000 ~150 bytes #define IRSND_SUPPORT_NEC16_PROTOCOL 0 // NEC16 >= 10000 ~150 bytes #define IRSND_SUPPORT_NEC42_PROTOCOL 0 // NEC42 >= 10000 ~150 bytes #define IRSND_SUPPORT_IR60_PROTOCOL 0 // IR60 (SDA2008) >= 10000 ~250 bytes #define IRSND_SUPPORT_GRUNDIG_PROTOCOL 0 // Grundig >= 10000 ~300 bytes #define IRSND_SUPPORT_SIEMENS_PROTOCOL 0 // Siemens, Gigaset >= 15000 ~150 bytes #define IRSND_SUPPORT_NOKIA_PROTOCOL 0 // Nokia >= 10000 ~400 bytes

// exotic protocols, enable here! Enable Remarks F_INTERRUPTS Program Space #define IRSND_SUPPORT_KATHREIN_PROTOCOL 0 // Kathrein >= 10000 DON'T CHANGE, NOT SUPPORTED YET! #define IRSND_SUPPORT_NUBERT_PROTOCOL 0 // NUBERT >= 10000 ~100 bytes #define IRSND_SUPPORT_BANG_OLUFSEN_PROTOCOL 0 // Bang&Olufsen >= 10000 ~250 bytes #define IRSND_SUPPORT_RECS80_PROTOCOL 0 // RECS80 >= 15000 ~100 bytes #define IRSND_SUPPORT_RECS80EXT_PROTOCOL 0 // RECS80EXT >= 15000 ~100 bytes #define IRSND_SUPPORT_THOMSON_PROTOCOL 0 // Thomson >= 10000 ~250 bytes #define IRSND_SUPPORT_NIKON_PROTOCOL 0 // Nikon >= 10000 ~150 bytes #define IRSND_SUPPORT_NETBOX_PROTOCOL 0 // Netbox keyboard >= 10000 DON'T CHANGE, NOT SUPPORTED YET! #define IRSND_SUPPORT_FDC_PROTOCOL 0 // FDC IR keyboard >= 10000 (better 15000) ~150 bytes #define IRSND_SUPPORT_RCCAR_PROTOCOL 0 // RC CAR >= 10000 (better 15000) ~150 bytes #define IRSND_SUPPORT_ROOMBA_PROTOCOL 0 // iRobot Roomba >= 10000 ~150 bytes #define IRSND_SUPPORT_RUWIDO_PROTOCOL 0 // RUWIDO, T-Home >= 15000 ~250 bytes #define IRSND_SUPPORT_A1TVBOX_PROTOCOL 0 // A1 TV BOX >= 15000 (better 20000) ~200 bytes #define IRSND_SUPPORT_LEGO_PROTOCOL 0 // LEGO Power RC >= 20000 ~150 bytes

To enable a protocol, set it to 1, to disable it, set it to 0. Disabled protocols will not be compiled. This saves program space in Flash. (See code comments above.) Refer to the article IRMP for more tips on saving memory if absolutely necessary.

When using the APPLE protocol, set IRSND_SUPPORT_NEC_PROTOCOL to 1, since it is simply a special case of the NEC protocol.

IRSND_OCx

To transmit IR signals, IRSND needs a PWM-capable output pin, because the signal needs to be modulated. The following settings are possible:

#define IRSND_OCx IRSND_OC2 // OC2 on ATmegas supporting OC2, e.g. ATmega8 #define IRSND_OCx IRSND_OC2A // OC2A on ATmegas supporting OC2A, e.g. ATmega88 #define IRSND_OCx IRSND_OC2B // OC2B on ATmegas supporting OC2B, e.g. ATmega88 #define IRSND_OCx IRSND_OC0 // OC0 on ATmegas supporting OC0, e.g. ATmega162 #define IRSND_OCx IRSND_OC0A // OC0A on ATmegas/ATtinys supporting OC0A, e.g. ATtiny84, ATtiny85 #define IRSND_OCx IRSND_OC0B // OC0B on ATmegas/ATtinys supporting OC0B, e.g. ATtiny84, ATtiny85

Default value:

#define IRSND_OCx IRSND_OC2B

For PIC and STM32 MCUs use the appropriate values, see comments in irsndconfig.h.

IRSND_USE_CALLBACK

Default value:

#define IRSND_USE_CALLBACK 0 // flag: 0 = don't use callbacks, 1 = use callbacks, default is 0

If callbacks are enabled, your callback functions will be called whenever the IR signal changes (IR modulation on/off). This can by used to output an unmodulated signal on another pin, for example:

#define LED_PORT PORTD // LED at PD6 #define LED_DDR DDRD #define LED_PIN 6

/*-----------------------------------------------------------------------------------------------------------------------

*/ void led_callback (uint8_t on) { if (on) { LED_PORT &= ~(1 << LED_PIN); } else { LED_PORT |= (1 << LED_PIN); } }

int main () { ... LED_DDR |= (1 << LED_PIN); // LED pin to output LED_PORT |= (1 << LED_PIN); // switch LED off (active low) irsnd_init (); irsnd_set_callback_ptr (led_callback); sei (); ... }

Using IRSND

IRSND assembles the frame to be transmitted on the fly from the IRMP data structure. It includes:

  1. ID for the protocol in use
  2. Address or vendor code
  3. Command

To transmit the IR frame, call the function

irsnd_send_data (IRMP_DATA * irmp_data_p)

The return value is 1 if the frame can be successfully transmitted, otherwise 0. In the first case the struct members

irmp_data_p->protocol
irmp_data_p->address
irmp_data_p->command
irmp_data_p->flags

are read and then transmitted as a frame in the selected IR protocol.

irmp_data_p->flags specifies the number of repetitions, e.g.

irmp_data_p->flags = 0: no repetition irmp_data_p->flags = 1: 1 repetition irmp_data_p->flags = 2: 2 repetitions usw.

Important: Make sure that irmp_data_p->flags has a defined value before calling irsnd_send_data()!

Example:

IRMP_DATA irmp_data;

irmp_data.protocol = IRMP_NEC_PROTOCOL; // use NEC protocol irmp_data.address = 0x00FF; // use address 0x00FF irmp_data.command = 0x0001; // use command 0001 irmp_data.flags = 0; // no repetition!

(void) irsnd_send_data (&irmp_data, FALSE); // transmit, don't wait

The frame will be transmitted asynchronously by the interrupt routine irsnd_ISR(), so the function irsnd_send_data() returns immediately. When repetitions are specified, depending on the protocol, the frame will be repeated after a wait specified in the protocol, or a protocol-specific repeat frame (e.g. for NEC) will be sent.

NEC Repeat Frames

IRSND normally transmits repeat frames itself, according to the number of repetitions specified in the flags. (See above.)

Starting with version 3.2.6 and specifically for the NEC protocol, repeat frames can be transmitted on their own. This is useful for IR repeaters in particular.

The following flags must be set:

IRMP_DATA irmp_data;

irmp_data.protocol = IRMP_NEC_PROTOCOL; // use NEC protocl irmp_data.address = 0x00FF; // address is ignored irmp_data.command = 0x0001; // command is ignored irmp_data.flags = IRSND_RAW_REPETITION_FRAME; // transmit NEC repeat frame

(void) irsnd_send_data (&irmp_data, TRUE); // transmit and wait

Multiple repeat frames can be transmitted by setting a repetition value as follows:

irmp_data.flags = IRSND_RAW_REPETITION_FRAME | 0x02; // transmit NEC repeat frame and repeat 2 more times

Up to 14 repetitions can be set, so up to 15 repeat frames.

Waits

When irsnd_send_data() is called again, it waits until the preceding frame has been transmitted completely. You can test whether IRSND is busy or not:

while (irsnd_is_busy ()) { ; // wait here or do something else... } (void) irsnd_send_data (&irmp_data, FALSE); // transmit without testing and without waiting

When irsnd_send_data() is called with TRUE as the second argument, the function only returns once the frame has been transmitted completely.

In the example source irsnd-main-avr.c, in addition to how to use irsnd_send_data(), the timer call is also demonstrated:

ISR(TIMER1_COMPA_vect) { irsnd_ISR()) // call irsnd ISR // call other timer interrupt routines... }

Using IRMP and IRSND Simultaneously

To use IRMP and IRSND at the same time (that is, both transmitter and receiver), the ISR function should read as follows:

ISR(TIMER1_COMPA_vect) { if (! irsnd_ISR()) // call irsnd ISR { // if not busy... irmp_ISR(); // call irmp ISR } // call other timer interrupt routines... }

This causes the receiver ISR to be called only when irsnd_ISR() is idle, and thus the receiver is disabled while irsnd_ISR() is transmitting data.

The timer initialization routine is identical for IRMP and IRSND.

A combined main function could look like:

int main (void) { IRMP_DATA irmp_data;

irmp_init(); // initialize irmp irsnd_init(); // initialize irsnd timer_init(); // initialize timer sei (); // enable interrupts

for (;;) { if (irmp_get_data (&irmp_data)) { irmp_data.flags = 0; // reset flags! irsnd_send_data (&irmp_data); } } }

What the code above does is obvious: A received frame is fully decoded, then reencoded and finally transmitted with the IR emitting diode. This can be used to transmit signals around a corner, or extend them over a wire.

Another application is protocol translation, for example to convert NEC frames to RC5 to substitute a lost RC5 remote control.

Other uses are left to the reader's imagination. ;-)

Here the possible values for irmp_data.protocol, see also irmpprotocols.h:

#define IRMP_SIRCS_PROTOCOL 1 // Sony #define IRMP_NEC_PROTOCOL 2 // NEC, Pioneer, JVC, Toshiba, NoName etc. #define IRMP_SAMSUNG_PROTOCOL 3 // Samsung #define IRMP_MATSUSHITA_PROTOCOL 4 // Matsushita #define IRMP_KASEIKYO_PROTOCOL 5 // Kaseikyo (Panasonic etc) #define IRMP_RECS80_PROTOCOL 6 // Philips, Thomson, Nordmende, Telefunken, Saba #define IRMP_RC5_PROTOCOL 7 // Philips etc #define IRMP_DENON_PROTOCOL 8 // Denon, Sharp #define IRMP_RC6_PROTOCOL 9 // Philips etc #define IRMP_SAMSUNG32_PROTOCOL 10 // Samsung32: no sync pulse at bit 16, length 32 instead of 37 #define IRMP_APPLE_PROTOCOL 11 // Apple, very similar to NEC #define IRMP_RECS80EXT_PROTOCOL 12 // Philips, Technisat, Thomson, Nordmende, Telefunken, Saba #define IRMP_NUBERT_PROTOCOL 13 // Nubert #define IRMP_BANG_OLUFSEN_PROTOCOL 14 // Bang & Olufsen #define IRMP_GRUNDIG_PROTOCOL 15 // Grundig #define IRMP_NOKIA_PROTOCOL 16 // Nokia #define IRMP_SIEMENS_PROTOCOL 17 // Siemens, e.g. Gigaset #define IRMP_FDC_PROTOCOL 18 // FDC keyboard #define IRMP_RCCAR_PROTOCOL 19 // RC Car #define IRMP_JVC_PROTOCOL 20 // JVC (NEC with 16 bits) #define IRMP_RC6A_PROTOCOL 21 // RC6A, e.g. Kathrein, XBOX #define IRMP_NIKON_PROTOCOL 22 // Nikon #define IRMP_RUWIDO_PROTOCOL 23 // Ruwido, e.g. T-Home Media Receiver #define IRMP_IR60_PROTOCOL 24 // IR60 (SDA2008) #define IRMP_KATHREIN_PROTOCOL 25 // Kathrein #define IRMP_NETBOX_PROTOCOL 26 // Netbox keyboard (bitserial) #define IRMP_NEC16_PROTOCOL 27 // NEC with 16 bits (incl. sync) #define IRMP_NEC42_PROTOCOL 28 // NEC with 42 bits #define IRMP_LEGO_PROTOCOL 29 // LEGO Power Functions RC #define IRMP_THOMSON_PROTOCOL 30 // Thomson #define IRMP_BOSE_PROTOCOL 31 // BOSE #define IRMP_A1TVBOX_PROTOCOL 32 // A1 TV Box #define IRMP_ORTEK_PROTOCOL 33 // ORTEK - Hama #define IRMP_TELEFUNKEN_PROTOCOL 34 // Telefunken (1560) #define IRMP_ROOMBA_PROTOCOL 35 // iRobot Roomba vacuum cleaner #define IRMP_RCMM32_PROTOCOL 36 // Fujitsu-Siemens (Activy remote control) #define IRMP_RCMM24_PROTOCOL 37 // Fujitsu-Siemens (Activy keyboard) #define IRMP_RCMM12_PROTOCOL 38 // Fujitsu-Siemens (Activy keyboard) #define IRMP_SPEAKER_PROTOCOL 39 // Another loudspeaker protocol, similar to Nubert #define IRMP_LGAIR_PROTOCOL 40 // LG air conditioner #define IRMP_SAMSUNG48_PROTOCOL 41 // air conditioner with SAMSUNG protocol (48 bits) #define IRMP_MERLIN_PROTOCOL 42 // Merlin (Pollin 620 185) #define IRMP_PENTAX_PROTOCOL 43 // Pentax camera #define IRMP_FAN_PROTOCOL 44 // FAN (ventilator), very similar to NUBERT, but last bit is data bit instead of stop bit #define IRMP_S100_PROTOCOL 45 // very similar to RC5, but 14 instead of 13 data bits #define IRMP_ACP24_PROTOCOL 46 // Stiebel Eltron ACP24 air conditioner #define IRMP_TECHNICS_PROTOCOL 47 // Technics, similar to Matsushita, but 22 instead of 24 bits #define IRMP_PANASONIC_PROTOCOL 48 // Panasonic (video projector), start bits similar to KASEIKYO #define IRMP_MITSU_HEAVY_PROTOCOL 49 // Mitsubishi heavy air conditioner, similar timing to Panasonic video projector #define IRMP_VINCENT_PROTOCOL 50 // Vincent #define IRMP_SAMSUNGAH_PROTOCOL 51 // SAMSUNG AH #define IRMP_IRMP16_PROTOCOL 52 // IRMP specific protocol for data transfer, e.g. between two microcontrollers via IR #define IRMP_GREE_PROTOCOL 53 // Gree climate #define IRMP_RCII_PROTOCOL 54 // RC II Infrared Remote Control Protocol for FM8 #define IRMP_METZ_PROTOCOL 55 // METZ #define IRMP_ONKYO_PROTOCOL 56 // Onkyo

The best way to determine the address and command codes is to use IRMP, see above ;-)

IRSND under Linux and Windows

Compiling IRSND

irsnd.c can be compiled under Linux to create frames in the same format as the IRMP scan files. Simply enter:

make -f makefile.unx

Starting IRSND

To start IRSND, enter:

./irsnd protocol-number hex-address hex-command [repeat] > filename.txt

Example for NEC protocol, address 0x00FF, command 0x0001:

./irsnd 2 00FF 0001 > nec.txt # start irsnd

IRSND under Windows

You can also use IRSND under Windows:

You can then use IRMP to check whether the frame generated by IRSND is correct:

       ./irmp-15kHz < nec.txt

or under Windows:

       irmp.exe < nec.txt

It also works without using an intermediate file, e.g.:

       ./irsnd-15kHz 2 00FF 0001 | ./irmp-15kHz

or under Windows:

       irsnd.exe 2 00FF 0001 | irmp.exe

The output of IRMP is then as follows:

       11111111000000001000000001111111 p =  2, a = 0x00ff, c = 0x0001, f = 0x00

IRMP identified the frame generated by IRSND as protocol number 2, address 0x00FF and command 0x0001.

Under Linux/Windows, IRSND always emulates a key press twice, with a wait between the frames. The output is therefore:

       11111111000000001000000001111111 p =  2, a = 0x00ff, c = 0x0001, f = 0x00
       11111111000000001000000001111111 p =  2, a = 0x00ff, c = 0x0001, f = 0x00

The reason is simple: This makes it easy to test whether IRSND correctly handles the toggle bit used by some protocols:

       ./irsnd-15kHz 7 2 3 0 | ./irmp-15kHz
       1100010000011 p= 7 (RC5), a=0x0002, c=0x0003, f=0x00  **First key press**
       1000010000011 p= 7 (RC5), a=0x0002, c=0x0003, f=0x00  **Second key press**
        ^
        Toggle bit

Note: Depending on the protocol, the bit widths of addresses and commands can differ, see IR Protocols in Detail.

Consequently, 16 bit addresses and commands cannot be transmitted transparently with every protocol.

Appendix

Software History

Changes to IRSND in 3.0.x

Version 3.2.6:

Version 3.2.5:

Version 3.2.4:

Version 3.1.5:

Version 3.1.2:

Version 3.0.9:

Version 3.0.8:

Version 3.0.2:

Version 3.0.0:

Older versions