from machine import Pin, PWM, ADC
from time import sleep
# Constants
B_REF = 0.5 # Target brightness
MAX_ADC = 4095 # 12-bit ADC max value
SERVO_MIN = 0 # 0° PWM duty
SERVO_MAX = 180 # 180° PWM duty
Kp, Ki, Kd = 30, 5, 10 # PID gains
DT = 1.0 # Time step
# Hardware setup
ldr = ADC(Pin(4)) # LDR sensor
ldr.atten(ADC.ATTN_11DB) # Full voltage input
servo = PWM(Pin(41)) # Servo motor
servo.freq(50) # Servo PWM frequency
# Control variables
integral = 0
last_error = 0
# Helper functions
def brightness():
return 1.0 - (ldr.read() / MAX_ADC) # Inverted brightness
def clamp(u):
return max(SERVO_MIN, min(SERVO_MAX, int(u))) # Keep angle in 0–180
# Logging header
print("t\tb(t)\te(t)\tu(t)")
# Simulation loop: 0 to 50 seconds
for t in range(51):
b = brightness()
error = b - B_REF
integral += error * DT
derivative = (error - last_error) / DT
# PID control
u = clamp(Kp * error + Ki * integral + Kd * derivative + 90)
servo.duty(u) # direct duty set, same as your original logic
print(f"{t}\t{b:.3f}\t{error:.3f}\t{u}")
last_error = error
sleep(1)