Hacer una computadora funcional de un Arduino Uno

8

¿Algún entusiasta de Arduino?

Oye, he estado pensando en esto y cuanto más lo pienso, más creo que puedo hacer esto. Mi idea es básicamente esta: hacer una computadora funcional con un microcontrolador Arduino Uno.

Mi único objetivo para esta computadora es la capacidad de editar y ejecutar programas BASIC. Eso es todo. Solo lo quiero para la programación, ya que eso es lo único que me interesa en este momento :)

Entonces, tal como lo veo, necesitaré tres componentes principales de hardware:

  1. alguna forma de pantalla (pantalla VGA o algo así)
  2. alguna forma de registrar la entrada del teclado, y
  3. alguna forma de almacenar datos en la memoria externa.

¿Alguien sabe de alguna manera de hacer esto? Sé de maneras de mostrar en una pantalla, pero no conozco un buen componente de API / hardware para registrar la entrada del teclado o almacenar memoria externa.

Voy a necesitar mucha ayuda en esto. ¿Alguien puede ayudarme y ofrecer ideas y consejos y sugerencias útiles para un buen hardware / una buena biblioteca de código abierto, o dos, o tres, o diez?

Adicional:

Blog Creación de una computadora Arduino Uno para cualquier persona interesada.

Lincoln Bergeson
fuente
Esto suena como mi tipo de proyecto descabellado;) Espero con interés escuchar cómo lo llevas adelante. Espero que bloguees tu progreso.
Majenko
1
Solo quería señalar un proyecto similar que puede ser de interés. El chip Parallax Propeller ha experimentado un gran desarrollo en lo que respecta a BASIC. Hay al menos dos intérpretes diferentes disponibles. Además, tiene la capacidad de emitir directamente la señal a un televisor de un monitor.
AndrejaKo
1
Incluso hay una placa de demostración que tiene VGA, TV, teclado y mouse PS / 2, audio y algunos conectores más. Ahora sé que desea hacer esto con un Arduino, pero al menos podría usar los esquemas de la placa presentados allí para obtener algunos indicadores básicos sobre cómo generaron la señal, etc. (todo está en el software).
AndrejaKo
¡También +1 por querer hacer algo como esto! Recuerdo que en la escuela primaria cuando nos mudamos de la computadora Orao a las computadoras Pentium III, BASIC perdió todo su encanto.
AndrejaKo
1
Una alternativa al uso de una pantalla VGA es tomar una pantalla LCD y usarla para la pantalla. Puede que tenga que entrecerrar los ojos, ¡pero interactuar con él será MUCHO más fácil!
SingleNegationElimination

Respuestas:

11

El teclado se puede hacer simplemente usando un teclado PS / 2: es solo serie y hay muchos tutoriales disponibles para ello.

El almacenamiento de datos se puede hacer simplemente en una tarjeta SD: ya existe un escudo para hacerlo.

En cuanto al video, eso es considerablemente más difícil. Si desea que el Arduino genere una señal de video PAL, por ejemplo, entonces tiene su trabajo cortado para usted. Sí, es posible, y alguien ha creado un juego Arduino "pong", pero tiene gráficos muy gruesos y solo blanco y negro.

Para VGA, necesitará alguna forma de interfaz para hacer el trabajo por usted. Sparkfun solía vender la tarjeta de video Picaso que podría funcionar con el Arduino, pero desafortunadamente se ha descontinuado y aún no hay planes para un reemplazo.

TBH, su mejor opción sería usar algo como un terminal Wyse y comunicarse con el Arduino por completo usando el serial. Mucho más simple que jugar con señales de video y demás.

Majenko
fuente
3

Veo el punto de Olin aquí: si solo desea editar / ejecutar / aprender BASIC, simplemente use una PC.

Sin embargo, si el objetivo es el desafío de crear una computadora que pueda ejecutar BASIC y aprender sobre el hardware y la implementación de nivel inferior al mismo tiempo, entonces esto es un poco diferente. Estoy a favor de cosas como esta, es una excelente manera de mejorar el conocimiento y estoy seguro de que sacarás mucho provecho de ello. Como Steven menciona todas las capas confusas y (en su mayoría) irrelevantes que, por ejemplo, tiene Windows, se pueden eliminar, dejando los conceptos básicos (sin juego de palabras).

De todos modos, es posible que desee ver algo un poco más poderoso como el PIC32 para esto, ya que debería ser capaz de manejar toda la funcionalidad (por ejemplo, VGA básica) por sí mismo.
Aquí hay una placa compatible con Arduino, la UNO32
The Maximite es una computadora con un intérprete BASIC basado en un PIC32, es posible que desee ver el Diseño y la Construcción para algunas ideas.

Oli Glaser
fuente
Dadas las especificaciones de las PC que ejecutan Microsoft Basic bajo un Z80, no debería haber ningún problema real.
mckenzm
2

Estás de suerte, ¡porque estoy trabajando en una PC Arduino ahora mismo! Sin embargo, no es mucho, solo el primer modelo. El firmware también es muy simple y tiene un pequeño conjunto de API. Pero, la cosa funciona! No es lo suficientemente bueno para editar BASIC (o cualquier idioma excepto el propio), pero este es solo el primer modelo. La placa madre es bastante simple, y que utiliza este . Aquí está el firmware que utilicé:

        #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;
            }
        }
    }
}

La descripción del método es difícil de explicar, pero el código se almacena como bytes sin formato. Debería tener el software de desarrollo pronto ... Espero que esto ayude. Si alguna vez quiere usar esto para algún proyecto, DEBE TENER UN archivo BIOS.mk8 en el directorio raíz de la SD o el sistema no funcionará.

Jaca
fuente
1
Afortunadamente, si no lo ha descubierto en los tres años transcurridos desde la primera vez que preguntó
Scott Seidman el
@ScottSeidman Sí, buen punto. Además, el firmware todavía está en pruebas, y a esta versión le faltan elementos clave.
Jaca
1

Con el debido respeto a David Brin (me gustan mucho sus libros; no estoy calificado para juzgar lo bueno que es como astrofísico), no es ni programador ni educador.

Estuve alrededor y codificando en los primeros días de las PC, y escribí una buena cantidad de código BASIC. Y he estado escribiendo código profesionalmente desde entonces.

La razón por la que usamos BASIC en ese entonces era que sus dos opciones eran usar BASIC o escribir en ensamblaje, y el ensamblaje era más difícil de entender y mucho más engorroso de usar. Tan basico.

En los más de 30 años desde entonces, ha habido mejoras significativas en la instrucción de programación. Mi esposa enseña una clase de programación inicial que usa Alice (www.alice.org), y es mucho mejor conceptualmente que los enfoques más antiguos.

Creo que la solución de Brin fue bastante elegante. Podrías construir algo bastante simple en un Raspberry PI. En el arduino, creo que será un reto meter todo lo que necesitas en 2K de RAM; que tiene que contener cualquier OS / Monitor que termine escribiendo, un intérprete de comandos, código para hacer la visualización y almacenamiento para el programa básico en sí.

Sin mencionar el hecho de que tendrá que hacer una gran cantidad de programación difícil y personalizada para poder escribir código en un entorno simple.

Eric Gunnerson
fuente
0

No lo entiendo Si solo desea tener un medio para programar en Basic, ejecute un intérprete básico en su PC. No entiendo cómo esperas que el Arduino ayude con esto. El Arduino es un microcontrolador con mucho software sofisticado para ocultar los detalles del hardware. Parte del costo de esto es un menor rendimiento y más uso de recursos que el programa equivalente que se ejecuta directamente en el microcontrolador. ¿Ahora desea escribir el código Arduino para convertirlo nuevamente en una computadora de uso más general, todo para que a su vez pueda ejecutar un intérprete básico en esa computadora de uso general? Esto tiene poco sentido.

Dado que su único objetivo es poder editar y ejecutar programas básicos (ejecutar un intérprete básico), comience con una plataforma informática de propósito más general, preferiblemente incluso una que ya tenga un intérprete básico disponible. Su PC es exactamente una plataforma de este tipo. Si desea que este sea un hardware externo, parece que una computadora de placa única estándar satisfaría sus necesidades mucho mejor que un Arduino.

Adicional:

Ahora dice que no desea ejecutar en una PC y encuentra este enlace sobre alguien que quiere la línea de comando básica para que su hijo aprenda. Es cierto que no leí todo el artículo (no me gusta que la gente responda con enlaces. Debería poder expresar su punto de forma independiente en unas pocas oraciones), pero no veo cómo una PC con un intérprete básico de línea de comandos no aborda su problema ¿Por qué no se permite que el intérprete básico se ejecute en una PC pero se puede ejecutar en un Arduino? Recuerde, usted dijo de antemano que su único objetivo era editar y ejecutar programas básicos. Nada en esa declaración dice en qué hardware tiene que ejecutarse, y ninguna de sus explicaciones posteriores explica por qué una PC no funcionaría bien.

Probablemente hay intérpretes básicos que se ejecutan en la línea de comandos. El antiguo QBASIC aún podría funcionar en algún modo de compatibilidad con DOS. Incluso si no es así, dado que está dispuesto a dedicar hardware a esto, ¿cómo es que ejecutar DOS y QBASIC en una PC no proporciona lo que solicitó?

Olin Lathrop
fuente
Mi punto era que no quiero programar en una PC. Quiero programar en un entorno similar a, por ejemplo, un Texas Instruments TI-84 +. ¿Mi razón para esto? Consulte el siguiente enlace, "Por qué Johnny no puede codificar" salon.com/technology/feature/2006/09/14/basic/index.html
Lincoln Bergeson
3
Esto no es realmente una respuesta. Sí, la idea del OP puede estar un poco a la izquierda del centro, pero ¿dónde estaríamos si nadie intentara algo fuera de lo común, o para empujar los límites de lo que ya existe? Decirle al OP que es una idea tonta no es útil ni constructivo. El OP ha decidido que le gustaría hacerlo, y nos está pidiendo ayuda con cómo hacerlo. No pregunta si es una buena idea o no. Sí, bien puede ser una Bad Idea ™, pero el OP aprenderá mucho mientras lo descubre, lo que en sí mismo puede ser más valioso que el resultado final.
Majenko
@Majenko: Lo que escribí es una respuesta razonable a lo que escribió originalmente el OP. Recuerde, él dijo: " Mi único objetivo para esta computadora es la capacidad de editar y ejecutar programas BASIC ". Esto no dice nada acerca de que se ejecute en hardware alternativo. Aparentemente quiere un intérprete básico de línea de comando simple para enseñar a los niños. ¿Cómo ejecutar una cosa así en una PC no es una respuesta válida? ¿No es una PC con QBASIC o algo exactamente lo que está pidiendo?
Olin Lathrop
1
@Olin El OP está de acuerdo conmigo ... Creo que estás interpretando mal la pregunta.
Majenko
2
@Olin - Puedo entender a Butts. ¿Recuerdas las computadoras de casa de finales de los 70 y principios de los 80? Agregó una memoria asignada 74LS373 y pudo controlar las E / S a través de pokedeclaraciones. No se deben instalar controladores COM virtuales, no hay USB a ningún puente, no se debe cargar un IDE de desarrollador complejo. Los SBC son comparables, pero generalmente carecen de la interfaz de teclado / video (¡y almacenamiento de cassettes!) De las computadoras domésticas.
stevenvh
0

Me gusta la idea de ejecutar una aplicación común, como BASIC en un Arduino, especialmente si la construiste tú mismo. Me gusta la conveniencia de tener un práctico dispositivo Arduino alimentado por batería que ejecute la aplicación que quería. Si fuera yo, usaría quizás un Arduino MEGA para tener suficientes pines para el teclado y un escudo SD para el almacenamiento.

Elegiría una pantalla LCD de gráficos en color o una pantalla TFT en vez de VGA para simplificar la programación y las conexiones, una forma de hacer un seguimiento de la fecha y la hora (RTC), y ¿qué es una aplicación sin internet o red (escudo de ethernet)? ¿RAMs I2C adicionales (24LC256) quizás? Y algunos I2C MCP223017 en caso de que necesite algunos puertos adicionales. ¿Qué tal si varios Arduino hacen una tarea paralela? Eso mejoraría el rendimiento, estoy seguro.

Mark Navarro
fuente
Los enlaces a las hojas de datos son apreciados por la comunidad. Además, no use demasiadas mayúsculas y asegúrese de que su respuesta sea legible agregando espacios en blanco.
2
Como es, esta es una respuesta de muy baja calidad. Pero hay algunos sentimientos aquí que podrían valer la pena si se limpian y se presentan mejor.
Chris Stratton el