8
\$\begingroup\$

Any Arduino enthusiasts out there?

Hey, I've been thinking about this and the more I think about it, the more I think I can actually do this. My idea is basically this: Make a functional computer out of an Arduino Uno microcontroller.

My only goal for this computer is the ability to edit and execute BASIC programs. That's all. I only want it for the programming, as that's just about the only thing I'm interested in right now :)

So the way I see it, I'll need three main hardware components:

  1. some form of a display (VGA screen or something)
  2. some way to register keyboard input, and
  3. some way to store data to external memory.

Does anyone know of any way to do this? I know of ways to display to a screen, but I don't know a good API/hardware component to register keyboard input or to store external memory.

I'm going to need a lot of help on this. Can anyone help me out and offer ideas and useful tips and suggestions for good hardware / a good open source library, or two, or three, or ten?

Added:

Blog Making an Arduino Uno Computer for anyone who's interested.

\$\endgroup\$
  • \$\begingroup\$ This sounds like my kind of hair-brained project ;) I look forward to hearing how you get on with it. I hope you'll blog your progress. \$\endgroup\$ – Majenko Sep 21 '11 at 15:07
  • 1
    \$\begingroup\$ I just wanted to point out a similar project that may be of interest. The Parallax Propeller chip has seen quite a lot of development as far as BASIC is concerned. There are at least two different interpreters available. Plus it has the ability to directly output signal to a TV of a monitor. \$\endgroup\$ – AndrejaKo Sep 21 '11 at 16:05
  • 1
    \$\begingroup\$ There's even the Demo Board which has VGA, TV, PS/2 keyboard and mouse, audio and few more connectors. Now I know that you want to do this with an Arduino, but at least you could use the board schematics presented there to get some basic pointers at how they did signal generation and so on (it's all in software). \$\endgroup\$ – AndrejaKo Sep 21 '11 at 16:08
  • \$\begingroup\$ Also +1 for wanting to do something like this! I remember back in elementary school when we moved form the Orao computer to Pentium III computers BASIC lost all of its charm. \$\endgroup\$ – AndrejaKo Sep 21 '11 at 16:10
  • 1
    \$\begingroup\$ An alternative to using a VGA display is to pick up an LCD shield and use that for the display. You may have to squint, but interfacing with it will be MUUUCH easier! \$\endgroup\$ – SingleNegationElimination Sep 21 '11 at 17:57
11
\$\begingroup\$

The keyboard can be done simply using a PS/2 keyboard - it's just serial, and there's plenty of tutorials out there for it.

Storing data can be done simply on an SD card - there is a shield out there already to do that.

As for the video - that's considerably harder. If you want the Arduino to generate a PAL video signal for instance then you have your work cut out for you. Yes, it is possible, and someone has created an Arduino "pong" game, but it's very chunky graphics and only black and white.

For VGA you will require some form of interface to do the work for you. Sparkfun used to sell the Picaso video card that could be made to work with the Arduino, but alas that has been discontinued and there are no plans as yet for a replacement.

TBH your best bet would be to use something like a Wyse terminal and communicate with the Arduino completely using serial. Much simpler than messing with video signals and such.

\$\endgroup\$
3
\$\begingroup\$

I see Olin's point here - if you only want to edit/run/learn BASIC just use a PC.

However if the goal is the challenge of creating a computer that can run BASIC and learn about the hardware and lower level implementation at the same time then this is a bit different. I am all for stuff like this, it's a great way to improve knowledge and am sure will you get a lot out of it. As Steven mentions all the confusing and (mostly)irrelevant layers that e.g. Windows has can be stripped away, leaving the basic (no pun intended) concepts.

Anyway, you might want to look at something a little more powerful like the PIC32 for this, as it should be able deal with all of the functionality (e.g. basic VGA) on it's own.
Here is an Arduino compatible board, the UNO32
The Maximite is a computer with BASIC interpreter based around a PIC32, you might want to look at the Design and Construction for a few ideas.

\$\endgroup\$
  • \$\begingroup\$ Given the specs of PC's running Microsoft Basic under a Z80, there should be no real issue. \$\endgroup\$ – mckenzm Aug 2 at 2:37
2
\$\begingroup\$

Your in luck, sort of, because I am actually working on an arduino PC right now! It isn't much though, only the first model. The firmware is also very simple, and has a small API set. But, the thing works! Not good enough to edit BASIC (or any language except its own), but this is only the first model. The mobo is quite simple, and I used this. Here is the firmware I used:

        #include <LCD4884.h>
#include <SD.h>
#include <SPI.h>
#include <SoftwareSerial.h>

void setup() {   
    lcd.LCD_init();             
    lcd.LCD_clear();
    lcd.LCD_write_string_big(0, 0, "Gilbert", MENU_NORMAL);
    pinMode(10, OUTPUT);
    delay(3000);
}

byte line = 10;
SoftwareSerial FC(8,9);
byte RAM[501];
byte Error = 0;
char tempString[15];

void loop() {
    // <editor-fold defaultstate="collapsed" desc="Initilization">
    FC.begin(4800);
    if (!FC.available()) {
        lcd.LCD_clear();
        lcd.LCD_write_string(0, 0, "FC Failed!", MENU_NORMAL);
        delay(1000);
    }
    int address = 1;
    lcd.LCD_clear();
    lcd.LCD_write_string(0, 0, "SD Init...", MENU_NORMAL);
    if (!SD.begin(10)) {
        lcd.LCD_clear();
        lcd.LCD_write_string(0, 0, "SD Failed!", MENU_NORMAL);
        while (true) {
            ;
        }
    }
    lcd.LCD_clear();
    lcd.LCD_write_string(0, 0, "Loading...", MENU_NORMAL);
    File file;
    file = SD.open("BIOS.mk8", FILE_READ);
    RAM[0] = 53;
    RAM[file.read()] = 8;
    while (file.available()) {
        RAM[address] = file.read();
        address++;
    }
    address++;
    RAM[address] = 55;
    long loops = 0;
    long time1 = 0;
    long time2 = 0;
    address = 0;
    byte instruction = 0;
    int exeaddress;
    byte tempbyte;
    lcd.LCD_clear();
    lcd.LCD_write_string(0, 0, "EMU. Started", MENU_NORMAL);// </editor-fold>
    //emulation loop
    while(true){
        switch(RAM[address]){
            // <editor-fold defaultstate="collapsed" desc="Codes 1-10">
            case 1:
            {//getCycleCount[intvar i]
                tempbyte = (loops) / ((time2 - time1) / 1000);
                convert(address + 1);
                writeInt(exeaddress, tempbyte);
                break;
            }
            case 2:
            {//getTemp[intvar i]
                tempbyte = (((analogRead(A1) / 1024.0) * 5.0) - .5) * 100;
                convert(address + 1);
                writeInt(exeaddress, tempbyte);
                break;
            }
            case 3:
            {//getKey[intvar i]
                //Up 745
                //Down 332
                //Left 0
                //Right 509
                //Center 145
                switch (analogRead(A0)) {
                    case 745:
                    {
                        tempbyte = 1;
                        break;
                    }
                    case 332:
                    {
                        tempbyte = 2;
                        break;
                    }
                    case 0:
                    {
                        tempbyte = 3;
                        break;
                    }
                    case 509:
                    {
                        tempbyte = 4;
                        break;
                    }
                    case 145:
                    {
                        tempbyte = 5;
                        break;
                    }
                }
                convert(address + 1);
                writeInt(exeaddress, tempbyte);
                break;
            }
            case 4:
            {//printLine[variable v]
                if (line > 70) {
                    lcd.LCD_clear();
                    line = 0;
                }
                switch(RAM[address + 1]){
                    case 9:{
                        tempbyte = RAM[address + 1];
                        tempString[0] = char(tempbyte);
                        break;
                    }
                    case 15:{
                        convert(address + 1);
                        break;
                    }
                }
                lcd.LCD_write_string(0, line, tempString, MENU_NORMAL);
                line += 10;
                break;
            }
            case 5:
            {//exe detector
                exeaddress = address;
                break;
            }
            case 7:
            {//lcdClear
                lcd.LCD_clear();
                line = 0;
                break;
            }
            case 10:
            {//declareInteger[string name]
                convert(address + 1);
                tempbyte = 0;
                while (tempbyte != 15) {
                    RAM[address + tempbyte + 1] = tempString[tempbyte];
                }
                break;
            }// </editor-fold>
            case 11:{//getError[intvar i]
                tempbyte = Error;
                Error = 0;
                convert(address + 1);
                writeInt(exeaddress, tempbyte);
                break;
            }
            case 12:{//deadlock
                while(true){;}
                break;
            }
            case 13:{//assignInteger[int value, intvar i]
                tempbyte = RAM[address + 1];
                convert(address + 2);
                writeInt(exeaddress, tempbyte);
                break;
            }
            case 14:{//transferInteger[intvar i1, intvar i2]
                convert(address + 1);
                writeInt(exeaddress, RAM[getIntAddr(exeaddress)]);
                break;
            }
        }
        // <editor-fold defaultstate="collapsed" desc="post loop process">
        address++;
        time2 = millis();
        loops++;
        if (loops < 0) {
            loops = 0;
        }// </editor-fold>
    }
}

void convert(int startAddress){
    byte charadd = 0;
    while(RAM[startAddress] != 6){
        tempString[charadd] = RAM[startAddress];
        charadd++;
        startAddress++;
    }
}

void writeInt(int exeStart, byte value){
    byte count = 0;
    char compare[15];
    while(true){
        if (RAM[exeStart] == 9) {
            exeStart++;
            while (count != 15) {
                compare[count] = RAM[exeStart];
                exeStart++;
                count++;
            }
            if(compare == tempString){
                RAM[exeStart + 2] = value;
                break;
            }else{
                exeStart += 3;
            }
            if(RAM[exeStart] == 8){
                Error = 1;
            }
        }
    }
}

int getIntAddr(int exeStart){
    byte count = 0;
    char compare[15];
    while(true){
        if (RAM[exeStart] == 9) {
            exeStart++;
            while (count != 15) {
                compare[count] = RAM[exeStart];
                exeStart++;
                count++;
            }
            if(compare == tempString){
                return RAM[exeStart + 2];
                break;
            }else{
                exeStart += 3;
            }
            if(RAM[exeStart] == 8){
                Error = 1;
            }
        }
    }
}

The method description is hard to explain, but the code is stored as raw bytes. I should have development software up soon... Hope this helps! If you ever want to use this for any projects, YOU MUST HAVE A BIOS.mk8 file on the root directory of the SD or the system will not work.

\$\endgroup\$
  • 1
    \$\begingroup\$ Lucky indeed, if he hasn't figured it out in the three years since he first asked \$\endgroup\$ – Scott Seidman Aug 30 '14 at 23:16
  • \$\begingroup\$ @ScottSeidman Yeah, good point. Also, the firmware is still in testing, and this version is missing key elements. \$\endgroup\$ – Jaca Aug 31 '14 at 4:30
1
\$\begingroup\$

With all due respect to David Brin (I happen to like his books a lot; I'm not qualified to judge how good he is as an astrophysicist), he's neither a programmer or an educator.

I was around and coding in the early days of PCs, and I wrote a fair amount of BASIC code. And I've been writing code professionally since then.

The reason we used BASIC back then was that your two options were to use BASIC or to write in assembly, and assembly was both harder to understand and much more cumbersome to use. So, BASIC.

In the 30+ years since then, there have been significant improvements in programming instruction. My wife teaches a beginning programming class that uses Alice (www.alice.org), and it's far better conceptually than the older approaches.

I think Brin's solution was pretty elegant. You could build something pretty simple on a Raspberry PI. On the arduino, I think it will be challenging to stuff everything you need into 2K of RAM; that has to hold whatever OS/Monitor you end up writing, a command interpretor, code to do the display, and storage for the basic program itself.

Not to mention the fact that you're going to have to do a whole lot of difficult and custom programming so that you can write code in a simple environment.

\$\endgroup\$
0
\$\begingroup\$

I don't get it. If you only want to have a means to program in Basic, run a basic interpreter on your PC. I don't understand how you expect the Arduino to help with this. The Arduino is a microcontroller with a lot of fancy software to hide the hardware details. Part of the cost of that is lower performance and more resource usage than the equivalent program running on the bare microcontroller directly. Now you want to write Arduino code to turn it back into a more general purpose computer, all so you can in turn run a Basic interpreter on that general purpose computer? This makes little sense.

Since your only goal is to be able to edit and execute Basic programs (run a Basic interpreter), start with a more general purpose computing platform in the first place, preferably even one that already has a Basic interpreter available. Your PC is exactly such a platform. If you want this to be external hardware, it sounds like a off the shelf single-board computer would meet your needs much better than a Arduino.

Added:

You now say you don't want to run on a PC and site this link about someone wanting command line Basic for his kid to learn from. Admittedly I didn't read the whole article (I don't like people answering with links. You should be able to state your point independently in a few sentences), but I don't see how a PC running a command line Basic interpreter doesn't address your problem. Why is the Basic interpreter not allowed to run on a PC but it's OK to run on a Arduino? Remember, you said up front that your only goal was to edit and run Basic programs. Nothing in that statement says what hardware it has to run on, and none of your subsequent explanation explains why a PC wouldn't do fine.

There are probably Basic interpreters that run on the command line. The old QBASIC might still work in some DOS compatibility mode. Even if not, since you're willing to dedicate hardware to this, how is running DOS and QBASIC on a PC not provide what you asked for?

\$\endgroup\$
  • \$\begingroup\$ My point was that I don't want to program on a PC. I want to program in a similar environment to, say for example, a Texas Instruments TI-84+. My reason for this? Check out the following link, "Why Johnny Can't Code" salon.com/technology/feature/2006/09/14/basic/index.html \$\endgroup\$ – Lincoln Bergeson Sep 21 '11 at 14:24
  • 3
    \$\begingroup\$ This is not really an answer. Yes, the idea of the OP may be a bit left of center, but where would we be if no one ever tried anything out of the ordinary, or to push the limits of what is already existing? Telling the OP that it's a silly idea is neither helpful nor constructive. The OP has decided that he'd like to do it, and is asking us for help with how to go about it. He's not asking if it's a good idea or not. Yes, it may well be a Bad Idea™, but the OP will learn a huge amount while finding that out, which itself can be more valuable than the end result. \$\endgroup\$ – Majenko Sep 21 '11 at 14:30
  • \$\begingroup\$ @Majenko: What I wrote is a reasonable answer to what the OP originally wrote. Remember, he said "My only goal for this computer is the ability to edit and execute BASIC programs". This doesn't say anything about it running on alternate hardware. Apparently he wants a simple command line Basic interpreter for teaching kids. How is running such a thing on a PC not a valid answer? Isn't a PC running QBASIC or something exactly what he's asking for? \$\endgroup\$ – Olin Lathrop Sep 21 '11 at 14:37
  • 1
    \$\begingroup\$ @Olin The OP agrees with me... I think you are interpreting the question wrong. \$\endgroup\$ – Majenko Sep 21 '11 at 15:01
  • 2
    \$\begingroup\$ @Olin - I can understand Butts. Remember home computers late 70s, early 80s? You added a memory mapped 74LS373 and you could control I/Os through poke statements. No virtual COM drivers to install, no USB to whatever bridges, no complex developer IDE to load. SBCs are comparable, but generally lack the keyboard/video interface (and cassette storage!) of the home computers. \$\endgroup\$ – stevenvh Sep 21 '11 at 15:22
0
\$\begingroup\$

I like the idea of running a common app, such as BASIC on an Arduino especially if you hand-built it yourself. I like the convenience of having a handy, battery-powered Arduino device running the app I wanted. If it were me I'd use maybe an Arduino MEGA so I'd have enough pins for the keypad and an SD shield for storage.

I'd choose a color graphics LCD or a TFT screen over VGA for simplicity in programming and connections, a way of keeping track of date and time (RTC), and what's an app without internet or networking (ethernet shield)? Extra I2C RAMs (24LC256) maybe? And a few I2C MCP223017 just in case I'd need a few extra ports. How about multiple Arduino's doing a parallel task? That would improve the performance I'm sure.

\$\endgroup\$
  • \$\begingroup\$ Links to datasheets are appreciated by the community. Also, please do not use too much capitals and make sure your answer is readable by adding white spaces. \$\endgroup\$ – user17592 Jan 9 '13 at 15:37
  • 2
    \$\begingroup\$ As is, this is a very poor quality answer. But there are some sentiments here which could be worthwhile if cleaned up and better presented. \$\endgroup\$ – Chris Stratton Jan 9 '13 at 16:00

Not the answer you're looking for? Browse other questions tagged or ask your own question.