Week 4 Assignments - Embedded Programming
Group Assignment
The group assignment for this week was to:
- Demonstrate and compare the toolchains and development workflows for available embedded architectures
- Document your work to the group work page and reflect on your individual page what you learned
Outcomes
Link to Group Site
The group assignment page for this week is on the 2025 Charlotte Super Fab Lab group site for Week 4 - Embedded Programming.
What Was Learned
In the group assignment, we considered toolchains and development workflows for the ESP32 and RP2040 microcontroller families with XIAO development boards, using the Arduino IDE/C++ and Thonny/Circuit Python environments. We were able to set up the software / development environments needed, set up the XIAO board appropriately, and use the environments to run basic programs for controlling LEDs. This provided us experience on:
- How to set up different development environments for use with microcontroller boards
- How to set up the set up a microcontroller to run software environments like circuit python
- How to use use development environments / IDEs to program microcontroller boards
Individual Assignment
The individual assignment for this week was to:
- Browse through the datasheet for your microcontroller
- Write a program for a microcontroller, and simulate its operation, to interact (with local input and/or output devices) and communicate (with remote wired or wireless connection)
Outcomes
Microcontroller Documentation Review
I selected the XIAO ESP32C3 as the microcontroller board to explore. I selected this board, because it has more robust microcontroller functionality as well as integrated wireless communication that may be helpful for my final project.
XIAO ESP32C3 Microcontroller Board1
I reviewed two primary sources of documentation from the microprocessor manufacturer (Espressif) and from the XIAO development board manufacturer (Seeed Studio).
- ESP32-C3 Datasheet
- XIAO ESP32C3 Datasheet - as part of development board documentation
- Espressif ESP32-C3 Datasheet - microcontroller manufacturer documentation
- Seeed Studio Wiki - Getting Started with Seed Studio XIAO ESP32C3
Datasheet Review
The Espressif ESP32-C3 Datasheet includes a number of sections that highlight the primary capabilities of the microcontroller.
The high-level functional architecture of the microcontroller is shown in the product overview (p. 2).
ESP32-C3 Datasheet Functional Block Diagram (p. 2)
Primary features of the microcontroller are outlined in the Features overview (p. 3-5), including summary details on:
- Wi-Fi (IEEE 802.11b/g/n)
- Bluetooth® (Bluettoth LE: Bluetooth 5, Bluetooth mesh)
- CPU and Memory (32-bit RISC-V single-core processor up to 160MHz, 400KB SRAM)
- Peripherals (GPIOs, UART/SPI/I2C connectivity)
- Power Management (power modes: active, sleep)
- Security (encryption modes, cryptographic hardware acceleration)
- RF Module (antenna characteristics)
Specific sections of the datasheet go into detail on ESP32-C3 microcontroller components, characteristics, and use. Some highlights from the datasheet follow.
Section 2 (p. 14-29) provides detail on the pin layout for the microcontroller chip, including packaging and pin characteristics.
ESP32-C3 Datasheet Pin Layout (§ 2.1, p. 14)
ESP32-C3 Datasheet Pin Overview - Part 1 (§ 2.2, p. 16)
ESP32-C3 Datasheet Pin Overview - Part 2 (§ 2.2, p. 17)
Section 4 (p. 33-53) provides detail on functional characteristics, including:
- System (Microprocessor, Memory Organization, System Control, Security)
- Peripherals (Connectivity Interface, Analog Signal Processing)
- Wireless Communication (Radio, Wi-Fi, Bluetooth LE)
Section 5 provides detail on electrical characteristics, such as for maximum ratings and recommended operating conditions.
ESP32-C3 Datasheet Absolute Maximum Ratings (§ 5.1, p. 54)
ESP32-C3 Datasheet Recommended Operating Conditions (§ 5.2, p. 54)
Development Board Documentation Review
In addition to the microcontroller manufacturer datasheet, the development board manufacturer Seeed Studio provides practical documentation about the development board and usage: Getting Started with Seeed Studio XIAO ESP32C3.
In review of the datasheet and documentation, I noted some of the main points of functionality / use for the XIAO ESP32C3.
XIAO ESP32C3 Microcontroller Board Front1
XIAO ESP32C3 Microcontroller Board Back1
- There is a USB Type-C connector for primary development interaction with the board
- The board is designed around the ESP32-C3 chip - a 32bit RISC-V single core processor that operates at up to 160 MHz
- There are integrated WiFi and Bluetooth subsystems for wireless communication
- The board also includes buttons for boot and reset, as well as a charge LED that can indicate board connection.
- There are pad connections on the back of the board for battery (up to 3.7V) and other functions. For surface mount on a board this may need to be accounted for.
The board is configured for 3.3V logic, which is very important to note for working with inputs / outputs.
Pinout diagram for the XIAO ESP32C31
There are 14 pins available for connection. Some pins support multiple functions, but overall functionality available covers:
- 3 pins for power functions - 5V, GND, 3.3V
- 10 pins could be used for Digital I/O (D0-D10)
- 3 pins could be used for Analog I/O (A0-A2)
- 2 pins could be used for I2C communication (SDA, SCL)
- 2 pins could be used for UART communication (RX, TX)
- 3 pins could be used for SPI communication (MOSI, MISO, SCK)
The wiki documentation provides sample code for a variety of basic setup and functionality. This includes:
- Software setup with Arduino IDE
- Sample setup / code for basic LED blinking
Programming Process
For exploring the microcontroller operation in simulation, I adopted the Arduino and C/C++ programming environment and process afforded by the Wokwi site for microcontroller simulation.
The microcontroller is operated by a set of instructions specified as a computer program using the C/C++ language. A program in the Arduino environment is referred to as a "Sketch." An Arduino sketch is structured with 2 fundamental parts.
- Setup - the setup part is a set of instructions that runs only once when the sketch first starts. This will happen once when the microcontroller board is powered on or reset. The setup part is used for configuration and initialization, such as:
- including code libraries for additional functionality
- designating a pin on the board as being for input or output
- setting initial values of variables in the program
- Loop - the loop part is a set of instructions that runs over and over continuously. Consecutive runs of loop instructions enables the program to check inputs, change variables / data, and respond with updates or outputs. The loop section of the sketch actively controls the board during operation.
The bare minimum skeleton for an Arduino sketch has 2 functions: one for setup()
and one for loop()
, as shown in the Arduino documentation for Bare Minimum code needed.
Bare Minimum Code for Arduino Sketch | |
---|---|
A simple, functional example of the Arduino code structure is the Blink
sketch for blinking a single LED light, as shown in the Arduino documentation for the Blink example. The example sketch includes the following steps to turn the built in LED on and off continuously:
- setup()
pinMode(LED_BUILTIN, OUTPUT);
- set the designated pin for the builtin LED to be in output mode
- loop ()
digitalWrite(LED_BUILTIN, HIGH);
- set a high voltage level on the builtin LED control pin, in order to turn the LED ondelay(1000);
- wait for 1000 milliseconds (1 second)digitalWrite(LED_BUILTIN, LOW);
- set a low voltage level on the builtin LED control pin, in order to turn the LED offdelay(1000);
- wait for 1000 milliseconds (1 second)
Simulated Board Programming - Interaction
I used the Wokwi site for microcontroller simulation. Wokwi supports the XIAO ESP32C3 as a microcontroller board for simulation, and I wanted to explore the use of the board. Wokwi has a specific section for ESP32 boards. The ESP32 section has a template for XIAO ESP32-C3.
The template for XIAO ESP32-C3 demonstrates a basic application for lighting up a Red, Green, and Blue LED in repeating sequence - each for a brief period of time.
Wokwi template for XIAO ESP32-C3
To explore interaction connecting both inputs and outputs, I modified the Wokwi template for XIAO ESP32-C3. I explored connecting the inputs and outputs for the XIAO by accelerating the speed of the LED sequence in response to a button being pressed. I made the following changes:
- Added a pushbutton
- connected to the D0 pin for input reading
- connection to 3.3V when pressed
- connection to GND with pulldown resistor when not pressed
- Revised the code to change speed in response to the pushbutton
- set a default duration for each LED to display
- check whether the button is pressed
- if the button is pressed, set the duration to be shorter (faster run)
Pushbutton Accelerated LED Setup
Pushbutton Accelerated LED Sequence Demo
Simulated Board Programming - Communication
To explore communication, I considered the WiFi support for ESP32 provided by the Wowki simulator. WiFi support is documented at: Wokwi ESP32 WiFi Networking.
Wowki enables a simulation to connect to a virtual WiFi access point (Wowki-GUEST) in order to access internet connectivity.
The WiFi support page provides a set of project examples. The NTP Client example connects to an NTP server online in order to retrieve the current date and time. The NTP Client example uses a non-XIAO ESP32 developer kit board. It also uses an LCD display that employs the I2C communication protocol for control.
I2C is a serial communication protocol that uses 2 connection lines for communication between a microcontroller (main) and multiple peripheral (secondary) devices, where each peripheral has a unique address to facilitate communication. The two I2C control lines are SDA: (for serial data) and SCL (for serial clock).
NTP Client Example with non-XIAO ESP32 Developer Kit Board
In order to get the experience of developing simulated WiFi connectivity more specifically for my selected XIAO ESP32C3 board, I needed to rework the original NTP Client example from scratch.
I began by opening a new Wokwi starter template for XIAO ESP32-C3. The starter template has the XIAO ESP32C3 development board, but the circuit and code in the template is set up for blinking red / green / blue LED lights only.
Wokwi Starter Template for XIAO ESP32C3 Development Board
In order to develop the NTP Client example for the XIAO ESP32C3 board, I first made the following modifications to the circuit:
- Removed LED light components
- Removed Resistor components
- Added a 16x2 LCD Component (I2C version)
- Connected the ground and power pins from the XIAO ESP32C3 board to the ground and power pins on the LCD
- Connected the I2C control pins (SDA/SCL) from the XIAO ESP32C3 board to the corresponding control pins on the LCD
In order to program the XIAO ESP32C3 board for the NTP Client example, I made the following modifications to the code:
- Removed the RGB LED control code completely
- Copied the NTP Client example code into the XIAO ESP32C3 project
NTP Client Example Circuit and Code Redeveloped for XIAO ESP32C3
Since the microcontroller pins required for connection to the LCD are specific for power, ground and I2C communication (SDA / SCL) pins, no changes to the NTP Client example code were required. The main parts of the code are broken down and described below.
The NTP Client example code consists of the several main parts. The first is that several libraries are included, in order to provide addtional required functionality. The included libraries are:
WiFi.h
- provides functionality for connecting to Wi-Fi for wireless communicationWire.h
- provides functionality for communicating with I2C devicesLiquidCrystal_I2C.h
- provides functionality for controlling I2C liquid crystal displays
#include <WiFi.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
The NTP Client example uses the LiquidCrystal_I2C.h
library to create a program component that represents the specific kind of LCD being used. In this program, the parameters specify the unique address to be used with the LCD, as well as the number of rows and columns available.
The NTP Client example needs to connect to the online service for Network Time Protocol, and includes the required connection details.
#define NTP_SERVER "pool.ntp.org"
#define UTC_OFFSET 0
#define UTC_OFFSET_DST 0
In order to use the LCD for display of status and data, the NTP example defines two helper functions, spinner()
and printLocalTime()
. The spinner()
function tells the LCD to display a spinner, which is a sequence of different shaped glyphs printed over one another at the same spot on the LCD.
void spinner() {
static int8_t counter = 0;
const char* glyphs = "\xa1\xa5\xdb";
LCD.setCursor(15, 1);
LCD.print(glyphs[counter++]);
if (counter == strlen(glyphs)) {
counter = 0;
}
}
The printLocalTime()
function retrieves available time data and tells the LCD how to display the time data. If no time data is currently available, an error message is displayed. If time data is available, the time and date information is formatted and displayed.
void printLocalTime() {
struct tm timeinfo;
if (!getLocalTime(&timeinfo)) {
LCD.setCursor(0, 1);
LCD.println("Connection Err");
return;
}
LCD.setCursor(8, 0);
LCD.println(&timeinfo, "%H:%M:%S");
LCD.setCursor(0, 1);
LCD.println(&timeinfo, "%d/%m/%Y %Z");
}
With all of the libraries, configuration, and helper functions in place, the main parts of the sketch define the setup and operation. The setup()
function does the one-time initialization steps. First, the I2C connection is established with the LCD and a status message for connecting to Wi-Fi is displayed.
Serial.begin(115200);
LCD.init();
LCD.backlight();
LCD.setCursor(0, 0);
LCD.print("Connecting to ");
LCD.setCursor(0, 1);
LCD.print("WiFi ");
Next, the setup()
function attempts to make the connection to Wi-Fi. This uses the WiFi library functionality to connect with the simulated Wokwi Wi-Fi guest network. While the connection is being attempted, the spinner()
function is used to display status. If the Wi-Fi connection is completed, the status is displayed on the LCD, along with the assigned IP address.
WiFi.begin("Wokwi-GUEST", "", 6);
while (WiFi.status() != WL_CONNECTED) {
delay(250);
spinner();
}
Serial.println("");
Serial.println("WiFi connected");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
Next, presuming a Wi-Fi connection has been estalbished, the setup()
function proceeds to display a status update. It then connects to the NTP time service and configures the time on the microcontroller board using the configTime()
function. This completes the setup stage.
LCD.clear();
LCD.setCursor(0, 0);
LCD.println("Online");
LCD.setCursor(0, 1);
LCD.println("Updating time...");
configTime(UTC_OFFSET, UTC_OFFSET_DST, NTP_SERVER);
With the setup complete, the loop()
function continuously repeats a straightforward process of:
- get and print the time using the
printLocalTime()
helper function - pause for a quarter-second before the next update
void loop() {
printLocalTime();
delay(250);
}
The full code for the NTP WiFi Client example is shown below.
The running NTP WiFi Client example redeveloped for the XIAO ESP32C3 is shown below.
NTP WiFi Client for XIAO ESP32C3 Demo