Before the loop, the NeoSliders, rotary encoder, and VL53L4CD are setup.

#  VL53L4CD setup
vl53 = adafruit_vl53l4cd.VL53L4CD(board.I2C())

# rotary encoder setup
encoder = seesaw.Seesaw(board.I2C(), addr=0x36)
encoder.pin_mode(24, encoder.INPUT_PULLUP)
rot_encoder = rotaryio.IncrementalEncoder(encoder)

#  neoslider setup - analog slide pot and neopixel
# 0x30 = red control
# 0x31 = green control
# 0x32 = blue control
red_slider = seesaw.Seesaw(board.I2C(), 0x30)
red_pot = AnalogInput(red_slider, 18)
r_pix = neopixel.NeoPixel(red_slider, 14, 4)

g_slider = seesaw.Seesaw(board.I2C(), 0x31)
green_pot = AnalogInput(g_slider, 18)
g_pix = neopixel.NeoPixel(g_slider, 14, 4)

b_slider = seesaw.Seesaw(board.I2C(), 0x32)
blue_pot = AnalogInput(b_slider, 18)
b_pix = neopixel.NeoPixel(b_slider, 14, 4)

#  rotary encoder position tracker
last_position = 0

#  neoslider position trackers
last_r = 0
last_g = 0
last_b = 0

#  VL53L4CD value tracker
last_flight = 0

#  rotary encoder index
x = 0

#  VL53L4CD start-up
vl53.inter_measurement = 0
vl53.timing_budget = 200

vl53.start_ranging()

Socket Setup

This is followed by the setup for the socket. The socket allows communication between the Python code and the Processing code. 

First, s is setup as the socket object. Then, a port is created called 12345. It can be any number, since this is a virtual port that only exists to link the Python and Processing scripts.

The socket begins listening on port 12345 using s.listen(1). While the socket is listening, the Processing code will be able to connect to the Python code.

Once a connection is established on the port, got connected is printed to the REPL. Then, you'll see the Processing animations begin to run full screen on the Raspberry Pi. The Python script also begins running the loop.

#  HTTP socket setup
s = socket.socket()
print("socket check")

port = 12345

s.bind(('', port))
print("socket binded to %s" %(port))

s.listen(1)
print("listening")

time.sleep(10)

c, addr = s.accept()
print('got connected', addr)

The Loop

position and flight are setup to hold the incoming values from the rotary encoder and the VL53L4CD.

The NeoSliders have a default value range of 0 to 1023. The map_range() function is used to change their range to 0 to 255. This allows them to send RGB values directly to the Processing sketch since they will be affecting the background color of each animation.

#  reset the VL53L4CD
    vl53.clear_interrupt()

	#  rotary encoder position read
    position = -rot_encoder.position

    #  VL53L4CD distance read
    flight = vl53.distance

    #  mapping neosliders to use 0-255 range for RGB values in Processing
    r_mapped = simpleio.map_range(red_pot.value, 0, 1023, 0, 255)
    g_mapped = simpleio.map_range(green_pot.value, 0, 1023, 0, 255)
    b_mapped = simpleio.map_range(blue_pot.value, 0, 1023, 0, 255)

    #  converting neoslider data to integers
    r_pot = int(r_mapped)
    g_pot = int(g_mapped)
    b_pot = int(b_mapped)

Update the NeoSlider NeoPixels

The NeoSliders' NeoPixels are set to match the background color of the Processing animations.

#  set neopixels on neosliders to match background color of Processing animations
    r_pix.fill((r_pot, g_pot, b_pot))
    g_pix.fill((r_pot, g_pot, b_pot))
    b_pix.fill((r_pot, g_pot, b_pot))

Reading the Rotary Encoder

The rotary encoder controls which animation is active in the Processing script. c.send() sends the rotary encoder's position over the socket to Processing.

The data is encoded as a string with str.encode(). enc is sent at the first part of the string so that Processing can identify that it is receiving data from the rotary encoder. You can think of it as sending a variable name. x holds the encoder's position and is sent as the second part of the encoded string.

#  rotary encoder position check
    if position != last_position:
        #  rotary encoder is ranged to 0-3
        if position > last_position:
            x = (x + 1) % 4
        if position < last_position:
            x = (x - 1) % 4
        #  send rotary encoder value over socket
        #  identifying string is "enc"
        c.send(str.encode(' '.join(["enc", str(x)])))
        #  reset last_position
        last_position = position

Reading the NeoSliders

Each slider is setup to compare the current value to the previous value. When that value changes above a certain threshold, the new value is sent over the socket.

Similar to the rotary encoder, each NeoSlider has an identifying string label that acts as a variable in Processing.

#  sliders only update data for changes >15 to avoid flooding socket
    #  red neoslider position check
    if abs(r_pot - last_r) > 15:
        #  send red neoslider data over socket
        #  identifying string is "red"
        c.send(str.encode(' '.join(["red", str(r_pot)])))
        #  reset last_r
        last_r = r_pot

Reading the VL53L4CD

The flight and last_flight are setup to compare the current value to the previous value of the VL53L4CD. When that value changes above a certain threshold, the new value, flight, is sent over the socket.

A maximum value of 45 is setup so that the range of expected data from the VL53L4CD can be setup in the Processing script. Just like the other hardware interfaces, the VL53L4CD has an identifying string label, flight, that acts as a variable in Processing when its data is sent over the socket.

#  VL53L4CD value check
    if abs(flight - last_flight) > 2:
        #  setting max value of 45
        if flight > 45:
            flight = 45
        #  send VL53L4CD data over socket
        #  identifying string is "flight"
        c.send(str.encode(' '.join(["flight", str(flight)])))
        #  reset last_flight
        last_flight = flight

This guide was first published on Mar 29, 2022. It was last updated on Mar 29, 2022.

This page (How the CircuitPython Code Works) was last updated on Mar 24, 2022.

Text editor powered by tinymce.