first re-commit.

This commit is contained in:
2025-08-05 22:33:23 +02:00
commit e1ff579d1a
295 changed files with 107130 additions and 0 deletions

View File

@@ -0,0 +1,3 @@
Function to hash a code from an IR receiver (reading an IR remote control).
Follow the instructions in the test file to build and run.

View File

@@ -0,0 +1,136 @@
#include <stdlib.h>
#include <pigpio.h>
#include "ir_hasher.h"
/*
This code forms a hash over the IR pulses generated by an
IR remote.
The remote key press is not converted into a code in the manner of
the lirc module. No attempt is made to decode the type of protocol
used by the remote. The hash is likely to be unique for different
keys and different remotes but this is not guaranteed.
This hashing process works for some remotes/protocols but not for
others. The only way to find out if it works for one or more of
your remotes is to try it and see.
*/
struct _Pi_Hasher_s
{
int gpio;
Pi_Hasher_CB_t callback;
int timeout;
int in_code;
uint32_t hash_val;
int edges;
int t1;
int t2;
int t3;
int t4;
};
static uint32_t _hash(uint32_t hv, int old_val, int new_val)
{
int val;
if (new_val < (old_val * 0.60)) val = 13;
else if (old_val < (new_val * 0.60)) val = 23;
else val = 2;
hv ^= val;
hv *= 16777619; /* FNV_PRIME_32 */
return hv;
}
static void _cb(int gpio, int level, uint32_t tick, void *user)
{
Pi_Hasher_t * hasher;
hasher = user;
if (level != PI_TIMEOUT)
{
if (hasher->in_code == 0)
{
hasher->in_code = 1;
gpioSetWatchdog(gpio, hasher->timeout);
hasher->hash_val = 2166136261U; /* FNV_BASIS_32 */
hasher->edges = 1;
hasher->t1 = 0;
hasher->t2 = 0;
hasher->t3 = 0;
hasher->t4 = tick;
}
else
{
hasher->edges++;
hasher->t1 = hasher->t2;
hasher->t2 = hasher->t3;
hasher->t3 = hasher->t4;
hasher->t4 = tick;
if (hasher->edges > 3)
{
hasher->hash_val =
_hash(hasher->hash_val,
(hasher->t2)-(hasher->t1),
(hasher->t4)-(hasher->t3));
}
}
}
else
{
if (hasher->in_code)
{
hasher->in_code = 0;
gpioSetWatchdog(gpio, 0);
if (hasher->edges > 12) /* Anything less is probably noise. */
{
(hasher->callback)(hasher->hash_val);
}
}
}
}
Pi_Hasher_t *Pi_Hasher(int gpio, Pi_Hasher_CB_t callback, int timeout)
{
Pi_Hasher_t *hasher;
hasher = malloc(sizeof(Pi_Hasher_t));
hasher->gpio = gpio;
hasher->callback = callback;
hasher->timeout = 5;
hasher->in_code = 0;
gpioSetMode(gpio, PI_INPUT);
gpioSetAlertFuncEx(gpio, _cb, hasher);
return hasher;
}
void Pi_Hasher_cancel(Pi_Hasher_t *hasher)
{
if (hasher)
{
gpioSetAlertFunc(hasher->gpio, 0);
free(hasher);
hasher = NULL;
}
}

View File

@@ -0,0 +1,33 @@
#ifndef IR_HASHER_H
#define IR_HASHER_H
#include <stdint.h>
typedef void (*Pi_Hasher_CB_t)(uint32_t);
struct _Pi_Hasher_s;
typedef struct _Pi_Hasher_s Pi_Hasher_t;
Pi_Hasher_t * Pi_Hasher(int gpio, Pi_Hasher_CB_t callback, int timeout);
/*
This function establishes an IR hasher on the gpio.
A gap of timeout milliseconds without a new bit indicates
the end of a code.
When code end is detected the callback function is called
with the code hash.
A pointer to a private data type is returned. This should be passed
to Pi_Hasher_cancel if the hasher is to be cancelled.
*/
void Pi_Hasher_cancel(Pi_Hasher_t *hasher);
/*
This function releases the resources used by the hasher.
*/
#endif

View File

@@ -0,0 +1,47 @@
#include <stdio.h>
#include <pigpio.h>
#include "ir_hasher.h"
/*
REQUIRES
An IR receiver output pin connected to a Pi gpio.
TO BUILD
gcc -o ir_hash_c test_ir_hasher.c ir_hasher.c -lpigpio -lrt -lpthread
TO RUN
sudo ./ir_hash_c
*/
void callback(uint32_t hash)
{
printf("hash=%u\n", hash);
}
int main(int argc, char *argv[])
{
Pi_Hasher_t *hasher;
if (gpioInitialise() < 0) return 1;
/*
This assumes the output pin of an IR receiver is
connected to gpio 7.
*/
hasher = Pi_Hasher(7, callback, 5);
sleep(300);
Pi_Hasher_cancel(hasher);
gpioTerminate();
}