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.