First release of porting 'Infrared Multiprotocol' library from mikrocontroller.net

Dependents:   IRMP_Receiver

IRMP - Infrared Multiprotocol Decoder

This library is a mbed version of the famous IRMP code, developed by members of the german forum http://mikrocontroller.net. It can receive and analyze a large number of infrared remote codes. In the original version there is also code for an IR transmitter, this will be added to this lib soon.

Base for this initial release is version 2.9.7 from 2015/11. A detailed description for this lib can be found here : https://www.mikrocontroller.net/articles/IRMP_-_english.

The code was originally written for AVR mikrocontrollers and has been ported to different platforms already. It works also great with the mbed target as it can use the unique I/O and ticker code.

Actually, the code uses the static C functions and is not ported to C++ yet to maintain compatibility to the original library. This requres the DigitalIn Pinname setting in the irmpconfig.h.

The required hardware is e.g. just an TSOP31238 (for 38 kHz modulated IR) or similar.

Information

How to use

  • import this library
  • edit irmpconfig.h and turn on the desired protocols
  • change F_INTERRUPTS if necessary, check the protocol table for the minimum necessary frequency
  • search for 'IRMP_PIN' in the irmpconfig and replace with your hardware input

The irmp_ISR() must be called cyclic with a fixed frequency, a simple task for the mbed ticker. In the main program the result is checked by calling irmp_get_data(). This function returns the decoded protocol, address, command and flags like key pressed or released.

Information

Tested platforms

  • simple LPC1347 board, works fine
  • EA LPC4088 QuickStart Board works fine
  • LPCXpresso1549 bad, there is a (known?) issue with slow Ticker ISR processing, ISR consumes >30µs instead of 3 µs
  • STM32F103 board: bad, also known problems with Ticker implementation
  • Test results with other boards are welcome.

Sample code

prints the information about decoded signals to stdout. The ISR contains additional code for performance mesuring which can be omitted in controlling applications.

Import programIRMP_Receiver

Sample code for IRMP library

Sample for decoding and performance test

#include "mbed.h"
#include "irmp.h"

#define LED_ON  0
#define LED_OFF 1

// LED as test output
DigitalOut led(LED1, LED_OFF);
DigitalOut flash(LED2, LED_OFF);

// cyclic interrupt for IRMP ISR worker
Ticker t;

// only for performance test
Timer   timerPerfTest;
int     timeISRMax = 0;
float   timeISRAvg;
int     timeISRAvgSum = 0;
int     countISRCalls = 0;

// this ISR must be called cyclic
void irmpISR(void)
{
    int t1 = timerPerfTest.read_us();               // read performance timer

    irmp_ISR();                                     // call irmp ISR

    int timeISR = timerPerfTest.read_us() - t1;     // calc time spent in worker ISR
    if (timeISR > timeISRMax)                       // store maximum
        timeISRMax = timeISR;
    timeISRAvgSum += timeISR;                       // sum for avg
    countISRCalls++;
}

int main() {
    printf("IRMP on mbed\n");

    led = LED_OFF;
    timerPerfTest.start();

    // irmp_data holds result of received IR code
    IRMP_DATA irmp_data;

    irmp_init();                                                            // initialize irmp
    t.attach_us(&irmpISR, 1E6 / F_INTERRUPTS);                              // call ISR 15.000 / s

    // infinite loop, interrupts will blink PORTD pins and handle UART communications.
    while (1)
    {
        flash = !flash;     // test output. flashes at 15/2 kHz, you will not see it blinking

        // check for received IR commands
        if (irmp_get_data (&irmp_data))
        {
            // ir signal decoded, do something here...
            // irmp_data.protocol is the protocol, see irmp.h
            // irmp_data.address is the address/manufacturer code of ir sender
            // irmp_data.command is the command code
            // irm_data.flags is press/release information
            // irmp_protocol_names[irmp_data.protocol] is the protocol name (if enabled, see irmpconfig.h)
            // printf("proto %d addr %d cmd %d\n", irmp_data.protocol, irmp_data.address, irmp_data.command );

            // sample decoding, turn LED on / off
            if (irmp_data.protocol == IRMP_RC5_PROTOCOL && irmp_data.address == 5)      // old RC5 VCR Remote. TV uses address 0
            {
                if (irmp_data.flags == 0)       // switch only on button press
                {
                    switch (irmp_data.command)
                    {
                    case 0:     // Key '0'
                        led = LED_OFF;
                        break;
                    case 1:     // Key '1'
                        led = LED_ON;
                        break;
                    case 53:        // Key 'play'
                        printf("bring me a beer!\n");
                        break;
                    case 54:        // Key 'stop'
                        timeISRAvg = (float)timeISRAvgSum / countISRCalls;
                        timeISRAvgSum = 0;
                        countISRCalls = 0;
                        printf("ISR max / avg runtime [microseconds] : %d / %5.2f\n", timeISRMax, timeISRAvg);
                        timeISRMax = 0;
                        break;
                    }
                }
            }

            // log to stdout
            printf("proto %d addr %d cmd %d flags %x name %s\n", irmp_data.protocol, irmp_data.address, irmp_data.command, irmp_data.flags, irmp_protocol_names[irmp_data.protocol] );
        }
    }

}

irmpconfig.h

Committer:
JojoS
Date:
2016-01-09
Revision:
0:a0715ea739cb

File content as of revision 0:a0715ea739cb:

/*---------------------------------------------------------------------------------------------------------------------------------------------------
 * irmpconfig.h
 *
 * DO NOT INCLUDE THIS FILE, WILL BE INCLUDED BY IRMP.H!
 *
 * Copyright (c) 2009-2015 Frank Meyer - frank(at)fli4l.de
 * Extensions for PIC 12F1820 W.Strobl 2014-07-20
 *
 * $Id: irmpconfig.h,v 1.145 2015/11/18 08:27:50 fm Exp $
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *---------------------------------------------------------------------------------------------------------------------------------------------------
 */

#ifndef _IRMPCONFIG_H_
#define _IRMPCONFIG_H_

#ifndef _IRMP_H_
#  error please include only irmp.h, not irmpconfig.h
#endif

/*---------------------------------------------------------------------------------------------------------------------------------------------------
 * Change F_INTERRUPTS if you change the number of interrupts per second,
 * Normally, F_INTERRUPTS should be in the range from 10000 to 15000, typical is 15000
 * A value above 15000 costs additional program space, absolute maximum value is 20000.
 * On PIC with XC8/C18 Compiler, use 15151 as the correct value.
 *---------------------------------------------------------------------------------------------------------------------------------------------------
 */
#ifndef F_INTERRUPTS
#  define F_INTERRUPTS                          15000   // interrupts per second, min: 10000, max: 20000, typ: 15000
#endif

/*---------------------------------------------------------------------------------------------------------------------------------------------------
 * Change settings from 1 to 0 if you want to disable one or more decoders.
 * This saves program space.
 *
 * 1 enable  decoder
 * 0 disable decoder
 *
 * The standard decoders are enabled per default.
 * Less common protocols are disabled here, you need to enable them manually.
 *
 * If you want to use FDC or RCCAR simultaneous with RC5 protocol, additional program space is required.
 * If you don't need RC5 when using FDC/RCCAR, you should disable RC5.
 * You cannot enable both DENON and RUWIDO, only enable one of them.
 *---------------------------------------------------------------------------------------------------------------------------------------------------
 */

// typical protocols, disable here!             Enable  Remarks                 F_INTERRUPTS            Program Space
#define IRMP_SUPPORT_SIRCS_PROTOCOL             1       // Sony SIRCS           >= 10000                 ~150 bytes
#define IRMP_SUPPORT_NEC_PROTOCOL               1       // NEC + APPLE          >= 10000                 ~300 bytes
#define IRMP_SUPPORT_SAMSUNG_PROTOCOL           1       // Samsung + Samsg32    >= 10000                 ~300 bytes
#define IRMP_SUPPORT_KASEIKYO_PROTOCOL          1       // Kaseikyo             >= 10000                 ~250 bytes

// more protocols, enable here!                 Enable  Remarks                 F_INTERRUPTS            Program Space
#define IRMP_SUPPORT_JVC_PROTOCOL               0       // JVC                  >= 10000                 ~150 bytes
#define IRMP_SUPPORT_NEC16_PROTOCOL             0       // NEC16                >= 10000                 ~100 bytes
#define IRMP_SUPPORT_NEC42_PROTOCOL             0       // NEC42                >= 10000                 ~300 bytes
#define IRMP_SUPPORT_MATSUSHITA_PROTOCOL        0       // Matsushita           >= 10000                  ~50 bytes
#define IRMP_SUPPORT_DENON_PROTOCOL             0       // DENON, Sharp         >= 10000                 ~250 bytes
#define IRMP_SUPPORT_RC5_PROTOCOL               1       // RC5                  >= 10000                 ~250 bytes
#define IRMP_SUPPORT_RC6_PROTOCOL               1       // RC6 & RC6A           >= 10000                 ~250 bytes
#define IRMP_SUPPORT_IR60_PROTOCOL              0       // IR60 (SDA2008)       >= 10000                 ~300 bytes
#define IRMP_SUPPORT_GRUNDIG_PROTOCOL           0       // Grundig              >= 10000                 ~300 bytes
#define IRMP_SUPPORT_SIEMENS_PROTOCOL           0       // Siemens Gigaset      >= 15000                 ~550 bytes
#define IRMP_SUPPORT_NOKIA_PROTOCOL             0       // Nokia                >= 10000                 ~300 bytes

// exotic protocols, enable here!               Enable  Remarks                 F_INTERRUPTS            Program Space
#define IRMP_SUPPORT_BOSE_PROTOCOL              0       // BOSE                 >= 10000                 ~150 bytes
#define IRMP_SUPPORT_KATHREIN_PROTOCOL          0       // Kathrein             >= 10000                 ~200 bytes
#define IRMP_SUPPORT_NUBERT_PROTOCOL            0       // NUBERT               >= 10000                  ~50 bytes
#define IRMP_SUPPORT_FAN_PROTOCOL               0       // FAN (ventilator)     >= 10000                  ~50 bytes
#define IRMP_SUPPORT_SPEAKER_PROTOCOL           0       // SPEAKER (~NUBERT)    >= 10000                  ~50 bytes
#define IRMP_SUPPORT_BANG_OLUFSEN_PROTOCOL      0       // Bang & Olufsen       >= 10000                 ~200 bytes
#define IRMP_SUPPORT_RECS80_PROTOCOL            0       // RECS80 (SAA3004)     >= 15000                  ~50 bytes
#define IRMP_SUPPORT_RECS80EXT_PROTOCOL         0       // RECS80EXT (SAA3008)  >= 15000                  ~50 bytes
#define IRMP_SUPPORT_THOMSON_PROTOCOL           0       // Thomson              >= 10000                 ~250 bytes
#define IRMP_SUPPORT_NIKON_PROTOCOL             0       // NIKON camera         >= 10000                 ~250 bytes
#define IRMP_SUPPORT_NETBOX_PROTOCOL            0       // Netbox keyboard      >= 10000                 ~400 bytes (PROTOTYPE!)
#define IRMP_SUPPORT_ORTEK_PROTOCOL             0       // ORTEK (Hama)         >= 10000                 ~150 bytes
#define IRMP_SUPPORT_TELEFUNKEN_PROTOCOL        0       // Telefunken 1560      >= 10000                 ~150 bytes
#define IRMP_SUPPORT_FDC_PROTOCOL               0       // FDC3402 keyboard     >= 10000 (better 15000)  ~150 bytes (~400 in combination with RC5)
#define IRMP_SUPPORT_RCCAR_PROTOCOL             0       // RC Car               >= 10000 (better 15000)  ~150 bytes (~500 in combination with RC5)
#define IRMP_SUPPORT_ROOMBA_PROTOCOL            0       // iRobot Roomba        >= 10000                 ~150 bytes
#define IRMP_SUPPORT_RUWIDO_PROTOCOL            0       // RUWIDO, T-Home       >= 15000                 ~550 bytes
#define IRMP_SUPPORT_A1TVBOX_PROTOCOL           0       // A1 TV BOX            >= 15000 (better 20000)  ~300 bytes
#define IRMP_SUPPORT_LEGO_PROTOCOL              0       // LEGO Power RC        >= 20000                 ~150 bytes
#define IRMP_SUPPORT_RCMM_PROTOCOL              0       // RCMM 12,24, or 32    >= 20000                 ~150 bytes
#define IRMP_SUPPORT_LGAIR_PROTOCOL             0       // LG Air Condition     >= 10000                 ~300 bytes
#define IRMP_SUPPORT_SAMSUNG48_PROTOCOL         0       // Samsung48            >= 10000                 ~100 bytes (SAMSUNG must be enabled!)
#define IRMP_SUPPORT_MERLIN_PROTOCOL            0       // Merlin               >= 15000 (better 20000)  ~300 bytes
#define IRMP_SUPPORT_PENTAX_PROTOCOL            0       // Pentax               >= 10000                 ~150 bytes
#define IRMP_SUPPORT_S100_PROTOCOL              0       // S100                 >= 10000                 ~250 bytes
#define IRMP_SUPPORT_ACP24_PROTOCOL             0       // ACP24                >= 10000                 ~250 bytes
#define IRMP_SUPPORT_TECHNICS_PROTOCOL          0       // TECHNICS             >= 10000                 ~250 bytes
#define IRMP_SUPPORT_PANASONIC_PROTOCOL         0       // PANASONIC Beamer     >= 10000                 ~250 bytes
#define IRMP_SUPPORT_RADIO1_PROTOCOL            0       // RADIO, e.g. TEVION   >= 10000                 ~250 bytes (experimental)

/*---------------------------------------------------------------------------------------------------------------------------------------------------
 * Change hardware pin here for ATMEL ATMega/ATTiny/XMega
 *---------------------------------------------------------------------------------------------------------------------------------------------------
 */
#if defined (ATMEL_AVR) || defined (__AVR_XMEGA__)                      // use PB6 as IR input on AVR
#  define IRMP_PORT_LETTER                      B
#  define IRMP_BIT_NUMBER                       6

/*---------------------------------------------------------------------------------------------------------------------------------------------------
 * Change hardware pin here for PIC C18 or XC8 compiler
 *---------------------------------------------------------------------------------------------------------------------------------------------------
 */
#elif defined (PIC_C18)                                                 // use RB4 as IR input on PIC (C18 or XC8 compiler)
#  if defined(__12F1840)
#    define IRMP_PIN                            RA5                     // on 12F1840 with XC8 compiler
#  else
#    define IRMP_PIN                            PORTBbits.RB4           // PIC C18
#  endif

/*---------------------------------------------------------------------------------------------------------------------------------------------------
 * Change hardware pin here for PIC CCS compiler
 *---------------------------------------------------------------------------------------------------------------------------------------------------
 */
#elif defined (PIC_CCS)
#  define IRMP_PIN                              PIN_B4                  // use PB4 as IR input on PIC (CCS compiler)

/*---------------------------------------------------------------------------------------------------------------------------------------------------
 * Change hardware pin here for ARM STM32
 *---------------------------------------------------------------------------------------------------------------------------------------------------
 */
#elif defined (ARM_STM32)                                               // use C13 as IR input on STM32
#  define IRMP_PORT_LETTER                      C
#  define IRMP_BIT_NUMBER                       13

/*---------------------------------------------------------------------------------------------------------------------------------------------------
 * Change hardware pin here for Stellaris ARM Cortex M4
 *---------------------------------------------------------------------------------------------------------------------------------------------------
 */
#elif defined (STELLARIS_ARM_CORTEX_M4)                                 // use B4 as IR input on Stellaris LM4F
#  define IRMP_PORT_LETTER                      B
#  define IRMP_BIT_NUMBER                       4

/*---------------------------------------------------------------------------------------------------------------------------------------------------
 * Change hardware pin here for STM8
 *---------------------------------------------------------------------------------------------------------------------------------------------------
 */
#elif defined (SDCC_STM8)                                               // use PA1 as IR input on STM8
#  define IRMP_PORT_LETTER                      A
#  define IRMP_BIT_NUMBER                       1

/*---------------------------------------------------------------------------------------------------------------------------------------------------
 * Change hardware pin here for ESP8266
 *---------------------------------------------------------------------------------------------------------------------------------------------------
 */
#elif defined (__xtensa__) 
#  define IRMP_BIT_NUMBER                       12                      // use GPIO12 (Pin 7 UEXT) on ESP8266-EVB evaluation board

/*---------------------------------------------------------------------------------------------------------------------------------------------------
 * Change hardware pin here for Teensy 3.x with teensyduino gcc compiler
 *---------------------------------------------------------------------------------------------------------------------------------------------------
 */
#elif defined (TEENSY_ARM_CORTEX_M4)
#  define IRMP_PIN                              1                       // use Digital pin 1 as IR input on Teensy

/*---------------------------------------------------------------------------------------------------------------------------------------------------
 * Handling of unknown target system: DON'T CHANGE
 *---------------------------------------------------------------------------------------------------------------------------------------------------
 */
#elif defined(__MBED__)
#  define IRMP_PIN                              P0_22                      	// use P1_27 on LPC1347
#  define IRMP_PINMODE							PullUp						// hardware dependet
#elif !defined (UNIX_OR_WINDOWS)
#  error target system not defined.
#endif

/*---------------------------------------------------------------------------------------------------------------------------------------------------
 * Set IRMP_LOGGING to 1 if want to log data to UART with 9600Bd
 *---------------------------------------------------------------------------------------------------------------------------------------------------
 */
#ifndef IRMP_LOGGING
#  define IRMP_LOGGING                          0       // 1: log IR signal (scan), 0: do not. default is 0
#endif

/*---------------------------------------------------------------------------------------------------------------------------------------------------
 * Use external logging routines
 * If you enable external logging, you have also to enable IRMP_LOGGING above
 *---------------------------------------------------------------------------------------------------------------------------------------------------
 */
#ifndef IRMP_EXT_LOGGING
#  define IRMP_EXT_LOGGING                      0       // 1: use external logging, 0: do not. default is 0
#endif

/*---------------------------------------------------------------------------------------------------------------------------------------------------
 * Set IRMP_PROTOCOL_NAMES to 1 if want to access protocol names (for logging etc), costs ~300 bytes RAM!
 *---------------------------------------------------------------------------------------------------------------------------------------------------
 */
#ifndef IRMP_PROTOCOL_NAMES
#  define IRMP_PROTOCOL_NAMES                   1       // 1: access protocol names, 0: do not. default is 0
#endif

/*---------------------------------------------------------------------------------------------------------------------------------------------------
 * Use Callbacks to indicate input signal
 *---------------------------------------------------------------------------------------------------------------------------------------------------
 */
#ifndef IRMP_USE_CALLBACK
#  define IRMP_USE_CALLBACK                     0       // 1: use callbacks. 0: do not. default is 0
#endif

#endif // _IRMPCONFIG_H_