Skip to content

Latest commit

 

History

History
1019 lines (751 loc) · 30.3 KB

File metadata and controls

1019 lines (751 loc) · 30.3 KB

tinygo-keeb/workshop

This page is for the TinyGo Keeb Tour that started on 2024/08/04. If you have any questions, please create an issue in this repository or contact twitter:sago35tk.

This page has Japanese and English versions.

For hardware assembly, please refer to the build guide:

QR code for this page:

Environment Setup

TinyGo Installation

The following dependencies are required. For TinyGo, please use the latest version available.

Note that Go and TinyGo versions must be compatible. TinyGo typically requires the latest or previous version of Go.

TinyGo Compatible Go
0.41.1 1.26 - 1.25
0.40.1 1.25 - 1.24

You can verify your installation with these commands:

$ tinygo version
tinygo version 0.41.1 windows/amd64 (using go version go1.25.6 and LLVM version 20.1.1)
$ tinygo build -o out.uf2 --target waveshare-rp2040-zero --size short examples/serial
   code    data     bss |   flash     ram
   9720     108    5208 |    9828    5316
$ tinygo flash --target waveshare-rp2040-zero --size short examples/serial
   code    data     bss |   flash     ram
   9720     108    5208 |    9828    5316

$ tinygo monitor --target waveshare-rp2040-zero
Connected to COM12. Press Ctrl-C to exit.
hello world!
hello world!
hello world!

On macOS 15 Sequoia or later, specify the port when running tinygo flash. This also applies to the other tinygo flash commands shown below. Port names vary by environment; use tinygo ports to find yours if necessary.

$ tinygo flash -port=$(ls /dev/cu.usbmodem*) --target waveshare-rp2040-zero --size short examples/serial

Windows + WSL2

You can use the Linux version of TinyGo on Ubuntu in WSL2. However, WSL2 cannot directly access USB devices connected to the Windows host. Even when using WSL2, it's generally better to install the Windows version of TinyGo in your Windows PATH. In this case, you'll also need to install the Windows version of Go.

If you insist on using TinyGo from WSL2, you can use usbipd as shown below. However, it's inconvenient because you need to attach usbipd every time you run tinygo flash.

Linux Setup

To use tinygo flash, tinygo monitor, or Vial on Linux, you need to configure udev rules. Create /etc/udev/rules.d/99-zero-kb02-udev.rules with the following contents and restart.

# RP2040
# ref: https://docs.platformio.org/en/latest/core/installation/udev-rules.html
ATTRS{idVendor}=="2e8a", ATTRS{idProduct}=="[01]*", MODE:="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"

# Vial
# ref: https://get.vial.today/manual/linux-udev.html
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{serial}=="*vial:f64c2b3c*", MODE="0660", GROUP="users", TAG+="uaccess", TAG+="udev-acl"

A copy of this file is available here:

This file was created from the following documents. For more details, please refer to:

TinyGo dev branch version

If you want to use the latest version under development, download Artifact > release-double-zipped built by GitHub Actions.

For more information, see:

LSP / gopls Support

TinyGo places packages like the machine package in GOROOT, so until you configure it, gopls will show errors and you won't be able to jump to definitions like machine.LED. TinyGo has an unfamiliar package structure (even if you know Go well) and many build-tag branches, so it's better to set up LSP for TinyGo.

The official documentation is available here:

For VS Code, we recommend installing the TinyGo extension. For Vim (+ vim-lsp), try github.com/sago35/tinygo.vim.

For information in Japanese, see:

Command-line Completion (Bash / Zsh / Clink)

If you use Bash, Zsh, or Clink, you can install command-line completion for TinyGo:

Development Target

The TinyGo Keeb Tour uses a custom keyboard/macro pad called zero-kb02. The microcontroller is an RP2040 (Cortex M0+), and the board is Waveshare RP2040-Zero.

Main features:

Schematics, firmware, pinouts, etc. can be found at:

Assembly

For soldering and assembly instructions, please refer to the build guide:

TinyGo Basics

First, clone this repository somewhere. From now on, we'll execute commands from the root of this repository. If you want to modify the source code, please edit the local code.

$ git clone https://github.com/tinygo-keeb/workshop

$ cd workshop

# Launch VS Code or other editor
$ code .

The source code is in paths like ./00_basic or ./12_matrix_basic.

Build & Flash (Method 1)

You can build and flash from the command line with TinyGo, but we'll learn how to flash manually too. Boards with RP2040 can boot into the bootloader by pressing the BOOT/BOOTSEL button while resetting (pressing the reset button or connecting to USB). When in bootloader mode, the PC recognizes it as an external drive, so you can flash it by copying the binary file (*.uf2) to the newly created external drive.

Try flashing the following:

If the LEDs on the key switches light up, the write was successful.

Note: This flashing method is also valid for uf2 files created outside of TinyGo. Putting the device into bootloader mode will help if for some reason the flash command does not work.

To create the 00_basic.uf2 yourself, execute the following command. If no error messages are displayed and 00_basic.uf2 is created, it's successful.

$ tinygo build -o 00_basic.uf2 --target waveshare-rp2040-zero --size short ./00_basic/
   code    data     bss |   flash     ram
  20420     192    3240 |   20612    3432

Build & Flash (Method 2) + Serial Monitor

You can also build and flash at once using the tinygo flash command. If no error messages are displayed, the flash has completed successfully. If it fails in a Linux environment, check the udev rules settings mentioned earlier.

$ tinygo flash --target waveshare-rp2040-zero --size short examples/serial
   code    data     bss |   flash     ram
   7836     108    3152 |    7944    3260

The examples/serial program displays hello world! to the serial output. You can verify it's working with the following:

$ tinygo monitor
Connected to COM7. Press Ctrl-C to exit.
hello world!
hello world!
hello world!

If you can't connect properly, check the port and add the --port option. The waveshare-rp2040-zero uses the same USB VID/PID as other boards with the RP2040 microcontroller, so the Boards section might not display correctly, but don't worry about it.

$ tinygo ports
Port                 ID        Boards
COM7                 2E8A:0003 waveshare-rp2040-zero

$ tinygo monitor --port COM7
Connected to COM7. Press Ctrl-C to exit.
hello world!
hello world!
hello world!

There's also a way to run tinygo flash --monitor which combines tinygo flash and tinygo monitor. However, depending on the environment, it may connect to the wrong port, so if it doesn't work well, run them separately as shown above.

$ tinygo flash --target waveshare-rp2040-zero --size short --monitor examples/serial
   code    data     bss |   flash     ram
   7836     108    3152 |    7944    3260
Connected to COM7. Press Ctrl-C to exit.
hello world!
hello world!
hello world!

Troubleshooting: tinygo flash doesn't work on macOS 15 Sequoia (TinyGo 0.37 and earlier only)

Note: This issue was fixed by micchie and merged into TinyGo 0.38.

Add NO NAME to msd-volume-name in $TINYGOROOT/targets/rp2040.json. You can find $TINYGOROOT with tinygo env.

The modified JSON file is as follows:

{
    "inherits": ["cortex-m0plus"],
    "build-tags": ["rp2040", "rp"],
    "flash-1200-bps-reset": "true",
    "flash-method": "msd",
    "serial": "usb",
    "msd-volume-name": ["RPI-RP2", "NO NAME"],
    "msd-firmware-name": "firmware.uf2",
    "binary-format": "uf2",
    "uf2-family-id": "0xe48bff56",
    "rp2040-boot-patch": true,
    "extra-files": [
        "src/device/rp/rp2040.s"
    ],
    "linkerscript": "targets/rp2040.ld",
    "openocd-interface": "picoprobe",
    "openocd-transport": "swd",
    "openocd-target": "rp2040"
}

How to stop "Disk Not Ejected Properly" notifications from accumulating on macOS

Open a terminal and run the following, then restart:

$ sudo defaults write /Library/Preferences/SystemConfiguration/com.apple.DiskArbitration.diskarbitrationd.plist DADisableEjectNotification -bool YES && sudo pkill diskarbitrationd

To revert back, run the following and restart:

$ sudo defaults delete /Library/Preferences/SystemConfiguration/com.apple.DiskArbitration.diskarbitrationd.plist DADisableEjectNotification && sudo pkill diskarbitrationd

See: https://www.reddit.com/r/mac/comments/vsn1t6/how_to_disable_not_ejected_safely_notification_on/

If you absolutely cannot flash to the device

This could be due to:

  • There's a problem with the USB cable
    • Check if it's recognized with tinygo ports or as a drive (try booting into bootloader mode)
  • Writing to external drives is restricted
    • Company computers may restrict writing for security reasons
    • In this case, neither tinygo flash nor copying uf2 files will work

LED Blink

Run the following:

$ tinygo flash --target waveshare-rp2040-zero --size short ./01_blinky1/

If the RGB LED on the RP2040 Zero lights up successfully, try changing the color or blink speed by modifying the source code. You can set a color.Color at the black or white locations below:

// 01_blinky1/main.go
for {
    time.Sleep(time.Millisecond * 500)
    ws.PutColor(black)
    time.Sleep(time.Millisecond * 500)
    ws.PutColor(white)
}

Here are some other color examples. You can set any color by specifying RGBA. You can (somewhat) reduce the brightness by making the 0xFF values smaller.

red     = color.RGBA{R: 0xFF, G: 0x00, B: 0x00, A: 0x00}
green   = color.RGBA{R: 0x00, G: 0xFF, B: 0x00, A: 0x00}
blue    = color.RGBA{R: 0x00, G: 0x00, B: 0xFF, A: 0x00}
yellow  = color.RGBA{R: 0xFF, G: 0xFF, B: 0x00, A: 0x00}
cyan    = color.RGBA{R: 0x00, G: 0xFF, B: 0xFF, A: 0x00}
magenta = color.RGBA{R: 0xFF, G: 0x00, B: 0xFF, A: 0x00}

LED Blink (2)

Let's light up the keys. The board has 12 SK2812MINI-E LEDs (WS2812B compatible). They are mounted in the following positions/order:

 0  3  6  9
 1  4  7 10
 2  5  8 11

Run the following: If it works successfully, try changing the color, blink speed, or blink pattern by modifying the source code.

$ tinygo flash --target waveshare-rp2040-zero --size short ./02_blinky2/

It's almost the same as before, but WriteRaw() is used instead of PutColor(). Here, colors[0][:i+1] is specified, but if [:1] is specified, only the first LED is set. [:4] would change a total of 4 LEDs.

// ./02_blinky2/main.go
ws.WriteRaw(colors[0][:i+1])

WriteRaw() allows you to specify colors as uint32. The values are set as Green / Red / Blue, 8 bits each from the most significant bit. For example:

// ./02_blinky2/main.go
colors := []uint32{
    0xFFFFFFFF, // white
    0xFF0000FF, // green
    0x00FF00FF, // red
    0x0000FFFF, // blue
}

You can (somewhat) reduce the brightness by making the 0xFF values smaller.

USB CDC Hello World

Let's also try USB CDC, which is useful for printf debugging and other purposes. USB CDC stands for Universal Serial Bus Communications Device Class, and simply put, it enables serial communication between a computer and a microcontroller through the USB cable. Rather than explaining, it's easier to understand by trying it, so first run the following:

$ tinygo flash --target waveshare-rp2040-zero --size short examples/serial

$ tinygo monitor

On Windows, it will look like this:

$ tinygo flash --target waveshare-rp2040-zero --size short examples/serial
   code    data     bss |   flash     ram
   7836     108    3152 |    7944    3260

$ tinygo monitor
Connected to COM7. Press Ctrl-C to exit.
hello world!
hello world!
hello world!
(omitted)

The examples/serial source is located at ./03_usbcdc-serial. It repeatedly displays hello world! and then waits for 1 second. Try changing the wait time, display string, or using fmt.Printf() for writing.

$ tinygo flash --target waveshare-rp2040-zero --size short ./03_usbcdc-serial/

Standard input can be handled with code like ./04_usbcdc-echo/. After pressing Enter/Return, you need to press Ctrl-j for a line break.

$ tinygo flash --target waveshare-rp2040-zero --size short ./04_usbcdc-echo/
// ./04_usbcdc-echo/main.go
package main

import (
        "bufio"
        "fmt"
        "os"
)

func main() {
        scanner := bufio.NewScanner(os.Stdin)
        for scanner.Scan() {
                fmt.Printf("you typed : %s\n", scanner.Text())
        }
}

Rotary Encoder

You can use encoders/quadrature-interrupt from tinygo-org/drivers.

Here's the configuration adjusted for zero-kb02:

// ./05_rotary/main.go
enc := encoders.NewQuadratureViaInterrupt(
    machine.GPIO3,
    machine.GPIO4,
)
enc.Configure(encoders.QuadratureConfig{
    Precision: 4,
})

You can write and check operation with the following commands. When you turn the rotary encoder, the value display will update. Try linking it with the LEDs as an exercise.

$ tinygo flash --target waveshare-rp2040-zero --size short ./05_rotary/
   code    data     bss |   flash     ram
   8276     108    3624 |    8384    3732

$ tinygo monitor
Connected to COM7. Press Ctrl-C to exit.
value:  -1
value:  -2
value:  -1
value:  0
value:  1
value:  2
(omitted)

Note that the rotary encoder can also be used as a button when pressed. Getting the pressed state of the rotary encoder will be discussed in the next section.

Getting the Pressed State of the Rotary Encoder

When the rotary encoder is pressed, it connects to GND and goes Low. With pull-up enabled, it will be High when not pressed.

The basic code is as follows:

// ./13_rotary_button/main.go
if !btn.Get() {
    println("pressed")
} else {
    println("released")
}
$ tinygo flash --target waveshare-rp2040-zero --size short ./13_rotary_button/

$ tinygo monitor

When you press the rotary encoder, pressed will be output to the terminal running tinygo monitor.

Analog Joystick

The analog joystick can be recognized as a digital value when pressed, and as analog values for the X and Y axes. So it can be handled as follows:

$ tinygo flash --target waveshare-rp2040-zero --size short ./06_joystick/
   code    data     bss |   flash     ram
  56792    1536    3176 |   58328    4712

$ tinygo monitor
Connected to COM7. Press Ctrl-C to exit.
7440 8000 false
7130 7F90 true
(omitted)

From the left, it shows X-axis value (voltage value), Y-axis value, and whether it's pressed. When not doing anything, values close to 0x8000 are displayed.

OLED

You can use ssd1306/i2c_128x64 from tinygo-org/drivers.

Here's the configuration adjusted for zero-kb02:

// ./07_oled/main.go
machine.I2C0.Configure(machine.I2CConfig{
    Frequency: machine.TWI_FREQ_400KHZ,
    SDA:       machine.GPIO12,
    SCL:       machine.GPIO13,
})
display := ssd1306.NewI2C(machine.I2C0)
display.Configure(ssd1306.Config{
    Address: 0x3C,
    Width:   128,
    Height:  64,
})

You can write and check operation with the following command:

$ tinygo flash --target waveshare-rp2040-zero --size short ./07_oled/

Note: As of 2024/08/04, OLED drawing sometimes stops (currently investigating)

Drawing Shapes

$ tinygo flash --target waveshare-rp2040-zero --size short ./08_oled_tinydraw/

Drawing Text

$ tinygo flash --target waveshare-rp2040-zero --size short ./09_oled_tinyfont/

Rotating the Screen

On zero-kb02, the OLED is mounted upside down, so you need to rotate the screen somehow. Here, let's try rotating it via hardware.

As shown below, you can rotate with Rotation in the Config. For SSD1306, only Rotation0 (no rotation) and Rotation180 (inverted) can be used.

// ./10_oled_rotated/main.go
display.Configure(ssd1306.Config{
    Address:  0x3C,
    Width:    128,
    Height:   64,
    Rotation: drivers.Rotation180,
})

You can also rotate with SetRotation() outside of Configure() time.

display.SetRotation(drivers.Rotation180)
$ tinygo flash --target waveshare-rp2040-zero --size short ./16_oled_inverted_hw/

Rotating the Screen 90 Degrees

We have seen how to implement no rotation or inversion; however, in some cases you might want to rotate the display 90 degrees to use it in portrait mode. In this case, you need to rotate via software. Screen drawing basically corresponds to the following Displayer interface, so we define a Displayer that can rotate the screen.

// https://github.com/tinygo-org/drivers/blob/release/displayer.go
type Displayer interface {
    // Size returns the current size of the display.
    Size() (x, y int16)

    // SetPixel modifies the internal buffer.
    SetPixel(x, y int16, c color.RGBA)

    // Display sends the buffer (if any) to the screen.
    Display() error
}

Here, we've defined the following. We embed Displayer in the struct and process the x and y values of Size and SetPixel.

// ./16_oled_inverted_hw/main.go
type RotatedDisplay struct {
        drivers.Displayer
}

func (d *RotatedDisplay) Size() (x, y int16) {
        return y, x
}

func (d *RotatedDisplay) SetPixel(x, y int16, c color.RGBA) {
        _, sy := d.Displayer.Size()
        d.Displayer.SetPixel(y, sy-x, c)
}
$ tinygo flash --target waveshare-rp2040-zero --size short ./10_oled_rotated/

Animating

You can update the screen without flickering by using display.ClearBuffer() and display.Display().

$ tinygo flash --target waveshare-rp2040-zero --size short ./11_oled_animation/

Displaying Japanese

Currently, either BDF or OTF/TTF fonts can be displayed.
For small displays with 1-bit color like zero-kb02, BDF fonts are more suitable.
You can use them as follows:

$ tinygo flash --target waveshare-rp2040-zero --size short ./17_oled_japanese_font/

Getting Key Press States

zero-kb02 uses a wiring method called a matrix for its key connections. As shown in the circuit below, 12 switches are connected using 7 pins in a COL:4 x ROW:3 configuration.

The reading process works as follows:

  1. Set only COL1 to High, and set COL2 through COL4 to Low
  2. Wait a moment
  3. Read ROW1 through ROW3 in that state
    • If ROW1 is High, SW1 is pressed
    • If ROW2 is High, SW5 is pressed
    • If ROW3 is High, SW9 is pressed

Next, if only COL2 is set to High, SW2 / SW6 / SW10 can be read, and so on.

Matrix wiring is a widely used connection method in custom keyboards, so let's implement it. A simple implementation of the above would look like this:

// ./12_matrix_basic/main.go
colPins[0].High()
colPins[1].Low()
colPins[2].Low()
colPins[3].Low()
time.Sleep(1 * time.Millisecond)

if rowPins[0].Get() {
    fmt.Printf("sw1 pressed\n")
}
if rowPins[1].Get() {
    fmt.Printf("sw5 pressed\n")
}
if rowPins[2].Get() {
    fmt.Printf("sw9 pressed\n")
}

By implementing the same pattern for all columns, you can detect the press state of all keys.

$ tinygo flash --target waveshare-rp2040-zero --size short --monitor ./12_matrix_basic/

By organizing the loops and making the number of keys variable, you can move closer to a keyboard firmware.

Note: For those who want to learn more about matrix wiring, please see: https://blog.ikejima.org/make/keyboard/2019/12/14/keyboard-circuit.html

USB HID Keyboard Using Pin Input

Let's create a USB HID Keyboard using the rotary encoder's press state. The following code allows you to link the press state with the A key. In TinyGo, you can import machine/usb/hid/keyboard and call keyboard.Port(), so your device will act as a keyboard recognized by the computer.

// ./14_hid_keyboard/main.go
kb := keyboard.Port()
for {
    if !btn.Get() {
        kb.Down(keyboard.KeyA)
    } else {
        kb.Up(keyboard.KeyA)
    }
}
$ tinygo flash --target waveshare-rp2040-zero --size short ./14_hid_keyboard/

Press the rotary encoder to verify it's working properly.

USB HID Mouse Using Pin Input

Now let's create a USB HID Mouse using the rotary encoder's press state. With the following code, pressing the button becomes a mouse left click.

// ./15_hid_mouse/main.go
m := mouse.Port()
for {
    if !btn.Get() {
        m.Press(mouse.Left)
    } else {
        m.Release(mouse.Left)
    }
}
$ tinygo flash --target waveshare-rp2040-zero --size short ./15_hid_mouse/

Press the rotary encoder to verify it's working properly.

Using MIDI

TinyGo supports USB MIDI, so you can make MIDI sound sources or MIDI instruments.
You can use the 12 keys and the rotary encoder press.

$ tinygo flash --target waveshare-rp2040-zero --size short ./18_midi/

After creation, you can test it on sites like:

In Windows environments, MIDI-OX is a good option:

Please also refer to the following examples:

Using a Buzzer

Note: This example requires an external driven buzzer. Note: Connect the buzzer between EX01 and 3V3. With the board face up, connect the buzzer to the top-left pin and the third pin from the left in the top row.

There are various ways to drive a buzzer, but here we use PWM. When using PWM with TinyGo, note that some microcontroller-specific configuration is required.

For RP2040, when using the back panel pins (EX01 - EX04) on zero-kb02, you can use the following configuration. You need to know which pin to use and which PWMGroup it corresponds to. Below is a map of pins to their corresponding PWMGroup:

var pinToPWM = map[machine.Pin]tone.PWM{
	machine.GPIO14: machine.PWM7, // for EX01
	machine.GPIO15: machine.PWM7, // for EX02
	machine.GPIO26: machine.PWM5, // for EX03
	machine.GPIO27: machine.PWM5, // for EX04
}

After this, you can use tinygo.org/x/drivers/tone to produce sound:

func main() {
	bzrPin := machine.GPIO14
	pwm := pinToPWM[bzrPin]
	speaker, err := tone.New(pwm, bzrPin)
	if err != nil {
		println("failed to configure PWM")
		return
	}

	song := []tone.Note{
		tone.C5,
		tone.D5,
		tone.E5,
		tone.F5,
		tone.G5,
		tone.A5,
		tone.B5,
		tone.C6,
		tone.C6,
		tone.B5,
		tone.A5,
		tone.G5,
		tone.F5,
		tone.E5,
		tone.D5,
		tone.C5,
	}

	for {
		for _, val := range song {
			speaker.SetNote(val)
			time.Sleep(time.Second / 2)
		}
	}
}
$ tinygo flash --target waveshare-rp2040-zero --size short ./22_buzzer/

Using an I2C Temperature/Humidity Sensor

Note: This example requires an I2C-connected SHT4x sensor (SHT40 / SHT41, etc.). Note: Connect it to the GROVE connector.

Here we use an I2C sensor connected to the GROVE connector. Since the GROVE connector shares the same pins as the OLED, you need to use I2C0.

The frequency is set to 2.8MHz here, but according to specifications, it should be lowered to around 400KHz.

Temperature and humidity can be obtained using ReadTemperatureHumidity():

	// import "tinygo.org/x/drivers/sht4x" is required
	machine.I2C0.Configure(machine.I2CConfig{
		Frequency: 2.8 * machine.MHz,
		SDA:       machine.GPIO12,
		SCL:       machine.GPIO13,
	})
	sensor := sht4x.New(machine.I2C0)
	temp, humidity, _ := sensor.ReadTemperatureHumidity()
	t := fmt.Sprintf("Temperature %.2f C", float32(temp)/1000)
	h := fmt.Sprintf("Humidity %.2f %%", float32(humidity)/1000)

Using sago35/tinygo-keyboard

The necessary elements for a custom keyboard vary from person to person. However, some common requirements include:

  • Layer functionality
  • Ability to change settings without rebuilding
  • Package-based methods for reading various switches

Creating these from scratch each time can be challenging and time consuming, so using some kind of library is common. Here, let's create a custom keyboard using the package sago35/tinygo-keyboard.

With sago35/tinygo-keyboard, you can easily implement the following features:

  • Support for various key input methods (matrix, GPIO, rotary encoder, etc.)
    • Possibility to write your own extensions
  • Layer functionality
  • Integration with mouse clicks and pointer movement
  • Split keyboard support via TRRS cable
  • Configuration changes through Vial via web browser
    • Keymaps
    • Layers
    • Matrix tester (key switch press test)
    • Macro functionality

The Vial integration is particularly important as it makes it easy to change settings according to individual preferences without the need to re-flash the firmware again. Vial is available at the following URL and can be accessed from Edge/Chrome browsers that support the WebHID API:

Basic Usage

For detailed usage instructions, please refer to:

zero-kb02 firmware

Available here:

koebiten

We are developing a 2D game engine for TinyGo called koebiten. It is positioned as a TinyGo version of Ebitengine, a 2D game engine for Go. It features support for multiple hardware platforms including zero-kb02, and a simple API.

You can start by just running the samples. UF2 files can be downloaded from:

An introductory guide is available on Zenn (in Japanese):

Troubleshooting

  • Cannot flash the program

Check if the microcontroller is recognized with the tinygo ports command. If recognized correctly, waveshare-rp2040-zero will be displayed.

$ tinygo ports
Port                 ID        Boards
COM7                 2E8A:0003 waveshare-rp2040-zero

If not recognized, disconnect the microcontroller from the PC and reconnect it. Try putting it in bootloader mode: hold the BOOT button on the back, press the RST button and release both.

Examples

Other Tips

  • When taking photos or videos, setting to 30 frames/second prevents LCD flickering.

Announcements

I wrote a technical book "Learning TinyGo Embedded Development from the Basics" (released on 2022/11/12) using TinyGo 0.26 + Wio Terminal. Please check it along with this page.