I'm trying to connect a Joystick/Encoder/Button (Copal Electronics CJ25) to a Raspberry PI. Using gpiotest I managed to get it up and running pretty well - using 3.3V input (though the data sheet mentions 5V).

The problem is, that each of the joystick's axes has 3 levels of voltage as output. 0x, 0.5x and 1x input voltage. So with 3.3V input there's 0V, ~1.7V, 3.3V.

Is there a way to simply step up/down voltage (resistors?), so that by using two different GPIOs I can detect all three states with those digital I/Os ?

  • 1
    Ah, the joystick's tristate logic of 0V, 1.7V, 3.3V is interesting. I immediately think of using an ADC, eg MCP3208 to convert to 2 bit values, 00, 01, 10. Of course for Arduino with ADC pins, we don't need any external ADC. For Rpi, Low level max is about 0.8V, so 1.7V and 3.3V are above 0.8V will be read as High. Your two different pins way looks good. So if we step down the input to 1/3, then one pin can tell 0V and 1.7V/3 = 0.6V as low. The other pin can tell the non stepped down 1.7V and 3.3V as high. In other words, if one pin says high, the other pin says low. Then it middle. – tlfong01 Jun 21 '19 at 9:11
  • Thanks! l'd really like to avoid any additional ADC, but by using two GPIOs I'ld need to know what resistor values to use, and that depends not only on voltage but on current, right? As I understand the max overall current is 50mA for all GPIOs. Maybe someone had a hint on how to safely connect that single input to two GPIOs stepping down the voltage by resistors on the 2nd GPIO? Thanks in advance!! – ftw Jun 21 '19 at 9:45
  • The Pi is pretty irrelevant to this question. – joan Jun 21 '19 at 12:34
  • 1
    I agree two GPIO pins is better than an external ADC. I said I immediately thought about ADC because I have been using ADC too often. I must admire your two input pins to differentiate 3 logic level is innovative and I have never thought of that. Coming back to the voltage divider using resistors, a very simple rule of thumb is to limit GPIO current to 2mA. So take 3V3 as maximum, a safe total resistor value is 3V3/ 2mA ~= 3k/2 ~= 1.5k. To add a little bit safe margin, I would use total resistance ~= 4k7 to 10K. My calculation is dodgy, not proofread. :) – tlfong01 Jun 21 '19 at 12:38
  • @ftw, I read about tri state logic but never seen a real device using tri state logic. So I was curious to read the datasheet to see the spec. But I was surprised not to find and logic table showing three states as you said 0x, 0.5x and 1x. Can you confirm if you are really using CJ25, and let me know which logic table shows three states. As I can see the "A" and "B" outputs are only two states. – tlfong01 Jun 21 '19 at 14:38

Attach level shifters with different thresholds on two GPIO pins to distinguish more than two states:


simulate this circuit – Schematic created using CircuitLab

Q1 will output 3.3V only when the input is below 0.6..0.8V, otherwise it will output 0.3V or less

Q2 will output output 0V only when the input is above 2.5..2.7V, otherwise it will output 3.3V.

| improve this answer | |
  • 1
    This works perfectly, thanks a lot! – ftw Jul 10 '19 at 19:34

You MAY be able to use the Pi logic levels to detect this, but it would be unreliable. (The trigger point is ~1.3V, but varies from Pi to Pi.)

The only thing you can rely on in <0.8V => LOW; >2.0V => HIGH.

See Electrical Specifications of GPIO and https://www.raspberrypi.org/documentation/hardware/raspberrypi/gpio/README.md

An ADC would be overkill, all you need are voltage comparators - these are cheap, and available in multi comparator packages e.g. LM339 or LM393. See https://en.wikipedia.org/wiki/Comparator

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.