Developing in C for the ATmega328P: Raspberry Pi and VS Code Setup Part 1 Trixie

10 minute read

A new and improved version of where I setup the Standard C tool chain for the ATmega328P on the Raspberry Pi, however I use VS Code on my Mac (or Windows) for development and connect via SSH to the Raspberry Pi. This is the easy setup and requires the least amount of tool installation.

Note: This new, “easy” version is due to using Raspberry Pi OS Trixie, which now provides fairly up-to-date tools for the AVR microcontollers. The previous version has been deprecated. Make sure you are on the latest version of Raspberry Pi OS (which as of December 2025 is Trixie.

Introduction

This is the best setup, period. Why? It provides the most, simple tool chain installation, a stable, known platform and enables hardware debugging, should you want to do so.

Linux has always been the preferred platform for open-source embedded development, as the Standard C tools are native to Linux. macOS is second, as its Unix bloodline, enables it to resemble a Linux system quite easily. Windows is a distant third, as the hoops to jump through to build the tool chain are a pain (Note: WSL2 still can’t easily interact with the serial port).

In this entry, I’ll use the one of the least expensive Linux systems, the Raspberry Pi (RPi) and my Mac as a complete development system. While I might continue to develop on the Mac, in future entries, I’ll use this platform setup as its the most consistent and stable platform.

As I stated earlier, I will use VS Code on my Mac for development. Given the RPi is so great, why continue to use the Mac for development? The graphics are better on the Mac, I have other tools I might want to use on my Mac for the development process and the speed of the Mac, outside of AVR development, is significantly faster. The same point can also be made of a Windows PC. While the RPi is great for command line-based C development, it is sorely lacking in performance in a browser or other GUI application.

Know

Good to Know

Introduction

This repository is for an introductory course on the C language using the Arduino Uno R3, the C tool chain (avr-gcc, avrdude etc) and the AVR C Library. The content is for students who desire understanding C using an embedded microcontroller, in this case the Arduino Uno R3. This content uses the avr tool chain via command line (also called the terminal), it doesn’t use the Arduino IDE nor does it use the Arduino software framework.

The directory, examples, contains the programming examples. Each example folder demonstrates how to use a particular functionality of AVR_C. Each folder has a file called main.c and a file called makefile. The file main.c is the example code and the makefile is the required file using make to compile/link/load it to an UNO. Think of the main.c file as the Arduino IDE sketch and the makefile as a command-line version of the Arduino IDE. The files in Library are similar to those found in the Arduino framework.

Dependencies

These instructions assume you already have an Arduino Uno R3 (or similar microcontroller) or will have one supplied to you.

Additional dependencies are:

1. Raspberry Pi

The approach this class follows is to use a standardized platform running the C tool chain. This removes the pain of having to maintain documentation and support for each of the major computing platforms, macOS, Windows and Linux. Instead, the platform will be an inexpensive Raspberry Pi (RPi) running Raspberry Pi OS with all of the required programs pre-installed.

I typically use a Raspberry Pi 4 with 2GB of memory. I have tested the tools using a Raspberry Pi 3 with no noticeable performance issues. Raspberry Pi

2. VS Code

In order to use this content you need to have VS Code installed on your computer or a computer you will be using in class. We will use both the VS Code editor and VS Code Terminal or command line interface (CLI), connected remotely to the RPi.

3. Raspberry Pi Connect Login

You will also need a Raspberry Pi Connect login. You may obtain one for free here. This provides a easy, safe, secure way to connect to the Raspberry Pi.

4. Raspberry Pi Imager v2.0+

This is the software from the Raspberry Pi organization which will create a bootable image for your Raspberry Pi. It must be v2.0 or later as this new version provides the capability of Raspberry Pi Connect. You will want the one for your primary computer, in my case it is a Mac. Your’s might be a Windows computer.

NOTE: The latest version 2.0.2, has a bug which doesn’t program an open wireless connection properly. This has been fixed and will be incorporated in later versions. The instructions below resolve the bug.

Installation

1. Use Pi Imager v2.0+ for creating Raspberry Pi OS Image

Before starting insert your SD Card or USB Drive for the Raspberry Pi into your computer or SD Card interface. In the steps below, you will need to enter the appropriate information as requested, such as your timezone, username, password etc.

  1. Open Pi Imager (it must be v2.0 or greater)
  2. Select your device -> Next
  3. Select Raspberry Pi OS (other) -> Raspberry Pi OS Lite (64-bit) -> Next
  4. Select Your Storage Device (this will be the SD card or USB Drive from above) -> Next
  5. Choose Hostname -> Next
  6. Select:
    • Capital city:
    • Time zone:
    • Keyboard layout: us -> Next
  7. Enter:
    • Username:
    • Password
    • Confirm password: -> Next
  8. Select Secure Network:
    • SSID:
    • Password
    • Confirm password: -> Next
  9. Enable SSH (turn on) -> Use password… -> Next
  10. Enable Raspberry Pi Connect (turn on) -> Open Raspberry Pi Connect -> confirm Authentication token: is filled in -> Next

CONFIRM BEFORE CONTINUING

Your window needs to look similar to this:

Photo of Pi Imager prior to Writing
Pi Imager, ready to Write

Large Version to see detail

Confirm the following:

  • Hostname, Localisation, User Account, and Wi-Fi configured
  • SSH and Raspberry Pi Connect enabled
  1. Write -> I UNDERSTAND, ERASE AND WRITE -> Enter System Password to write to storage device
  2. Wait for the Write to finish

NOTE: If connecting to an open network (no WiFi password), apply NOTE: 251217 below.

  1. Remove SD card/USB drive and place in Raspberry Pi
  2. Power up and wait for it to show up in the Raspberry Pi Connect dashboard . (Normally takes about 90 seconds.)

Your Connect page needs to indicate it has found your Raspberry Pi as indicated by a Connect button as shown below for pidev-6:

Photo of Devices page on connect.raspberrypi.com
Devices page on connect.raspberrypi.com

Large Version to see detail

2. Connect via Raspberry Connect

Raspberry Pi Connect

NOTE: In the instructions below, Command/Control means, in macOS, press the command key and in Windows, press the Control key.

This step will connect you to the Raspberry Pi using the command line interface in your browser window.

1. Connect

Click on the connect button as shown above. This will open a small browser window showing a terminal interface or CLI for the RPi. For this step, we’ll use this browser-based terminal interface for connecting and working with the Raspberry Pi.

2. Copy and Paste

sudo apt update && sudo apt upgrade -y &&
sudo apt-get install gcc-avr binutils-avr avr-libc gdb-avr avrdude git tio -y &&
git clone https://github.com/lkoepsel/AVR_C.git

Copy and paste the text above then hit return. This action will take several minutes.

3. Obtain Uno device address

# Connect an Arduino Uno via USB cable and run:
tio -l  # lowercase l as in leo

Under Device will be something like: /dev/ttyUSB0 or /dev/ttyACM0.

Copy this string, we’ll refer to it as DEVICE.

4. Confirm or change the DEVICE address

In the CLI, do the following:

cd AVR_C

You will now be in the AVR_C folder and will need to create then edit the env.make file. The git version is a default version, we’ll copy it for the make program to use it. We’ll then want to ensure we’re connecting to the DEVICE we found above.

cp env.def env.make  # copy default environment
nano env.make

In nano, do the following:

  1. Use your arrow keys to move down to line 39
  2. You use left/right arrow keys to edit the line
  3. The line will look like this: SERIAL = /dev/ttyACM0
  4. Either confirm SERIAL equals DEVICE found above

OR

  1. overwrite it, with DEVICE

  2. You will probably* end up with one of two variations below:

    • SERIAL = /dev/ttyACM0

    • SERIAL = /dev/ttyUSB0

Ctrl-S to save, Ctrl-X to exit

* There can be a third version, however, I rarely see it.

cd examples/blink
make flash

Confirm the Uno is blinking at a fast rate.

6. Change delay and recompile/load program

nano main.c
# use the down arrow key to move to line 10
    int delay_ms = 200;
# change the 200 to 2000, by adding an extra 0

Ctrl-S to save, Ctrl-X to exit

make flash

Confirm the Uno is blinking at a slow rate (every 2 seconds).

This confirms everything is working properly.

7. Obtain the IP address to connect using VS Code

hostname -I # uppercase I as in Indigo

The first address will be a IP4 address similar to 10.0.0.223, 192.168.1.5, or 172.24.21.220. This number will be referred to as IP_ADDRESS below.

3. Connect via VS Code Remote

Open VS Code. For this step, we’ll use VS Code editor and terminal interface for connecting and working with the Raspberry Pi.

1. Install the required extensions

Please install or confirm these extensions before continuing.

ms-vscode-remote.remote-containers
ms-vscode-remote.remote-ssh
ms-vscode-remote.remote-ssh-edit
ms-vscode.cpptools
ms-vscode.cpptools-themes
ms-vscode.remote-explorer

2. Open a remote connection

In VS Code, do the following:

  1. Shift-command/Control-P
  2. Enter “remo” and click on Remote-SSH: Connect to Host
  3. Enter username@IP_ADDRESS, where:
    • username is the username, you used on creating the Raspberry Pi OS image from 1.7 above
    • IP_ADDRESS is the IP_ADDRESS of your Raspberry Pi from 2.5 above
  4. Click Continue on Are you sure you want to continue?
  5. Enter password
  6. Click on Open Folder -> AVR_C -> OK and might need to click Yes to “Trust…authors
  7. Use the Explorer to open examples/blink/main.c
  8. Change the 2000 on line 10, to 200 and command/Control-s to save the file
  9. Shift-command/Control-B and click on flash

Now the Uno will be blinking at its original fast rate.

If you were successful in getting the Uno to blink both fast and slow, you are now ready to begin programming!

Usage

The recommended method to develop code using this repository is to use both VS Code code editor and the VS Code terminal, side-by-side. This allows you to quickly and easily perform functions in either window.

Editor Steps

  1. Connect the Uno to the Raspberry Pi via the USB cable.
  2. Follow the steps 1-6 from Step 3.2 Open a remote connection. This will open the VS Code Editor, running remotely on the Raspberry Pi.

Terminal Steps

  1. To have a terminal open as well, in VS Code -> Terminal -> New Terminal.
  2. To make the Terminal window fill the right half of your monitor screen, (if not already) right-click on the Terminal tab -> Panel Postion -> Right.

Your screen now similar to this, with Editor on the left and Terminal on the right:

VS Code with editor and terminal
VS Code with editor and terminal

Large Version to see detail

  1. Column contains file Explorer, git status and commands, extension management.
  2. Code editor
  3. Terminal or CLI

Additional Sources of Information

  • Developing in C on the AVR ATmega328P A series of web pages explaining in detail how to use specific aspects of the AVR C software framework.
  • AVR LibC This library is the basis for the Clanguage for the AVR. From GNU “AVR Libc is a Free Software project whose goal is to provide a high quality C library for use with GCC on Atmel AVR microcontrollers.

Directories

  • examples - contains code demonstrating how to use specific functions in the Library
  • Library - AVR C Library, specific Arduino functions rewritten in C such as analogRead(), analogWrite(), digitalRead(), and pinMode()

Nest Step: Editing Remotely

Solutions to known issues

1. Connecting to an open wireless connection on initial boot

Update: 251224 This appears to be fixed as of 2.0.3, however, more testing needs to be done on an open network.

NOTE: 251217

A bug exists in the Pi Imager 2.0.2 software, where the password on an open wireless network is set to “”. This is incorrect, it needs to be changed via auth -> key-management “none”. See OPEN NETWORK…. Immediate response to the bug was, it had been fixed for the next release (2.0.3). Will confirm. Then delete these solutions.

In the meantime, this is the best approach and has been confirmed to work, multiple times:

Prior to initial boot, edit network-config

Open network-config on the boot partition (bootfs) on Windows/macOS and change it to the following:

version: 2
wifis:
  wlan0:
    dhcp4: true
    optional: true
    regulatory-domain: US
    access-points:
      "mpc-wifi":
        auth:
          key-management: none

If the solution above doesn’t work, either Option 2 or Option 3 work, however, they require an ethernet connection to the RPi.

Option 2. Connect via ethernet and enter

sudo nmcli radio wifi on
sudo nmcli dev wifi connect mpc-wifi password ""

Then disconnect ethernet and cycle power

Option 3. Connect via ethernet and use sudo nmtui to activate the mpc-wifi connection.

Then disconnect ethernet and cycle power

Comments powered by Talkyard.