from machine import Pin, ADC, PWM
from time import ticks_us, ticks_diff, sleep
# =====================================================
# TASK C - Raspberry Pi Pico + Encoder + Potentiometer
# =====================================================
# -----------------------------------------------------
# MOTOR DRIVER (L293D or similar)
# -----------------------------------------------------
pinM1 = Pin(10, Pin.OUT) # IN1
pinM2 = Pin(11, Pin.OUT) # IN2
pinPWM = PWM(Pin(12)) # ENABLE / PWM
pinPWM.freq(1000)
# -----------------------------------------------------
# ENCODER
# -----------------------------------------------------
# WOKWI ROTARY ENCODER
pinENA = Pin(14, Pin.IN, Pin.PULL_UP) # CLK
pinENB = Pin(15, Pin.IN, Pin.PULL_UP) # DT
# -----------------------------------------------------
# WHEN USING THE REAL LAB ENCODER:
# Uncomment and connect the REAL encoder pins here
# -----------------------------------------------------
# pinENA = Pin(14, Pin.IN, Pin.PULL_UP) # Encoder Channel A
# pinENB = Pin(15, Pin.IN, Pin.PULL_UP) # Encoder Channel B
# -----------------------------------------------------
# POTENTIOMETER
# -----------------------------------------------------
pot = ADC(Pin(26))
# -----------------------------------------------------
# ENCODER VARIABLES
# -----------------------------------------------------
PPR = 12 # Pulses per revolution
dA = 360 / PPR
t0 = ticks_us()
RPMs = 0
# -----------------------------------------------------
# ENCODER INTERRUPT FUNCTION
# -----------------------------------------------------
def measureENC(pin):
global t0, RPMs
t1 = ticks_us()
dt = ticks_diff(t1, t0)
t0 = t1
if dt <= 0:
return
# ---------------------------------------------
# Direction detection
# ---------------------------------------------
if pinENB.value() == 1:
direction = -1
else:
direction = 1
# ---------------------------------------------
# RPM CALCULATION
# ---------------------------------------------
RPMs = direction * (60_000_000 / (PPR * dt))
# -----------------------------------------------------
# INTERRUPT
# -----------------------------------------------------
pinENA.irq(trigger=Pin.IRQ_RISING, handler=measureENC)
# -----------------------------------------------------
# MAIN LOOP
# -----------------------------------------------------
while True:
# ---------------------------------------------
# READ POTENTIOMETER
# ---------------------------------------------
potValue = pot.read_u16() # 0 → 65535
# ---------------------------------------------
# PWM VALUE
# ---------------------------------------------
pwmValue = potValue
# ---------------------------------------------
# MOTOR DIRECTION
# ---------------------------------------------
pinM1.high()
pinM2.low()
# ---------------------------------------------
# FOR REVERSE DIRECTION IN LAB:
# Uncomment these lines
# ---------------------------------------------
# pinM1.low()
# pinM2.high()
# ---------------------------------------------
# MOTOR SPEED CONTROL
# ---------------------------------------------
pinPWM.duty_u16(pwmValue)
# ---------------------------------------------
# FOR REAL LAB MOTOR:
# Uncomment if minimum PWM is needed
# (some motors don't move at low PWM)
# ---------------------------------------------
# if pwmValue < 12000:
# pwmValue = 12000
# pinPWM.duty_u16(pwmValue)
# ---------------------------------------------
# SERIAL MONITOR / SERIAL PLOTTER
# ---------------------------------------------
print(-150, 150, RPMs)
# ---------------------------------------------
# FOR LAB DEBUGGING:
# Uncomment these lines
# ---------------------------------------------
# print("Potentiometer:", potValue)
# print("PWM:", pwmValue)
# print("RPM:", RPMs)
sleep(0.02)