Skip to content

Instantly share code, notes, and snippets.

@perXautomatik
Created August 26, 2023 00:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save perXautomatik/0036a51f6f89922aec240de9b787edd2 to your computer and use it in GitHub Desktop.
Save perXautomatik/0036a51f6f89922aec240de9b787edd2 to your computer and use it in GitHub Desktop.

a project based on a smart power switch that detects changes in light using a Raspberry Pi Pico:

Approximate time to do this tutorial: 1 hours

Smart Power Switch

Introduction

The purpose of this project is to create a smart power switch that can turn on or off an appliance based on the ambient light level. The project will use a Raspberry Pi Pico, a photoresistor, a relay module, and an LED to sense and control the power switch. The project will also use a web app to display the light level and the switch status on a web page.

Hardware

The hardware components required for this project are:

  • Raspberry Pi Pico
  • Photoresistor x2
  • Relay module
  • LED
  • Breadboard
  • Jumper wires
  • Power supply

Software

The software components required for this project are:

  • MicroPython
  • Thonny IDE
  • Flask web framework
  • Socket.IO library

Implementation

The implementation steps for this project are:

  1. Connect the photoresistor, the relay module, and the LED to the Raspberry Pi Pico using the breadboard and the jumper wires. The photoresistor will be connected to GPIO pin 26 (ADC0), the relay module will be connected to GPIO pin 15, and the LED will be connected to GPIO pin 14.
  2. Install MicroPython on the Raspberry Pi Pico using the Thonny IDE following the instructions from [this guide].
  3. Create a MicroPython script named main.py that will read the light level from the photoresistor, write it to a global variable named light, and compare it with a predefined threshold named threshold. If the light level is below the threshold, the script will turn on the relay module and the LED, otherwise it will turn them off. The script will also use Socket.IO to communicate with the web app and send or receive messages. The script will look something like this:
import machine
import utime
import socketio

# Set up GPIO pins
adc = machine.ADC(26) # photoresistor pin
relay = machine.Pin(15, machine.Pin.OUT) # relay module pin
led = machine.Pin(14, machine.Pin.OUT) # LED pin

# Set up global variables for light level and threshold
light = 0 # light level in percentage (0% = dark, 100% = bright)
threshold = 50 # threshold in percentage

# Set up Socket.IO client
sio = socketio.Client()

# Define callback function for Socket.IO connection
def on_connect():
    print("Connected to web app")

# Define callback function for Socket.IO disconnection
def on_disconnect():
    print("Disconnected from web app")

# Define callback function for Socket.IO messages
def on_message(data):
    # Get message as string
    message = data.decode("utf-8")
    # Check if message is "ON" or "OFF"
    if message == "ON":
        # Turn on relay module and LED
        relay.value(1)
        led.value(1)
    elif message == "OFF":
        # Turn off relay module and LED
        relay.value(0)
        led.value(0)

# Register callback functions for Socket.IO events
sio.on("connect", on_connect)
sio.on("disconnect", on_disconnect)
sio.on("message", on_message)

# Connect to web app using Socket.IO
sio.connect("http://localhost:5000")

# Main loop
while True:
    # Read light level from photoresistor (0 - 65535)
    value = adc.read_u16()
    # Convert light level to percentage (0% - 100%)
    light = value / 655.35 
    # Send light level to web app using Socket.IO
    sio.emit("light", light)
    # Check if light level is below threshold
    if light < threshold:
        # Turn on relay module and LED if not already on
        if relay.value() == 0:
            relay.value(1)
            led.value(1)
    else:
        # Turn off relay module and LED if not already off
        if relay.value() == 1:
            relay.value(0)
            led.value(0)
    # Wait for 1 second before next iteration
    utime.sleep(1)

# Disconnect from web app using Socket.IO
sio.disconnect()
  1. Create a web app using Flask and Socket.IO that will display the light level and the switch status on a web page. The web app will also allow the user to manually control the switch by sending “ON” or “OFF” messages to the Raspberry Pi Pico. The web app will look something like this:
from flask import Flask, render_template
from flask_socketio import SocketIO

# Set up Flask app and Socket.IO server
app = Flask(__name__)
socketio = SocketIO(app)

# Set up global variable for switch status
switch = "OFF"

# Define route for home page
@app.route("/")
def index():
    # Render index.html template with switch variable
    return render_template("index.html", switch=switch)

# Define event handler for Socket.IO connection
@socketio.on("connect")
def on_connect():
    print("Connected to Raspberry Pi Pico")

# Define event handler for Socket.IO disconnection
@socketio.on("disconnect")
def on_disconnect():
    print("Disconnected from Raspberry Pi Pico")

# Define event handler for Socket.IO light event
@socketio.on("light")
def on_light(data):
    # Get light level as float
    light = float(data)
    # Emit light level to web page using Socket.IO
    socketio.emit("light", light)

# Define event handler for Socket.IO message event
@socketio.on("message")
def on_message(data):
    # Get message as string
    message = data.decode("utf-8")
    # Update global switch variable
    global switch
    switch = message
    # Emit switch status to web page using Socket.IO
    socketio.emit("switch", switch)

# Define route for switch on button
@app.route("/switch/on")
def switch_on():
    # Send "ON" message to Raspberry Pi Pico using Socket.IO
    socketio.send("ON")
    # Redirect to home page
    return index()

# Define route for switch off button
@app.route("/switch/off")
def switch_off():
    # Send "OFF" message to Raspberry Pi Pico using Socket.IO
    socketio.send("OFF")
    # Redirect to home page
    return index()

# Run Flask app and Socket.IO server in debug mode
if __name__ == "__main__":
    socketio.run(app, debug=True)
  1. Create an HTML template named index.html that will display the light level and the switch status on a web page. The template will also have buttons to manually control the switch by sending requests to the web app. The template will also use JavaScript and jQuery to handle the Socket.IO events and update the web page dynamically. The template will look something like this:
<html>
<head>
    <title>Smart Power Switch</title>
    <!-- Load jQuery library -->
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <!-- Load Socket.IO library -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.1.3/socket.io.min.js"></script>
</head>
<body>
    <h1>Smart Power Switch</h1>
    <p>Light level: <span id="light">0</span>%</p>
    <p>Switch status: <span id="switch">OFF</span></p>
    <form action="/switch/on" method="get">
        <button type="submit">Switch ON</button>
    </form>
    <form action="/switch/off" method="get">
        <button type="submit">Switch OFF</button>
    </form>
    <!-- Define script for Socket.IO events -->
    <script>
        // Create Socket.IO client object
        var socket = io();
        // Define function for Socket.IO light event
        socket.on("light", function(data) {
            // Get light level as float
            var light = parseFloat(data);
            // Update light span element with light level
            $("#light").text(light.toFixed(2));
        });
        // Define function for Socket.IO switch event
        socket.on("switch", function(data) {
            // Get switch status as string
            var switch = data;
            // Update switch span element with switch status
            $("#switch").text(switch);
        });
    </script>
</body>
</html>
  1. Run the MicroPython script and the web app on the Raspberry Pi Pico and open the web page on a browser to see the results.

Conclusion

This project demonstrates how to create a smart power switch that can turn on or off an appliance based on the ambient light level. The project uses a Raspberry Pi Pico, a photoresistor, a relay module, and an LED to sense and control the power switch. The project also uses a web app to display the light level and the switch status on a web page. The project also allows the user to manually control the switch by sending “ON” or “OFF” messages to the Raspberry Pi Pico. This project can be further improved by adding more sensors, such as motion, sound, etc., and more features, such as timers, schedules, etc., to make it more smart and convenient.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment