vsulako / AFFBWheel

Arduino based racing wheel controller with force feedback
MIT License
88 stars 19 forks source link

Using a multiplexer for button inputs #42

Open Zredy opened 10 months ago

Zredy commented 10 months ago

Hello, I want to use a multiplexer (4 pins for selecting the readable channel + 1 pin that reads the channel) to read the button states from my wheel. I tried poking around and implemeting something but I can't figure out how the button values are stored in the "d" or "buttons" variable. Are they stored in a bit fashion or some other way? Any help would be appreciated :)

vsulako commented 10 months ago

Every bit of 32-bit variable stores state of button. 1=pressed, 0=not pressed. 0b00000000000000000000000000000001 = button #1 is pressed 0b00000000000000000000000000000010 = button #2 is pressed and so on.

E.g. you have 74HC4067 multiplexer. It has pins Y0-Y15 as inputs, pins S0-S3 for selecting input, E pin for enabling input and Z pin for output. Z pin internally connects to Yx pin selected by S0-S03, like a rotary switch. This allows to simplify circuit a bit: you don't need pullup for every button, but only for Z pin.

Y0-Y15 are connected to buttons, pressing button connects pin Yx to GND. E to GND to enable input. Pins S0-S3 and Z - to arduino pins. (PIN_S0, PIN_S1, PIN_S2, PIN_S3 and PIN_Z)

Code can be like that:

//configure pins, once at start
pinMode(PIN_Z, INPUT_PULLUP); 
pinMode(PIN_S0, OUTPUT);
pinMode(PIN_S1, OUTPUT);
pinMode(PIN_S2, OUTPUT);
pinMode(PIN_S3, OUTPUT);

...

buttons = 0; //clear state of all buttons

for(i=0;i<16;i++) //read 16 buttons
{
    //Write channel number to S0-S3
    digitalWrite(PIN_S0, bitRead(i,0));
    digitalWrite(PIN_S1, bitRead(i,1));
    digitalWrite(PIN_S2, bitRead(i,2));
    digitalWrite(PIN_S3, bitRead(i,3));

    //then read Z pin and write it's state to corresponding bit of buttons variable
    bitWrite(buttons, i, !digitalRead(PIN_Z)); //state is inverted, because pressed button reads as 0, unpressed as 1.
}
Zredy commented 10 months ago

Amazing stuff. I managed to implement it in my own way but this way with bitRead and bitWrite is so much sleeker. I have everything working, from HX711 brake(which im probably going to replace), to reading the angle and writing the force effect to an esp32 that's running FOC code for the stepper!

Only thing, I tried Forza Horizon 5, and it reads all the buttons etc but the force feedback doesn't work, so i run Forza Emuwheel to get the feedback working, Have you seen anything similar?

vsulako commented 10 months ago

In my case, Forza Emuwheel did not work with Forza. The only solution I could find was GIMX.