STEPico & Micropython

A quick guide to the STEPico part for Traffic Light project

Quick Download

This main.py file is the complete Micro-python code that implements program

Board Configuration

This tutorial is tailored for Windows users. For those using different operating systems, there are numerous guides readily available via a quick Google or YouTube search

Please follow the following steps to configure the board.

Start by downloading and installing Thonny, which is an integrated development environment (IDE) that makes it easy to write and run code.

STEP 1: Install Thonny

You can download Thonny from the official website (https://thonny.org/) and follow the installation instructions for your operating system.

STEP 2: Connect the board to USB

Now, take your STEPico board and connect it to your computer using a USB cable. Make sure the board is properly connected and powered on.

Step 3: Set the STEPico in Bootloader Mode

To program the STEPico, you need to put it in bootloader mode. This mode allows you to transfer your code to the board. To do this, press and hold the BOOT button on your STEPico board (the button is usually labeled as "BOOT" or "SW1"). While holding the button, press the RUN button on the board (labeled as "RESET," "SW2," or β€œRUN”). Release the BOOTSEL button.

Step 4: STEPico Appears as a Drive

After entering bootloader mode, your STEPico will appear as a removable drive on your β€œThis PC” found in the file explorer. It may be named "RPI-RP2" or something similar. Open the drive.

Step 5: Download MicroPython

Visit the MicroPython website (https://micropython.org/download/rp2-pico/) and download the latest "uf2" file for the STEPico.

Step 6: Transfer MicroPython to the STEPico

Locate the downloaded "uf2" file and drag it to the STEPico drive that appeared in step 4. This will transfer the MicroPython firmware to the board.

Step 7: STEPico Reboots

After transferring the MicroPython firmware, the STEPico board will reboot automatically. Wait a few seconds for the reboot to complete. The device should no longer show up under devices and drives.

Step 8: Open Thonny

Open the Thonny IDE that you installed in step 1. It should detect the STEPico board automatically.

Step 9: Select Board and Serial Port

In Thonny, go to the "Tools" menu and select "Options." Under the "Interpreter" tab, choose "MicroPython (RP2040)" as the board. Then, select the correct serial port (port number may vary) for your RP2040 board. Click "OK" to save the settings.

Step 10: Write and Run Code

Now you're ready to write and run code on your STEPico! In the Thonny editor, start writing your MicroPython code. When saving the code, there will be an option to save locally on your PC or directly onto the STEPico.

Name the code main.py when downloading directly onto the microcontroller to enable automatic code execution on battery power. If you name something else, such as test.py, then the program ONLY works when it is connected to computer USB.

Micropython Code

main.py (The complete code)
#------------------------------------------------------------------------------------------------------------------------
# Importing Libraries
#------------------------------------------------------------------------------------------------------------------------

import time, math
from machine import Pin


#------------------------------------------------------------------------------------------------------------------------
# Defining Functions
#------------------------------------------------------------------------------------------------------------------------

# LDR Signal Callback; LDR == 0 when daytime, LDR == 1 when night time
def ldr_callback(pin):
    global isDaytime
    if LDR_sense.value() == 1:
        isDaytime = False
        road_lights.value(1)
    elif LDR_sense.value() == 0:
        isDaytime = True
        road_lights.value(0)
        
# Pedestrian Walk Signal Callback
def walk_callback(pin):
    if LDR_sense.value() == 1:
        night_sequence()

# Car Signal Callback
def car_callback(pin):
    # If car signals triggered during night, start night traffic light sequence
    if (car_signal_2.value() == 1 and LDR_sense.value() == 1) or (car_signal_4.value() == 1 and LDR_sense.value() == 1):
        night_sequence()

# Function to run night time traffic sequence
def night_sequence():
    # Set Main Street traffic lights (No.2 and No.4) to yellow (STATE 1)
    G_Main_St.value(0)
    Y_Main_St.value(1)
    time.sleep_ms(Y_timing)
    
    # Set Main Street light (No.2 and No.4) red, Small Avenue light (No.1 and No.3) green (STATE 2)
    Y_Main_St.value(0)
    R_Main_St.value(1)   
    G_Small_Ave.value(1)
    R_Small_Ave.value(0)
    time.sleep_ms(G_timing_night_Small_Ave)

    # Set Small Avenue (No.1 and No.3) traffic lights to yellow (STATE 3)
    G_Small_Ave.value(0)
    Y_Small_Ave.value(1)
    time.sleep_ms(Y_timing)
    
    # Set Small Avenue light (No.1 and No.3) red, Main Street lights (No.2 and No.4) green (STATE 4)
    Y_Small_Ave.value(0)
    R_Small_Ave.value(1)
    R_Main_St.value(0)
    G_Main_St.value(1)

    # Wait 5 seconds before allowing traffic light change again
    time.sleep_ms(5000)

# Function to run daytime traffic sequence
def day_sequence():
    # wait some time before changing the traffic lights
    time.sleep_ms(G_timing_day_Main_St)

    # Set Main Street traffic lights (No.2 and No.4) to yellow (STATE 1)
    G_Main_St.value(0)
    Y_Main_St.value(1)
    time.sleep_ms(Y_timing)
    
    # Set Main Street light (No.2 and No.4) red, Small Avenue light (No.1 and No.3) green (STATE 2)
    Y_Main_St.value(0)
    R_Main_St.value(1)
    G_Small_Ave.value(1)
    R_Small_Ave.value(0)
    time.sleep_ms(G_timing_day_Small_Ave)
    
    # Set Small Avenue (No.1 and No.3) traffic lights to yellow (STATE 3)
    G_Small_Ave.value(0)
    Y_Small_Ave.value(1)
    time.sleep_ms(Y_timing)
    
    # Set Small Avenue light (No.1 and No.3) red, Main Street lights (No.2 and No.4) green (STATE 4)
    Y_Small_Ave.value(0)
    R_Small_Ave.value(1)
    R_Main_St.value(0)
    G_Main_St.value(1)


#------------------------------------------------------------------------------------------------------------------------
# Initializations
#------------------------------------------------------------------------------------------------------------------------

# Road Lights
road_lights = Pin(0, Pin.OUT)

# Traffic Lights installed on corners "No.1" and "No.3"
G_Small_Ave = Pin(1, Pin.OUT)  # Green light
Y_Small_Ave = Pin(2, Pin.OUT)  # Yellow light
R_Small_Ave = Pin(3, Pin.OUT)  # Red light

# Traffic Lights installed on corners "No.2" and "No.4"
G_Main_St = Pin(4, Pin.OUT)  # Green light
Y_Main_St = Pin(5, Pin.OUT)  # Yellow light
R_Main_St = Pin(6, Pin.OUT)  # Red light

# Light Dependent Resistor (LDR)
LDR_sense = Pin(11, Pin.IN)  # LDR signal pin

# Car and Walk Signals
car_signal_2 = Pin(7, Pin.IN)   # Car signal on corner "No.2"
car_signal_4 = Pin(8, Pin.IN)   # Car signal on corner "No.4"
walk_signal_2 = Pin(9, Pin.IN)  # Pedestrian walk signal on corner "No.2"
walk_signal_4 = Pin(10, Pin.IN) # Pedestrian walk signal on corner "No.4"

# Setting up interrupt requests for LDR Sensor, walk, and car signals
LDR_sense.irq(handler=ldr_callback, trigger=Pin.IRQ_FALLING | Pin.IRQ_RISING)  # Callback on signal change
walk_signal_2.irq(handler=walk_callback, trigger=Pin.IRQ_FALLING)  # Callback on pedestrian walk signal change
walk_signal_4.irq(handler=walk_callback, trigger=Pin.IRQ_FALLING)  # Callback on pedestrian walk signal change
car_signal_2.irq(handler=car_callback, trigger=Pin.IRQ_FALLING)  # Callback on car signal change
car_signal_4.irq(handler=car_callback, trigger=Pin.IRQ_FALLING)  # Callback on car signal change

# Initializing street light states
G_Small_Ave.value(0)
Y_Small_Ave.value(0)
R_Small_Ave.value(1)
G_Main_St.value(1)
Y_Main_St.value(0)
R_Main_St.value(0)
road_lights.value(0)

# Add a flag to check if it's daytime or not
isDaytime = False

# Initial LDR check; checks for LDR state at the start of the program
if LDR_sense.value() == 0:
    isDaytime = True
    road_lights.value(0)

# Adjust the day sequence traffic light timing here (milliseconds)
G_timing_night_Small_Ave = 5000
G_timing_day_Small_Ave = 7000
G_timing_day_Main_St = 15000
Y_timing = 3000


#------------------------------------------------------------------------------------------------------------------------
# Main Loop
#------------------------------------------------------------------------------------------------------------------------

while True:
    if isDaytime:  #if it is daytime run the daytime traffic light sequence
        day_sequence() 

    else:  # Night mode (in standby mode until walk or car interrupt occurs)
        time.sleep(0)  # sleep for a while to reduce CPU usage (seconds)

Last updated