12V PC Fan Control Using Raspberry Pi Pico W By PWM

Posted

in

by

Tags:

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 WL298n Module
GP9IN1
GNDGND
VSYS
(Connect this only when you save as “main.py” in raspberry pi.)
+5V
12V PC FANL298n 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()

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *