Introduction
This week’s goal was to program the Quentorres board created in week 4, focusing on utilizing its onboard button and LEDs.
Objectives
- Modify and run a basic LED example.
- Execute a MicroPython sketch with Thonny IDE.
- Compare the Arduino and MicroPython workflows.
- SeeedStudio XIAO ESP32S3
- Arduino IDE
- Thonny IDE
- Quentorres Board
Process
Arduino IDE Setup
- Installed the Arduino IDE and set up the XIAO ESP32 following the official instructions.
- Ran the example blink sketch from the Arduino examples, initially affecting only the XIAO’s onboard LED.
- Modified the sketch to control the two LEDs on the Quentorres board by defining their I/O pins according to the Pinout Diagram. I also adapted the sketch to use the
millis()
function for non-blocking LED blinking, which allows other code to run simultaneously.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
| // Define LED pins
const int ledPin1 = 1; // LED connected to digital pin 1 on XIAO, 26 on qtpy
const int ledPin2 = 44; // LED connected to digital pin 44 on XIAO, 7 on qtpy
// Variables to store the last time the LED was updated
unsigned long previousMillisLed1 = 0;
unsigned long previousMillisLed2 = 0;
// Interval at which to blink (milliseconds)
const long intervalLed1 = 1500; // blink every second
const long intervalLed2 = 500; // blink every 5 seconds
void setup() {
// Initialize the LED pins as outputs:
pinMode(ledPin1, OUTPUT);
pinMode(ledPin2, OUTPUT);
}
void loop() {
unsigned long currentMillis = millis();
// Handle the first LED blink logic
if (currentMillis - previousMillisLed1 >= intervalLed1) {
// Save the last time you blinked the LED
previousMillisLed1 = currentMillis;
// If the LED is off, turn it on and vice-versa:
int ledState = digitalRead(ledPin1); // Read the current state of LED
digitalWrite(ledPin1, !ledState); // Set LED to the opposite state
}
// Handle the second LED blink logic
if (currentMillis - previousMillisLed2 >= intervalLed2) {
// Save the last time you blinked the LED
previousMillisLed2 = currentMillis;
// If the LED is off, turn it on and vice-versa:
int ledState = digitalRead(ledPin2); // Read the current state of LED
digitalWrite(ledPin2, !ledState); // Set LED to the opposite state
}
}
|
This code ran on both boards (XIAO and QTPY) on arduino IDE, by just changing the output pins for each LED. And selecting the board on the IDE.
Here is the result:
MicroPython with Thonny IDE
Next, I experimented with MicroPython on the XIAO, uploading sketches through Thonny IDE. The transition to MicroPython maintained the expected functionality.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
| from machine import Pin
import utime
# Define LED pins
ledPin1 = Pin(1, Pin.OUT) # LED on pin 1
ledPin2 = Pin(44, Pin.OUT) # LED 2 on pin 44
# Variables to store the last time the LED was updated
previousMillisLed1 = 0
previousMillisLed2 = 0
# Interval at which to blink (milliseconds)
intervalLed1 = 1500 # blink every 1.5 seconds
intervalLed2 = 500 # blink every 0.5 seconds
def blink_led(led_pin, interval, previous_millis):
current_millis = utime.ticks_ms()
if current_millis - previous_millis >= interval:
led_pin.value(not led_pin.value()) # Toggle LED state
return current_millis # Update the last blink time
return previous_millis # Return the previous time if not blinked
while True:
previousMillisLed1 = blink_led(ledPin1, intervalLed1, previousMillisLed1)
previousMillisLed2 = blink_led(ledPin2, intervalLed2, previousMillisLed2)
utime.sleep_ms(1) # Small delay to prevent blocking
|
Conclusion
Both Arduino and MicroPython workflows proved to be straightforward, with MicroPython possibly offering an edge for more interactive projects. A challenge encountered was that starting the REPL in Thonny blocks the running program.
An advanced example involved using the button to alter the blink interval, developed with assistance from ChatGPT:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
| from machine import Pin
import utime
from machine import Pin
import utime
# Define LED and button pins
ledPin = Pin(1, Pin.OUT)
button = Pin(2, Pin.IN, Pin.PULL_UP)
# Variables to store the last time the LED was updated
previousMillisLed = 0
# Interval at which to blink (milliseconds)
intervalLed = 1500 # Initial blink interval for LED
def blink_led(led_pin, interval, previous_millis):
current_millis = utime.ticks_ms()
if current_millis - previous_millis >= interval:
led_pin.value(not led_pin.value()) # Toggle LED state
return current_millis
return previous_millis
def measure_button_press():
start_time = 0
end_time = 0
if not button.value():
start_time = utime.ticks_ms()
while not button.value():
utime.sleep_ms(10) # Small delay to prevent bouncing
end_time = utime.ticks_ms()
return end_time - start_time if (end_time - start_time) > 0 else 0
while True:
previousMillisLed = blink_led(ledPin, intervalLed, previousMillisLed)
press_duration = measure_button_press()
if press_duration > 0:
intervalLed = press_duration
print(f"New blink interval: {intervalLed} ms")
utime.sleep_ms(10) # Small delay to keep loop manageable
|