Skip to content

Commit f5208b2

Browse files
committed
feat: add micropython in the browser workshop
1 parent 14b33c5 commit f5208b2

File tree

12 files changed

+708
-0
lines changed

12 files changed

+708
-0
lines changed
54.6 KB
Loading
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
---
2+
title: Daniel Paul
3+
---
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
---
2+
title: "MicroPython Jupyter in the Browser with ESP32-C3 - Assignment 1: Blink - Control the NeoPixel LED"
3+
date: 2025-10-17T00:00:00+01:00
4+
showTableOfContents: false
5+
series: ["WS00M"]
6+
series_order : 2
7+
showAuthor: false
8+
---
9+
10+
## Assignment 1: Blink
11+
12+
Let's continue by controlling the onboard NeoPixel LED.
13+
14+
### Understanding NeoPixel LEDs
15+
16+
NeoPixel (WS2812) LEDs are individually addressable RGB LEDs. Each LED can display any color by mixing red, green, and blue values (0-255 each). The ESP32-C3 Rust board has one NeoPixel on GPIO 2.
17+
18+
Open the Assignment 1 Jupyter notebook and work through the following tasks:
19+
20+
### Task 1: Initialize the NeoPixel
21+
22+
```python
23+
neopixel_led = neopixel.NeoPixel(machine.Pin(2), 1)
24+
```
25+
26+
### Task 2: Set the Solid Colors
27+
28+
```python
29+
def set_color(r, g, b):
30+
"""Set the NeoPixel to a specific RGB color"""
31+
neopixel_led[0] = (r, g, b)
32+
neopixel_led.write()
33+
34+
def clear_led():
35+
"""Turn off the LED"""
36+
set_color(0, 0, 0)
37+
38+
39+
# Try different colors
40+
set_color(255, 0, 0) # Red
41+
time.sleep(1)
42+
set_color(0, 255, 0) # Green
43+
time.sleep(1)
44+
set_color(0, 0, 255) # Blue
45+
time.sleep(1)
46+
set_color(255, 255, 0) # Yellow
47+
time.sleep(1)
48+
clear_led()
49+
```
50+
51+
### Task 3: Rainbow cycle effect
52+
53+
```python
54+
def rainbow_cycle():
55+
"""Cycle through rainbow colors"""
56+
colors = [
57+
(255, 0, 0), # Red
58+
(255, 127, 0), # Orange
59+
(255, 255, 0), # Yellow
60+
(0, 255, 0), # Green
61+
(0, 0, 255), # Blue
62+
(75, 0, 130), # Indigo
63+
(148, 0, 211) # Violet
64+
]
65+
66+
for color in colors:
67+
set_color(*color)
68+
time.sleep(0.3)
69+
clear_led()
70+
71+
rainbow_cycle()
72+
```
73+
74+
### Task 4: Breathing Effect
75+
76+
```python
77+
def breathing_effect(r, g, b, duration=2, steps=50):
78+
"""
79+
Create a breathing effect with the specified color
80+
"""
81+
step_delay = duration / (steps * 2)
82+
83+
# Fade in
84+
for i in range(steps):
85+
brightness = i / steps
86+
set_color(int(r * brightness), int(g * brightness), int(b * brightness))
87+
time.sleep(step_delay)
88+
89+
# Fade out
90+
for i in range(steps, 0, -1):
91+
brightness = i / steps
92+
set_color(int(r * brightness), int(g * brightness), int(b * brightness))
93+
time.sleep(step_delay)
94+
95+
clear_led()
96+
97+
breathing_effect(0, 100, 255)
98+
```
99+
100+
Click on the ESP Control Panel and `Disconnect device` the device from the Jupyter notebook before proceeding with the next [assignment](../assignment-2/).
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
---
2+
title: "MicroPython Jupyter in the Browser with ESP32-C3 - Assignment 2: Button Input"
3+
date: 2025-10-17T00:00:00+01:00
4+
showTableOfContents: false
5+
series: ["WS00M"]
6+
series_order : 2
7+
showAuthor: false
8+
---
9+
10+
## Assignment 2: Button Input
11+
12+
Learn to read button input and create interactive LED responses.
13+
14+
If prompted with selecting kernel, select `Embedded Kernel`, click on the ESP Control Panel and connect your device.
15+
16+
{{< alert icon="circle-info" cardColor="#b3e0f2" iconColor="#04a5e5">}}
17+
In this assignment you will be configuring a `boot` button located on Pin 9.
18+
{{< /alert >}}
19+
20+
### Understanding Pull-up Resistors
21+
22+
Buttons create a connection when pressed. Pull-up resistors ensure a defined logic level when the button is not pressed:
23+
24+
Button not pressed: GPIO reads HIGH (1) due to pull-up resistor.
25+
26+
Button pressed: GPIO reads LOW (0) as it connects to ground.
27+
28+
The ESP32 has internal pull-up resistors that can be enabled in software.
29+
30+
### Task 1: Configure button
31+
32+
```python
33+
button = machine.Pin(9, machine.Pin.IN, machine.Pin.PULL_UP)
34+
```
35+
36+
### Task 2: Simple Button Press Detection
37+
38+
```python
39+
def wait_for_button_press():
40+
"""Wait until button is pressed"""
41+
while button.value() == 1:
42+
time.sleep(0.01)
43+
print("Button pressed!")
44+
```
45+
46+
### Task 3: Toggle LED on Button Press
47+
48+
```python
49+
led_state = False
50+
51+
while True:
52+
if button.value() == 0: # Button pressed
53+
led_state = not led_state
54+
if led_state:
55+
set_color(255, 0, 0)
56+
else:
57+
clear_led()
58+
59+
# Wait for button release (debounce)
60+
while button.value() == 0:
61+
time.sleep(0.01)
62+
time.sleep(0.1) # Additional debounce delay
63+
```
64+
65+
### Task 4: Measure Press duration
66+
67+
```python
68+
def measure_press_duration():
69+
"""Measure how long the button is held down"""
70+
start = time.ticks_ms()
71+
while button.value() == 0:
72+
time.sleep(0.01)
73+
duration = time.ticks_diff(time.ticks_ms(), start) / 1000.0
74+
return duration
75+
76+
wait_for_button_press()
77+
duration = measure_press_duration()
78+
print(f"Button held for {duration:.2f} seconds")
79+
```
80+
81+
### Bonus Challenge: Visual Feedback Based on Duration
82+
83+
Change LED color based on how long the button is pressed:
84+
- Short press (< 1s): Blue
85+
- Medium press (1-3s): Yellow
86+
- Long press (> 3s): Red
87+
88+
Click on the ESP Control Panel and `Disconnect device` the device from the Jupyter notebook before proceeding with the next [assignment].
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
---
2+
title: "MicroPython Jupyter in the Browser with ESP32-C3 - Assignment 3: ESP-NOW Communication - Receiver"
3+
date: 2025-10-17T00:00:00+01:00
4+
showTableOfContents: false
5+
series: ["WS00M"]
6+
series_order : 2
7+
showAuthor: false
8+
---
9+
10+
## Assignment 3: ESP-NOW Communication - Receiver
11+
12+
Your task will be to receive Morse code sent by the sender and display it on an LED.
13+
In order to receive the Morse code, you will need to initialize the ESP-NOW communication protocol and set up a callback function to handle incoming messages. The sender will need your MAC address to send the Morse code.
14+
15+
If prompted with selecting kernel, select `Embedded Kernel`, click on the ESP Control Panel and connect your device.
16+
17+
### Task 1: Initialize Receiver
18+
19+
```python
20+
# Setup WiFi and ESP-NOW
21+
sta = network.WLAN(network.STA_IF)
22+
sta.active(True)
23+
24+
# Get and print MAC address
25+
print("My MAC address:", sta.config('mac'))
26+
```
27+
28+
### Task 2: Initialize NeoPixel LED
29+
30+
```python
31+
# Setup NeoPixel
32+
neopixel_led = neopixel.NeoPixel(machine.Pin(2), 1)
33+
```
34+
35+
### Task 3: Initialize ESP-NOW
36+
37+
```python
38+
# Initialize ESP-NOW
39+
e = espnow.ESPNow()
40+
e.active(True)
41+
42+
# Timing constants
43+
DOT_TIME = 0.2 # Green LED duration
44+
DASH_TIME = 0.6 # Red LED duration
45+
PAUSE = 0.2 # Gap after symbol
46+
```
47+
48+
### Task 4: LED Display Functions
49+
50+
```python
51+
def set_color(r, g, b):
52+
"""Set the NeoPixel to a specific RGB color"""
53+
neopixel_led[0] = (r, g, b)
54+
neopixel_led.write()
55+
56+
def clear_led():
57+
"""Turn off the NeoPixel LED"""
58+
set_color(0, 0, 0)
59+
60+
def blink_dot():
61+
"""Display dot: green LED"""
62+
set_color(0, 255, 0)
63+
time.sleep(DOT_TIME)
64+
clear_led()
65+
66+
def blink_dash():
67+
"""Display dash: red LED"""
68+
set_color(255, 0, 0)
69+
time.sleep(DASH_TIME)
70+
clear_led()
71+
72+
def blink_morse_symbol(symbol):
73+
"""
74+
Display the received Morse symbol with appropriate color and timing.
75+
Includes pause after each symbol.
76+
"""
77+
if symbol == ".":
78+
blink_dot()
79+
elif symbol == "-":
80+
blink_dash()
81+
82+
```
83+
84+
### Task 5: Receive Morse Code
85+
86+
```python
87+
print("Morse Code Receiver ready...")
88+
print("Dot = Green LED, Dash = Red LED")
89+
90+
while True:
91+
host, msg = e.recv(0) # Non-blocking receive
92+
if msg:
93+
symbol = msg.decode()
94+
print("Received:", symbol)
95+
blink_morse_symbol(symbol)
96+
97+
time.sleep(PAUSE)
98+
```
99+
100+
### Bonus Challenge: Extend the receiver to decode complete Morse code letters and display them.
101+
102+
103+
Click on the ESP Control Panel and `Disconnect device` the device from the Jupyter notebook before proceeding with the next [assignment](../assignment-4/).
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
---
2+
title: "MicroPython Jupyter in the Browser with ESP32-C3 - Assignment 3: ESP-NOW Communication - Sender"
3+
date: 2025-10-17T00:00:00+01:00
4+
showTableOfContents: false
5+
series: ["WS00M"]
6+
series_order : 2
7+
showAuthor: false
8+
---
9+
10+
## Assignment 3: ESP-NOW Communication - Sender
11+
12+
Your task will be to send Morse code to the receiver based on the length of the button presses. Ask your partner for his MAC Address and replace `<MAC_ADDRESS>` with it.
13+
14+
If prompted with selecting kernel, select `Embedded Kernel`, click on the ESP Control Panel and connect your device.
15+
16+
### Task 1: Initialize ESP-NOW
17+
18+
```python
19+
# Create WiFi station interface
20+
sta = network.WLAN(network.STA_IF)
21+
sta.active(True)
22+
23+
# Initialize ESP-NOW
24+
e = espnow.ESPNow()
25+
e.active(True)
26+
27+
# MAC address of receiver (replace <MAC_ADDRESS> receiver's MAC!)
28+
peer_mac = b'<MAC_ADDRESS>'
29+
30+
# Try to delete any existing peer
31+
try:
32+
e.del_peer(peer_mac)
33+
except OSError:
34+
pass
35+
36+
e.add_peer(peer_mac)
37+
```
38+
39+
### Task 2: Implement Morse Detection
40+
41+
```python
42+
# Button configuration
43+
button = machine.Pin(9, machine.Pin.IN, machine.Pin.PULL_UP)
44+
45+
DOT_THRESHOLD = 0.3 # seconds
46+
DEBOUNCE = 0.05
47+
48+
def wait_for_button_press():
49+
"""Wait until button is pressed"""
50+
while button.value() == 1:
51+
time.sleep(0.01)
52+
53+
def measure_press_duration():
54+
"""Measure how long the button is held down"""
55+
start = time.ticks_ms()
56+
while button.value() == 0:
57+
time.sleep(0.01)
58+
duration = time.ticks_diff(time.ticks_ms(), start) / 1000.0
59+
return duration
60+
61+
def determine_morse_symbol(duration):
62+
"""Determine if press was dot or dash"""
63+
if duration < DEBOUNCE:
64+
return None
65+
symbol = '.' if duration < DOT_THRESHOLD else '-'
66+
return symbol
67+
68+
def send_morse_symbol(symbol):
69+
"""Send morse symbol via ESP-NOW"""
70+
print("Sending:", symbol)
71+
e.send(peer_mac, symbol.encode())
72+
```
73+
74+
### Task 3: Send Morse Symbols
75+
76+
```python
77+
print("Morse Code Sender Ready!")
78+
print("Press button: short = dot (.), long = dash (-)")
79+
print("Press the stop button on the toolbar to terminate the while loop.")
80+
81+
while True:
82+
# Wait for button press
83+
wait_for_button_press()
84+
85+
# Measure duration
86+
duration = measure_press_duration()
87+
88+
# Determine symbol
89+
symbol = determine_morse_symbol(duration)
90+
if symbol:
91+
# Send symbol via ESP-NOW
92+
send_morse_symbol(symbol)
93+
```
94+
95+
Click on the ESP Control Panel and `Disconnect device` the device from the Jupyter notebook before proceeding with the next [assignment](../assignment-4/).

0 commit comments

Comments
 (0)