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

}
Committer:
JojoS
Date:
Sat Jan 09 14:15:56 2016 +0000
Revision:
0:a0715ea739cb
First release of 'Infrared Receiver Multi Protocol'  IRMP porting from mikrocontroller.net

Who changed what in which revision?

UserRevisionLine numberNew contents of line
JojoS 0:a0715ea739cb 1 /*---------------------------------------------------------------------------------------------------------------------------------------------------
JojoS 0:a0715ea739cb 2 * irmpsystem.h - system specific includes and defines
JojoS 0:a0715ea739cb 3 *
JojoS 0:a0715ea739cb 4 * Copyright (c) 2009-2015 Frank Meyer - frank(at)fli4l.de
JojoS 0:a0715ea739cb 5 *
JojoS 0:a0715ea739cb 6 * $Id: irmpsystem.h,v 1.21 2015/11/18 08:27:50 fm Exp $
JojoS 0:a0715ea739cb 7 *
JojoS 0:a0715ea739cb 8 * This program is free software; you can redistribute it and/or modify
JojoS 0:a0715ea739cb 9 * it under the terms of the GNU General Public License as published by
JojoS 0:a0715ea739cb 10 * the Free Software Foundation; either version 2 of the License, or
JojoS 0:a0715ea739cb 11 * (at your option) any later version.
JojoS 0:a0715ea739cb 12 *---------------------------------------------------------------------------------------------------------------------------------------------------
JojoS 0:a0715ea739cb 13 */
JojoS 0:a0715ea739cb 14
JojoS 0:a0715ea739cb 15 #ifndef _IRMPSYSTEM_H_
JojoS 0:a0715ea739cb 16 #define _IRMPSYSTEM_H_
JojoS 0:a0715ea739cb 17
JojoS 0:a0715ea739cb 18 #if !defined(_IRMP_H_) && !defined(_IRSND_H_)
JojoS 0:a0715ea739cb 19 # error please include only irmp.h or irsnd.h, not irmpsystem.h
JojoS 0:a0715ea739cb 20 #endif
JojoS 0:a0715ea739cb 21
JojoS 0:a0715ea739cb 22 #if defined(__18CXX) // Microchip PIC C18 compiler
JojoS 0:a0715ea739cb 23 # define PIC_C18
JojoS 0:a0715ea739cb 24 #elif defined(__XC8) // PIC XC8 compiler
JojoS 0:a0715ea739cb 25 # include <xc.h>
JojoS 0:a0715ea739cb 26 # define PIC_C18
JojoS 0:a0715ea739cb 27 #elif defined(__PCM__) || defined(__PCB__) || defined(__PCH__) // CCS PIC compiler
JojoS 0:a0715ea739cb 28 # define PIC_CCS
JojoS 0:a0715ea739cb 29 #elif defined(STM32L1XX_MD) || defined(STM32L1XX_MDP) || defined(STM32L1XX_HD) // ARM STM32
JojoS 0:a0715ea739cb 30 # include <stm32l1xx.h>
JojoS 0:a0715ea739cb 31 # define ARM_STM32
JojoS 0:a0715ea739cb 32 # define ARM_STM32L1XX
JojoS 0:a0715ea739cb 33 # define F_CPU (SysCtlClockGet())
JojoS 0:a0715ea739cb 34 #elif defined(STM32F10X_LD) || defined(STM32F10X_LD_VL) \
JojoS 0:a0715ea739cb 35 || defined(STM32F10X_MD) || defined(STM32F10X_MD_VL) \
JojoS 0:a0715ea739cb 36 || defined(STM32F10X_HD) || defined(STM32F10X_HD_VL) \
JojoS 0:a0715ea739cb 37 || defined(STM32F10X_XL) || defined(STM32F10X_CL) // ARM STM32
JojoS 0:a0715ea739cb 38 # include <stm32f10x.h>
JojoS 0:a0715ea739cb 39 # define ARM_STM32
JojoS 0:a0715ea739cb 40 # define ARM_STM32F10X
JojoS 0:a0715ea739cb 41 # define F_CPU (SysCtlClockGet())
JojoS 0:a0715ea739cb 42 #elif defined(STM32F4XX) // ARM STM32
JojoS 0:a0715ea739cb 43 # include <stm32f4xx.h>
JojoS 0:a0715ea739cb 44 # define ARM_STM32
JojoS 0:a0715ea739cb 45 # define ARM_STM32F4XX
JojoS 0:a0715ea739cb 46 #elif defined(__SDCC_stm8) // STM8
JojoS 0:a0715ea739cb 47 # define SDCC_STM8
JojoS 0:a0715ea739cb 48 #elif defined(TARGET_IS_BLIZZARD_RA2) // TI Stellaris (tested on Stellaris Launchpad with Code Composer Studio)
JojoS 0:a0715ea739cb 49 # define STELLARIS_ARM_CORTEX_M4
JojoS 0:a0715ea739cb 50 # define F_CPU (SysCtlClockGet())
JojoS 0:a0715ea739cb 51 #elif defined(__xtensa__)
JojoS 0:a0715ea739cb 52 # include "ets_sys.h"
JojoS 0:a0715ea739cb 53 # include "osapi.h"
JojoS 0:a0715ea739cb 54 # include "gpio.h"
JojoS 0:a0715ea739cb 55 # include "os_type.h"
JojoS 0:a0715ea739cb 56 # include "c_types.h"
JojoS 0:a0715ea739cb 57 # define uint_fast8_t uint8_t
JojoS 0:a0715ea739cb 58 # define uint_fast16_t uint16_t
JojoS 0:a0715ea739cb 59 #elif defined(TEENSYDUINO) && (defined(__MK20DX256__) || defined(__MK20DX128__)) // Teensy 3.x (tested on Teensy 3.1 in Arduino 1.6.5 / Teensyduino 1.2.5)
JojoS 0:a0715ea739cb 60 # include <core_pins.h>
JojoS 0:a0715ea739cb 61 # define TEENSY_ARM_CORTEX_M4
JojoS 0:a0715ea739cb 62 #elif defined(unix) || defined(WIN32) || defined(__APPLE__) // Unix/Linux or Windows or Apple
JojoS 0:a0715ea739cb 63 # define UNIX_OR_WINDOWS
JojoS 0:a0715ea739cb 64 #elif defined(__MBED__) // mbed platform
JojoS 0:a0715ea739cb 65 // #include "mbed.h" // if mbed.h is used, source must be compiled as cpp
JojoS 0:a0715ea739cb 66 #include "gpio_api.h"
JojoS 0:a0715ea739cb 67 #else
JojoS 0:a0715ea739cb 68 # define ATMEL_AVR // ATMEL AVR
JojoS 0:a0715ea739cb 69 #endif
JojoS 0:a0715ea739cb 70
JojoS 0:a0715ea739cb 71 #include <string.h>
JojoS 0:a0715ea739cb 72
JojoS 0:a0715ea739cb 73 #ifdef UNIX_OR_WINDOWS // Analyze on Unix/Linux or Windows
JojoS 0:a0715ea739cb 74 # include <stdio.h>
JojoS 0:a0715ea739cb 75 # include <stdlib.h>
JojoS 0:a0715ea739cb 76 # define F_CPU 8000000L
JojoS 0:a0715ea739cb 77 # define ANALYZE
JojoS 0:a0715ea739cb 78 # ifdef unix
JojoS 0:a0715ea739cb 79 # include <stdint.h>
JojoS 0:a0715ea739cb 80 # else
JojoS 0:a0715ea739cb 81 typedef unsigned char uint8_t;
JojoS 0:a0715ea739cb 82 typedef unsigned short uint16_t;
JojoS 0:a0715ea739cb 83 # endif
JojoS 0:a0715ea739cb 84 #endif
JojoS 0:a0715ea739cb 85
JojoS 0:a0715ea739cb 86
JojoS 0:a0715ea739cb 87 #if defined(ATMEL_AVR)
JojoS 0:a0715ea739cb 88 # include <stdint.h>
JojoS 0:a0715ea739cb 89 # include <stdio.h>
JojoS 0:a0715ea739cb 90 # include <avr/io.h>
JojoS 0:a0715ea739cb 91 # include <util/delay.h>
JojoS 0:a0715ea739cb 92 # include <avr/pgmspace.h>
JojoS 0:a0715ea739cb 93 # include <avr/interrupt.h>
JojoS 0:a0715ea739cb 94 # define IRSND_OC2 0 // OC2
JojoS 0:a0715ea739cb 95 # define IRSND_OC2A 1 // OC2A
JojoS 0:a0715ea739cb 96 # define IRSND_OC2B 2 // OC2B
JojoS 0:a0715ea739cb 97 # define IRSND_OC0 3 // OC0
JojoS 0:a0715ea739cb 98 # define IRSND_OC0A 4 // OC0A
JojoS 0:a0715ea739cb 99 # define IRSND_OC0B 5 // OC0B
JojoS 0:a0715ea739cb 100
JojoS 0:a0715ea739cb 101 # define IRSND_XMEGA_OC0A 0 // OC0A
JojoS 0:a0715ea739cb 102 # define IRSND_XMEGA_OC0B 1 // OC0B
JojoS 0:a0715ea739cb 103 # define IRSND_XMEGA_OC0C 2 // OC0C
JojoS 0:a0715ea739cb 104 # define IRSND_XMEGA_OC0D 3 // OC0D
JojoS 0:a0715ea739cb 105 # define IRSND_XMEGA_OC1A 4 // OC1A
JojoS 0:a0715ea739cb 106 # define IRSND_XMEGA_OC1B 5 // OC1B
JojoS 0:a0715ea739cb 107
JojoS 0:a0715ea739cb 108 #elif defined(STELLARIS_ARM_CORTEX_M4)
JojoS 0:a0715ea739cb 109
JojoS 0:a0715ea739cb 110 # include "inc/hw_ints.h"
JojoS 0:a0715ea739cb 111 # include "inc/hw_memmap.h"
JojoS 0:a0715ea739cb 112 # include "inc/hw_types.h"
JojoS 0:a0715ea739cb 113 # include "inc/hw_gpio.h"
JojoS 0:a0715ea739cb 114 # include "driverlib/fpu.h"
JojoS 0:a0715ea739cb 115 # include "driverlib/sysctl.h"
JojoS 0:a0715ea739cb 116 # include "driverlib/interrupt.h"
JojoS 0:a0715ea739cb 117 # include "driverlib/gpio.h"
JojoS 0:a0715ea739cb 118 # include "driverlib/rom.h"
JojoS 0:a0715ea739cb 119 # include "driverlib/systick.h"
JojoS 0:a0715ea739cb 120 # include "driverlib/pin_map.h"
JojoS 0:a0715ea739cb 121 # include "driverlib/timer.h"
JojoS 0:a0715ea739cb 122 # define PROGMEM
JojoS 0:a0715ea739cb 123 # define memcpy_P memcpy
JojoS 0:a0715ea739cb 124 # define APP_SYSTICKS_PER_SEC 32
JojoS 0:a0715ea739cb 125
JojoS 0:a0715ea739cb 126 #elif defined(ARM_STM32F10X)
JojoS 0:a0715ea739cb 127
JojoS 0:a0715ea739cb 128 # include "stm32f10x_gpio.h"
JojoS 0:a0715ea739cb 129 # include "stm32f10x_rcc.h"
JojoS 0:a0715ea739cb 130 # include "stm32f10x_tim.h"
JojoS 0:a0715ea739cb 131 # include "misc.h"
JojoS 0:a0715ea739cb 132 # define PROGMEM
JojoS 0:a0715ea739cb 133 # define memcpy_P memcpy
JojoS 0:a0715ea739cb 134
JojoS 0:a0715ea739cb 135 #elif defined(SDCC_STM8)
JojoS 0:a0715ea739cb 136
JojoS 0:a0715ea739cb 137 # include "stm8s.h"
JojoS 0:a0715ea739cb 138 # define PROGMEM
JojoS 0:a0715ea739cb 139 # define memcpy_P memcpy
JojoS 0:a0715ea739cb 140 # define __attribute__(x)
JojoS 0:a0715ea739cb 141 # define uint_fast8_t uint8_t
JojoS 0:a0715ea739cb 142 # define uint_fast16_t uint16_t
JojoS 0:a0715ea739cb 143
JojoS 0:a0715ea739cb 144 #elif defined(TEENSY_ARM_CORTEX_M4)
JojoS 0:a0715ea739cb 145 # define PROGMEM
JojoS 0:a0715ea739cb 146 # define memcpy_P memcpy
JojoS 0:a0715ea739cb 147
JojoS 0:a0715ea739cb 148 #elif defined(__MBED__)
JojoS 0:a0715ea739cb 149 # define PROGMEM
JojoS 0:a0715ea739cb 150 # define memcpy_P memcpy
JojoS 0:a0715ea739cb 151
JojoS 0:a0715ea739cb 152 #else
JojoS 0:a0715ea739cb 153 # define PROGMEM
JojoS 0:a0715ea739cb 154 # define memcpy_P memcpy
JojoS 0:a0715ea739cb 155
JojoS 0:a0715ea739cb 156 #endif
JojoS 0:a0715ea739cb 157
JojoS 0:a0715ea739cb 158 #if defined(PIC_CCS) || defined(PIC_C18) || defined(ARM_STM32) || defined(STELLARIS_ARM_CORTEX_M4)
JojoS 0:a0715ea739cb 159 typedef unsigned char uint8_t;
JojoS 0:a0715ea739cb 160 typedef unsigned short uint16_t;
JojoS 0:a0715ea739cb 161 #endif
JojoS 0:a0715ea739cb 162
JojoS 0:a0715ea739cb 163 #if defined (PIC_C18) // PIC C18 or XC8 compiler
JojoS 0:a0715ea739cb 164 # include <p18cxxx.h> // main PIC18 h file
JojoS 0:a0715ea739cb 165 #ifndef __XC8
JojoS 0:a0715ea739cb 166 # include <timers.h> // timer lib
JojoS 0:a0715ea739cb 167 # include <pwm.h> // pwm lib
JojoS 0:a0715ea739cb 168 #endif
JojoS 0:a0715ea739cb 169 # define IRSND_PIC_CCP1 1 // PIC C18 RC2 = PWM1 module
JojoS 0:a0715ea739cb 170 # define IRSND_PIC_CCP2 2 // PIC C18 RC1 = PWM2 module
JojoS 0:a0715ea739cb 171 #endif
JojoS 0:a0715ea739cb 172
JojoS 0:a0715ea739cb 173 #ifndef TRUE
JojoS 0:a0715ea739cb 174 # define TRUE 1
JojoS 0:a0715ea739cb 175 # define FALSE 0
JojoS 0:a0715ea739cb 176 #endif
JojoS 0:a0715ea739cb 177
JojoS 0:a0715ea739cb 178 typedef struct __attribute__ ((__packed__))
JojoS 0:a0715ea739cb 179 {
JojoS 0:a0715ea739cb 180 uint8_t protocol; // protocol, e.g. NEC_PROTOCOL
JojoS 0:a0715ea739cb 181 uint16_t address; // address
JojoS 0:a0715ea739cb 182 uint16_t command; // command
JojoS 0:a0715ea739cb 183 uint8_t flags; // flags, e.g. repetition
JojoS 0:a0715ea739cb 184 } IRMP_DATA;
JojoS 0:a0715ea739cb 185
JojoS 0:a0715ea739cb 186 #endif // _IRMPSYSTEM_H_