viernes, 6 de abril de 2018

Computadora de 4 Bits - Capítulo 5: Unidad Aritmética Lógica (ALU)


En este capítulo explico el funcionamiento de la ALU, es decir la unidad aritmética lógica, como su nombre lo indica es la parte del procesador que se encarga de hacer las operaciones aritméticas (suma, resta, multiplicación, división, etc) y lógicas (AND, OR, NOT, etc).


http://hyperphysics.phy-astr.gsu.edu/hbase/Electronic/nand.html
https://en.wikipedia.org/wiki/Adder_(electronics)

miércoles, 4 de abril de 2018

ESP32 desde Cero - Tutorial 1: Instalación para la IDE de Arduino en Windows


En este primer tutorial sobre ESP32 explico como instalar todo lo necesario para poder programar nuestros ESP32 usando la IDE de Arduino bajo Windows.



sábado, 24 de marzo de 2018

sábado, 17 de marzo de 2018

Computadora de 4 Bits - Capítulo 2: Descripción de la Arquitectura


En el segundo capítulo de describo la arquitectura de mi computadora de 4 bits, es decir el diseño conceptual, sus elementos constitutivos y las interconexiones.



sábado, 10 de marzo de 2018

Computadora de 4 Bits – Capítulo 1: Presentación


El proyecto proyecto consiste en el diseño completo de una computadora de 4 bits basándome en integrados sencillos (compuertas lógicas, contadores, flip-flops, decodificadores, etc). Abarcando por completo hasta el último detalle, desde el contador de programas, la unidad de control, la ALU, los registros, puertos de entrada y salida, el juego de instrucciones, el microcódigo, etc.


Características:

·         Arquitectura Harvard (memoria de programas y memoria de datos por separado)
·         Memoria de programas (32 programas de hasta 256 bytes)
·         16 instrucciones regulares de 8 bits (13 implementadas) (RISC) (1 ciclo de reloj por instrucción)
o   4 bits superiores para el código de operación
o   4 bits inferiores para el operando


·         No tiene RAM
·         2 puertos de salida (4 bits cada uno)
·         1 puerto de entrada (4 bits)
·         1 registro de dirección (4 bits)
·         1 registro de uso general (4 bits)
·         ALU de dos operaciones, una aritmética (SUMA) y una lógica (NAND)




domingo, 29 de octubre de 2017

Proyecto #4 ESP8266 – Vehículo Controlado Por WebSocket

En este proyecto vamos a ver cómo fabricar un vehículo con un protoboard, algunas piezas impresas, dos moto-reductores para Arduino y unas pocas piezas más. El vehículo está conectado a un NodeMCU mediante un driver L293D, el ESP8266 está funcionado en modo SoftAP y tiene alojado un webserver con websokets, lo que permite controlar el vehículo, sin latencia, desde una aplicación web basada en JavaScript.


Lista de Materiales:

1) NodeMCU (ESP8266)
1) L293D
1) Cargador USB portátil 5V 5600mah
1) Cable USB
2) Motor DC 3v A 6v caja reductora rueda goma para Arduino
2) Rodamientos 624zz
2) Tornilos de 5/32"W x 5/8 (ó M4x16)
2) Tuercas de 5/32"W (ó M4)
2) Arandelas grower de 5/32" 
1) Protoboard 830 puntos
1) Piezas impresas en 3D (https://www.thingiverse.com/thing:2614185)
5) Presintos de 3,6 x 200mm

vehiculo:

#include <ESP8266WiFi.h>
#include <WebSocketsServer.h>
#include <ESP8266WebServer.h>

#define PWM_IZQ     05 // D1
#define PWM_DER     04 // D2

#define IZQ_AVZ     14 // D5
#define IZQ_RET     12 // D6
#define DER_AVZ     13 // D7
#define DER_RET     02 // D4

const char* ssid = "Vehiculo";
const char* password = "asdfghjk";

String pagina ="<html>"
"<head>"
"<style type='text/css'>"
"* { margin: 0px; padding: 20px; }"
"#avz, #ret { width: 100%; height: 33%; }"
"#izq, #der { width:  49.7%; height: 33% }"
"input[type=range] { height: 26px; -webkit-appearance: none; margin: 10px 0; width: 120px; }"
"input[type=range]:focus { outline: none; }"
"input[type=range]::-webkit-slider-runnable-track { width: 100%; height: 50px; cursor: pointer; animate: 0.2s; box-shadow: 1px 1px 1px #50555C; "
"  background: #50555C; border-radius: 25px; border: 0px solid #000000; }"
"input[type=range]::-webkit-slider-thumb { box-shadow: 0px 0px 0px #000000; border: 0px solid #000000; height: 80px; width: 80px; border-radius: 25px;"
"      background: #007FFF; cursor: pointer; -webkit-appearance: none; margin-top: -15px; }"
"input[type=range]:focus::-webkit-slider-runnable-track { background: #50555C; }"
"input[type=range]:focus::-ms-fill-lower { background: #50555C; }"
"input[type=range]:focus::-ms-fill-upper { background: #50555C; }"
"</style>"
"<script>"
"var connection = new WebSocket('ws://'+location.hostname+':81/', ['arduino']);"
"connection.onopen = function ()       { connection.send('Connect ' + new Date()); };"
"connection.onerror = function (error) { console.log('WebSocket Error ', error);};"
"connection.onmessage = function (e)   { console.log('Server: ', e.data);};"
"function sendAvz() {"
"var avz = parseInt(document.getElementById('avz').value);"
"var dir = '#';"
"if(avz < 16) {  dir = dir + '+' + avz.toString(16) + '+f'; }"
"if(avz >= 16) { avz = 31 - avz; dir = dir + '+f+' + avz.toString(16); }"
"console.log(dir);"
"connection.send(dir);"
"}"
"function sendIzq() {"
"var izq = parseInt(document.getElementById('izq').value);"
"izq = 15 - izq;"
"var dir = '#';"
"dir = dir + '-' + izq.toString(16) + '+' + izq.toString(16);" 
"console.log(dir);"
"connection.send(dir);"
"}"
"function sendDer() {"
"var der = parseInt(document.getElementById('der').value);"
"var dir = '#';"
"dir = dir + '+' + der.toString(16) + '-' + der.toString(16);"
"console.log(dir);"
"connection.send(dir);"
"}"
"function sendRet() {"
"var ret = parseInt(document.getElementById('ret').value);"
"var dir = '#';"
"if(ret < 16) {  dir = dir + '-' + ret.toString(16) + '-f'; }"
"if(ret >= 16) { ret = 31 - ret; dir = dir + '-f-' + ret.toString(16); }"
"console.log(dir);"
"connection.send(dir);"
"}"
"function SendParar() { console.log('#+0+0'); connection.send('#+0+0'); }"
"</script>"
"</head>"
"<body>"
"<input id='avz' type='range' min='0' max='31' step='1' value='16' oninput='sendAvz();' onmouseup='SendParar();' ontouchend='SendParar();'/>"
"<input id='izq' type='range' min='0' max='15' step='1' value='16' oninput='sendIzq();' onmouseup='SendParar();' ontouchend='SendParar();'/>"
"<input id='der' type='range' min='0' max='15' step='1' value='0'  oninput='sendDer();' onmouseup='SendParar();' ontouchend='SendParar();'/>"
"<input id='ret' type='range' min='0' max='31' step='1' value='16' oninput='sendRet();' onmouseup='SendParar();' ontouchend='SendParar();'/>"
"</body>"
"</html>";

ESP8266WebServer server = ESP8266WebServer(80);
WebSocketsServer webSocket = WebSocketsServer(81);

void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) {

    switch(type) {
        case WStype_DISCONNECTED:
            Serial.printf("[%u] Disconnected!\n", num);
            analogWrite(PWM_IZQ, 0);
            analogWrite(PWM_DER, 0);
            break;
        case WStype_CONNECTED: {
            IPAddress ip = webSocket.remoteIP(num);
            Serial.printf("[%u] Connected from %d.%d.%d.%d url: %s\n", num, ip[0], ip[1], ip[2], ip[3], payload);

            // send message to client
            webSocket.sendTXT(num, "Connected");
        }
            break;
        case WStype_TEXT:
            Serial.printf("[%u] get Text: %s\n", num, payload);

            if(payload[0] == '#') {
                if(payload[1] == '+') {
                  digitalWrite(IZQ_AVZ,  0);
                  digitalWrite(IZQ_RET,  1);
                }
                if(payload[1] == '-') {
                  digitalWrite(IZQ_AVZ,  1);
                  digitalWrite(IZQ_RET,  0);
                }
                if(payload[3] == '+') {
                  digitalWrite(DER_AVZ,  0);
                  digitalWrite(DER_RET,  1);
                }
                if(payload[3] == '-') {
                  digitalWrite(DER_AVZ,  1);
                  digitalWrite(DER_RET,  0);
                }
                uint8_t izq = (uint8_t) strtol((const char *) &payload[2], NULL, 16);
                uint8_t der = (uint8_t) strtol((const char *) &payload[4], NULL, 16);

                analogWrite(PWM_IZQ, izq);
                analogWrite(PWM_DER, der);
            }
            break;
    }
}

void setup() {
  Serial.begin(115200);
  Serial.println();

  WiFi.softAP(ssid, password);
  IPAddress myIP = WiFi.softAPIP(); 
  Serial.print("IP del access point: ");
  Serial.println(myIP);
  Serial.println("WebServer iniciado...");

  pinMode(PWM_IZQ, OUTPUT);
  pinMode(PWM_DER, OUTPUT);
  pinMode(IZQ_AVZ, OUTPUT);
  pinMode(IZQ_RET, OUTPUT);
  pinMode(DER_AVZ, OUTPUT);
  pinMode(DER_RET, OUTPUT);

  // start webSocket server
  webSocket.begin();
  webSocket.onEvent(webSocketEvent);

  // handle index
  server.on("/", []() {
      server.send(200, "text/html", pagina);
  });

  server.begin();

  digitalWrite(PWM_IZQ, 0);
  digitalWrite(PWM_DER, 0);
  digitalWrite(IZQ_AVZ,  1);
  digitalWrite(IZQ_RET,  1);
  digitalWrite(DER_AVZ,  1);
  digitalWrite(DER_RET,  1);

  analogWriteRange(15);
}

void loop() {
    webSocket.loop();
    server.handleClient();
}