c++raspberry-piinterruptlcdwiringpi

Use wiringPi with interrupts and lcd simultaneous


I'm new to C++ programming on Linux. I try to use an rotary encoder to control values on a lcd. Depending on which wiringPi Setup routine I use, only interrupts or the lcd work, but not both at the same time. I exported all necessary GPIOs so that sudo is not needed.

#Interrupt Pins Encoder
gpio edge 23 both
gpio edge 24 both
gpio mode 4 up
gpio mode 5 up

#Pins LCD
gpio export 17 out
gpio export 18 out
gpio export 27 out
gpio export 22 out
gpio export 8 out
gpio export 7 out

Here the C++ code:

#include <wiringPi.h>
#include <lcd.h>
#include <stdio.h>

#define A   23
#define B   24

char a = 0;
char b = 0;
const char a1 = 1, a2 = 2, a3 = 3, b1 = 4, b2 = 5, b3 = 6;
char state = 0;

volatile int counter = 0;
volatile int counter_l = 0;
void interrupt();

int main(void)
{
    printf("wiringPiSetup\n");
    //wiringPiSetupSys();  //Interrupts working
    wiringPiSetup();  //LCD working

    pinMode(17, OUTPUT);
    pinMode(18, OUTPUT);
    pinMode(27, OUTPUT);
    pinMode(22, OUTPUT);
    pinMode(8, OUTPUT);
    pinMode(7, OUTPUT);

    int fd = lcdInit(2, 16, 4, 11, 10, 0, 1, 2, 3, 0, 0, 0, 0);
    lcdClear(fd);
    lcdPosition(fd, 0, 0);
    lcdPrintf(fd,"Test");

    wiringPiISR(A, INT_EDGE_BOTH, &interrupt);
    wiringPiISR(B, INT_EDGE_BOTH, &interrupt);

    pinMode(A, INPUT);
    pinMode(B, INPUT);

    while (true)
    {
        if (counter != counter_l)
        {
            counter_l = counter;
            printf("%i\n", counter);
            lcdPosition(fd, 0, 0);
            lcdPrintf(fd, "%i   ", counter);
        }
    }
    return 0;
}

void interrupt(){
    a = !digitalRead(A);
    b = !digitalRead(B);
    switch (state)
    {
    case a1:
        if (!a) 
            state = 0;
        else if (b) 
            state = a2;
        break;
    case a2:
        if (!a&&b)
            state = a3;
        else if (a&&!b)
            state = a1;
        break;
    case a3:
        if (a&&b)
            state = a2;
        else if (!a&&!b) {
            state = 0;
            counter++;
        }
        break;
    case b1:
        if (!b)
            state = 0;
        else if (a)
            state = b2;
        break;
    case b2:
        if (!b&&a)
            state = b3;
        else if (b&&!a)
            state = b1;
        break;
    case b3:
        if (b&&a)
            state = b2;
        else if (!b&&!a) {
            state = 0;
            counter--;
        }
        break;
    default:
        if (a&&b) 
            state = 0;
        else if (a)
            state = a1;
        else if (b)
            state = b1;
        break;
    }   
}

Now the question is why it behaves like that and what can/should I do?


Solution

  • I found the solution in the different numbering used with the setup functions. WirinpPi has its own Pin numbering and there is the native BCM numbering. The solution is to change the numbering in the lcdInit function to the BCM numbering.

                            //wiringPi Nr.
    pinMode(17, OUTPUT);    //0
    pinMode(18, OUTPUT);    //1
    pinMode(27, OUTPUT);    //2
    pinMode(22, OUTPUT);    //3
    pinMode(8, OUTPUT);     //10
    pinMode(7, OUTPUT);     //11
    
    //int fd = lcdInit(2, 16, 4, 11, 10, 0, 1, 2, 3, 0, 0, 0, 0);   //wiringPi Nr.
    int fd = lcdInit(2, 16, 4, 7, 8, 17, 18, 27, 22, 0, 0, 0, 0);   //BCM Nr.