Search code examples
pythonesp32micropythonadafruitthonny

Using PWM to Blink LED on ESP32 Huzzah (MicroPython)


I've written the following program to make the onboard LED on an ESP32 Huzzah board blink. I've connected an ultrasonic distance sensor to the board, and if an object is more than 30 cm away (or the sensor is outputting garbage values) from the sensor, then I want the LED to blink at 1 Hz. Otherwise the LED should blink at 2 Hz.

The code calculates the mean distance using 5 consecutive samples and also calculates the variance of those samples. If the mean distance is less than 30 cm and the variance is less than 2 cm^2, the PWM frequency should be 2 Hz, otherwise it should be 1 Hz. The variance helps filter out garbage readings.

The math part works okay, I can print out the mean distance and the variance, but the LED does not blink. It does when I stop the REPL (I'm using the Thonny Python IDE), the frequency is based on whatever condition was true just before stopping the REPL.

What do I need to change the make the LED blink (and change frequency based on distance) without stopping the REPL?

Any help would be greatly appreciated.

# Import required modules.
from machine import Pin, PWM
import time
from hcsr04 import HCSR04

# Define hardware output pin.
# Pin 13 is the onboard LED.
# Initialize distance sensor, the trigger pin is 26 and the echo pin is 25.

frequency = 1
led_board = Pin(13, Pin.OUT)
led_pwm = PWM(led_board, freq = frequency, duty = 512)
sensor = HCSR04(trigger_pin = 26, echo_pin = 25)
temp_0 = [0, 0, 0, 0, 0]

# Main never ending loop which makes the onboard LED blink at 1 Hz (ON for 500 milliseconds...
# ... and OFF for 500 milliseconds) if an object is more than 30 cm away from the sensor,...
# ...otherwise the LED blinks at 2 Hz (ON for 250 milliseconds and OFF for 250 milliseconds).
while True:
    for i in range(5):
        temp_0[i] = sensor.distance_cm()
        
    mean_distance = sum(temp_0)/5
    temp_1 = [j - mean_distance for j in temp_0]
    temp_2 = [k**2 for k in temp_1]
    var_distance = sum(temp_2)/5
    
    if mean_distance < 30 and var_distance < 2:
        frequency = 2
    else:
        frequency = 1
        
    print(mean_distance, ' ', var_distance)
    
    led_pwm.freq(frequency)

Solution

  • From what I can see, calling PWM.freq(frequency) actually resets the LEDC timer, so by calling it every loop, you aren't allowing the controller to run and blink the LED. Try only calling that method if the frequency changes:

    # Check if the frequency has changed, if so, set the new frequency of the LED
    if (led_pwm.freq() != frequency):
      led_pwm.freq(frequency)