How to control a 12V PC fan using Pulse Width Modulation (PWM) signals with the Raspberry Pi Pico W board and an L298N motor driver module. I will use the MicroPython programming language and the Thonny IDE to write and run the code.
Raspberry Pi Pico W | L298n Module |
---|---|
GP9 | IN1 |
GND | GND |
VSYS (Connect this only when you save as “main.py” in raspberry pi.) | +5V |
12V PC FAN | L298n Module |
---|---|
Positive Lead(+12V wire) | OUT1 |
Negative Lead | OUT2 |
Micropython Code
import network
import socket
import time
from time import sleep
from picozero import pico_temp_sensor, pico_led
import machine
ssid = 'Abhay'
password = 'AK26@#36'
wdt = machine.WDT(timeout=5000) # Timeout in milliseconds (e.g., 5000ms = 5 seconds)
def feed_watchdog(timer):
wdt.feed() # Feed the watchdog timer to reset the countdown
timerWdt = machine.Timer()
timerWdt.init(period=1000, mode=machine.Timer.PERIODIC, callback=feed_watchdog)
GPIO_PIN_9 = machine.Pin(9)
pwm9 = machine.PWM(GPIO_PIN_9)
pwm9.freq(25000)
current_pwm_duty = 0
sleep_duration = 0.01
def updateFan(x,y):
global current_pwm_duty,sleep_duration
current_pwm_duty = x
if sleep_duration > 0 and sleep_duration <= 2:
sleep_duration = y
else:
sleep_duration = 0.01
def fanon(timer):
global current_pwm_duty,sleep_duration
pwm9.duty_u16(current_pwm_duty)
time.sleep(sleep_duration)
pwm9.duty_u16(0)
def fanoff():
pwm9.duty_u16(0)
timerUpdate = machine.Timer()
timerUpdate.init(period=2000, mode=machine.Timer.PERIODIC, callback=fanon)
def connect():
#Connect to WLAN
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(ssid, password)
while wlan.isconnected() == False:
print('Waiting for connection...')
sleep(1)
ip = wlan.ifconfig()[0]
print(f'Connected on {ip}')
return ip
def open_socket(ip):
# Open a socket
address = (ip, 80)
connection = socket.socket()
connection.bind(address)
connection.listen(1)
return connection
def webpage(temperature, state,user_value):
#Template HTML
html = f"""
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<form action="./lighton" style="display: flex; justify-content: center;">
<input type="submit" value="Light on" style="font-size: 40px;" />
</form>
<form action="./lightoff" style="display: flex; justify-content: center;">
<input type="submit" value="Light off" style="font-size: 40px;" />
</form>
<p style="font-size: 20px;">LED is {state}</p>
<p style="font-size: 20px;">Temperature is {temperature}</p>
<form action="./fanon_LOW" style="display: flex; justify-content: center;">
<input type="submit" value="FAN on LOW" style="font-size: 40px;" />
</form>
<form action="./fanon_MID" style="display: flex; justify-content: center;">
<input type="submit" value="FAN on MID" style="font-size: 40px;" />
</form>
<form action="./fanon_FULL" style="display: flex; justify-content: center;">
<input type="submit" value="FAN off FULL" style="font-size: 40px;" />
</form>
<form action="./fanoff" style="display: flex; justify-content: center;">
<input type="submit" value="FAN off" style="font-size: 40px;" />
</form>
<h1>Numeric Form</h1>
<form method=POST action="/usrval">
<label for="value">Enter a numeric value:</label><br>
<input type="number" id="value" name="value" min="30" max="65" value="30"required><br><br>
<input type="submit" value="Submit">
</form>
<p>User value: {user_value}</p> <!-- Display the user-submitted value -->
</body>
</html>
"""
return str(html)
def serve(connection):
#Start a web server
state = 'OFF'
pico_led.off()
temperature = 0
user_value = None # Variable to store the user-submitted value
usr_int = 0
while True:
client = connection.accept()[0]
request = client.recv(1024)
request = str(request)
rqst1 = request.split()
'''
for x1 in rqst1:
if(x1.find("usrval") != -1):
print(rqst1)
#print(x1)
#print(rqstfind)
'''
try:
for x1 in rqst1:
if "value=" in x1:
user_value = x1.split("=")[2].strip("'")
usr_int = int(user_value) * 1000
if usr_int >= 65535:
usr_int = 65535
if usr_int <= 0:
usr_int = 0
print(user_value," ",type(user_value)," int:",usr_int," ",type(usr_int))
except:
pass
try:
request = request.split()[1]
except IndexError:
pass
if request == '/lighton?':
pico_led.on()
state = 'ON'
elif request =='/lightoff?':
pico_led.off()
state = 'OFF'
elif request == '/fanon_LOW?':
#put the usr value in the pwm duty
updateFan(30000,1.75)
elif request == '/fanon_MID?':
#put the usr value in the pwm duty
updateFan(45000,1.5)
elif request == '/fanon_FULL?':
#put the usr value in the pwm duty
updateFan(65000,1.6)
elif request == '/fanoff?':
updateFan(0,1)
temperature = pico_temp_sensor.temp
html = webpage(temperature, state,user_value)
client.send(html)
client.close()
try:
ip = connect()
connection = open_socket(ip)
serve(connection)
except KeyboardInterrupt:
machine.reset()
Leave a Reply