book collections email follower instructable user
Picture of Commodore 64 Revamp With Raspberry Pi, Arduino and Lego
commodoreSide.JPG
commodoreBack1.JPG
CommodoreBack2.JPG

This project lets you rediscover the 1980's gaming scene by resurrecting an old Commodore 64 home computer using new components and those ever-versatile Lego bricks! If you had one of these computers, this build will let you replay forgotten games and beat old high scores. If you're new to retro-computing, now's your chance to see why the Commodore 64 was so incredibly popular.

  • A Raspberry Pi computer is used to replace the motherboard
  • RetroPie provides the emulation platform for the Commodore (and other systems)
  • A small Arduino Micro allows the Commodore 64 keyboard to be used as a fully operational USB keyboard
  • Lego pieces are used to build the internal housing
  • Keystone connectors provide the Commodore with USB, HDMI and network ports which are connected internally to the Pi

This project does not require programming or electronics skills. Makers who have used the Raspberry Pi or Arduino boards will find this build quite easy and it certainly helps if you have used Lego before - surely everyone has?!

This project will not physically alter the Commodore 64 case or keyboard, just in case you decide to use it in a different way in future. You may need to make repairs to an old one though.

Step 1: Get the Components Together

The components needed are listed in this section. If you don't have them all, there are links and suggestions available for getting hold of them with an approximate indication of price in US dollars (as at August 2019). It is worth reading this article in full to help decide on the Lego and exact cables you will use.

Once you have everything, you should be able to easily complete this build over a weekend.

Commodore 64

  • Ideally get a defunct machine but with a working keyboard. It would be a shame to dissemble a working machine or one that might need slight attention to repair! If you can't get a Commodore 64, then a Vic 20 or C16 should work instead with minor build changes mentioned in this guide
  • The Commodore is probably the hardest part to get but they are available on eBay in the US and UK starting at around $50. Best to look at one that is being sold for parts and needs some TLC. You just need the case and keyboard so you may be able to purchase those parts separately

Raspberry Pi

  • The Raspberry Pi 2 and 3B will work well. The Pi 4 is a great new addition to the Pi family but check that you can get a Lego case for it. Also note that the cable requirements are different because it has micro-HDMI and USB-C ports
  • A Pi 3B is available for around $35. Use your favourite search engine to find one or follow the link and change to your location: Raspberry Pi 3B+

Lego Raspberry Pi case

  • This is the best choice for building the Pi into the internal Lego casing. There are so many cases for the Pi so it might be possible to get away with other options, fitting Lego pieces around it
  • The Lego case from the Pi Hut was used for this build. It costs around $10 and comes in a choice of colours. Use this link to find one: Lego Raspberry Pi case

Micro SD card

  • Your Pi will need a micro SD card to install RetroPie software onto
  • RetroPie is an ideal choice if you will be using your Commodore 64 as a games machine
  • Micro SD cards are widely available and are cheap, around $5. A 16GB card is an ideal choice for most users

Raspberry Pi power supply

  • The official Raspberry Pi power supply is the safest choice
  • You should be able to get the official power supply from the same place you get the Raspberry Pi from

Arduino Micro

  • This small microprocessor translates the Commodore 64 matrix keyboard into a USB HID compliant keyboard which is plugged into the Pi
  • The software needed to do the translation is available in this article and is uploaded to the Micro using the Arduino IDE. If you do a Vic 20 or C16 build, then this software will require minor changes to the matrix mapping table, explained later
  • It is one of the smallest Arduino boards and costs around $20. Use your favourite search engine to find one or follow this link and change to your location: Arduino Micro

Half-size breadboard

  • This is used to connect the Arduino Micro to the 20 pin connector on the Commodore 64
  • They are available from electronics shops and online, priced around $5. This link is for a half-size breadboard from Adafruit: Half-size breadboard

Jumper wires

  • These male to male and male to female jumper wires are used with the breadboard and to connect the Commodore 64 LED to GPIO pins on the Pi
  • They are available from electronics shops and online, priced around $2 to $4 per pack. This link is for a 40 pack of 75mm male to male jumper wires from Adafruit: 40 pack of 75mm male to male. This link is for a 20 pack of 75mm female to male jumper wires from Adafruit: 20 pack of 75mm female to male

Keystone inserts

  • These provide the USB, HDMI and Network ports on the Commodore 64 to plug into. They include:
    • 2 x Keystone USB inserts
    • 1 x Keystone HDMI insert
    • 1 x Keystone RJ45 network insert
  • Lego pieces generally fit well around Keystone inserts with some minor modification (mentioned in the build steps later). Cables from the Pi connect to the other end of the Keystone inserts
  • They are available from electronics shops and online, the best place to start looking is probably eBay searching for "keystone usb", "keystone hdmi" and "keystone rj45". They are a standard size and each part costs between $5 and $10

Cables

  • Cables between the Pi and Keystone inserts above are needed. These are:
    • 2 x male to male USB cables
    • 1 x male to female micro-USB extension cable
    • 1 x male to male HDMI cable
    • 1 x network lead. This cable will be cut in two for connection to the Keystone RJ45 network insert, so re-use an old one if possible. I found one with a broken clip on one end to re-use
    • 1 x male USB to male micro-USB cable
  • They are readily available from computer, TV and electronics shops and online, selling for around $5
  • As they will all fit inside the Commodore, try to get short cables, around 20cm if possible. Avoid cables like my half-metre HDMI cable snaking around inside the case!

Lego

  • A good assortment of Lego pieces are needed, particularly plates and bricks of varying lengths with a single stud width. For a Vic 20 or C16 build, you will need slightly different pieces to fit around their external ports compared to the Commodore 64
  • They are available from toy shops, markets and on-line. I got most of the pieces needed from a Sunday market but pick-a-brick from the Lego shop website is a good online choice to get the exact pieces needed: Pick a Brick
kerryp2421 days ago
I've wired up an Arduino Micro, exactly, as your pinout description. I've taken your, keys, rowPins and colPins and put them into a simple program using Keypad to output the key/codes found to the serial port. EVERYTHING is working fine... EXCEPT... if I hit any key in row 7 (e.g. 2, 4 6, 8, etc) the micro resets. ONLY this row! Also there is cases where any of the rows that have two defined values at the end of the row (e.g. {'1','3','5','7','9','+',KEY_POUND, KEY_DELETE},) both of the last two keys respond with TWO codes.. If I hit the pound key I get back both KEY_POUND and KEY_DELETE. If I hit the delete key I get back both the KEY_POUND and KEY_DELETE codes.
This second condition, I'll figure out, but the reset issue has me baffled.
Any thoughts or ideas to look at?

Here's the code if you feel adventurous.

Thanks
Kerry

-------------------------------------------------------------------------------

/* @file MultiKey.ino
|| @version 1.0
|| @author Mark Stanley
|| @contact mstanley@technologist.com
||
|| @description
|| | The latest version, 3.0, of the keypad library supports up to 10
|| | active keys all being pressed at the same time. This sketch is an
|| | example of how you can get multiple key presses from a keypad or
|| | keyboard.
|| #
*/
#include <Keypad.h>
#define KEY_TAB 0x09
#define KEY_RETURN 0x0d
#define KEY_ESC 0x1b
#define KEY_QUOTE 0x22
#define KEY_HASH 0x23
#define KEY_APOSTROPHE 0x27
#define KEY_AT_SIGN 0x40
#define KEY_LEFT_SQUARE 0x5b
#define KEY_BACKSLASH 0x5C
#define KEY_RIGHT_SQUARE 0x5d
#define KEY_PIPE 0x7C
#define KEY_TILDE 0x7E
#define KEY_DELETE 0x7f
#define KEY_POUND 0x9c
#define KEY_NULL 0xFF
#define KEY_LEFT_CTRL 0x80
#define KEY_LEFT_SHIFT 0x81
#define KEY_LEFT_ALT 0x82
#define KEY_LEFT_GUI 0x83
#define KEY_RIGHT_CTRL 0x84
#define KEY_RIGHT_SHIFT 0x85
#define KEY_RIGHT_ALT 0x86
#define KEY_RIGHT_GUI 0x87
#define KEY_UP_ARROW 0xDA
#define KEY_DOWN_ARROW 0xD9
#define KEY_LEFT_ARROW 0xD8
#define KEY_RIGHT_ARROW 0xD7
#define KEY_BACKSPACE 0xB2
#define KEY_TAB 0xB3
#define KEY_RETURN 0xB0
#define KEY_ESC 0xB1
#define KEY_INSERT 0xD1
#define KEY_DELETE 0xD4
#define KEY_PAGE_UP 0xD3
#define KEY_PAGE_DOWN 0xD6
#define KEY_HOME 0xD2
#define KEY_END 0xD5
#define KEY_CAPS_LOCK 0xC1
#define KEY_F1 0xC2
#define KEY_F2 0xC3
#define KEY_F3 0xC4
#define KEY_F4 0xC5
#define KEY_F5 0xC6
#define KEY_F6 0xC7
#define KEY_F7 0xC8
#define KEY_F8 0xC9
const byte ROWS = 8;
const byte COLS = 8;
uint8_t keys[ROWS][COLS] = {
{'1','3','5','7','9','+',KEY_POUND, KEY_DELETE},
{KEY_TAB, 'w','r','y','i','p','*', KEY_RETURN},
{KEY_LEFT_CTRL, 'a','d','g','j','l',';', KEY_RIGHT_ARROW},
{KEY_ESC, KEY_LEFT_SHIFT, 'x','v','n',',','/', KEY_DOWN_ARROW},
{' ','z','c','b','m','.', KEY_RIGHT_SHIFT, KEY_F1},
{KEY_LEFT_ALT, 's','f','h','k',':','=', KEY_F3},
{'q','e','t','u','o', KEY_AT_SIGN, KEY_PAGE_DOWN, KEY_F5},
{'2','4','6','8','0','-', KEY_HOME, KEY_F7}
};
uint8_t shiftkeys[ROWS][COLS] = {
{'!', KEY_HASH,'%', KEY_APOSTROPHE,')','+', KEY_POUND, KEY_INSERT},
{KEY_TAB, 'W','R','Y','I','P','*', KEY_RETURN},
{KEY_LEFT_CTRL, 'A','D','G','J','L',']', KEY_LEFT_ARROW},
{KEY_ESC, KEY_NULL, 'X','V','N','<','?', KEY_UP_ARROW},
{' ','Z','C','B','M','>', KEY_NULL, KEY_F2},
{KEY_LEFT_ALT, 'S','F','H','K','[','_', KEY_F4},
{'Q','E','T','U','O', KEY_AT_SIGN, KEY_PAGE_UP, KEY_F6},
{KEY_QUOTE, '$','&','(','0','-', KEY_END, KEY_F8}
};
byte rowPins[ROWS] = {4,5,6,7,8,9,10,11};
byte colPins[COLS] = {A5,A4,A3,A2,A1,A0,2,3};
Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
unsigned long loopCount;
unsigned long startTime;
String msg;
void setup() {
Serial.begin(9600);
loopCount = 0;
startTime = millis();
msg = "";
}
bool killLoopFlag = false;
void loop()
{
char c, dspbuf[32];
if (!killLoopFlag)
{
if (Serial.available())
{
c = Serial.read();
if ((c == 'q') || (c == 'Q'))
{
killLoopFlag = true;
Serial.end();
}
}
loopCount++;
if ( (millis()-startTime)>5000 )
{
Serial.print("Average loops per second = ");
Serial.println(loopCount/5);
startTime = millis();
loopCount = 0;
}
// Fills kpd.key[ ] array with up-to 10 active keys.
// Returns true if there are ANY active keys.
if (kpd.getKeys())
{
for (int i=0; i<LIST_MAX; i++) // Scan the whole key list.
{
if ( kpd.key[i].stateChanged ) // Only find keys that have changed state.
{
sprintf(dspbuf, "Key 0x%02X ", kpd.key[i].kchar);
switch (kpd.key[i].kstate) { // Report active key state : IDLE, PRESSED, HOLD, or RELEASED
case PRESSED:
msg = " PRESSED.";
strcat(dspbuf, " PRESSED");
break;
case HOLD:
msg = " HOLD.";
strcat(dspbuf, " HOLD");
break;
case RELEASED:
msg = " RELEASED.";
strcat(dspbuf, " RELEASED");
break;
case IDLE:
msg = " IDLE.";
strcat(dspbuf, " IDLE");
}
// sprintf(dspbuf, "Key 0x%02X %s", kpd.key[i].kchar, msg);
Serial.println(dspbuf);
// Serial.print("Key ");
// Serial.print(kpd.key[i].kchar);
// Serial.println(msg);
}
}
}
}
else
{
delay(500);
}
} // End loop
RaspberryPioneer (author)  kerryp2419 days ago
Hi Kerry
I've tried the code you provided and it works well for me. I tried all keys on the matrix. If you're using the same keypad library (v3.1.1), then I guess the wiring would be the next place to check. I've got two C64s and micros on this pinout mapping, which I checked in the article just in case ... Failing that, then if you've got another Arduino, that would be worth a try. Maybe the C64 keyboard is faulty but I'm not sure how that would reset the micro. Good luck - let me know how you go?
Thanks for your testing and reply. I have tried this on both an Arduino Micro and NANO. When I had the row on pin 11 (as in your article) and I hit any of those row keys... the micros would reset. I moved row 7 to pin 12 and put the RESTORE key on pin 11. Problem went away. Of course, if I hit the RESTORE key, the micro resets. So, either the issue is how pin 11 is setup by the Keypad code or ... Anyway, I've worked around it. Thanks for your help and the article. I'm actually 3D printing side and back panels for the Pi and ports to be accessed. I'll shoot you a pic when done. Regards
RaspberryPioneer (author)  kerryp2414 days ago
A bit puzzling but good to hear your problem has mostly been resolved with the workaround. I would be interested to see your 3D printed results! My brother has created some 3D prints (he has the other C64 I mentioned) and the results are very professional looking. I've also got a PCB for the keyboard now, pic below. Might be an option for your set-up?
pic1.jpgpic2.jpg
attosa19 days ago
Wow. I still have my Commodore 64 but I'd need some assistance for this build. Impressive :)
Wow great project! A lot of time must have been put in to this, looks a lot of fun with the old games!
demosthien22 days ago
Nicely put together project and ‘ible.

I look forward to seeing your PCB solution to replace the breadboard.
temman7426 days ago
All this project is it available for amstrad 6128?
Does anyone know positive?
I have one in the ground floor...

You make me happy my friend
Thanks
RaspberryPioneer (author)  temman7426 days ago
The Amstrad 6128 also has a matrix style keyboard and the documents
for it are on-line so I think with a bit of tinkering with the Arduino code and
jumper connections you should have a decent chance of getting that to work
I have been looking at a similar solution, but run into a problem that RetroPi + Vice doesn't want to drop you into the basic prompt. IMHO nostalgic value would increase if it would do the following:
* Start Vice directly at boot of the PI
* Make Vice start with the basic prompt by default.

Does anyone know how to do that?
I’ve not tried this myself but instead of RetroPie, it might
be worth looking at Combian 64 https://cmaiolino.wordpress.com/.
It boots into VICE. To get the VICE settings and to load the games, pressing
the Control key and F7 on my Commodore build (which is F12) should get you
there
RaymondR626 days ago
I admire the complete build, but I foresee a power issue in the Micro USB port in step 12. I strongly recommend upgrading to a USB type C port, which is very common now for Samsung and Apple products, has no issue if the plug is inserted upside down, and can carry over 5 amps (25 Watts) of power. After replacing many Micro USB ports in laptops, smartphones, and even Chromebooks, I know that the USB type C port is the much better power option.
RaspberryPioneer (author)  RaymondR626 days ago
Thanks for the tip. I might add a USB hard disk inside the Commodore which needs
a powered USB hub, so will look at USB-C port for that connection
Instrukta26 days ago
Impressive and thx for sharing. Now, i think i have to build the same :-)
wgb771826 days ago
Wow! This is a great project! I wish I didn't take my old C64s to Goodwill, but now I know what I'm going to do if I come across another!
pettenatib327 days ago
and Lego...
seamster27 days ago
Very cool! Nicely presented details, thank you! : )