I'm teaching a hands on Raspberry Pi Pico class at my local library using Thonny Python.
The class is mostly doing small hands on projects, explain the wiring, explain the code, expound on any principles that are part of the lesson, let the students type in the code and watch it run.
The next class topic is reading analog inputs and doing something physical with it.
- In code pasted below ReadPot_GP26_DimLED_GP2.py The analog input's u16 value is read and directly used for writing a PWM u16 duty cycle value, and works fine.
- I got really lucky with servo PWM code, the duty cycles are so small, 5% to 10%, the python interpreter doesnt issue with the duty values.
- Creating some control examples using a photoresistor, those programs work well, until I try to write a value as a u16. See program DuskToDawnLEDwDimmer.py.
The DuskToDawnLEDwDimmer.py. program has a parameter to turn on a LED at a certain level of light on the photoresistor. At that turn on point, the task is to have an LED at its full brightess (PWM duty = 100%) and the LED is to dim itself as the ambient light lessens (gets dark) . I tried everything I could think of to get the LED's dimmer duty cycle = 65535 and have it infinitely adjustable down to 0. I could not create any variable that was u16 and satisfy Python compilation. My brute force solution was to check for photoresistor level intensity points based on volts, and write a constant value to duty cycle.
Has anyone else had issues writing u16 values ? Any suggestions on approaching the coding differently ?
ReadPot_GP26_DimLED_GP2.py
This is an example that works w
from machine import Pin, ADC, PWM
import utime
PWM1A=PWM(Pin(2)) # GP2 pin 4
PWM1A.freq(1000)
PotWiperCounts=ADC(Pin(26)) # can also call machine.ADC(3)
#GP2OFFSET=288 # The PotWiperCounts when the pot is full CCW
#GP2GAIN=1.004 # GP2 read 65535 at full cw, however once 288 counts are
# subtracted from it, it needs multiplied by the ratio to make it back to 65535 full scale
while True:
print(PotWiperCounts.read_u16())
# PotWiperCountsReal=PotWiperCounts*1.0
# PotWiperCountsReal=(PotWiperCountsReal-(GP2OFFSET))
# yes, in code you can read a value, do math, and put the value back to the same name
# PotWiperCountsReal=1.004*PotWiperCounts
duty=PotWiperCounts.read_u16()
PWM1A.duty_u16(duty)
utime.sleep(.05)
# print("Adjusted GP2 value is:", PotWiperCountsReal)
# MAKE a NOTE what the PotWiperCounts are at full CW - full up________
# MAKE a NOTE what the PotWiperCounts are at full CCW - full down________
# The value at full CCW should be zero. The value it really shows is called OFFSET !!
# The next program you will build will have parameters to correct the OFFSET and then also adjust the gain error - The value at full CW !
DuskToDawnLEDwDimmer.py
from machine import Pin, ADC, PWM
import utime
#import constant # wierd
PotWiperCounts=ADC(Pin(26))
LDR_Counts=ADC(Pin(27))
u16_to_volts = 3.3/(65535)
#volts_2_U16 = (65535)/3.3
# DuskToDawnLED= Pin(25, machine.Pin.OUT)#GP25 is the Pico mounted LED
# DuskToDawnLED.value(0)
DuskToDawnLED= PWM(Pin(2))# physical pin 4
DuskToDawnLED.freq(100)
LightOnAdjust=1.5 ## in volts at GPIO
# volts_to_U16 = (65535)/LightOnAdjust
volts_to_U16 = (65535)/LightOnAdjust
while True:
#print(PotWiperCounts.read_u16())
#print(LDR_Counts.read_u16())
LDR_Volts=(LDR_Counts.read_u16())*u16_to_volts
print(LDR_Volts)
if ((LDR_Volts) < (LightOnAdjust)): ## floating point value of volts
DimmerDutyCounts=65535
if ((LDR_Volts) < ((LightOnAdjust)*.8)): ## floating point value of volts
DimmerDutyCounts=52400
if ((LDR_Volts) < ((LightOnAdjust)*.6)): ## floating point value of volts
DimmerDutyCounts=39000
if ((LDR_Volts) < ((LightOnAdjust)*.4)): ## floating point value of volts
DimmerDutyCounts=26200
if ((LDR_Volts) < ((LightOnAdjust)*.2)): ## floating point value of volts
DimmerDutyCounts=13000
if ((LDR_Volts) > ((LightOnAdjust))): ## floating point value of volts
DimmerDutyCounts=0
DuskToDawnLED.duty_u16(DimmerDutyCounts)
utime.sleep(2)