Introduction: ESP32 Basic PC With VGA Output
In this Instructable I am going to show how to build a simple retro style PC done with a single ESP32 and few other components.
This PC runs Tiny Basic, a simplified dialect of BASIC, and generates the output for a VGA monitor.
The resolution is 640x350 pixels, allowing 80x25 asci characters in 8 colors. A PS2 keyboards can be connected and used to write the code, allowing up to 14059 bytes of memory.
The ESP32 I/O pins can be directly driven by dedicated BASIC commands.
This project is made possible by the awesome ESP32 VGA library written by Fabrizio Di Vittorio. See here for more details.
Step 1: ESP32 Boards, Arduino IDE Installation and VGA Library Configuration.
First of all you need to purchase an ESP32 revision 1 or upper. There are many versions available, but I recommend to choose one with many pins. I am using this version, but I think many other are fine too. For instance, in the description of this video, you can find three other models which are below 5 bucks.
Once you get the board, you need to proceed with the following three sub-steps:
- Install the last Arduino IDE
- Configure the ESP32 in the IDE and
- Install the VGA library
Sub-step 1.
There are different methods to program the ESP32, but here you need to use the latest Arduino IDE (I am using the version 1.8.9). To install it, you can go to the Arduino IDE page and follow the instruction.
Sub-step 2.
Once the previous operation is done, you need to configure your ESP32 within the Arduino IDE. This is not trivial, since the ESP32 is not (yet?) native in it. You can follow this tutorial, or the following steps.
1) open the Arduino IDE
2) open the preferences window, File/Preference, alternatively press "Ctrl+comma"
3) go to the “Additional Board Manager URLs”, copy and paste the following text:
https://dl.espressif.com/dl/package_esp32_index.json
and click the OK button .
4) Open boards manager. Go to Tools/Board/Boards Manager…
5) Search for ESP32 and press the install button for the “ESP32 by Espressif Systems“:
6) At this point, when you connect for the first time your ESP32, you should choose the right model in the long list of available ESP32 boards (see the picture in this step). In case of doubts about the model, just choose the generic one, i.e. the first one. It works for me.
7) the system should also choose the right USB port and the Upload Speed (normally 921600). At this point the connection between your PC and the ESP32 board should be established.
Sub-step 3.
Finally you have to install the FabGL VGA library. [update July 2019] You need and old version of this libray: you can download the zip file src.old.zip at the bottom of this step, uncompress and rename the folder as "src" in your
"...\arduino-1.8.9\libraries" folder.
Once you have done these operations, you can go to the next step and upload the modified TinyBasic following the next step.
Attachments
Step 2: Uploading Tiny Basic Code to the ESP32
Download ESP32_TinyBasicPlus_PS2_FabLab_beta.ino at the bottom of this step.
Open it with the Arduino IDE and upload it to your raw ESP32.
If you have no error messages, the code should already be running.
Facultative step: if you want to test TinyBasic before connecting the VGA and PS2 keyboard, you can already do it with a SSH and telnet client. I use PuTTY.
You can see how it looks in the pictures in this step.
Step 3: Connecting the VGA Port
You need the following parts:
- a DSUB15 Connector, i.e. a VGA female connector or a VGA cable to be cut.
- three 270 Ohm resistors.
Connect the ESP32 GPIO pin 2, 15 and 21 to VGA Red, Green and Blue respectively, through the 270 Ohm resistors.
Connect the VGA Hsync and Vsync to ESP32 GPIO pins 17 and 4 respectively.
Connect the DSUB15 connectors pins 5, 6, 7, 8 and 10 to ESP32 GND.
For the VGA DSUB15 connector pin definition, see the picture in this step. NB, this is the soldering side of the female connector.
Step 4: Connecting the PS2 Port
You need a PS2 keyboard female connector.
You can get one from an old PC motherboard, simply unsold it with a heat gun.
In the picture shown in this step, you can find the function of the needed pins of the PS2 connector.
The connection are:
- Keyboard Data to ESP32 GPIO pin 32
- Keyboard IRQ (clock) to ESP32 GPIO pin 33
- You also need to connect the 5V pin and the GND one.
Step 5: Programming With Tiny Basic
At this point, if you can connect the VGA monitor and PS2 keyboard and the ESP32 to power supply.
The image shown here should appear on the monitor. Now you can play a bit with Tiny Basic commands.
Try, for instance, the mandatory Hello, Word! infinite loop:
10 print "Hello, World!"
20 goto 10
run
You can change in four different colors pressing the esc button, and stop the loop with ctrl+c
Note that if you make a typo, you cannot cancel it! Or better, you can cancel but then the typo correction is not recognized. You need to rewrite the whole command line.
Now you can try something more complex, such as driving the blinking of an LED with a basic program. Connect, for instance, the LED anode (the long leg) to ESP32 GPIO pin 13, and the cathode to GND.
Then write:
new
10 i=1000
20 print i
30 delay i
40 dwrite 13,high
50 delay i
60 dwrite 13,low
70 i=i*9/10
80 if i>0 goto 20
90 end
run
You can see the result in the video embedded in this Instructable.
Step 6: Connecting an SD Memory Card.
A vintage PC, it dos not matter how little and weak, cannot be complete if you cannot store your programs permanently.
In this step I will show how to connect a SD memory card, but unfortunately, for the moment (I hope only for the moment), the storing of programs does not work!
BTW, I used a microSD to SD card adapter and I soldered 8 L-shaped pins as shown in the picture in this step.
I then connected the SD adapters pins to the ESP32 according to he second picture, i.e. I connected the ESP32 GPIO pins 5, 18, 19, 23 to SC, clock, MISO, MOSO respectively, plus 3.3V and two GND.
I also followed the instructions and examples found here, and with the example code SD_test.ino, I can write on my 2 GBytes microSD card.
Thus if anybody find a solution, please inform me asap to my email rocaj74@gmail.com and I will complete this Instructable.
Step 7: Acknowledgments
I wish to express my tanks to Fabrizio Di Vittorio for his awesome ESP32 VGA library. For more details, examples, and... Space Invaders, visit his site here.
many thanks also to the authors of Tiny Basic:
- Mike Field
- Scott Lawrence
- Brian O'Dell
Finally, if you like this project, please write a comment or share a picture of the device you build... and, over all, vote for it in the Arduino contest!

Participated in the
Arduino Contest 2019
24 Comments
4 months ago
So far, doesn't work. I get lots of error codes and I can't make out what to activate, deactivate, comment or remove from the compiling codes to make it work on an stock ESP32-WROOM.
Is there an updated version, ONLY for ESP32?
Arduino: 1.8.13 (Linux), Board: "ESP32 Dev Module, Disabled, Default 4MB with spiffs (1.2MB APP/1.5MB SPIFFS), 240MHz (WiFi/BT), QIO, 80MHz, 4MB (32Mb), 921600, Core 1, Core 1, None, Disabled"
/home/jan/Data/ESP32-IOT2/Opd3.ESP32_TinyBasicPlus_PS2_FabLab_beta/Opd3.ESP32_TinyBasicPlus_PS2_FabLab_beta.ino:108: warning: "ARDUINO" redefined
#define ARDUINO 1
<command-line>: note: this is the location of the previous definition
/home/jan/Data/ESP32-IOT2/Opd3.ESP32_TinyBasicPlus_PS2_FabLab_beta/Opd3.ESP32_TinyBasicPlus_PS2_FabLab_beta.ino: In function 'void loop()':
/home/jan/Data/ESP32-IOT2/Opd3.ESP32_TinyBasicPlus_PS2_FabLab_beta/Opd3.ESP32_TinyBasicPlus_PS2_FabLab_beta.ino:1600:32: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
address = (unsigned char *)value;
^~~~~
Opd3.ESP32_TinyBasicPlus_PS2_FabLab_beta:1593:20: error: variable 'address' set but not used [-Werror=unused-but-set-variable]
unsigned char *address;
^~~~~~~
Opd3.ESP32_TinyBasicPlus_PS2_FabLab_beta:1718:20: error: variable 'txtposBak' set but not used [-Werror=unused-but-set-variable]
unsigned char *txtposBak;
^~~~~~~~~
Opd3.ESP32_TinyBasicPlus_PS2_FabLab_beta:991:11: error: unused variable 'alsoWait' [-Werror=unused-variable]
boolean alsoWait = false;
^~~~~~~~
Opd3.ESP32_TinyBasicPlus_PS2_FabLab_beta:1142:1: error: label 'unimplemented' defined but not used [-Werror=unused-label]
unimplemented:
^~~~~~~~~~~~~
/home/jan/Data/ESP32-IOT2/Opd3.ESP32_TinyBasicPlus_PS2_FabLab_beta/Opd3.ESP32_TinyBasicPlus_PS2_FabLab_beta.ino: At global scope:
Opd3.ESP32_TinyBasicPlus_PS2_FabLab_beta:473:23: error: 'stack' defined but not used [-Werror=unused-variable]
static unsigned char *stack; // Software stack for things that should go on the CPU stack
^~~~~
Opd3.ESP32_TinyBasicPlus_PS2_FabLab_beta:313:22: error: 'sentinel' defined but not used [-Werror=unused-variable]
static const char * sentinel = "HELLO";
^~~~~~~~
cc1plus: some warnings being treated as errors
Multiple libraries were found for "SD.h"
Used: /home/jan/.arduino15/packages/esp32/hardware/esp32/2.0.5/libraries/SD
Not used: /home/jan/Data/SOFTWARE/Arduino/arduino-1.8.13/libraries/SD
exit status 1
variable 'address' set but not used [-Werror=unused-but-set-variable]
This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.
Reply 4 months ago
It looks like you are using a "wrong" (newer) version ofESP32 VGA library.
See the sub-step 3 in step-1 above and follow the instructions to download the old ones. Make sure to remove the newer ones, otherwise you may have conflicts.
For instance, it seems you also have multiple libraries for "SD.h" too:
Used: /home/jan/.arduino15/packages/esp32/hardware/esp32/2.0.5/libraries/SD
Not used: /home/jan/Data/SOFTWARE/Arduino/arduino-1.8.13/libraries/SD
Question 1 year ago
Is it possible to replace the ps/2 port with a usb port?
1 year ago
How can I connect esp32 to VGA and stream video from smart phone?
Reply 1 year ago
I don't know but I do not think if it is even possible...
2 years ago on Step 7
I wrote a improved version of TinyBasic based on this project. The source can be found in:
https://github.com/fg1998/ESP32-Basic-vga
1 - Works with latest version of FABgl http://www.fabglib.org/classfabgl_1_1_terminal.html
2 - Compatible with TTGO VGA32 Version 1.4 http://www.lilygo.cn/prod_view.aspx?TypeId=50033&Id=1083&FId=t3:50033:3
3 - Add SDCard support (CS=13 CLK=14 MISO=2 MOSI=12). To save or load add '/' as the file name first chr ex load "/foo.bas"
4 - Adjust screen resolution to 640x200 (80x25 text) for low ram use
5 - TEXT AND GRAPHICS CAN BE MIXED TOGHETER
6 - Include file platformio.ini for using with platformIO Visual Studio Code plugin.
** New commands
- CLS - Clear screen
- COLOR FORECOLOR, BACKCOLOR - set screen color
- POINT COLOR, X, Y - draw a pixel
- LINE, INIT X, INIT Y, END X, END Y, PEN WIDTH
- RECTANGLE COLOR, COLOR FILL (-1 USES NO COLOR), INIT X, INIT Y, END X, END Y, PEN WIDTH
- ELIPSE COLOR, X, Y, WIDTH, HEIGHT, PEN WIDTH
- CURSOR 0/1 -> ENABLE/DISABLE CURSOR
- AT X,Y -> puts cursor on x,y
ENJOY !!!!Reply 2 years ago
Dear fg1998,
I have briefly tried your version of ESP32 TinyBasic PC and it is awesome!!!
As shown in the picture below I used the TTGO VGA32 Version 1.4.
Can I also use a bare ESR32, such as the ESP32 NodeMCU WiFi - CP2102, shown in this Instructable?I tried already, connecting the VGA as shown in the FabGl GitHub page here, but it does not work. Do you know the pinout?
My Idea would be to insert an ESP32 inside an old PS2 keyboard to have a “Commodore 64 Like” vintage PC…
Reply 2 years ago
Hi there. Do you have more clues for me to help solve that ?
Reply 2 years ago
Hi, I solved the problem a while ago. You can see it here:
I also designed a PC board, I just finished to assemble it few days ago (see picture below).
Do you think it is possible to add to Tiny Basic a couple of fonctions:
1) the command inkey (or inkey$), to enter a variable while the code is running without pausing it
2) a graphic command to read the color of a pixel (such as "get x,y"), this would be very useful to develop simple graphic games
Reply 2 years ago
Hi Rob, thanks for the message. Of course you can use your own version of a VGA32 board. I used to use one build by myself before get TTGO board from aliexpress.
Your 'c64 like' ideia looks great, but what about a 'Zx Spectrum' version, since there are 2 zx spectrum emulators running on VGA32 boards ?
I´m using standard FabGl Pinout, but not in the sdCard. Attention for this or you got issues.
VGA
Red - 21/22
Green - 18/19
Blue - 4/5
Hsync - 23
Vsync - 15
SD Card
SCK = 14
MISO = 02
MOSI = 12
CS = 13
Keyboard
Data = 32
Clock = 33
Reply 2 years ago
Dear fg1998,
I'm getting some strange errors, and I think I'm not implementing FabGL library. Can you please explain to me how I should do it?
Thanks in advance!
Reply 2 years ago
Dear fg1998,
I tried again your code and everything works perfectly. Congratulation, it is awesome!
I plan to use it soon in a little project...
Reply 2 years ago
That's great! looking forword to test it!
2 years ago
Is it possible to make this work with the current FabGL VGA library?
Reply 2 years ago
yes, this versions works fine with FabGL 0.9.0
https://github.com/fg1998/ESP32-Basic-vga/blob/main/README.md
Question 2 years ago on Step 1
Hi Rob, do I need to include the vga part even if I only first want to test with the Putty aproach?
Answer 2 years ago
Hi middelbh, if you upload the code in step 2, you need at least to include the VGA library.
If you upload the bare TinyBasic, there is no VGA at all.
Question 3 years ago
hii rob nice to see you again
i try to make this project but when i test TinyBasicPlus with putty
i have some problems as in photo below
the first one is when i'm writing the code sometimes i have "What?" or "how" even the instruction was corect
the another problem is when i finish writing code and enter "run" i have "what?"
i think the TinyBasicPlus is unstable because it sometimes accebt the instruction and sometimes works well so what is the problem and what is the solution
i'm using ESP32 WROOM
Answer 3 years ago
i try it with serial monitor and every thing works fine but when i use "dwrite" instruction like "dwrite 13,high" the output bit volt become 3.3v not 5v why
Reply 3 years ago
I have the same problem. Problem occures when you "enter" backspace while writing a line of code. For example, if you write "for t=...", and then you decide to delete "t" and then you hit backspace to remove it and enter new character instead of "t", error will occure when you will run the program.
Current solution is just to rewrite the same line without using backspace (deleting a character).