Andreas Motzek
Published © CC BY

Complex behaving Hardware with CircuitPython - Part III

Some projects need more than loops and sleeps. See how to use the cooperative_multitasking library with this four part guide.

IntermediateProtip1 hour57
Complex behaving Hardware with CircuitPython - Part III

Things used in this project

Hardware components

Circuit Playground Express
Adafruit Circuit Playground Express
×1
Dual H-Bridge motor drivers L298
SparkFun Dual H-Bridge motor drivers L298
×1
LDR, 1 Mohm
LDR, 1 Mohm
×2
Resistor 10k ohm
Resistor 10k ohm
×2
Sunfounder Analog Hall Sensor Module
×1
Fischertechnik 554195 Creative Box Basic
×1
Fischertechnik 505281 Motor Set XS
×1
Fischertechnik 108278 Magnet
×1

Story

Read more

Schematics

Schematics

See how to connect the components. D1-D4, R3, R4 and the LM393 are part of the motor driver and hall sensor boards.

Code

Example 3: Cart that goes back and forth

Python
Copy the code to code.py in the CircuitPython root directory. Don't forget to put the mpy-file to the lib folder.
from cooperative_multitasking import Tasks
import board
from analogio import AnalogIn
from digitalio import DigitalInOut, Direction
from neopixel import NeoPixel

motor_enable = DigitalInOut(board.A1)
motor_enable.direction = Direction.OUTPUT
motor_enable.value = False
motor_in1 = DigitalInOut(board.A2)
motor_in1.direction = Direction.OUTPUT
motor_in2 = DigitalInOut(board.A3)
motor_in2.direction = Direction.OUTPUT
ldr_right = AnalogIn(board.A4)
ldr_left = AnalogIn(board.A5)
hall_left = DigitalInOut(board.A6)
hall_left.direction = Direction.INPUT
black = (0, 0, 0)
colors = [black, (32, 0, 0), (32, 19, 0), (0, 32, 0), (0, 0, 32)]
pixels = NeoPixel(board.NEOPIXEL, 10, brightness=0.3, auto_write=False)
pixels.fill(black)
pixels.show()
count = 0

def stop():
    motor_enable.value = False
    motor_in1.value = False
    motor_in2.value = False

def drive_right():
    motor_in1.value = False
    motor_in2.value = True
    motor_enable.value = True

def drive_left():
    motor_in1.value = True
    motor_in2.value = False
    motor_enable.value = True

def is_dark():
    return ldr_right.value > 35000 and ldr_left.value > 35000

def is_light():
    return ldr_right.value < 25000 and ldr_left.value < 25000

def is_right():
    return ldr_right.value > 35000

def is_left():
    return (ldr_left.value > 35000 and ldr_right.value < 25000) or not hall_left.value

def is_between():
    return not (is_left() or is_right())

tasks = Tasks()

def at_right_end_position():
    stop()
    increase_and_show_count()
    tasks.after(300000, drive_to_left_end_position)

def drive_to_left_end_position():
    drive_left()
    tasks.only_one_of(tasks.if_then(is_left, at_left_end_position),
                      tasks.after(15000, fault))

def at_left_end_position():
    stop()
    increase_and_show_count()
    tasks.only_one_of(tasks.if_then(is_dark, drive_to_waiting_position),
                      tasks.after(300000, drive_to_right_end_position))

def drive_to_right_end_position():
    drive_right()
    tasks.only_one_of(tasks.if_then(is_right, at_right_end_position),
                      tasks.after(15000, fault))

def drive_to_waiting_position():
    drive_right()
    tasks.after(2000, at_waiting_position)

def at_waiting_position():
    stop()
    tasks.if_for_then(is_light, 60000, drive_to_left_end_position)

def fault():
    stop()

def increase_and_show_count():
    global count
    count += 1
    value = count
    for index in range(0, 10):
        pixels[index] = colors[value % 5]
        value //= 5
    pixels.show()
    tasks.after(20000, hide_count)

def hide_count():
    pixels.fill(black)
    pixels.show()

def init():
    if is_dark():
        at_waiting_position()
    elif is_right() or is_between():
        drive_to_left_end_position()
    else:
        drive_to_right_end_position()

tasks.now(init)

while tasks.available():
    tasks.run()

Credits

Andreas Motzek
20 projects • 9 followers
I like algorithms, code, statistics and decisions based on them, solving difficult problems and, if possible, avoiding them elegantly.

Comments