Skip to content

4. Embedded Programming

0. Preparation

0-1: Ideas and Design

  • Fab academy must learn at ten times the speed of self-study. 10x, that is a very attractive word. If we want to learn at the usual speed of 10, we must make full use of everything.

Three updated policies up to Week 03

I Proceed with preparation according to these three points.

step01: Investigate requirements and needs in advance

  • First, take notes on what Neil said during the lecture (in other words, this draft of the document has been created since Tuesday, the day before the lecture).
    • Assignment requirements
      • Create a function linked to the final project.
      • Engage in dialogue and communication.
      • Use a simulator. Then try it on the actual device!
  • Furthermore, utilize IT from here.
    • First, obtain the subtitles from Vimeo as appropriate text data.
    • Next, pass the downloaded subtitle data to chatgpt (model o3-mini-high) and have it extract the requirements.
user_prompt
This file is a lecture on embedded programming for fab academy 2025.
It explains the details of the assignment requirements.
Please summarize the details of the assignment requirements in detail.
LLM response
### **Fab Academy 2025 - Embedded Programming Assignment Requirements (Detailed Summary)**

#### **1. Overview of the Assignment**
- This week is an introduction to **embedded programming**.
- Program a small microcontroller (e.g., ATtiny 412).
- However, this year we will try a new approach, proceeding with the steps of **designing and modeling using a simulator before creating the actual hardware**.
- **Goal:** Each participant will create a custom board and fabricate it after simulation.

---

#### **2. Assignment Requirements**
##### **2.1 Group Assignment**
- **Compare multiple processors**:
  - Compare different architectures (e.g., AVR, ARM, RISC-V, etc.).
  - Understand the characteristics of each processor (speed, memory, power consumption, applications).

##### **2.2 Individual Assignment**
- **Create a program for the microcontroller**:
  - Develop the program in a simulation environment.
  - Implement interaction with input/output devices (e.g., pressing a button lights up an LED).
  - **Optional:** Test the operation on actual hardware.

---

#### **3. Learning Content and Technical Elements**
##### **3.1 Basics of Embedded Systems**
- **Types of Processors**:
  - **AVR (ATtiny series)**: Inexpensive, simple, and easy to use.
  - **ARM (RP2040, SAMD series)**: 32-bit, higher performance, USB compatible.
  - **RISC-V (e.g., ESP32-C3)**: Open-source architecture, strong in wireless communication.

- **Computer Architecture**
  - **Harvard Architecture** vs **Von Neumann Architecture**:
    - Harvard: Program memory and data memory are separated (for high-speed processing).
    - Von Neumann: Both are integrated (high flexibility).

  - **RISC (Reduced Instruction Set Computing)** vs **CISC (Complex Instruction Set Computing)**
    - This lecture will use **RISC-based** microcontrollers.

##### **3.2 Memory and Data Processing**
- **Types of Memory**
  - **Registers**: Fastest memory area (for CPU arithmetic processing).
  - **SRAM**: Fast but high power consumption (working memory).
  - **EEPROM**: Retains data even when the power is off (for saving settings).
  - **Flash Memory**: Stores programs but is difficult to rewrite.

##### **3.3 Programming and Development Environment**
- **Programming Languages Used**
  - **C / C++**: Allows for high-speed and low-level control.
  - **Rust**: A language with enhanced security, but setup is complex.
  - **Python (MicroPython)**: Easy to develop but slow execution speed and high memory consumption.

- **Development Environment (IDE)**
  - **Arduino IDE**: For beginners, based on C++.
  - **VS Code**: A more general development environment.
  - **Thonny**: For MicroPython.

- **Writing Programs**
  - **Arduino Bootloader**
  - **UPDI (1-pin programming for AVR)**
  - **JTAG (debug interface for ARM)**

##### **3.4 Simulation Environment**
- **Wokwi**: Simulation environment for processors (supports RP2040, ESP32, etc.).
- **AVR8js**: Digital and analog simulation for AVR microcontrollers.
- **TinkerCAD Circuits**: Simulator for beginners (not compatible with the latest chips).

##### **3.5 Debugging and Communication**
- **Debugging using Serial Monitor (UART, USB)**
- **Debugging using Embedded Debuggers (GDB, OpenOCD)**
- **Feedback through LED blink and serial communication**

---

#### **4. Deliverables**
- **Simulation Results**
  - Create a program with **input/output** using Wokwi or AVR8js.
  - Example: **Pressing a button lights up an LED or sends a message via serial communication**.

- **Description of the Selected Processor**
  - Why that processor was chosen (applications, performance, price, etc.).

- **Code and Operation Records**
  - The language and development environment used.
  - The implementation process (issues and solutions).
  - Screenshots or logs of output results.

- **(Optional) Confirmation of Operation on Actual Device**
  - If the code was run on an actual microcontroller, record that as well.

---

#### **5. Future Steps**
- This week: Development of embedded programs using simulation.
- **In two weeks:** Design a custom board based on the designed circuit.
- **In four weeks:** Manufacture the board and run the program.

---

### **Summary**
- **Programming based on simulation**  **Processor selection**  **Code creation**  **Debugging and operation confirmation**
- **Ultimately creating a custom board**
- **Learning more advanced programming (C, Rust, Python) and debugging techniques**

      In this assignment, it is required to **utilize the simulator to understand the basic concepts of embedded programming while ultimately selecting a microcontroller suitable for your project**.

Look, the missing requirements have come out.

The requirements that were overlooked in recognition are as follows.

  • Requirements
    • Compare multiple processors:
      • Compare different architectures (e.g., AVR, ARM, RISC-V, etc.).
      • Understand the characteristics of each processor (speed, memory, power consumption, applications).
  • Deliverables
    • Simulation Results
      • Create a program with input/output using Wokwi or AVR8js.
      • Example: Pressing a button lights up an LED or sends a message via serial communication.
    • Description of the Selected Processor
      • Why that processor was chosen (applications, performance, price, etc.).
    • Code and Operation Records
      • The language and development environment used.
      • The implementation process (issues and solutions).
      • Screenshots or logs of output results.
    • (Optional) Confirmation of Operation on Actual Device
      • If the code was run on an actual microcontroller, record that as well.

step02: Buy time efficiency with money and use wisdom to be resourceful

  • I understood that to learn embedded programming from Neil’s lectures, it is necessary to read multiple PDF files of about 500 pages each for one microcontroller.
  • It is indeed difficult to read this amount of PDF files while doing group work, document creation, and working.
  • Therefore, I decided to adopt two specific strategies:
    • Strategy 1: Use Google NotebookLM to prepare an LLM specialized for cheat sheets.
      • I think I would want a personal assistant that can appropriately browse data sheets and provide source information when I ask a little question.
      • Google NotebookLM is an AI research assistant using Gemini provided by Google. By the way, it’s free if you have a Google account! You can’t miss out on this!
      • Get started with NotebookLM and NotebookLM Plus
      • Of course, there are also precautions.

Warning

Google can view the contents of this NotebookLM. Therefore, never let it read confidential information, and only let it read publicly available information!

The information to be read this time is as follows:

  • Xiao RP2040 data sheet
  • Raspberry Pi Pico data sheet
  • ATtiny1614-1616-1617-Auto-DataSheet data sheet
  • Data sheet regarding FT120 USB device controller
  • Wokwi Docs URL link
  • Raspberry Pi Pico data sheet
  • barduino-ftdi-2.0 · master · fablabbcn-projects URL link One of the joys of NotebookLM is that it creates a “study guide.”

The study guide I actually created
RP2040 and Raspberry Pi Pico Study Guide
Quiz
What is the purpose of the BOOTSEL mode in the Raspberry Pi Pico?
Where can you find information about recommended operating conditions for the Raspberry Pi Pico?
What does GPIO stand for, and where in the datasheet is this topic covered?
Why is the chip called RP2040?
What is the role of the AHB-Lite Crossbar in the RP2040's system architecture?
What is the purpose of the SIO block within the processor subsystem?
Describe the function of the Interpolator in the RP2040.
What is the purpose of the Bootrom in the RP2040, and what is the RPI-RP2 Drive?
Explain the purpose of PLLs in the RP2040.
What is the function of the Watchdog timer?
Quiz Answer Key
BOOTSEL mode allows the Raspberry Pi Pico to be recognized as a mass storage device when connected to a computer via USB, allowing users to easily program the flash memory. It's typically entered by holding the BOOTSEL button while powering on or resetting the Pico.
Information regarding recommended operating conditions for the Raspberry Pi Pico can be found in Section 2.3 of the "pico-datasheet.pdf" document, which specifies voltage and temperature ranges.
GPIO stands for General Purpose Input/Output, and this topic is covered in Section 4.2 of the "pico-datasheet.pdf," and in section 2.18 of the "rp2040_datasheet.pdf." It refers to pins that can be configured by the user for various input or output functions.
The RP2040's name reflects Raspberry Pi's internal project numbering: RP stands for Raspberry Pi, and 2040 was simply the project number assigned during development. The datasheet explains the chip's naming convention.
The AHB-Lite Crossbar acts as a central interconnect, allowing multiple master devices (like CPUs and DMA controllers) to access multiple slave devices (like memory and peripherals) concurrently, maximizing data throughput. It facilitates communication between different components within the RP2040.
The SIO (Single-cycle I/O) block provides direct, single-cycle access to GPIO pins and other system functions, offering a low-latency interface for time-critical operations. It enables fast interaction with external devices.
The Interpolator is a hardware accelerator that performs fast linear interpolation calculations, often used in graphics applications like texture mapping. It efficiently calculates intermediate values between two endpoints.
The Bootrom is a small read-only memory containing code that executes upon power-up or reset, and the RPI-RP2 Drive is the name of the USB mass storage device that appears when the RP2040 is in BOOTSEL mode. The Bootrom initializes the system and allows programming of the flash memory.
PLLs (Phase-Locked Loops) are used to generate stable, high-frequency clock signals from a lower-frequency reference clock. They are essential for precisely timing the operation of various components within the RP2040.
The Watchdog timer is a safety mechanism that resets the system if the software fails to "kick" (reset) the timer within a specified period. It prevents the system from getting stuck in an infinite loop or other error state.
Essay Questions
Discuss the RP2040's power supply architecture. What are the different voltage domains, and why is power supply sequencing important?
Explain the boot sequence of the RP2040. How does the Bootrom function, and what are the different ways to program the flash memory?
Describe the PIO (Programmable Input/Output) subsystem of the RP2040. What are its key features, and how can it be used to implement custom peripherals?
Compare and contrast the different clock sources available in the RP2040. What are the trade-offs between them in terms of accuracy, stability, and power consumption?
Explain the role of interrupts in the RP2040 system. How are interrupts handled by the NVIC, and how can they be used to implement responsive and efficient software?
Glossary of Key Terms
ADC (Analog-to-Digital Converter): A peripheral that converts analog voltage signals into digital values that can be processed by the microcontroller.
AHB-Lite: A simplified version of the Advanced High-performance Bus (AHB) protocol, used for high-speed data transfers within the RP2040.
APB (Advanced Peripheral Bus): A bus protocol used for communication with slower peripherals in the RP2040.
Atomic Register Access: A mechanism ensuring that a read-modify-write operation on a register is performed as a single, uninterruptible transaction.
BOOTSEL mode: A mode where the RP2040 is recognized as a USB mass storage device to facilitate easy flash programming.
Bootrom: A small read-only memory containing code that runs upon power-up or reset to initialize the system.
CPUID (CPU Identifier): A register containing information about the CPU, such as its architecture and features.
Cortex-M0+: An ARM processor core used in the RP2040, known for its low power consumption and efficient instruction set.
DMA (Direct Memory Access): A feature that allows peripherals to access memory directly, without involving the CPU, increasing data transfer efficiency.
DORMANT State: A low-power sleep mode where most of the RP2040's functionality is turned off to conserve energy.
FIFO (First-In, First-Out): A data structure where the first element added is the first one removed, used for buffering data between different components.
GPIO (General Purpose Input/Output): Pins on the RP2040 that can be configured as either inputs or outputs, allowing interaction with external devices.
I2C (Inter-Integrated Circuit): A serial communication protocol commonly used for connecting low-speed peripherals.
Interpolator: A hardware accelerator for performing fast linear interpolation calculations.
IRQ (Interrupt Request): A signal indicating that a peripheral needs attention from the CPU.
MPU (Memory Protection Unit): A hardware unit that allows the operating system to define memory regions with specific access permissions, enhancing security and stability.
NVIC (Nested Vectored Interrupt Controller): A component that manages interrupts in the Cortex-M0+ processor.
PIO (Programmable Input/Output): A flexible subsystem allowing the creation of custom peripherals through programmable state machines.
PLL (Phase-Locked Loop): A circuit used to generate stable, high-frequency clock signals.
Power-on Reset: A reset that occurs when power is first applied to the RP2040.
Ring Oscillator (ROSC): An on-chip oscillator that can be used as a clock source.
RP2040: The microcontroller chip at the heart of the Raspberry Pi Pico.
RPI-RP2 Drive: The USB mass storage device that appears when the RP2040 is in BOOTSEL mode, enabling easy file drag and drop programming..
SPI (Serial Peripheral Interface): A synchronous serial communication interface used for connecting peripherals.
Surface-mount Footprint: The physical layout of pads on a PCB for soldering a surface-mount component.
SWD (Serial Wire Debug): A debugging interface that allows the programmer to step through code and inspect memory.
Syscfg (System Configuration): A module that configures system-level settings.
Sysinfo (System Information): A module that provides information about the system.
UART (Universal Asynchronous Receiver/Transmitter): A serial communication interface commonly used for asynchronous data transmission.
UF2: A file format used for programming the flash memory of the RP2040.
USB PICOBOOT Interface: A communication interface via USB to program the flash memory.
VBUS: The 5V power line from a USB connection.
Watchdog: A timer that resets the system if the software fails to reset it within a specified time.
XIP (eXecute In Place): A technique that allows the processor to execute code directly from flash memory without copying it to RAM first.
XOSC (Crystal Oscillator): An oscillator circuit using a crystal as its frequency determining element.
This will improve learning efficiency!

By the way, it is generally displayed in the language set in the Google account. However, there may be times when you want it to be displayed in English, like this time. In that case, you can change the display language of NotebookLM to English by adding “?hl=en” to the end of the URL. For example, for this URL, it would look like this:

https://notebooklm.google.com/notebook/your.notebook.ml.id?hl=en

step3: Use Readble to translate the data sheet into Japanese

Of course, directly accessing primary information is very important for building a mental model. Data sheets are all written in English, which can be a bit of a barrier for native Japanese speakers to learn quickly. Therefore, this time we will use the paid service “Readable.” It is unlimited for less than 1000 yen per month. There’s no reason not to use it.

  • readable.jp
    • Readable is a service that can translate English PDF files into Japanese while maintaining the original layout. Its strength is that the layout does not break even after translation. Additionally, it can create PDFs that allow you to check English and Japanese side by side. This makes it convenient to quickly check translations that might be confusing.
    • The downside is that it can only read 100 pages. Let’s cut the PDF into appropriate sections.

step4: Conduct preliminary research and learning

01. Group work

In the group work, the following was implemented.

  • Comparison and demonstration of toolchains and development workflows in multiple embedded architectures.
    • Microcontrollers used:
      • AVR ATmega328P (using Arduino UNO as ISP)
      • ARM SAMD11C (using XiaoSAM21 as DAPLink device)
      • Xtensa ESP32 (programming via USB serial cable)
  • Demonstration of configuration and code writing methods for each microcontroller.
    • Installed Arduino IDE and used Arduino UNO as a programmer.
    • As an example of a program, a sketch was used where LEDs blink alternately.

For details, please refer to the group work page.

https://fabacademy.org/2025/labs/kannai/Weekly_Group_Assignment/week04/

02. individual assignment_part01_simulation

02-1: First, let’s get used to simulation using Wokwi!

First, you need to get used to Wokwi itself.

https://wokwi.com/

Run the sample code introduced in the lecture for now.

docs/images/98_input_image/week04-v01-01.mp

02. individual assignment_part01_simulation

02-1: First, let’s get used to simulation using Wokwi!

First, you need to get used to Wokwi itself.

https://wokwi.com/

Run the sample code introduced in the lecture for now.

02-2: Getting stuck in parallel processing

What caught my attention was the following code.

https://academy.cba.mit.edu/classes/embedded_programming/RP2040/hello.button-blink.RP2040.2.py

#
# hello.button-blink.RP2040.2.py
#
# Seeed XIAO RP2040 button, blink, echo hello-world, two threads
#
# Neil Gershenfeld 12/28/23
#
# This work may be reproduced, modified, distributed,
# performed, and displayed for any purpose, but must
# acknowledge this project. Copyright is retained and
# must be preserved. The work is provided as is; no
# warranty is provided, and users accept all liability.
#
# load RP2040 MicroPython
#    https://micropython.org/download/RPI_PICO/
#    https://thonny.org/    
#
from machine import Pin
import sys,select,time,asyncio
#
# set up pins
#
led_pin = 1
button_pin = 0
led = Pin(led_pin,Pin.OUT)
button = Pin(button_pin,Pin.IN,Pin.PULL_UP)
button_up = True
#
# define thread 0
#
async def thread0():
   while True:
      ready = select.select([sys.stdin],[],[],0)[0]
      if (ready != []):
        line = ready[0].readline().rstrip()
        if (line != ''):
            led.value(1)
            print('you typed:',line)
            time.sleep(0.1)
            led.value(0)
      await asyncio.sleep(0) # pause for cooperative multitasking

#
# define thread 1
#
async def thread1():
   global button_up
   while True:
      if ((button.value() == 0) and button_up):
         led.value(1)
         print('button down')
         button_up = False
      elif ((button.value() == 1) and (not button_up)):
         led.value(0)
         print('button up')
         button_up = True
      await asyncio.sleep(0) # pause for cooperative multitasking
#
# define thread tasks in main
#
async def main():
    thread0_task = asyncio.create_task(thread0())
    thread1_task = asyncio.create_task(thread1())
    await asyncio.gather(thread0_task,thread1_task)
#
# run main
#
asyncio.run(main())

Why is it threaded?

I asked chatGPT.

user prompt
The following code is a sample code that runs on the Raspberry Pi Pico.
Please explain the intention of separating the threads into two.
system_response by chatgpt-o4
### **`asyncio` Role and Operation**
In this code, **`asyncio` (asynchronous processing library)** is used to achieve cooperative multitasking.  
In MicroPython, it is common to use asynchronous tasks (`asyncio`) for parallel processing **without directly using threads (`_thread`)**.

---

## **Reasons for Using `asyncio`**
1. **Achieve concurrent processing**
   - Python's `asyncio` provides **pseudo-multithreading**.
   - Functions defined with `async def` (asynchronous functions) operate **concurrently**.

2. **Efficient use of CPU**
   - By appropriately inserting `await asyncio.sleep(0)`, it can operate **while passing control to other processes**.
   - This allows for proper scheduling without wasting CPU resources.

3. **Lighter than threads**
   - Python's **normal threads (`_thread`) have more overhead**.
   - Using threads incurs context switch (switching cost), but `asyncio` is efficient because tasks explicitly pass control.

---

## **How `asyncio` is Used in This Code**
In this code, `asyncio` is utilized as follows.

### **1. Asynchronous Tasks Using `async def`**

python
async def thread0():
   while True:
      ready = select.select([sys.stdin],[],[],0)[0]
      if (ready != []):
        line = ready[0].readline().rstrip()
        if (line != ''):
            led.value(1)
            print('you typed:',line)
            time.sleep(0.1)
            led.value(0)
      await asyncio.sleep(0)  # Here, control is passed to other processes

- **Task monitoring keyboard input**  
- By using `await asyncio.sleep(0)`, it yields processing to button monitoring (`thread1`).

---

python
async def thread1():
   global button_up
   while True:
      if ((button.value() == 0) and button_up):
         led.value(1)
         print('button down')
         button_up = False
      elif ((button.value() == 1) and (not button_up)):
         led.value(0)
         print('button up')
         button_up = True
      await asyncio.sleep(0)  # Here, control is passed to other processes

- **Task monitoring button presses**  
- By using `await asyncio.sleep(0)`, it cooperates with other processes (i.e., `thread0`).

---

### **2. Concurrent Execution of Asynchronous Tasks with `asyncio.create_task()`**
python
async def main():
    thread0_task = asyncio.create_task(thread0())  # Task for thread0
    thread1_task = asyncio.create_task(thread1())  # Task for thread1
    await asyncio.gather(thread0_task,thread1_task)  # Execute both tasks in parallel

- `asyncio.create_task()` registers `thread0` and `thread1` as tasks.
- `await asyncio.gather(thread0_task, thread1_task)` **executes both tasks concurrently**.

---

### **3. Start Asynchronous Event Loop with `asyncio.run(main())`**

python
asyncio.run(main())

- `asyncio.run(main())` **starts the asynchronous event loop**.
- Inside `main()`, **both asynchronous tasks `thread0` and `thread1` are executed concurrently**.

---

## **Problems Without Using `asyncio`**
If you wrote the processing using a normal `while` loop without `asyncio`:
1. **`while True` would occupy the CPU, preventing other processes from running**
2. **While monitoring the button, standard input checks cannot be performed**  Responsiveness worsens
3. **Without adjusting sleep time, proper concurrent processing cannot be achieved**

 To prevent this, **asynchronous processing (`asyncio`) is used to efficiently perform concurrent processing**.

---

## **Summary**
- **Using `asyncio`, button monitoring and keyboard input can be processed concurrently**
- **`await asyncio.sleep(0)` appropriately passes control to other processes**
- **`asyncio.create_task()` allows for parallel execution of two asynchronous tasks**
- **Lighter than traditional threads (`_thread`), making it suitable for resource-constrained environments like Raspberry Pi Pico**

In this way, **using `asyncio` allows for smooth simultaneous execution of multiple processes**.

I found this content to be reasonably convincing. However, I realized that I didn’t know much about asyncio, so I checked the official Python documentation.

asyncio is a library to write concurrent code using the async/await syntax.
asyncio is used as a foundation for multiple Python asynchronous frameworks that provide high-performance network and web-servers, database connection libraries, distributed task queues, etc.
asyncio is often a perfect fit for IO-bound and high-level structured network code.
asyncio provides a set of high-level APIs to:
- run Python coroutines concurrently and have full control over their execution;
- perform network IO and IPC;
- control subprocesses;
- distribute tasks via queues;
- synchronize ; https://docs.python.org/3.13/library/asyncio.html

Then, I wanted to check what await is.

This is “yak_shaving”! I bet I can make a lot of coats OR cords. Yay!

yak_shaving
1. Any apparently useless activity which, by allowing one to overcome intermediate difficulties, allows one to solve a larger problem.
I was doing a bit of yak shaving this morning, and it looks like it might have paid off.

2. A less useful activity done consciously or subconsciously to procrastinate about a larger but more useful task.
I looked at a reference manual for my car just to answer one question, but I spent the whole afternoon with my nose buried in it, just yak shaving, and got no work done on the car itself.

https://en.wiktionary.org/wiki/yak_shaving

As I was researching, I came across the concept of Awaitable.

We say that an object is an awaitable object if it can be used in an await expression. Many asyncio APIs are designed to accept awaitables.

There are three main types of awaitable objects: coroutines, Tasks, and Futures.

https://docs.python.org/3.13/library/asyncio-task.html#id3

Next, I will dig into Python code. I will use Haystackediter to explore further.

Haystackediter
Navigate and refactor your code with ease

https://haystackeditor.com/

usr > local > Cellar > python@3.12 > 3.12.7.1 > Frameworks > Python.framework > Versions > 3.12 > lib > python3.12 > asyncio > tasks.py
@types.coroutine
def __sleep0():
    """Skip one event loop run cycle.

    This is a private helper for 'asyncio.sleep()', used
    when the 'delay' is set to 0.  It uses a bare 'yield'
    expression (which Task.__step knows how to handle)
    instead of creating a Future object.
    """
    yield


async def sleep(delay, result=None):
    """Coroutine that completes after a given time (in seconds)."""
    if delay <= 0:
        await __sleep0()
        return result

    loop = events.get_running_loop()
    future = loop.create_future()
    h = loop.call_later(delay,
                        futures._set_result_unless_cancelled,
                        future, result)
    try:
        return await future
    finally:
        h.cancel()

I understand that there is a decorator, but what does it mean?

user_prompt
What does @types.coroutine mean?
system_response_chatgpto4
A coroutine function is a function defined in Python for writing asynchronous processing, using the `async def` syntax. When this function is called, a coroutine object is returned immediately, and execution does not start. To start the execution of the coroutine object, you need to explicitly wait using `await`, or use functions like `asyncio.run()` or `asyncio.create_task()` to register it with the event loop.

Within a coroutine function, you can use the `await` keyword to wait for the completion of other coroutines. This allows you to write asynchronous processing in a linear and synchronous-like manner, avoiding complex callback hell.

Here is a basic example of a coroutine function. In this example, `asyncio.sleep()` is used to asynchronously wait for one second and then display a message.

python
import asyncio

async def my_coroutine():
    print("Starting process")
    await asyncio.sleep(1)
    print("Waited for 1 second")

async def main():
    await my_coroutine()

asyncio.run(main())

When you run this code, you will get the following output:

Starting process
Waited for 1 second

In this way, using coroutine functions allows you to write asynchronous processing simply and efficiently. 

I see! I can explicitly command that it is asynchronous! That’s super convenient!

I have spent two hours on this so far…

02-3: Arranging resistors and LEDs on the actual device

  • LEDs can break if the current is too high. To lower it, a resistor is placed in between (either before or after is fine).
  • I haven’t touched a resistor in a while.
  • In general, in Japanese industrial high schools, students memorize the color and number association of resistors, and up to binary 10 digits (1024) is memorized in the first semester of the first year.
  • There is a mnemonic for memorization, and students are usually taught to memorize it in a similar way.
  • When I shared this story in the group work, people were surprised. Isn’t this common? I didn’t know…
  • By the way, the mnemonic is as follows. Since it doesn’t make sense to put it in English, I will write it in Japanese.
「黒いレース(0)」
「小林一茶(1)」
「赤いニンジン(2)」
「第(橙)三者(3)」
「四季(黄)の色(4)」
「緑はGO(信号の緑は進むの意味)(5)」
「青むし(6)」
「紫式(七)部(7)」
「ハイヤー(8)」
「ホワイトクリスマス(9)」

Read the color code of resistors like this! Recognize resistance values and errors at a glance (in Japanese)

Big Boys Race Our Young Girls But Violet Generally Wins.
Better Be Right Or Your Great Big Venture Goes West.[1]
Beetle Bailey Runs Over Your General Before Very Good Witnesses.
Beach Bums Rarely Offer You Gatorade But Very Good Water.
Buster Brown Races Our Young Girls But Violet Generally Wins.
Better Be Right Or Your Great Big Vacation Goes Wrong.
Better Be Right Or Your Great Big Values Go Wrong.
Better Be Right Or Your Great Big Plan Goes Wrong. (with P = Purple for Violet)
Back-Breaking Rascals Often Yield Grudgingly But Virtuous Gentlemen Will Give Shelter Nobly. (with tolerance bands Gold, Silver or None)
Better Be Right Or Your Great Big Plan Goes Wrong - Go Start Now!
Black Beetles Running Over Your Garden Bring Very Grey Weather.
Bad Booze Rots Our Young Guts But Vodka Goes Well – get some now.[2]
Bad Boys Run Over Yellow Gardenias Behind Victory Garden Walls. [3]
Bat Brained Resistor Order You Gotta Be Very Good With.
Betty Brown Runs Over Your Garden But Violet Gingerly Walks.
Big Beautiful Roses Occupy Your Garden But Violets Grow Wild.
Big Brown Rabbits Often Yield Great Big Vocal Groans When Gingerly Slapped Needlessly.[4][5][6]
Black Bananas Really Offend Your Girlfriend But Violets Get Welcomed.
Black Birds Run Over Your Gay Barely Visible Grey Worms.
Badly Burnt Resistors On Your Ground Bus Void General Warranty.
Billy Brown Ran Out Yelling Get Back Violets Getting Wet.
Better Be Right Or You're Gonna Be Violently Gouged With Golden Spaghetti.
Bright Boys Rave Over Young Girls But Veto Getting Wed.
Black Bears Raid Our Yellow Green Bins Violently Grabbing Whatever Goodies Smell Nice.
Bad Bears Raid Our Yummy Grub But Veto Grey Waffles.
By Being Revolutionary, Our Young Girls Become Very Great Women.
Bachelor Boys Rush Our Young Girls But Veronica Goes Wild for Gold or Silver Necklaces.

02-3: Soldering

I will solder the pins of the rp2040. It was very helpful that I could do it at Fablab since I don’t have a soldering iron at home.

02-4: Question: How to differentiate between Arduino and Python?

I suddenly became curious about how to differentiate between Arduino and Python (Raspberry Pi).

Upon researching, I found a very easy-to-understand article.

https://qiita.com/akinami/items/f5b58689d546698d1ff9

Below is a summary generated by ChatGPT
In coding with Raspberry Pi, I will explain the differentiation and characteristics of Arduino and Python.

**Differences between Arduino and Raspberry Pi**

First, both Arduino and Raspberry Pi are widely used devices in electronics, but their design philosophies and applications differ.

- **Arduino**: A microcontroller board without an OS, suitable for simple control and processes requiring real-time performance.

- **Raspberry Pi**: A small computer equipped with a Linux-based OS, capable of complex processing and multitasking.

**Characteristics of Python on Raspberry Pi**

Since Raspberry Pi operates on an OS, it can use many programming languages, including Python. Python is simple and readable, with a wealth of libraries available, making it suitable for development on Raspberry Pi. It is particularly well-suited for advanced applications such as data processing, web server construction, and machine learning.

**Differentiating between Arduino and Python**

In coding with Raspberry Pi, Arduino and Python can be differentiated as follows:

- **Control requiring real-time performance**: Arduino is suitable for tasks that require high real-time performance since it does not have an OS. For example, it is suitable for timing-critical processes such as data acquisition from sensors or motor control.

- **Complex processing or multitasking**: By using Python on Raspberry Pi, applications can be developed that perform complex data processing or execute multiple tasks simultaneously. For example, it is possible to build web servers, manipulate databases, and run machine learning models.

**How to utilize them in combination**

By combining Arduino and Raspberry Pi, systems can be built that leverage the strengths of each. For example, Raspberry Pi can perform image processing or data analysis, and based on the results, Arduino can control hardware such as motors or LEDs.
**Summary**

In coding with Raspberry Pi, Arduino and Python each have different characteristics and areas of expertise. It is effective to use Arduino for simple control requiring real-time performance, and to use Python on Raspberry Pi for complex processing or multitasking. Additionally, by combining both, it is possible to build more flexible and high-functioning systems.

02. individual assignment_part02_Operational Check Using Actual Device

02-00. Prologue

  • I decided to use the Xiao rp2040.
    • To be honest, I was unsure about what to do.
    • First, let’s write out an execution plan. I believe that actions involving complexity can be achieved through verbalization and design.

02-01. Establishing an Execution Plan

  • This time, I am considering executing in the following order:
    • step01. Connect to PC via Type-C
    • step02. Investigate and read the Xiao guidebook.
    • step03. Find and implement a simple tutorial for Xiao.
    • step04. Think of specifications that meet the requirements of the individual assignment and implement them on the actual device.
    • step05. Consider specifications that meet the requirements of the final project.
  • This time, I have temporarily separated the individual assignment and the final project. The reason is that I am not very familiar with the Xiao rp2040. I believe that understanding the subject is essential for design.

02-02. step01: Connect to PC via Type-C

  • When I connected it, it started to blink.

02-03: Read XIAO_Big_Power_Small_Board-ebook to Gain Knowledge

At the end of the xiao pr2040 page, I found an e-book called XIAO_Big_Power_Small_Board. All skill acquisition begins with knowledge collection. First, I will read it. Below are the questions that arose while reading and the results of my investigations.

Q01: Who is the target audience for this book?

  • It is stated as follows in “about this book.”
    • https://mjrovai.github.io/XIAO_Big_Power_Small_Board-ebook/about_book.html
      By the end of this book, the reader will understand:
      The fundamentals of open-source hardware, focusing on the capabilities of the Seeed Studio XIAO series.
      How to transition from basic to advanced electronic projects, starting with simple LED controls and advancing to complex applications like telemetry and voice keyword detection.
      The concepts behind prototype design and its practical implications in product development.
      The intricacies of integrating various modules like the infrared receiver, ultrasonic distance sensor, and RTC clock with the XIAO platform.
      The significance and application of Tiny Machine Learning (TinyML), emphasizing its transformative power in hardware like the XIAO nRF52840 Sense and ESP32S3 Sense.
      Techniques to utilize advanced tools such as Edge Impulse Studio for real-world applications like anomaly and object detection and video or sound classification.
      The reader will be able to:
      Set up, program, and troubleshoot projects across all XIAO series boards, advancing from basic hardware interactions to intricate project designs.
      Convert abstract ideas into tangible electronic product prototypes, leveraging the insights from the course.
      Design and implement intermediate-level projects such as a Smart Watch and Air Piano using specialized sensors and modules.
      Harness the power of Wi-Fi and MQTT protocols with XIAO ESP32C3 for cloud communications and data exchange.
      Deploy TinyML on different XIAO boards, executing tasks like image, motion, and sound classification besides anomaly and object detection.
      Innovate and extend project ideas, drawing inspiration from a curated collection of XIAO projects and adapting them for custom needs.
      
  • It seems that my expectations were correct! I am confident that reading this book will greatly deepen my understanding.
    • Probably, if I read up to “Chapter 3: Intermediate Project Practice—Complex Projects,” I will be able to do roughly what “extra credit” is, and the subsequent “Chapter 4: Project Practice Advanced - tinyML Application” seems to be closely related to the final project.
    • In any case, I have strengthened my motivation to read it.

Q02: What is the Json being loaded into the IDE?

  • It is mentioned that a specific Json URL should be set in the Arduino IDE. What exactly is written in this Json file?
  • Upon examining the contents, there were package information, platform information, system-related information, and references lined up. A total of 26738 lines. It seems that all references are looking at github.com/earlephilhower. Upon researching, it appears that Earle F. Philhower, III is a developer of Arduino.

Q03: How to reset the RP2040?

  • Resetting the RP2040 is very simple. You just need to press a button. I think this is a significant improvement compared to the Seeed Studio XIAO SAMD21, which required shorting.

step03. Find and Implement a Simple Tutorial for Xiao.

From here, I will implement the simple tutorial mentioned in XIAO_Big_Power_Small_Board.

Videos of the actual implementation * delay(1000)

  • delay(300)
  • delay(100)

You can clearly see that the blinking interval of the LED has changed.

Trouble: No jumper wires!

Here, trouble occurred. I forgot to bring the jumper wires needed to construct the electronic circuit during the local session…

Since there’s no helping it, I decided to go shopping at the holy land of electronic components, “Tokyo: Akihabara.”

  • Akizuki Denshi Tsusho
    • You can buy electronic components cheaply.

  • Marutsu
    • The only exclusive distributor of Digikey in Japan, with the same prices as on the website.

  • Items purchased 1 . Set of breadboard and jumper wires
  • I was able to buy it cheaply as a set from Akizuki Denshi Tsusho.

2 . Rotary potentiometer

3 . Seeed Studio XIAO expansion board

4 . Tweezers

  • I purchased them to make it easier to work since the electronic components are very small.

5 . 4-pin jumper wires

  • Since the Seeed Studio XIAO expansion board supports 4 pins, I purchased these additionally.

6 . XIAO ESP32C3

Note

I purchased a soldering iron and solder because I didn’t have them at home. They are scheduled to be delivered on February 20 (Thursday) via Amazon. Once they arrive, I will solder the pins of the Xiao ESP 32c3 and try to implement chapter 3-4.

Placing buttons to control the external LED.

I will refer to the code executed in the simulation and run it on the actual device.

In the simulator, it was a Raspberry Pi Pico, but since the actual device is a Xiao RP2040, the pin positions are different. Therefore, I will refer to the comparison table and place the buttons accordingly.

The pin comparison table was helpful from the following site:

https://otoku-pc.com/xiao-rp2040-pinout/

  • The programming language used was Arduino, and the IDE used was Arduino IDE.
  • You can download the code from here.
    • Code

Q06: What are the differences between XIAO ESP32C3 and RP2040?

Earlier, I purchased the ESP32C3 at Akizuki Denshi Tsusho. Are there any differences between this microcontroller and the RP2040 besides whether it has built-in Wi-Fi or not?

Let’s check while comparing the datasheets.

Q06-01: What is the origin of the name?

  • RP2040. It is a microcontroller with two Cortex-M0+ cores used in Raspberry Pi, with 4 RAMs and no non-volatile memory (0). Very easy to understand.

  • ESP32C3
    • The naming convention for the chip series does not seem to be mentioned in the datasheet.
    • Upon investigation, it seems that it was released as a product of Espressif. ESP might be an abbreviation for Espressif?

Q06-02: What are the specific performance differences?

  • I referred to the datasheets and created a comparison table.
Feature XIAO ESP32C3 XIAO RP2040
Microcontroller ESP32-C3 (32-bit RISC-V, up to 160MHz) RP2040 (Dual-core ARM Cortex-M0+, up to 133MHz)
Memory 400KB SRAM, 4MB Flash memory 264KB SRAM, 2MB onboard Flash memory
Wireless Communication Built-in Wi-Fi and Bluetooth 5 (LE) No wireless communication capabilities
Interface 11× Digital I/O pins, 4× Analog I/O pins, 1× I2C, 1× SPI, 2× UART, 1× JTAG, PWM supported 11× Digital I/O pins, 4× Analog I/O pins, 1× I2C, 1× SPI, 1× UART, 1× SWD, PWM supported
Power Management Equipped with a built-in battery charging chip No battery charging chip
Programming Compatible with Arduino, MicroPython, CircuitPython Compatible with Arduino, MicroPython, CircuitPython

XIAO ESP32C3 is suitable for IoT projects that require wireless communication or low power consumption applications. On the other hand, XIAO RP2040 is suitable for data processing that takes advantage of its high-performance dual-core processor and projects that do not require wireless communication.

Note: If you feel this applies to you, please read this book.

For those who came looking for hints as Fab academy students

Chapters 2 and 3 describe a series of processes to create specific prototypes. I believe it will be helpful to you.

To my project members

Let’s read the original text of Chapters 2, 3, and 4 together. Here, you can deepen your understanding of creating prototypes. This is closely related to our areas of PoC, MVP, HCD, and PMF. Don’t worry. I will follow up on the parts that are difficult to understand.

For those who have no time but want to learn about prototyping quickly

I think it would be good to read at least Chapter 2-1. It condenses the mindset, principles, processes, and examples of prototyping.

step04. Consider specifications that meet the requirements of the individual assignment

  • So far, I have read up to Chapter 4. With sufficient knowledge, I will reconsider the specifications that meet the requirements of the individual assignment.
  • That said, I think it would be good if I could reproduce the interactive sample code that Neil has already prepared on the actual device.

Here is the code:

https://gitlab.fabcloud.org/academany/fabacademy/2025/labs/kannai/students/shintaro-ito/-/raw/main/code/week04_03_dialogue_bottun_led/week04_03_dialogue_bottun_led.ino?ref_type=heads

You can see the operation in this video.

Looking back, I spent 90% of my time on preparation and knowledge input. However, I feel that this method is the best for me. The most terrifying thing is to execute blindly without understanding and succeed without learning. Even if we randomly hit the keyboard and produce the works of William Shakespeare, no one will be happy (infinite monkey theorem). There is no next step to success without growth.

step05. Consider specifications that meet the requirements of the final project.

Rough specifications

  • Brush
    • Strength
    • ON/OFF
    • Timer (3 minutes)
  • Propeller
    • ON/OFF
    • Timer (5 minutes)
  • Pump
    • ON/OFF
    • Turns OFF in sync with the brush operation
  • Power status monitoring
    • When the power is low, the red LED lights up
    • When charging, the blue LED 1 lights up
  • LED indicating power ON/OFF
    • When ON, the blue LED 2 lights up
  • Mechanism for switching power from one motor for the brush, propeller, and pump
    • When the brush is ON
      • If the switch’s initial value is not the brush, it changes to the brush before the switch turns ON
      • If the switch’s initial value is the brush, the switch turns ON as is
    • When the propeller is ON
      • If the switch’s initial value is not the propeller, it changes to the propeller before the switch turns ON
      • If the switch’s initial value is the propeller, the switch turns ON as is

Next, I will start coding.

final project code.ino
# Definition section: Setting each pin
#define BRUSH_PIN D2  // Control pin for the brush
#define PROPELLER_PIN D3  // Control pin for the propeller
#define PUMP_PIN D4  // Control pin for the pump
#define SWITCH_PIN D6  // Motor switch control pin
#define LED_RED D7  // Warning LED for low power
#define LED_BLUE1 D8  // Indicator LED for charging
#define LED_BLUE2 D9  // Indicator LED for power ON
#define POWER_SENSOR_PIN A0  // Power monitoring sensor
#define CHARGING_STATUS_PIN A1  // Charging status sensor

// Variables for timer control
unsigned long brushStartTime = 0;
unsigned long propellerStartTime = 0;
bool brushState = false;
bool propellerState = false;
bool pumpState = false;
int currentMode = -1; // -1: none, 0: brush, 1: propeller

void setup() {
    // Set each pin as input or output
    pinMode(BRUSH_PIN, OUTPUT);
    pinMode(PROPELLER_PIN, OUTPUT);
    pinMode(PUMP_PIN, OUTPUT);
    pinMode(SWITCH_PIN, OUTPUT);
    pinMode(LED_RED, OUTPUT);
    pinMode(LED_BLUE1, OUTPUT);
    pinMode(LED_BLUE2, OUTPUT);
    pinMode(POWER_SENSOR_PIN, INPUT);
    pinMode(CHARGING_STATUS_PIN, INPUT);
    Serial.begin(115200); // Start serial communication
}

void loop() {
    checkPowerStatus(); // Monitor power status
    handleBrush(); // Manage brush operation
    handlePropeller(); // Manage propeller operation
    handlePump(); // Manage pump operation
}

// Monitor power and control LEDs
void checkPowerStatus() {
    int powerLevel = analogRead(POWER_SENSOR_PIN);
    int chargingStatus = digitalRead(CHARGING_STATUS_PIN);

    // Light up red LED when power is low
    if (powerLevel < 500) {
        digitalWrite(LED_RED, HIGH);
    } else {
        digitalWrite(LED_RED, LOW);
    }

    // Light up blue LED1 when charging
    if (chargingStatus == HIGH) {
        digitalWrite(LED_BLUE1, HIGH);
    } else {
        digitalWrite(LED_BLUE1, LOW);
    }
}

// Manage brush operation
void handleBrush() {
    if (brushState) {
        // Stop the brush after 3 minutes
        if (millis() - brushStartTime >= 180000) {
            brushState = false;
            digitalWrite(BRUSH_PIN, LOW);
            pumpState = false;
            digitalWrite(PUMP_PIN, LOW);
        }
    }
}

// Manage propeller operation
void handlePropeller() {
    if (propellerState) {
        // Stop the propeller after 5 minutes
        if (millis() - propellerStartTime >= 300000) {
            propellerState = false;
            digitalWrite(PROPELLER_PIN, LOW);
        }
    }
}

// Manage pump operation (synchronized with brush state)
void handlePump() {
    if (brushState) {
        digitalWrite(PUMP_PIN, HIGH);
    } else {
        digitalWrite(PUMP_PIN, LOW);
    }
}

// Motor switching process
void switchMotorMode(int mode) {
    if (currentMode != mode) {
        digitalWrite(SWITCH_PIN, LOW);
        delay(100); // Wait time for switch change
        currentMode = mode;
        digitalWrite(SWITCH_PIN, HIGH);
    }
}

// Function to activate the brush
void activateBrush() {
    brushStartTime = millis(); // Record start time
    brushState = true;
    switchMotorMode(0); // Set switch to brush
    digitalWrite(BRUSH_PIN, HIGH);
    pumpState = true; // Activate pump simultaneously
}

// Function to activate the propeller
void activatePropeller() {
    propellerStartTime = millis(); // Record start time
    propellerState = true;
    switchMotorMode(1); // Set switch to propeller
    digitalWrite(PROPELLER_PIN, HIGH);
}

I do not yet have the actual motor, pump, propeller, and switching mechanism, so we need to verify if this will work.

03. appendix

List of sensors(Grove only)

In the process of sharing this page with my own project, I was asked about sensor types. The following is a list of information that I have briefly researched, including sharing.

Prices are for reference only.

Name Price Function Sales Page Link
Grove - Temperature & Humidity Sensor (DHT11) ¥900 A sensor that can measure temperature and humidity with high precision and in a wide range. Link
Grove - Color Sensor V3.0 ¥1,360 A sensor that measures the chromaticity of the surrounding colors and the color of objects. Link
Grove - 3-Axis Digital Accelerometer (BMA400) ¥1,650 An ultra-low power 12-bit digital triaxial accelerometer that can detect motion and position. Link
Grove - Ultrasonic Distance Sensor ¥1,100 A sensor that measures distances from 3cm to 350cm using ultrasound. Link
Grove - CO2 & Temperature & Humidity Sensor (with SCD30) ¥11,220 A multifunctional sensor that can simultaneously measure temperature, humidity, and CO2 concentration. Link
Grove - Fingerprint Sensor ¥3,960 A sensor that enables highly accurate and low power fingerprint authentication. Link
Grove - Infrared Array Sensor (with AMG8833) ¥6,050 An infrared array sensor that can detect temperature at distances up to 7m. Link
Grove - I2C High Precision Temperature & Humidity Sensor (SHT35) ¥2,300 An I2C interface sensor that can measure temperature and humidity with high precision. Link
Grove - Barometer Sensor (BMP280) ¥1,510 A sensor that can measure atmospheric pressure and temperature with high precision. Link
Grove - Ultraviolet Sensor ¥1,750 A sensor that detects the intensity of ultraviolet light in a wide spectral range. Link
Grove - Moisture Sensor ¥500〜¥800 Detects soil moisture levels and can be used in irrigation systems, etc. Link
Grove - Smoke Sensor ¥1,000〜¥1,200 Detects smoke and signs of fire in the air. Link
Grove - Sound Sensor ¥700〜¥900 Measures the volume of the environment and can be used for voice recognition and noise monitoring. Link
Grove - Light Sensor (LDR) ¥400〜¥600 Measures the intensity of ambient light and can be used for automatic lighting control, etc. Link
Grove - Gas Sensor (MQ series) ¥1,200〜¥1,500 Detects the concentration of flammable and harmful gases and can be used for safety monitoring. Link
Grove - Accelerometer (ADXL345) ¥1,000〜¥1,300 Detects vibration and movement by measuring 3-axis acceleration. Link
Grove - Buzzer (Output Device) ¥1,375 Can output sound and can be used for alarms and notifications. Link
Grove - Button (P) ¥1,375 A simple input device that detects presses and can be used as a trigger for various operations. Link
Grove - Magnetic Switch ¥1,375 Detects the presence or absence of a magnetic field and can be used to detect the opening and closing of doors and windows. Link
Grove - GPS ¥1,375 Can obtain the latitude and longitude of the current position and can be used for projects that require location information. Link