Developing in C for the ATmega328P: Raspberry Pi and VS Code Setup Part 1 Trixie
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.
Links for Reading
Know
- Working with the Command Line
- Editing Remotely Using VS Code
- Developing in C on the AVR ATmega328P: Frequently Asked Questions (FAQ)
- Developing in C on the AVR ATmega328P: Frequently Found Errors (FFE)
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.
- Open Pi Imager (it must be v2.0 or greater)
- Select your device -> Next
- Select Raspberry Pi OS (other) -> Raspberry Pi OS Lite (64-bit) -> Next
- Select Your Storage Device (this will be the SD card or USB Drive from above) -> Next
- Choose Hostname -> Next
- Select:
- Capital city:
- Time zone:
- Keyboard layout: us -> Next
- Enter:
- Username:
- Password
- Confirm password: -> Next
- Select Secure Network:
- SSID:
- Password
- Confirm password: -> Next
- Enable SSH (turn on) -> Use password… -> Next
- 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:
Confirm the following:
- Hostname, Localisation, User Account, and Wi-Fi configured
- SSH and Raspberry Pi Connect enabled
- Write -> I UNDERSTAND, ERASE AND WRITE -> Enter System Password to write to storage device
- Wait for the Write to finish
NOTE: If connecting to an open network (no WiFi password), apply NOTE: 251217 below.
- Remove SD card/USB drive and place in Raspberry Pi
- 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:
2. Connect via Raspberry 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:
- Use your arrow keys to move down to line 39
- You use left/right arrow keys to edit the line
- The line will look like this:
SERIAL = /dev/ttyACM0 - Either confirm SERIAL equals DEVICE found above
OR
-
overwrite it, with DEVICE
-
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.
5. Compile and load Uno with blink program
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:
Shift-command/Control-P- Enter “remo” and click on Remote-SSH: Connect to Host
- 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
- Click
Continueon Are you sure you want to continue? - Enter password
- Click on Open Folder -> AVR_C -> OK and might need to click Yes to “Trust…authors”
- Use the
Explorerto open examples/blink/main.c - Change the 2000 on line 10, to 200 and
command/Control-sto save the file Shift-command/Control-Band 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
- Connect the Uno to the Raspberry Pi via the USB cable.
- 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
- To have a terminal open as well, in VS Code -> Terminal -> New Terminal.
- 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:
- Column contains file Explorer, git status and commands, extension management.
- Code editor
- 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()
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.