Let's put these two things together - drawing pixels + reading pots, to create our knob sketcher toy. We'll start with a minimalistic version called the Tiny Sketcher.
In addition to the ItsyBitsy M4, the Tiny Sketcher uses these parts.



The breadboard setup is shown below. The display has been rotated, but is otherwise wired the same as before. A second pot has been added, but they are both being used in the same way - as variable voltage dividers. The outputs are sent to different analog inputs.
And here is the CircuitPython code to create the sketcher.
import board, busio import adafruit_ssd1306 from simpleio import map_range from analogio import AnalogIn from digitalio import DigitalInOut # Create the I2C bus i2c = busio.I2C(board.SCL, board.SDA) # Define display dimensions and I2C address WIDTH = 128 HEIGHT = 64 ADDR = 0x3d # Create the digital out used for display reset rst = DigitalInOut(board.D7) # Create the display display = adafruit_ssd1306.SSD1306_I2C(WIDTH, HEIGHT, i2c, addr=ADDR, reset=rst) display.fill(0) display.show() # Create the knobs x_knob = AnalogIn(board.A0) y_knob = AnalogIn(board.A1) while True: x = map_range(x_knob.value, 0, 65535, WIDTH - 1, 0) y = map_range(y_knob.value, 0, 65535, 0, HEIGHT - 1) display.pixel(int(x), int(y), 1) display.show()
Most of this code is just setup. All the work to create the sketcher is done in the last 5 lines.
while True: x = map_range(x_knob.value, 0, 65535, WIDTH - 1, 0) y = map_range(y_knob.value, 0, 65535, 0, HEIGHT - 1) display.pixel(int(x), int(y), 1) display.show()
We read each of the knob values using the value
property. To turn those values into a pixel location, we use the very handy function map_range
. This function is so handy, it's a wonder why it wasn't built into the Python core. Instead, it is provided by the simpleio library - more info here. It basically converts one range of values into another range of values. In this case, from the range of analog read values, 0 to 65535, to the range of pixel locations, 0 to WIDTH or HEIGHT. (the - 1 is because of 0 indexing)
Note that the directionality of the knobs can be changed by swapping the order of the last two parameters. If you don't like the direction the pixel moves when you turn the knob, just swap these two and it will reverse it.
Once we have converted the knob values to pixel location, we draw the pixel. The int()
is needed since map_range
returns a float and pixel()
expects integers for the pixel location.
And then we just do that over and over again...forever!
Run the code and turn the knobs. It should be obvious how it works. Sketch away!
Page last edited March 08, 2024
Text editor powered by tinymce.