todbot / circuitpython-tricks

Some CircuitPython tricks, mostly reminders to myself
MIT License
577 stars 65 forks source link

Any tips on simplifying reading a DIP switch? #8

Closed TheExpertNoob closed 1 year ago

TheExpertNoob commented 1 year ago

What I currently have and, to me, is ugly, but works. I would like to eventually read an array of pins as a byte (up from this sudo nibble) and append the value to the "payload{dec}.dd" then return it.

def selectPayload():
    payload = "payload.dd"
    # check switch status
    # rotary1 = GPIO2 to GND
    # rotary2 = GPIO3 to GND
    # rotary4 = GPIO4 to GND
    # rotary8 = GPIO5 to GND
    rotary1Pin = digitalio.DigitalInOut(GP2)
    rotary1Pin.switch_to_input(pull=digitalio.Pull.UP)
    rotary1State = not rotary1Pin.value
    rotary2Pin = digitalio.DigitalInOut(GP3)
    rotary2Pin.switch_to_input(pull=digitalio.Pull.UP)
    rotary2State = not rotary2Pin.value
    rotary4Pin = digitalio.DigitalInOut(GP4)
    rotary4Pin.switch_to_input(pull=digitalio.Pull.UP)
    rotary4State = not rotary4Pin.value
    rotary8Pin = digitalio.DigitalInOut(GP5)
    rotary8Pin.switch_to_input(pull=digitalio.Pull.UP)
    rotary8State = not rotary8Pin.value

    if rotary1State == True and rotary2State == False and rotary4State == False and rotary8State == False:
        payload = "payload1.dd"

    elif rotary1State == False and rotary2State == True and rotary4State == False and rotary8State == False:
        payload = "payload2.dd"

    elif rotary1State == True and rotary2State == True and rotary4State == False and rotary8State == False:
        payload = "payload3.dd"

    elif rotary1State == False and rotary2State == False and rotary4State == True and rotary8State == False:
        payload = "payload4.dd"

    elif rotary1State == True and rotary2State == False and rotary4State == True and rotary8State == False:
        payload = "payload5.dd"

    elif rotary1State == False and rotary2State == True and rotary4State == True and rotary8State == False:
        payload = "payload6.dd"

    elif rotary1State == True and rotary2State == True and rotary4State == True and rotary8State == False:
        payload = "payload7.dd"

    elif rotary1State == False and rotary2State == False and rotary4State == False and rotary8State == True:
        payload = "payload8.dd"

    elif rotary1State == True and rotary2State == False and rotary4State == False and rotary8State == True:
        payload = "payload9.dd"

    elif rotary1State == False and rotary2State == True and rotary4State == False and rotary8State == True:
        payload = "payload10.dd"

    elif rotary1State == True and rotary2State == True and rotary4State == False and rotary8State == True:
        payload = "payload11.dd"

    elif rotary1State == False and rotary2State == False and rotary4State == True and rotary8State == True:
        payload = "payload12.dd"

    elif rotary1State == True and rotary2State == False and rotary4State == True and rotary8State == True:
        payload = "payload13.dd"

    elif rotary1State == False and rotary2State == True and rotary4State == True and rotary8State == True:
        payload = "payload14.dd"

    elif rotary1State == True and rotary2State == True and rotary4State == True and rotary8State == True:
        payload = "payload15.dd"

    else:
        # if all pins are high, then no switch is present
        # default to payload
        payload = "payload.dd"

    return payload
todbot commented 1 year ago

Hi! Why do you calling them rotary but the title is about a DIP switch?

TheExpertNoob commented 1 year ago

Using a Rotary Dip Switch

todbot commented 1 year ago

Ahh! I haven't seen those in a while. But I have one and tried out a couple of techniques. This may be the simplest:

import time
import board
import digitalio

dip_pins = (board.GP10, board.GP11, board.GP12, board.GP13)

dip = []  # make the pin objects, stick them in 'dip'
for p in dip_pins:
    d = digitalio.DigitalInOut(p)
    d.switch_to_input(digitalio.Pull.UP)
    dip.append(d)

def get_dip_val(dip):
    val = 0  # our return value
    for i in range(len(dip)):
        if dip[i].value == False:
            val |= (1 << i)  # set the bit in val if that dip switch is set
    return val

while True:
    val = get_dip_val(dip)
    print("dip val: %X" % val)
    time.sleep(0.1)
todbot commented 1 year ago

And if you want to turn the number val into your payloadN.dd, then you can do:

val = get_dip_val(dip)
payload = "payload%d" % val
TheExpertNoob commented 1 year ago

AH! I was missing something when I tried something similar...

if dip[i].value == False:

..and syntax in various places. Ultimately, this got it working for me! thanks!

def selectPayload():
    # Special thanks to todbot on simplifying this code for me! https://github.com/todbot/circuitpython-tricks/issues/8
    # check switch status
    # rotary pin1 = GPIO2
    # rotary pin2 = GPIO3
    # rotary pin4 = GPIO4
    # rotary pin8 = GPIO5
    payload = "payload.dd"
    dip_pins = (GP2, GP3, GP4, GP5)

    dip = []  # make the pin objects, stick them in 'dip'
    for p in dip_pins:
        d = digitalio.DigitalInOut(p)
        d.switch_to_input(digitalio.Pull.UP)
        dip.append(d)

    def get_dip_val(dip):
        val = 0  # our return value
        for i in range(len(dip)):
            if dip[i].value == False:
                val |= (1 << i)  # set the bit in val if that dip switch is set
        return val

    val = get_dip_val(dip)
    payload = "payload%d.dd" % val

    return payload