pigpio
pigpio C I/F
pigpiod
pigpiod C I/F
Python
pigs
piscope
Misc
Examples
Download
FAQ
Site Map
|
IR Remote Example
The following code shows one way to read an infrared remote
control device (the sort used in TVs and stereo systems).
SETUP
The device used
is a SFH5110 (IR Receiver for remote control,
carrier 38 kHz).
Pin 1 (left from front) may be connected to any spare
gpio. Here it's connected via a 4K7 current limiting
resistor. This isn't really needed as the device has an
internal 23K resistor in-line. It does no harm though.
Pin 2 should be connected to a Pi ground pin.
Pin 3 should be connected to a Pi 5V pin.
Here pin 1 to gpio7 (P1-26) via a 4K7 resistor, pin 2 to ground
(P1-14), and pin 3 to 5V (P1-2).

CODE
#include <stdio.h>
#include <pigpio.h>
#define IR_PIN 7
#define OUTSIDE_CODE 0
#define INSIDE_CODE 1
#define MIN_MESSAGE_GAP 3000
#define MAX_MESSAGE_END 3000
#define MAX_TRANSITIONS 500
/*
using the FNV-1a
hash
from
http://isthe.com/chongo/tech/comp/fnv/#FNV-param
*/
#define FNV_PRIME_32 16777619
#define FNV_BASIS_32 2166136261U
static volatile uint32_t ir_hash = 0;
typedef struct
{
int state;
int count;
int level;
uint16_t micros[MAX_TRANSITIONS];
} decode_t;
/* forward declarations */
void alert(int gpio, int level, uint32_t
tick);
uint32_t getHash(decode_t * decode);
void updateState(decode_t * decode, int
level, uint32_t micros);
int main(int argc, char * argv[])
{
if (gpioInitialise()<0)
{
return 1 ;
}
/* IR pin as input */
gpioSetMode(IR_PIN, PI_INPUT);
/* 5ms max gap after last pulse */
gpioSetWatchdog(IR_PIN, 5);
/* monitor IR level changes */
gpioSetAlertFunc(IR_PIN, alert);
while (1)
{
if (ir_hash)
{
/* non-zero means
new decode */
printf("ir code is
%u\ ", ir_hash);
ir_hash = 0;
}
gpioDelay(100000); /* check remote
10 times per second */
}
gpioTerminate();
}
void alert(int gpio, int level, uint32_t tick)
{
static int inited = 0;
static decode_t activeHigh, activeLow;
static uint32_t lastTick;
uint32_t diffTick;
if (!inited)
{
inited = 1;
activeHigh.state = OUTSIDE_CODE;
activeHigh.level = PI_LOW;
activeLow.state =
OUTSIDE_CODE; activeLow.level = PI_HIGH;
lastTick = tick;
return;
}
diffTick = tick - lastTick;
if (level != PI_TIMEOUT) lastTick = tick;
updateState(&activeHigh, level, diffTick);
updateState(&activeLow, level, diffTick);
}
void updateState(decode_t * decode, int level, uint32_t micros)
{
/*
We are dealing with active high as
well as active low
remotes. Abstract the common
functionality.
*/
if (decode->state == OUTSIDE_CODE)
{
if (level == decode->level)
{
if (micros >
MIN_MESSAGE_GAP)
{
decode->state = INSIDE_CODE;
decode->count = 0;
}
}
}
else
{
if (micros > MAX_MESSAGE_END)
{
/* end of message
*/
/* ignore if last
code not consumed */
if (!ir_hash)
ir_hash = getHash(decode);
decode->state =
OUTSIDE_CODE;
}
else
{
if
(decode->count < (MAX_TRANSITIONS-1))
{
if (level != PI_TIMEOUT)
decode->micros[decode->count++] = micros;
}
}
}
}
int compare(unsigned int oldval, unsigned int newval)
{
if (newval < (oldval
* 0.75)) {return 1;}
else if (oldval < (newval * 0.75)) {return 2;}
else
{return 4;}
}
uint32_t getHash(decode_t * decode)
{
/* use FNV-1a */
uint32_t hash;
int i, value;
if (decode->count < 6) {return 0;}
hash = FNV_BASIS_32;
for (i=0; i<(decode->count-2); i++)
{
value =
compare(decode->micros[i], decode->micros[i+2]);
hash = hash ^ value;
hash = (hash * FNV_PRIME_32);
}
return hash;
}
BUILD
cc -o ir_remote ir_remote.c -lpigpio -lrt
-lpthread
RUN
sudo ./ir_remote
A hash code is formed from the level transitions detected during
a remote key press. This is likely to be unique over multiple
remotes and keys.
While the program is running you can capture the waveform using
the notification feature built in to pigpio. Issue the
following commands on the Pi.
pigs no
pig2vcd </dev/pigpio0 >ir.vcd &
pigs nb 0 0x80 # set bits for gpios 7 (0x80)
Press a few different remotes and keys. Then enter
pigs nc 0
The file ir.vcd will contain the captured waveform, which can be
viewed using GTKWave.
Overview

Remote A typical waveform

Remote B typical waveform
|