In Part 1 we blinked an LED using the Commodore 64 User Port, in Part 2 and Part 3 we got input from the user port and analog signals from the control ports. Now let’s kick things up a notch and integrate our C64 with Arduino!
What is Arduino and why would you care?

Arduino Uno is a single board microcontroller based on the 8-bit, 16mhz ATmega328P with 14 digital IO pins (6 PWM), 6 analog and 32K RAM. It also has 1kb of EEPROM and both built-in and software serial.
Or, rather, that is the spec of the Arduino Uno which for most people is the stereotypical Arduino. There is in fact a whole vast range of Arduino boards in the ecosystem, from official to very not official. For example, in my C64 keyboard interface I used a tiny Arduino that can present itself as a USB device.
1. Extra Abilities
Using an Arduino in your electronics projects allows you access to all the many, many sensors, add-ons, etc, plus associated code examples and libraries that have been built up by companies and the community for years.
2. Extra Safety
Arduino boards are relatively cheap compared to your precious Commodore 64, especially if you get them via slow mail from overseas, plus they are a fair bit more robust than the C64 seeing as they were made for hobbyist electronics enthusiasts.
3. Parallel Processing
Your C64 can get on with it’s own tasks while the Arduino deals with interfacing with electronic input or output. Think of it like multitasking!
Isn’t it cheating?

No! Adding helpers to our projects is standard practice.

Back in the day we would have a whole grocery list of things we needed for C64 electronics projects, not just diodes and resistors but everything from transistors, motor drivers, and relays through to analog/digital converters. In addition we would often need a bunch of things that are covered by the Arduino, not least a robust and clean input voltage regulator and a whole suite of IO.
Just be glad instead of a bunch of discreet 74-series chips we can replace all that with Arduino code.
Two ways to interface the C64 and Arduino
There are essentially two main ways to interface the two.
- Connect IO pins
- Communicate over serial
The simplest approach for simple integration is to use the digital pins we already saw, or we could accept an analog signal into the C64 via the control port. For simple on/off switches this is fine, all the way up to individual bytes, seeing as the C64 has 8 digital pins.
For transmitting and receiving much more data, both the Arduino and C64 can communicate using a rich serial “RS-232-like” stream of bytes.
We have already covered enough digital input and output that I am sure I don’t need to go into more depth here so let’s take a look at the serial option.
C64 “RS-232”
RS-232 is a serial communications standard that dates back to the 1960s. It was at one time ubiquitous, but today it resides in niches due to the much higher bandwidth and more convenient options we have available to us.
The C64 user port has the built-in ability to communicate via an RS-232-like connection that is good enough for our purposes. For “actual” standardized RS-232 you would need to boost the signals as the C64 works at 5v whereas RS-232 dictates +-12v. As our Arduino projects standardize on 5v this is all to our benefit!
Our serial connections will be the most simple we can make them, utilizing just the minimal TX, RX, and Ground.

On the C64 side we have our user port adapter, and again we are using the BOTTOM, lettered row of pins. This is very important as you do NOT want to hook up to 9v!
A + N both connect to Ground, B + C both connect together and are RX, while M becomes TX.
RX and TX then switch on the Arduino side so when one side transmits the other receives and vice versa. For most projects you would connect these appropriately to the marked RX and TX pins (pins 0 and 1) but for learning and debugging we will use a cool feature of Arduino called Software Serial. This allows us to connect the Arduino to our Mac/PC with USB and connect it to the C64 at the same time!
Arduino RS-232 Echo Code
This code will open two serial connections, one using USB to our computer and the other connection via the Digital Pins 10 and 11, plus Ground. As well as offering some visual feedback of the communication taking place, it also allows us to power the Arduino from our computer rather than risk the C64 5v pin.
// Arduino Software Serial library
// Allows our Uno to have both local echo and C64 serial connections
#include <SoftwareSerial.h>
// ---------------------------------------------------------
// CONNECTIONS
// ---------------------------------------------------------
// 1. RX: Digital pin 10 (connect to TX of other device)
// 2. TX: Digital pin 11 (connect to RX of other device)
// 3. Connect Ground to Ground
// 4. Use external power supply for safety instead of C64 5v
// ---------------------------------------------------------
// Set up our Software Serial pins RX and TX
SoftwareSerial c64Serial(10, 11);
// Initialisation stuff - runs once on power-up/reset
void setup() {
// Open serial communication and wait for port to open:
Serial.begin(1200);
while (!Serial) {
; // Wait for serial - Only needed for built-in USB
}
// Send out local startup message
Serial.println("ATTEMPTING TO CONNECT TO C64 ...");
// Set the baud rate to speak to C64
c64Serial.begin(1200);
// Send message to C64
c64Serial.println("HELLO C64?");
}
// Run forever
void loop() {
// IF THE C64 HAS DATA THEN PRINT IT HERE
if (c64Serial.available()) {
Serial.write(c64Serial.read());
}
// SEND DATA *TO* C64 ..
if (Serial.available()) {
c64Serial.write(Serial.read());
}
}
C64 RS-232 Echo
Here is the C64 BASIC code for communicating with the Arduino running the above code.
10 rem 1200,8n1
20 print "{clear}{white}"
30 open2,2,4,chr$(8)+chr$(0):rem open the serial from user port
40 get#2,s$:rem get from serial to prime the pump
100 rem main loop
110 rem ---------
200 get k$:rem get from c64 keyboard
220 if k$<>""then print#2,k$;:rem send keypress to serial
230 get#2,s$:rem get byte from serial
240 print s$;k$;:rem print these bytes
245 if (peek(673)and1)then 245:rem wait until all chars transmitted
900 goto 110
1000 close 2:end

Both examples have the Baud rate set to 1200 which is pretty standard for C64.
Make sure your Arduino Serial Monitor is also set to 1200 to not see a garbled mess.

Now whatever you type on your C64 or your computer should be sent and received, like a very simplistic chat program:
And you don’t have to use the Arduino Serial Monitor, here I am using Screen from the Mac command line:

RGB LED Strip Controlled from C64
I mentioned being able to access all the many add-ons and libraries available to Arduino – how about controlling a strip of individually addressable “Neopixel-style” RGB LEDs?

Arduino Code
This code uses the FASTLED library but you could easily convert it to use any number of alternatives:
#include <FastLED.h>
// Constants
#define NUM_LEDS 8
#define DATA_PIN A0
// Define the array of leds
CRGB leds[NUM_LEDS];
// Our switch variable
int LIGHTS_ON=false;
// Char to hold byte
char THIS_CHAR=0;
// Delay
long previousMillis = 0; // will store last time LED was updated
long interval = 500; // interval at which to blink (milliseconds)
void setup() {
FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS); // GRB order
// Open serial communications and wait for port to open:
Serial.begin(2400);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
Serial.println("READY.\r\r");
}
void flash()
{
static bool sw=true;
if(sw)
{
// Turn the LED on, then pause
leds[0] = CRGB::Red;
leds[1] = CRGB::Red;
leds[2] = CRGB::Red;
leds[3] = CRGB::Red;
leds[4] = CRGB::Blue;
leds[5] = CRGB::Blue;
leds[6] = CRGB::Blue;
leds[7] = CRGB::Blue;
FastLED.setBrightness(4);
FastLED.show();
}
else
{
// Now switch
leds[0] = CRGB::Blue;
leds[1] = CRGB::Blue;
leds[2] = CRGB::Blue;
leds[3] = CRGB::Blue;
leds[4] = CRGB::Red;
leds[5] = CRGB::Red;
leds[6] = CRGB::Red;
leds[7] = CRGB::Red;
FastLED.show();
delay(500);
}
sw=!sw;
}
void loop() {
// IF THE C64 HAS DATA
if (Serial.available()) {
THIS_CHAR=Serial.read();
if(THIS_CHAR=='1')
{
LIGHTS_ON=true;
Serial.println("LIGHTS ON.\r");
}
else
{
LIGHTS_ON=false;
Serial.println("LIGHTS OFF.\r");
}
}
if(LIGHTS_ON)
{
unsigned long currentMillis = millis();
if(currentMillis - previousMillis > interval) {
// save the last time you blinked the LED
previousMillis = currentMillis;
// flash the LEDs
flash();
}
}
else
{
FastLED.setBrightness(0);
FastLED.show();
}
}
The code above waits for a ‘1’ to be input and responds by switching on the light sequence which will continue until something other than ‘1’ is received.
Our super-simple C64 user interface is … the same code as above! BUT with one change. Just to show the difference, this Arduino code is set to 2400 baud so we need to change the following line in the C64 BASIC code:
30 open2,2,4,chr$(10)+chr$(0):rem open the serial from user port

