IRSND - english

Wechseln zu: Navigation, Suche

By Frank M. (ukw)

This is the English translation of the german ISRND documentation.

IRSND - Infrared Multiprotocol Encoder

Scan eines NEC-kompatiblen Fernbedienungssignals

IRSND is the counterpart of IRMP. IRSND encodes IR frames and works as an IR sender.

Introduction

Connection of a simple IR sender to a MCU

IRSND is the counterpart of IRMP: it reproduces the original IR frame, e.g. previously received by IRMP, and sends it out via an infrared diode.

Supported MCUs

IRSND has been implemented on several MCU families:

AVR

  • ATtiny87, ATtiny167
  • ATtiny45, ATtiny85
  • ATtiny44, ATtiny84
  • ATmega8, ATmega16, ATmega32
  • ATmega162
  • ATmega164, ATmega324, ATmega644, ATmega644P, ATmega1284
  • ATmega88, ATmega88P, ATmega168, ATmega168P, ATmega328P

XMega

  • ATXmega128

PIC (C18-Compiler)

  • PIC12F1840
  • PIC18F4520

STM32

  • STM32F4xx
  • STM32F10x

TEENSY 3.0 (NEW!)

  • MK20DX256VLH7 (ARM Cortex-M4 72MHz)

Supported Protocols

IRSND supports the following IR protocols:

IRSND does NOT yet support the following protocols:

Download

Version 3.0.8, Date: 2017-08-25

Download of stable version: Irsnd.zip

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

Warning:

The version in the SVN can be a newer version than the stable version stored in Irmp.zip. In doubt, use the download link of Irsnd.zip.

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:

You should only include irsnd.h in your application file, therefore merely:

#include "irsnd.h"

All other include files will be automatically included by irsnd.h. See also example file irsnd-main-avr.c.

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

Adjustments in irsndconfig.h

F_INTERRUPTS

Number of interrupts per second. The value can be adjusted between 10000 and 20000.

Default value:

#define F_INTERRUPTS                            15000      // interrupts per second

IRSND_SUPPORT_xxx_PROTOCOL

Here you can adjust, which protocols of IRSND will be supported. The standard protocols are already activated. If you want to activate more protocols respectively you want to deactivate some protocols in order to same Flash and RAM, you should change the appropriate 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

If you want to deactivate a protocol, set it to 0, if you want to activate it, set it to 1. All deactivated protocols will NOT be compiled. This saves Flash and RAM, siehe the specifications in comments above. If you want to save more Flash, you can also follow the tipps given in the article of IRMP.

If you want to use the APPLE protocol, set IRSND_SUPPORT_NEC_PROTOCOL to 1. It is only a special case of the NEC protocol.

IRSND_OCx

In order to send the correct IR signals, IRSND need a PWM-able Output-Pin, because the signal needs to be modulated. 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 you use callbacks, your callback functions will be called, whenever the IR signal changes (IR modulation on/off). This can by used to send an unmodulated signal by another pin, for example:

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

/*-----------------------------------------------------------------------------------------------------------------------
 * Called (back) from IRSND module
 * This example switches a LED (which is connected to Vcc)
 *-----------------------------------------------------------------------------------------------------------------------
 */
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 ();
    ...
}

IRSND in Practice

IRSND builds the frame to be sended "on-the-fly" from the IRMP data structure. The members are:

1. ID for used protocol
2. Address repectivley vendor code
3. Command

You can send the IR frame by calling the function

  irsnd_send_data (IRMP_DATA * irmp_data_p)

The return value is 1, if the frame can be successfully sent out, 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

will be interpreted and then send out with the wanted IR protocol frame.

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.

Please consider: You should always make sure that irmp_data_p->flags has a defined value before you call 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);   // send, don't wait

The frrame will be sent asynchronisly via the interrupt routine irsnd_ISR(), so that the funtion irsnd_send_data() immediately returns. If you specify repetitions, the frame will be repeated after a while - according to the used protocol - or a special protocol dependent repetition frame (e.g. for NEC) will be sent.

If you call irsnd_send_data() again, thhe functions waits until the preceding frame will be sent completely. You can also check if IRSND is "busy" or not:

   while (irsnd_is_busy ())
   {
      ;                                          // wait here or do something else...
   }
   (void) irsnd_send_data (&irmp_data, FALSE);   // versende ohne Prüfung und ohne Warten

If you call irsnd_send_data() with the 2nd argument TRUE, the function returns, when the frame has been completely sent.

In the example source irsnd-main-avr.c you will find beside the calling of irsnd_send_data() also the timer call:

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

Parallel use of IRMP und IRSND

If you want to use IRMP and IRSND together (that is to say as sender and receiver), you should write the ISR function 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...
}

That means: Only when irsnd_ISR() has nothing to do, call the ISR of the receiver. Thereby the receiver is switched off, as long as irsnd_ISR() sends data. The timer initializing routine is identical for IRMP and IRSND.

A common main function could look as:

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);
    }
  }
}

The functionality of the source above is clear: A received frame will be encoded and sent again after decoding. So you can send signals over more than one rooms connected by wire.

Also you could transform some protocols, e.g. NEC frames into RC5, when you can't find your original RC5 remote control ;-)

All other stuff can be surrended by your phantasy ;-)

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 Mediareceiver
#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

In order to determine the needed data for the address and the command use IRMP, see above ;-)

IRSND under Linux and Windows

Compilation of IRSND

You can compile irsnd.c directly unter Linux in order to create frames in the same format as the IRMP scan files. Simply enter:

   make -f makefile.unx

Start of IRSND

The usage of IRSND is as follows:

   ./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:

  • Start the command interpreter
  • Change into the directory of IRSND
  • Enter:
           irsnd.exe 2 00FF 0001 > nec.txt

Now you can directly test IRMP to check, if the generated frame by IRSND can be decoded again:

           ./irmp-15kHz < nec.txt

respectively under Windows:

           irmp.exe < nec.txt

It works also without a temporary file, e.g.:

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

respectively 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

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

Actual IRSND under Linux/Windows simulates always the pressing of a key done twice - with a pause time 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: Here you can test, if IRSND handles the toggle bit used by some protocols correctly:

           ./irsnd-15kHz 7 2 3 0 | ./irmp-15kHz
           1100010000011 p= 7 (RC5), a=0x0002, c=0x0003, f=0x00  Erster Tastendruck
           1000010000011 p= 7 (RC5), a=0x0002, c=0x0003, f=0x00  Zweiter Tastendruck
            ^
            Toggle-Bit

Please consider: The data width of addresses and commands are different - dependent from the used protocol, see table IR Protocols in Detail.

Therefore you cannot send 16 bit addresses or commands with every protocol transparently.

Appendix

Software History

Changes of IRSND in 3.0.x

Version 3.0.8:

  • 2017-08-25: New protocol: IRMP16 for transparent 16 bit data communication

Version 3.0.2:

Version 3.0.0:

  • Renamed example main file to irsnd-main-avr.c

Older versions

  • 2015-11-17: New protocol: BOSE
  • 2015-11-17: New protocol: PANASONIC (Beamer)
  • 2015-11-17: Port to Teensy (3.x)
  • 2015-09-20: New protocol: TECHNICS
  • 2015-06-15: New protocol: ACP24
  • 2015-05-28: Timing corrections for FAN protocol
  • 2015-05-27: New protocol: MERLIN
  • 2015-05-27: New protocol: FAN
  • 2015-05-18: Added F_CPU macro for STM32L1XX
  • 2015-05-07: Some corrections of XMega port
  • 2015-04-23: New protocol: PENTAX
  • 2015-04-23: Port to AVR XMega
  • 2014-07-10: Some GPIO changes for STM32F10x (in IRSND).
  • 2014-07-10: New protocol: SAMSUNG48
  • 2014-06-23: New protocol: LGAIR
  • 2014-06-03: New protocol: TELEFUNKEN
  • 2014-05-30: New protocol: SPEAKER
  • 2014-05-30: Optimized timings for SAMSUNG
  • 2014-02-20: New protocol: RUWIDO
  • 2013-04-09: New protocol: ROOMBA
  • 2013-03-12: Allowed 15kHz for RECS80 and RECS80EXT
  • 2013-01-17: Added support for ATtiny44
  • 2012-12-12: New protocol: A1TVBOX
  • 2012-12-07: Corrected timing of NIKON protocol
  • 2012-10-26: Some timer corrections, adaptions to Arduino
  • 2012-06-18: Added support ATtiny87/167
  • 2012-06-05: Corrected port to ARM STM32 - now tested
  • 2012-05-23: Port to ARM STM32 (untested!)
  • 2012-05-23: Bugfix timing for 2nd frame of Denon protocol
  • 2012-02-27: New protocol: IR60 (SDA2008)
  • 2012-02-27: Bugfix sending Biphase frames (Manchester)
  • 2012-02-27: Port to C18 Compiler for PIC microcontrollers
  • 2012-02-15: Bugfix: only the 1st Frame has been sended
  • 2012-02-13: Timing corrections of SAMSUNG and SAMSUNG32
  • 2012-02-13: KASEIKYO: Genre2 bits will be now stored in upper nibble of flags
  • 2012-02-13: Additinak pause after sending the last frame
  • 2011-09-20: New protocol: THOMSON
  • 2011-09-20: New protocol: LEGO
  • 2011-09-20: New protocol: NEC16
  • 2011-09-20: New protocol: NEC42
  • 2011-09-20: Port to ATtiny84 und ATtiny85
  • 2011-09-20: Some corrections for pause lengths
  • 2011-09-20: Some corrections of irsnd_stop()
  • 2011-09-20: Corrected: SIEMENS timings
  • 2011-09-20: Changed DENON protocol to 36kHz modulation frequency
  • 2011-09-20: Corrected Handling of additional bits in SIRCS protocol
  • 2011-01-18: New protocol: RC6A
  • 2011-01-18: New protocol: RC6
  • 2011-01-18: New protocol: NIKON
  • 2011-01-18: Handling of additional bits (>12) in SIRCS protocol
  • 2011-01-18: Corrected some pause lengths
  • 2011-01-18: timing corrections for DENON protocol
  • 2010-09-02: New protocol: JVC
  • 2010-09-02: Corrected APPLE encoder - now compatible to IRMP-Version 1.7.3.
  • 2010-06-25: New protocol: RCCAR
  • 2010-06-09: New protocol: FDC (IR-keyboard)
  • 2010-06-09: Corrected timing for DENON protocol
  • 2010-06-02: New protocol: SIEMENS (Gigaset)
  • 2010-06-02: Simulation of long key presses
  • 2010-05-26: New protocol: NOKIA
  • 2010-04-16: Optimized all timing tolerancies
  • 2010-03-17: New protocol: NUBERT
  • 2010-03-17: Corrected length of pauses between frame repetitions
  • 2010-03-16: Corrected timer register TCCR2
  • 2010-03-16: Corrected RECS80 start bit timings
  • 2010-03-16: New protocol: RECS80 Extended
  • 2010-03-11: Adapted code to several ATMega types
  • 2010-03-07: Alpha version