# L01 transportband
# --- Imports ---
from machine import Pin, I2C, PWM
from display import Display
from rotary import Rotary
from steppermotor import StepperMotor
from time import sleep_ms
import settings # importeer settings module voor laden en opslaan van instellingen
# --- Constanten en configuratie ---
MOTORS_HALF_STEP = False # Gebruik half-step voor soepelere beweging (False voor meer koppel)
# --- Configuratie ---
# knoppen pins
button1_pin = 15 # knop 1
button2_pin = 4 # knop 2 (GPIO2 vermijden - heeft interne pull-down)
button3_pin = 16 # knop 3
button4_pin = 17 # knop 4
# rotary encoder pins
rotary_key_pin = 5 # rotary encoder knop
rotary_s1_pin = 18 # rotary encoder clk
rotary_s2_pin = 19 # rotary encoder dt
# ULN2003 driver pins
uln2003_in1_pin = 25 # IN1
uln2003_in2_pin = 26 # IN2
uln2003_in3_pin = 27 # IN3
uln2003_in4_pin = 14 # IN4
# buzzer pin
buzzer_pin = 13 # buzzer pin
# I2C pins voor display
scl_pin = 22
sda_pin = 21
# Stappenmotor parameters
steps_per_rev = 200 # aantal stappen per omwenteling
step_delay = 3 # milliseconden tussen stappen (28BYJ-48 is traag)
# Posities in stappen
position_start = 0 # start positie
position_1 = 1000 # positie 1 1000 stappen
position_2 = 2000 # positie 2 2000 stappen
# Rotary encoder instellingen
rotary_degrees_per_click = 1 # graden per rotary klik
rotary_steps_per_click = 1 # steps per rotary klik
# Calibration flag
calibrated = False # Flag om aan te geven of kalibratie is voltooid
# --- Initialisatie hardware ---
# Knoppen initialiseren
button1 = Pin(button1_pin, Pin.IN, Pin.PULL_UP)
button2 = Pin(button2_pin, Pin.IN, Pin.PULL_UP)
button3 = Pin(button3_pin, Pin.IN, Pin.PULL_UP)
button4 = Pin(button4_pin, Pin.IN, Pin.PULL_UP)
# Rotary initialiseren
rotary = Rotary(rotary_s1_pin, rotary_s2_pin, rotary_key_pin)
# Stappenmotor initialiseren (half_step=True voor soepel, False voor meer koppel)
motor = StepperMotor(
uln2003_in1_pin,
uln2003_in2_pin,
uln2003_in3_pin,
uln2003_in4_pin,
half_step=MOTORS_HALF_STEP,
step_delay=step_delay
)
# Buzzer initialiseren
buzzer = PWM(Pin(buzzer_pin), freq=1000, duty=0) # buzzer uit
# Display initialiseren (framerate=10: max 10 updates per seconde)
display = Display(scl_pin, sda_pin, framerate=10)
# --- Functies ---
def beep(duration_ms=100, freq=1000):
"""Laat de buzzer piepen voor een bepaalde duur."""
buzzer.freq(freq)
buzzer.duty(512) # 50% duty cycle
sleep_ms(duration_ms)
buzzer.duty(0) # buzzer uit
def calibrate():
"""Kalibreer de transportband door naar de startpositie te gaan."""
global calibrated
display.message("Kalibreren...")
# Beweeg CCW totdat knop 1 wordt ingedrukt (of al ingedrukt is)
max_steps = 3000 # veiligheidsgrens
steps_taken = 0
while button1.value() == 1 and steps_taken < max_steps:
motor._do_step(-1) # CCW richting
sleep_ms(step_delay)
steps_taken += 1
motor.off()
# Check of startpositie bereikt is
calibrated = button1.value() == 0
if calibrated:
print("btn1")
motor.reset_position()
display.message("Gekalibreerd!")
beep(200, 1500)
else:
print("timeout")
display.message("FOUT: geen start positie")
beep(500, 500)
def update_display():
"""Update het display met de huidige status."""
display.message(f"Current position\nSteps: {motor.position}\nDegrees: {motor.degrees:.1f}°")
# --- Hoofdprogramma ---
def main():
# Laad instellingen
settings_data = settings.load_settings()
global position_start, position_1, position_2
position_start = settings_data["position_start"]
position_1 = settings_data["position_1"]
position_2 = settings_data["position_2"]
"""Hoofdprogramma loop."""
display.message("Transportband")
sleep_ms(1000)
# Kalibratie bij opstarten
calibrate()
sleep_ms(500)
update_display()
# Hoofdloop
while True:
# 1. Input verwerken
# Rotary encoder: draai motor in dezelfde richting
if rotary.rotary_turned:
print("rotary")
steps = rotary_steps_per_click * rotary.rotary_direction
motor.set_target_relative(steps)
rotary.rotary_turned = False
# Knop 2: ga naar startpositie
if button2.value() == 0:
print("btn2")
beep(50)
motor.set_target(position_start)
sleep_ms(200) # debounce
# Knop 3: ga naar positie 1 (1000 stappen)
if button3.value() == 0:
print("btn3")
beep(50)
motor.set_target(position_1)
sleep_ms(200) # debounce
# Knop 4: ga naar positie 2 (2000 stappen)
if button4.value() == 0:
print("btn4")
beep(50)
motor.set_target(position_2)
sleep_ms(200) # debounce
# 2. Motor update: voer één stap uit richting doelpositie
stepped = motor.update()
# 3. Status update
# Beep en display wanneer motor doelpositie bereikt
if stepped and not motor.is_moving:
beep(50)
display.message(f"Current position\nSteps: {motor.position}\nDegrees: {motor.degrees:.1f}°", force=True)
# Display update (framerate beperkt)
if motor.is_moving:
display.message(f"-> {motor.target_position}\nPos: {motor.position}")
# Start het programma
if __name__ == "__main__":
main()
pos1
pos0
pos2
begin
spoel1
spoel2
spoel3
spoel4