qmk / qmk_firmware

Open-source keyboard firmware for Atmel AVR and Arm USB families
https://qmk.fm
GNU General Public License v2.0
18.12k stars 38.96k forks source link

Is QMK compatible with optical encoders? #6856

Closed HMarxen closed 2 years ago

HMarxen commented 5 years ago

The documentation says to connect the common pin of an encoder to ground but all optical encoders that I’ve found seem to connect their optical transistors to VCC. https://static6.arrow.com/aropdfconversion/b37bee95f5eae7e7f00cc37d7f45757e265dbb6b/50924574275363em14.pdf Would that still be compatible without messing with extra transistors? Do I need to change the Firmware? In Arduino I’d know that I just had to change HIGH to LOW somewhere but the syntax of proper C has me a bit confused. Also, I can't really test this. Since this is a quite pricy component, I wanted to ask before buying.

drashna commented 5 years ago

Well, we have support for rotary encoders: https://docs.qmk.fm/#/feature_encoders

A quick look and this may work the same?

Do you have a sample for arduino code?

HMarxen commented 5 years ago

Thank you for the reply. Yes, I know QMK supports encoders and I’ve looked at the code. But my point is that optical encoders work a bit differently than normal drag contact encoders. It uses an LED, two photo transistors and an interrupter wheel to generate the signal. With normal encoders you can connect the common pin of A and B to whatever you want but an optical encoder seems to behave as if the common pin is connected to VCC. And there is nothing I can change about it since everything is in a dust proof package. The benefit of optical encoders is that they don’t feel so scratchy and have a far, far longer lifespan because there is no friction on the conductive parts. Right now QMK seems to use the MCU's internal pullup on A and B, so If it were written in Arduino I would be looking for something like: pinMode(2, INPUT_PULLUP); and change that to normal “INPUT”.

HMarxen commented 5 years ago

Sorry, on a second reading I think you understood what I meant. ^^ I think I am slowly getting my head around this. I don’t think it would work the same. The optical encoder sends out either a small voltage (up to 0.8V) or around 4V on it's A and B pins as it rotates. So, If I understand it correctly, the internal pullup connects to VCC, the encoder does too and the Firmware waits for the pin to go Low. So, nothing would ever happen. I think I need to add two pulldowns on my end and change the Firmware so that it waits for the pin to go High.

Would perhaps changing:

setPinInputHigh(encoders_pad_a[i]);
setPinInputHigh(encoders_pad_b[i]);

To:

setPinInputLow(encoders_pad_a[i]);
setPinInputLow(encoders_pad_b[i]);

On line 68/69 in encoder.c be enough?

yanfali commented 5 years ago

You probably wouldn't change the values, you would just add a define around the existing behavior so that when you set ENABLE_OPTICAL_ENCODERS in your config.h it would use that code instead of the default. You'll have to test it out of course first with actual hardware before we would accept it.

HMarxen commented 5 years ago

I will but I am far away from it yet.^^ So, would what I'm describing above theoretically work?

drashna commented 5 years ago

If yan is right about that, then yeah, it should. You'd just need to change the code in /quantum/encoders.c and test it out.

Daveyr commented 3 years ago

Did you get anywhere with this? I'm having trouble with a rotary encoder that I think is an EC11 but I'm not sure. I followed the thread above to modify the encoder.c file but it is still unresponsive. I've also laid the whole thing out on a breadboard, swapped A and B lines, and changed the encoder resolution but nothing seems to work.

zvecr commented 2 years ago

This issue has been automatically closed because it has not had any recent activity. If this issue is still valid, re-open the issue and let us know.