# ESP32 and Mycropython: Programming your Hardware
# Author: Mordechai Bar Natan
#
# Lesson 7: Dim the LEDs
# https://wokwi.com/projects/394065911022911489
#
# Remember:
# On a LED, the long leg is the anode (+). Connect it to pin #2.
# The short leg is the cathode (-). Connect it to GND.
# On a momentary switch (button), connect one side to pin #4 and the other side to GND.
# The display has 4 connections: GND, VCC (to 3.3V), SCL (pin #22) & SDA (pin #21).
# The + on the buzzer connects to pin #23 on the ESP32.
#
# References
# https://docs.micropython.org/en/latest/library/machine.Pin.html
# https://docs.micropython.org/en/latest/esp8266/tutorial/ssd1306.html#ssd1306
# https://docs.micropython.org/en/latest/esp32/quickref.html#pwm-pulse-width-modulation
# https://micropython-on-wemos-d1-mini.readthedocs.io/en/latest/basics.html#beepers
from machine import Pin, SoftI2C, ADC, PWM
from time import sleep, sleep_ms
from ssd1306 import SSD1306_I2C
oled_scl_pin = 22 # Orange cable
oled_sda_pin = 21 # Blue cable
red_led_pin = 2
blue_led_pin = 15
left_button_pin = 4
right_button_pin = 17
buzzer_pin = 23 # Purple cable
i2c = SoftI2C(scl=Pin(oled_scl_pin), sda=Pin(oled_sda_pin), freq=4000000)
oled_w = 128 # display width (0..127)
oled_h = 64 # display hight (0..63)
oled = SSD1306_I2C(oled_w, oled_h, i2c) # oled will be the display bject
red_led = PWM(Pin(red_led_pin, Pin.OUT)) # need PWM to "fade" the LED
blue_led = PWM(Pin(blue_led_pin, Pin.OUT)) # need PWM to "fade" the LED
left_button = Pin(left_button_pin, Pin.IN, Pin.PULL_UP)
right_button = Pin(right_button_pin, Pin.IN, Pin.PULL_UP)
red_led_state = 0
blue_led_state = 0
left_button_state = 0
right_button_state = 0
red_led.freq(1000) # Set PWM frequency
blue_led.freq(1000) # Set PWM frequency
red_led.duty(0) # turn off LED
blue_led.duty(0) # turn off LED
# Define duty cycles for different LED intensities
red_intensity_levels = [0, 25, 50, 75, 100] # OFF, 1/4, 1/2, 3/4, ON
blue_intensity_levels = [0, 33, 66, 100] # OFF, 1/3, 2/3, ON
def play_note(note=1047, duration_ms=100, active_duty=200): # use my default values
buzzer = PWM(Pin(buzzer_pin, Pin.OUT)) # need PWM to generate (modulate) tones
buzzer.freq(note) # tune
buzzer.duty(active_duty) # duty of 50 is ok, more than 300 is distorted, just try
sleep_ms(duration_ms) # tone duration
buzzer.duty(0) # Turn off the buzzer
buzzer.deinit() # deinitialize the object
def display_led_status(red_intensity, blue_intensity):
oled.fill(0) # Clear display
oled.text("RED LED: " + str(red_intensity) + "%", 0, 0, 1)
oled.text("BLUE LED: " + str(blue_intensity) + "%", 0, 10, 1)
oled.show()
# Initial intensity
current_red_intensity_index = 0
current_blue_intensity_index = 0
current_red_intensity = red_intensity_levels[current_red_intensity_index]
current_blue_intensity = blue_intensity_levels[current_blue_intensity_index]
display_led_status(current_red_intensity, current_blue_intensity)
# toggle the LED when the button is pressed
while True:
left_button_last_state = left_button_state
left_button_state = left_button.value()
if left_button_state == 0 and left_button_last_state == 1:
# Cycle to next intensity level
current_red_intensity_index = (current_red_intensity_index + 1) % len(red_intensity_levels)
current_red_intensity = red_intensity_levels[current_red_intensity_index]
# Set LED intensity
red_led.duty(current_red_intensity * 10) # Duty cycle is in range 0-1023
play_note()
right_button_last_state = right_button_state
right_button_state = right_button.value()
if right_button_state == 0 and right_button_last_state == 1:
# Cycle to next intensity level
current_blue_intensity_index = (current_blue_intensity_index + 1) % len(blue_intensity_levels)
current_blue_intensity = blue_intensity_levels[current_blue_intensity_index]
# Set LED intensity
blue_led.duty(current_blue_intensity * 10) # Duty cycle is in range 0-1023
play_note()
# Display intensity on OLED
display_led_status(current_red_intensity, current_blue_intensity)
sleep(0.1)