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,4 @@
Function to decode a mechanical rotary encoder.
Follow the instructions in the test file to build and run.

View File

@@ -0,0 +1,94 @@
#include <stdio.h>
#include <stdlib.h>
#include <pigpio.h>
#include "rotary_encoder.h"
struct _Pi_Renc_s
{
int gpioA;
int gpioB;
Pi_Renc_CB_t callback;
int levA;
int levB;
int lastGpio;
};
/*
+---------+ +---------+ 0
| | | |
A | | | |
| | | |
+---------+ +---------+ +----- 1
+---------+ +---------+ 0
| | | |
B | | | |
| | | |
----+ +---------+ +---------+ 1
*/
static void _cb(int gpio, int level, uint32_t tick, void *user)
{
Pi_Renc_t *renc;
renc = user;
if (gpio == renc->gpioA) renc->levA = level; else renc->levB = level;
if (gpio != renc->lastGpio) /* debounce */
{
renc->lastGpio = gpio;
if ((gpio == renc->gpioA) && (level == 1))
{
if (renc->levB) (renc->callback)(1);
}
else if ((gpio == renc->gpioB) && (level == 1))
{
if (renc->levA) (renc->callback)(-1);
}
}
}
Pi_Renc_t * Pi_Renc(int gpioA, int gpioB, Pi_Renc_CB_t callback)
{
Pi_Renc_t *renc;
renc = malloc(sizeof(Pi_Renc_t));
renc->gpioA = gpioA;
renc->gpioB = gpioB;
renc->callback = callback;
renc->levA=0;
renc->levB=0;
renc->lastGpio = -1;
gpioSetMode(gpioA, PI_INPUT);
gpioSetMode(gpioB, PI_INPUT);
/* pull up is needed as encoder common is grounded */
gpioSetPullUpDown(gpioA, PI_PUD_UP);
gpioSetPullUpDown(gpioB, PI_PUD_UP);
/* monitor encoder level changes */
gpioSetAlertFuncEx(gpioA, _cb, renc);
gpioSetAlertFuncEx(gpioB, _cb, renc);
}
void Pi_Renc_cancel(Pi_Renc_t *renc)
{
if (renc)
{
gpioSetAlertFunc(renc->gpioA, 0);
gpioSetAlertFunc(renc->gpioB, 0);
free(renc);
}
}

View File

@@ -0,0 +1,25 @@
#ifndef ROTARY_ENCODER_H
#define ROTARY_ENCODER_H
typedef void (*Pi_Renc_CB_t)(int);
struct _Pi_Renc_s;
typedef struct _Pi_Renc_s Pi_Renc_t;
Pi_Renc_t * Pi_Renc(int gpioA, int gpioB, Pi_Renc_CB_t callback);
/*
This function establishes a rotary encoder on gpioA and gpioB.
When the encoder is turned the callback function is called.
A pointer to a private data type is returned. This should be passed
to Pi_Renc_cancel if the rotary encoder is to be cancelled.
*/
void Pi_Renc_cancel(Pi_Renc_t *renc);
/*
This function releases the resources used by the decoder.
*/
#endif

View File

@@ -0,0 +1,47 @@
#include <stdio.h>
#include <pigpio.h>
#include "rotary_encoder.h"
/*
REQUIRES
A rotary encoder contacts A and B connected to separate gpios and
the common contact connected to Pi ground.
TO BUILD
gcc -o rot_enc_c test_rotary_encoder.c rotary_encoder.c -lpigpio -lrt
TO RUN
sudo ./rot_enc_c
*/
void callback(int way)
{
static int pos = 0;
pos += way;
printf("pos=%d\n", pos);
}
int main(int argc, char *argv[])
{
Pi_Renc_t * renc;
if (gpioInitialise() < 0) return 1;
renc = Pi_Renc(7, 8, callback);
sleep(300);
Pi_Renc_cancel(renc);
gpioTerminate();
}