SlideShare una empresa de Scribd logo
1 de 20
PROYECTO FINAL DE CONTROL DIGITAL “EQUILIBRADOR” POR SERGIO RICARDO
MURGUIA SANTANA
1.- Descripción del proyecto.
El proyecto consiste en equilibrar una varilla colocada en una base que se conecta a un
potenciómetro. El potenciómetro a su vez está colocado en un carro sobre un riel. El objetivo es
equilibrar verticalmente la varilla haciendo que el carro permanezca lo más cerca posible a un
punto en el riel. La posición del carro también se mide con un potenciómetro. En la siguiente figura
se muestra el diagrama.
Los potenciómetros se conectan al microcontrolador M68hc908jk3 (de ahora en adelante
llamado micro) a los pines pb0 y pb4 para realizar la conversión analógico-digital. Los datos de la
conversión se mandan a una computadora, esta los procesa y regresa el voltaje que debe
aplicarse al motor del carro. Entonces el micro manda esta información a un conversor digital-
analógico conectado al puerto d. La salida de este conversor se conecta al motor del carro. Este es
el diagrama a bloques del proyecto:
En las siguientes secciones se describe el funcionamiento de la comunicación entre la
computadora y el micro, el funcionamiento del programa del micro, el programa de la computadora,
el conversor digital-analógico y por último, el diagrama completo del proyecto. El programa para la
computadora fue hecho en C++ Builder de Borland y el del micro en el programador de P&E Micro.
2.- Comunicación entre la computadora y el micro.
La comunicación entre la computadora y el micro se realiza a través del puerto paralelo de
la computadora y 6 pines del puerto B del micro. La comunicación es bidireccional pero no al
mismo tiempo, es decir, mientras la computadora transmite el micro recibe y mientras el micro
transmite la computadora recibe pero no pueden transmitir y recibir al mismo tiempo, si esto se
intenta ambas partes quedan en un ciclo esperando a que la otra parte responda el pedido de
comunicación. El algoritmo de comunicación es igual en las dos partes (solo se cambian las
conexiones). En el micro se tienen que configurar lo pines pb1, pb2 y pb3 como entradas y los
pines pb5, pb6 y pb7 como salidas. Los pines pb0 y pb4 se configuran como entradas pues en
estos se conectan los potenciómetros. Los pines pb3 y pb7 funcionan como bits de estado de
recepción y transmisión respectivamente (BR y BT), los pines pb2 y pb1 funcionan como bits de
datos de recepción (DR1 y DR2) y los pines pb6 y pb4 como bits de datos de transmisión (DT1 y
DT2). En a computadora la configuración que se aplica al puerto paralelo es la que se muestra en
el siguiente diagrama:
El algoritmo para la transmisión de un byte es el siguiente:
1. Esperar a que empiece la transmisión (que se ponga 1 en BR)
2. Ya que hay un 1 en BR, se lee en DR1 y DR2 los dos bits menos significativos.
3. Poner un 1 en BT para indicar que se leyeron los primeros dos bits.
4. Esperar a que se ponga un 0 en BR.
5. Leer los siguientes dos bits de los pines D1 y D2.
6. Poner 0 en el BT para indicar que se recibió la información
7. Esperar a que se ponga un 1 en BR.
8. Leer los siguientes dos bits.
9. Poner 1 en el BT.
10. Esperar a que BR tenga un 0.
11. Leer los últimos dos bits.
12. Poner 0 en BT.
13. Fin de la recepción.
La contraparte de este algoritmo es la transmisión de un bit:
1. Esperar a que BR esté en 0.
2. Poner en BT un 1 y en los DT1 y DT2 los bits menos significativos.
3. Esperar a que BR esté en 1.
4. Poner en 0 en BT y en DT1 y DT2 los siguientes dos bits.
5. Esperar a que haya un 0 en BR
6. Poner un 1 en BT y los siguientes dos bits en DT1 y DT2
7. Esperar hasta que en BR haya un 1.
8. Poner los dos bits más significativos en DT y colocar un 0 en BT.
9. Esperar hasta que en BR sea puesto un 0.
10. Fin de la recepción.
El esperar a que se pongan unos o ceros en los bits de transmisión y recepción es lo que
provoca que, al querer transmitir o recibir las dos partes al mismo tiempo, se trabe la comunicación
cayendo en un ciclo. Aparte de las rutinas de transmisión y recepción es necesario tener una de
inicialización, esta rutina manda y recibe de manera progresiva los números del 0 al 7 por BT, DT1
y DT2 y los recibe por BR, DR1 y DR2. Al final se vuelva a mandar y esperar un cero. El código
para la comunicación en el micro es el siguiente:
;configuración inicial:
lda #$E0 ;poner el puerto b los 5 bits menos significativos como
sta ddrb ;entradas y los 3 mas como salidas
;iniciar la comunicación
iniciacom
lda #$00 ;cargar con 0 el acumulador
ini2 sta salida ;colocar el valor del acumulador a en el PTB
sta PTB
ini1 lda PTB ;leer el puerto B
and #$0E ;hacer una mascara para obtener BR, DR1 y DR2
lsla ;ajustar
lsla
lsla
lsla
cmpa salida ;comparar lo que se leyó con lo transmitido
bne ini1 ;ir a ini1 si no son iguales
add #$20 ;agregar uno a lo que se transmite
cmpa #$00 ;verificar si no se han mandado todos los números del 0 al 7
bne ini2 ;ir a ini2 si aún faltan números
sta PTB ;poner 0 en PTB
ini3 lda PTB ;esperar a que la computadora ponga 0 en el puerto
and #$0E
cmpa #$00
bne ini3
lda #$00
sta PTB ;Poner nuevamente 0 en PTB
rts ;Salir.
;Recepción:
lee brclr 3,PTB,lee ;Esperar a que haya un uno en BR
lda PTB
and #$06 ;leer los dos bits menos significativos
lsra
sta entrada
bset 7,PTB ;poner en uno a BT
buclee brset 3,PTB,buclee;esperar un cero en BR
lda PTB
and #$06 ;Obtener los siguientes dos bits
lsla
add entrada
sta entrada
bclr 7,PTB ;poner 0 en BT
buclee2 brclr 3,PTB,buclee2;Esperar un 1 en BR
lda PTB
and #$06 ;Obtener los siguientes dos bits
lsla
lsla
lsla
add entrada
sta entrada
bset 7,PTB ;Poner un uno en BT
buclee3 brset 3,PTB,buclee3;esperar un cero en BR
lda PTB
and #$06 ;Leer los dos bits menos significativos
lsla
lsla
lsla
lsla
lsla
add entrada
sta entrada
bclr 7,PTB ;poner 0 en BT
sallee rts ;Fin de la transmisión
;Transmisión
escribe brset 3,PTB,escribe;esperar a que haya un 0 en BR
lda salida
and #$03 ;poner uno en BT y los dos bits menos significativos en DT
lsla
lsla
lsla
lsla
lsla
add #$80
sta PTB
bucesc1 brclr 3,PTB,bucesc1;esperar un uno en BR
lda salida
and #$0C ;Poner 0 en BT y los siguientes dos bits en DT
lsla
lsla
lsla
sta PTB
bucesc2 brset 3,PTB,bucesc2;Esperar un cero en BR
lda salida
and #$30 ;Poner un uno en BT y los siguientes dos bits en DT
lsla
add #$80
sta PTB
bucesc3 brclr 3,PTB,bucesc3;Esperar un uno en BR
lda salida
and #$C0 ;Poner un cero en BT y los dos bits mas significativos en DT
lsra
and #$7f
sta PTB
bucesc4 brset 3,PTB,bucesc4;Esperar un cero en BR
salesc rts ;Fin de la recepción
El siguiente es el código de la computadora para las funciones descritas anteriormente.
//--Esta función pone un byte (valor) en el puerto (puerto)--------------------
void salidapuerto(short int puerto,unsigned char valor)
{
asm{ mov dx,puerto
mov al,valor
out dx,al
}
}
//--Esta función es el complemento de la anterior, lee un byte del puerto------
unsigned char entradapuerto(short int puerto)
{
unsigned char r;
asm{ mov dx,puerto
in al,dx
shr al,03
mov r,al
}
if (r<16) //inverter el pin negado
{
r+=16;
}
else
{
r-=16;
}
return r;
}
//--Esta función es la que lee un byte del micro ------------------------------
void leepuerto(short int puerto,unsigned char &entrada)
{
unsigned char a;
a=entradapuerto(puerto);
while ((a&0x04)==0)
a=entradapuerto(puerto); //esperar a que haya un uno en BR
a=a&(0x03); //Leer DT
entrada=a;
salidapuerto(puerto-1,0x08); //Poner 1 en BT
do
{
a=entradapuerto(puerto);
}while ((a&(0x04))!=0); //esperar un 0 en BR
a=a&(0x03); //leer DT
a=a*4;
entrada+=a;
salidapuerto(puerto-1,0x00); //Poner 0 en BT
do
{
a=entradapuerto(puerto);
}while ((a&(0x04))==0); //Esperar un 1 en BR
a=a&(0x03); //Leer DT
a=a*16;
entrada+=a;
salidapuerto(puerto-1,0x08); //Poner 1 en BT
do
{
a=entradapuerto(puerto);
}while ((a&(0x04))!=0); //Esperar 0 en BR
a=a&(0x03); //Leer DT
a=a*64;
entrada+=a;
salidapuerto(puerto-1,0x00); //Poner 0 en BT
} //Fin de Recepción
//--Esta función es la que transmite un byte al micro--------------------------
void escribepuerto(short int puerto,unsigned char salida)
{
unsigned char a;
a=entradapuerto(puerto+1);
while((a&0x04)!=0)
a=entradapuerto(puerto+1); //Esperar a que haya un 0 en BR
a=salida&(0x03); //Poner 1 en BT y los dos bits menos significativos en DT
a=a*2;
a=a+8;
salidapuerto(puerto,a);
do
{
a=entradapuerto(puerto+1);
}while ((a&(0x04))==0); //Esperar a que haya un uno en BR
salida=salida/4;
a=salida&(0x03); //Poner los siguientes dos bits en DT y un 0 en BT
a=a*2;
salidapuerto(puerto,a);
do
{
a=entradapuerto(puerto+1);
}while ((a&(0x04))!=0); //Esperar un cero en BR
salida=salida/4;
a=salida&(0x03); //Poner 1 en BT y los siguientes bits en DT
a=a*2;
a=a+8;
salidapuerto(puerto,a);
do
{
a=entradapuerto(puerto+1);
}while ((a&(0x04))==0); //Esperar un uno en BR
salida=salida/4;
a=salida&(0x03); //Poner 0 en BT y los dos bits más significativos en DT
a=a*2;
salidapuerto(puerto,a);
do
{
a=entradapuerto(puerto+1);
}while ((a&(0x04))!=0); //Esperar un 0 en BR
} //Fin de Transmisión
//--Esta función inicia la comunicación con el micro--------------------------
void iniciapuerto(short int puerto)
{
bool ya[8],todos=false;
int i;
unsigned char nuevo;
for (i=0;i<8;i++) //Limpiar las banderas
{
ya[i]=false;
}
do
{
nuevo=entradapuerto(puerto+1)&0x07;//Leer un número
ya[nuevo]=true; //Activar la bandera de ese número
salidapuerto(puerto,nuevo*2); //Regresar el número leido
todos=true;
for (i=0;i<8;i++)
todos=todos&&ya[i]; //Ver si hace falta algún número
}while (!todos); //Seguir leyendo si aún faltan números
if (nuevo!=0) //Si el último no fue cero, esperar a que se mande un cero
{
while (nuevo!=0)
{
nuevo=entradapuerto(puerto+1)&0x07;//Leer el número
salidapuerto(puerto,nuevo*2); //Regresar el número
}
}
}
La conexión entre los dos puertos se hace se hace al enchufar los pines de transmisión
con los de recepción, es decir, BT con BR, DR1 con DT1 y DR2 con DT2, la siguiente figura ilustra
la conexión:
3.- Microcontrolador.
El programa del microcontrolador inicia configurando los puertos y el prescalador para la
conversión analógico-digital. Básicamente el programa se divide en 2 partes, en la primera se
configuran los puertos y el prescalador y se inicia la comunicación; en la segunda parte el
programa ejecuta un ciclo en el que lee el valor de los potenciómetros, los manda a la
computadora y recibe y manda al conversor el voltaje que debe aplicar al motor del carro. Este es
el diagrama de flujo del programa del microcontrolador:
Las rutinas para la transmisión de la posición y el ángulo, y para la recepción del voltaje ya
se describieron en la sección anterior. El código siguiente es el que corresponde al diagrama
anterior.
inicio
lda #$01
sta config1 ;desactivar el watchdog
lda #$ff ;poner el puerto d como salidas
sta ddrd
lda #$E0 ;poner el puerto b los 5 bits menos sig como
sta ddrb ;entradas y los 3 mas como salidas
lda #$40 ;ajustar las propiedades del reloj
sta adclk ;del cad
mov #$7F,ptd ;detener el carro
jsr iniciacom ;iniciar la comunicación por el puerto b y el paralelo de la
;computadora
bucle lda #$00 ;puerto pb0 con conversión uno sola vez para convertir el
jsr cad ; valor del potenciómetro de la posición
lda pos
sta salida
bsr escribe ;transmitir la posición
lda #$04 ;puerto pb4 con conversión una sola vez para convertir el
jsr cad ; valor del potenciómetro del ángulo
lda pos
sta salida
bsr escribe ;transmitir el ángulo
lda #$00
bsr lee ;Recibir el voltaje
lda entrada
sta ptd ;Mandar el voltaje al conversor digital-analógico.
lda #$00
bsr pausa
bra bucle ;Repetir desde la conversión del potenciómetro de la posición
pausa deca
bne pausa
rts
;rutina para hacer una conversión analógico-digital
cad sta adscr ;poner el puerto que se pide
cad1 brclr 7,adscr,cad1;espera a que se termine la conversión
lda adr
sta pos ;guardar en pos el resultado de la conversióm
rts ;salir
4.- Computadora.
El programa de la computadora está hecho en C++ Builder 5 de Borland. Este programa
inicia la comunicación con el micro, después de iniciarla se queda en un ciclo en el que recibe la
posición del carro y el ángulo de la varilla, calcula el voltaje que se le debe aplicar al motor y se lo
manda al micro, por último, actualiza las gráficas. El siguiente diagrama de flujo ilustra el programa.
Este es el código del programa de la computadora, no se incluyen las funciones de
comunicación porque están el la sección 2. La iniciación de la comunicación se realiza en el
constructor de la forma de la aplicación. En el ciclo principal hay una parte en la que se mandan
datos a un algoritmo genético, esta parte se tiene que activar si se quiere entrenar para conseguir
los valores de las constantes k1, k2, k3 y k4.
//--Este es el ciclo principal del programa----------------------------------
void __fastcall TForm1::bucle(TObject *Sender, bool &Done)
{
unsigned char voltaje,ayuda,pos2;
double posl,posdes,velocidad,pendulo,velopen,uno,dos,tres;
int tiempo=tiempopasadosinlimpiar(); //leer el tiempo para calcular lasvelocidades
Tregreso r;
TColor cuno,cdos,ctres;
//lectura de datos y cálculo del voltaje
cont++;
//leer posicion
leepuerto(0x379,ayuda);
agregaapos(ayuda);
posl=promediopos();
posdes=double(TrackBar2->Position)/10.0;//convertir a cm
//calcular velocidad del carro
velocidad=promedioposvel(tiempo);
//leer pendulo
leepuerto(0x379,ayuda);
agregaapen(ayuda);
pendulo=promediopen();
//calcular velocidad del péndulo
velopen=promediopenvel(tiempo);
//mandar datos al ag (cuando se está entrenando)/*
enfitness=true;
CheckBoxmover->Checked=trabajando;
CheckBoxpendulo->Checked=enfitness;
if (enfitness&&trabajando)
{
TrackBar2->Position=400;
k1=poblacion[voy].k1;
k2=poblacion[voy].k2;
k3=poblacion[voy].k3;
k4=poblacion[voy].k4;
Editk1->Text=FloatToStr(k1);
Editk2->Text=FloatToStr(k2);
Editk3->Text=FloatToStr(k3);
Editk4->Text=FloatToStr(k4);
}
variable[0].valor=posl-posdes;
variable[1].valor=pendulo;
if (trabajando)
{
r=f.evalua();
}
else
{
r.valor=0;
}
if (trabajando)
{
ag(r.valor,tiempo);
Caption=IntToStr(generacion)+", "+IntToStr(voy)+", "+FloatToStr(double(tiempoind)/1000.0)+",
"+FloatToStr(poblacion[0].fitness)+", "+FloatToStr(poblacion[voy].fitness);
}*/
//calcular y enviar voltaje
if (CheckBoxpendulo->Checked)
{
voltaje=calculavoltajeconpendulo(posdes,posl,velocidad,pendulo,velopen);
}
else
{
voltaje=calculavoltajesinpendulo(posdes,posl,velocidad);
}
Sleep(5);
if (CheckBoxmover->Checked)
{
escribepuerto(0x378,voltaje);
}
else
{
escribepuerto(0x378,0x7f);
}
//actualizar informacion de graficas y etiquetas
Edit4->Text=FloatToStr(pendulo);
pos2=int(posl);
Edit3->Text=FloatToStr(posdes);
Edit1->Text=FloatToStr(posl);
Edit2->Text=Edit2->Text.IntToHex(voltaje,2);
TrackBar1->Position=voltaje;
TrackBar3->Position=posl*10;
posl=posl*2.5;
velocidad=velocidad*2.5+127;
pendulo=pendulo*15+127;
if (posl<pendulo)
{
if (posl<velocidad)
{
tres=posl;
ctres=clRed;
if (pendulo<velocidad)
{
dos=pendulo;
cdos=clGreen;
uno=velocidad;
cuno=clWhite;
}
else
{
dos=velocidad;
cdos=clWhite;
uno=pendulo;
cuno=clGreen;
}
}
else
{
tres=velocidad;
ctres=clWhite;
dos=posl;
cdos=clRed;
uno=pendulo;
cuno=clGreen;
}
}
else
{
if (posl<velocidad)
{
tres=pendulo;
ctres=clGreen;
dos=posl;
cdos=clRed;
uno=velocidad;
cuno=clWhite;
}
else
{
uno=posl;
cuno=clRed;
if (pendulo<velocidad)
{
tres=pendulo;
ctres=clGreen;
dos=velocidad;
cdos=clWhite;
}
else
{
tres=velocidad;
ctres=clWhite;
dos=pendulo;
cdos=clGreen;
}
}
}
Image1->Canvas->MoveTo(voygraf,0);
Image1->Canvas->Pen->Color=clBlack;
Image1->Canvas->LineTo(voygraf,255-uno);
Image1->Canvas->Pen->Color=cuno;
Image1->Canvas->LineTo(voygraf,255-dos);
Image1->Canvas->Pen->Color=cdos;
Image1->Canvas->LineTo(voygraf,255-tres);
Image1->Canvas->Pen->Color=ctres;
Image1->Canvas->LineTo(voygraf,255);
voygraf=(voygraf+1)%Image1->Width;
Image1->Canvas->MoveTo(voygraf,0);
Image1->Canvas->Pen->Color=clWhite;
Image1->Canvas->LineTo(voygraf,256);
if (pos2%2==0)
{
CheckBox16->Checked=false;
}
else
{
CheckBox16->Checked=true;
}
pos2=pos2/2;
if (pos2%2==0)
{
CheckBox15->Checked=false;
}
else
{
CheckBox15->Checked=true;
}
pos2=pos2/2;
if (pos2%2==0)
{
CheckBox14->Checked=false;
}
else
{
CheckBox14->Checked=true;
}
pos2=pos2/2;
if (pos2%2==0)
{
CheckBox13->Checked=false;
}
else
{
CheckBox13->Checked=true;
}
pos2=pos2/2;
if (pos2%2==0)
{
CheckBox12->Checked=false;
}
else
{
CheckBox12->Checked=true;
}
pos2=pos2/2;
if (pos2%2==0)
{
CheckBox11->Checked=false;
}
else
{
CheckBox11->Checked=true;
}
pos2=pos2/2;
if (pos2%2==0)
{
CheckBox10->Checked=false;
}
else
{
CheckBox10->Checked=true;
}
pos2=pos2/2;
if (pos2%2==0)
{
CheckBox9->Checked=false;
}
else
{
CheckBox9->Checked=true;
}
Done=false;
}
//--Agrega el valor de v en las posiciones-----------------------------------
void TForm1::agregaapos(unsigned char v)
{
voypos=(voypos+1)%5;
pos[voypos]=v;
}
//--Regresa el promedio de la posición (quitar un poco de ruido--------------
double TForm1::promediopos(void)
{
double suma=0;
int i;
for (i=0;i<5;i++)
{
suma=suma+equivalencias[pos[i]];
}
return suma=suma/50; //regresa en centimteros
}
//--Regresa el promedio de la velocidad del carro----------------------------
double TForm1::promedioposvel(double tiempo)
{
if (tiempo!=0)
{
tiempoi=tiempof;
velante=100*(equivalencias[pos[voypos]]-equivalencias[pos[(voypos+4)%5]])/tiempo;
return velante;//regresa centimetros/s
}
return velante;
}
//--Agrega un valor a los ángulos--------------------------------------------
void TForm1::agregaapen(unsigned char v)
{
voypen=(voypen+1)%5;
pen[voypen]=v;
}
//--Regresa el promedio del ángulo-------------------------------------------
double TForm1::promediopen(void)
{
double suma=0;
int i;
for (i=0;i<5;i++)
{
suma+=pen[i];
}
suma=(189.9-suma/5)*1.523076923;
return suma;//en grados
}
//--Regresa la velocidad del ángulo------------------------------------------
double TForm1::promediopenvel(double tiempo)
{
if (tiempo!=0)
{
tiempoi=tiempof;
velantepen=-1523.076923*(pen[voypen]-pen[(voypen+4)%5])/tiempo;
}
return velantepen;
}
//--Calcula el voltaje que debe mandarse al carro sin considerar el péndulo--
unsigned char TForm1::calculavoltajesinpendulo(double xd,double x,double vel)
{
unsigned char r;
double calc=kp*(xd-x)-kd*vel;
if (calc>0)
{
calc=min(calc,maxvol);
}
else
{
calc=max(-maxvol,calc);
}
calc=127+12.7*calc;
r=int(calc);
return r;
}
//--Calcula el votaje considerando el péndulo--------------------------------
unsigned char TForm1::calculavoltajeconpendulo(double xd,double x,double vel,double alfa,double
velalfa)
{
unsigned char r;
double calc=k1*(xd-x)-k3*vel-k2*alfa-k4*velalfa;
if (calc>0)
{
calc=min(calc,maxvol);
}
else
{
calc=max(-maxvol,calc);
}
calc=127+12.7*calc;
r=int(calc);
return r;
}
Algoritmo Genético
La manera de calcular el voltaje cuando se considera el péndulo es la siguiente fórmula:
  4321 )( kxkkxxkV d 
Donde x es la posición del carro en centímetros y alfa el ángulo de la varilla en grados. El
problema es encontrar los valores del vector K=(k1,k2,k3,k4) que hagan que funcione de manera
correcta el sistema. Para obtener estos valores utilice un algoritmo genético, en este, los individuos
son vectores de cuatro dimensiones que representan los valores que se le asignan a K; la manera
de evaluar cada individuo es dejar que trate de equilibrar la varilla minimizando la integral de
alguna función, la función utilizada fue:
     
2
, dxxxF
La primera generación se inicia con valores cercanos a los recomendados en un manual
(modificados con ruido uniforme). La cruza se hizo con dos padres, se daba un volado por cada
valor del vector, es decir se obtenía un número aleatorio entre 0 y 1, si este era mayor que 0.5 se
le asignaba el valor de un padre y en caso contrario el del otro padre. Para la mutación se aplicó
una pequeña perturbación a los valores del vector, esta se hizo con ruido uniforme. El siguiente es
el código del algoritmo genético:
//--Función para calcular un número con distribución uniforme en el intervalo [0,1]
double uniforme(void)
{
return double(random(123456))/123455.0;
}
//--Esta es la estructura que tiene cada individuo
struct Tindividuo
{
double k1,k2,k3,k4,fitness;
};
//--Este apuntador es el que guardara la población completa
Tindividuo *poblacion;
//Esta función realiza una mutación en un individuo.
void mutaindividuo(Tindividuo &ind)
{
if (uniforme()>=pm)
{
ind.k1=ind.k1+(uniforme()-0.5)/2;
}
if (uniforme()>=pm)
{
ind.k2=ind.k2+(uniforme()-0.5);
}
if (uniforme()>=pm)
{
ind.k3=ind.k3+(uniforme()-0.5)/2;
}
if (uniforme()>=pm)
{
ind.k4=ind.k4+(uniforme()-0.5)/2;
}
}
//--Esta función toma dos individuos p y m y genera uno nuevo a partir de estos
void cruzapareja(Tindividuo &p,Tindividuo &m,Tindividuo &h)
{
h=p;
if (uniforme()>=0.5)
{
h.k1=m.k1;
}
if (uniforme()>=0.5)
{
h.k2=m.k2;
}
if (uniforme()>=0.5)
{
h.k3=m.k3;
}
if (uniforme()>=0.5)
{
h.k4=m.k4;
}
}
//--Esta function es auxiliar, sirve como parámetro de la función qsort
int comparaindividuos(const void *ae, const void *be)
{
Tindividuo *a=(Tindividuo *)ae,
*b=(Tindividuo *)be;
if (a->fitness<b->fitness)return -1;
if (a->fitness==b->fitness)return 0;
return 1;
}
//--La selección solamente ordena los individuos por el fitness
void seleccion(void)
{
qsort(poblacion,mu+lambda,sizeof(Tindividuo),comparaindividuos);
}
//--Esta función genera lambda individuos nuevos mediante cruza y después los muta
void cruzaymuta(void)
{
for (int i=mu;i<mu+lambda;i++)
{
cruzapareja(poblacion[random(mu)],poblacion[random(mu)],poblacion[i]);
mutaindividuo(poblacion[i]);
poblacion[i].fitness=0;
}
}
//--Esta es la función principal del algoritmo genético, es una modificación pues esta
//--ontiene el fitness dentro de otra función (el ciclo principal del programa)
void ag(double aumento,int tiempo)
{
if (trabajando)
{
if (enfitness)
{
if (tiempo>(tiempodeprueba-tiempoind))
{
tiempo=(tiempodeprueba-tiempoind);
}
poblacion[voy].fitness+=aumento*double(tiempo)/1000.0;
tiempoind+=tiempo;
if (tiempoind>=tiempodeprueba)
{
voy++;
tiempoind=0;
enfitness=false;
}
if (voy==(mu+lambda))
{
seleccion();
cruzaymuta();
voy=mu;
if (generacion%generacionesentreguardadas==0)
{
guardageneracion();
}
generacion++;
}
}
}
}
//--Esta función genera la población inicial
void generapoblacioninicial(void)
{
poblacion=new Tindividuo[mu+lambda];
for (int i=0;i<mu+lambda;i++)
{
poblacion[i].k1=0.26+uniforme()/2;
poblacion[i].k2=1.85+uniforme();
poblacion[i].k3=0.29+uniforme()/2;
poblacion[i].k4=0.19+uniforme()/2;
poblacion[i].fitness=0;
}
}
Después de 50 generaciones y con una población de 20+10 y evaluar 10 segundos cada
caso, se obtuvo un individuo con un fitness de 25.05, este logra equilibrar la varilla colocando al
carro no muy lejos del punto en el que se quiere que permanezca. Manualmente se exploraron
algunos de los individuos de esta generación, el que mas me gusto fue este:
individuo 5:
k1=1.059460
k2=0.430551
k3=0.330167
k4=0.112087
fitness=28.277874
5.- Convertidor Digital-Analógico.
El convertidor digital-analógico está hecho con dos circuitos integrado: el DAC0800 y el .
Tiene una respuesta de -10 a +10 voltios. El diagrama del convertidor es el siguiente:
6.- Diagrama.
Este es el diagrama completo del proyecto:
PROYECTO FINAL DE CONTROL DIGITAL “EQUILIBRADOR” POR SERGIO RICARDO
MURGUIA SANTANA
Enviado por:
Ing.+Lic. Yunior Andrés Castillo S.
“NO A LA CULTURA DEL SECRETO, SI A LA LIBERTAD DE INFORMACION”®
www.monografias.com/usuario/perfiles/ing_lic_yunior_andra_s_castillo_s/monografias
Página Web: yuniorandrescastillo.galeon.com
Correo: yuniorcastillo@yahoo.com
yuniorandrescastillosilverio@facebook.com
Twitter: @yuniorcastillos
Instagran:yuniorandrescastillo
Celular: 1-829-725-8571
Santiago de los Caballeros,
República Dominicana,
2016.
“DIOS, JUAN PABLO DUARTE, JUAN BOSCH Y ANDRÉS CASTILLO DE LEÓN – POR
SIEMPRE”®

Más contenido relacionado

La actualidad más candente

Compare capture pwm mode 5
Compare capture pwm mode 5Compare capture pwm mode 5
Compare capture pwm mode 5
georgemanson69
 
Tutorial proton ide plus part 1
Tutorial proton ide plus part 1Tutorial proton ide plus part 1
Tutorial proton ide plus part 1
dar851112
 
Programación del microcontrolador
Programación del microcontroladorProgramación del microcontrolador
Programación del microcontrolador
Juan Gamboa P
 

La actualidad más candente (20)

Display de cristal líquido grágico GLCD
Display de cristal líquido grágico GLCDDisplay de cristal líquido grágico GLCD
Display de cristal líquido grágico GLCD
 
Conexión serial
Conexión serialConexión serial
Conexión serial
 
3.4 matriz de le ds
3.4 matriz de le ds3.4 matriz de le ds
3.4 matriz de le ds
 
Clase MSI
Clase MSIClase MSI
Clase MSI
 
Compare capture pwm mode 5
Compare capture pwm mode 5Compare capture pwm mode 5
Compare capture pwm mode 5
 
Ejercicios 06 subrutinas con LCD continuación
Ejercicios 06 subrutinas con LCD continuaciónEjercicios 06 subrutinas con LCD continuación
Ejercicios 06 subrutinas con LCD continuación
 
Ejercicio 03 Porticos
Ejercicio 03 PorticosEjercicio 03 Porticos
Ejercicio 03 Porticos
 
comunicacion serial pc-pc
comunicacion serial pc-pccomunicacion serial pc-pc
comunicacion serial pc-pc
 
Ejercicio 07 Timers
Ejercicio 07 TimersEjercicio 07 Timers
Ejercicio 07 Timers
 
Usart 3
Usart 3Usart 3
Usart 3
 
Tutorial proton ide plus part 1
Tutorial proton ide plus part 1Tutorial proton ide plus part 1
Tutorial proton ide plus part 1
 
Programa pic.asm
Programa pic.asmPrograma pic.asm
Programa pic.asm
 
Proyecto2
Proyecto2Proyecto2
Proyecto2
 
Curso de microcontroladores capitulo 02
Curso de microcontroladores capitulo 02Curso de microcontroladores capitulo 02
Curso de microcontroladores capitulo 02
 
Funcionamiento del CAD
Funcionamiento del CADFuncionamiento del CAD
Funcionamiento del CAD
 
Introduccion a la programacion en c 18
Introduccion a la programacion en c 18Introduccion a la programacion en c 18
Introduccion a la programacion en c 18
 
04.Entradas y salidas digitales
04.Entradas y salidas digitales04.Entradas y salidas digitales
04.Entradas y salidas digitales
 
Sniffer USB 2.0 (FULL SPEED)
Sniffer USB 2.0 (FULL SPEED)Sniffer USB 2.0 (FULL SPEED)
Sniffer USB 2.0 (FULL SPEED)
 
Programación del microcontrolador
Programación del microcontroladorProgramación del microcontrolador
Programación del microcontrolador
 
Tutorial ii proyectos en basic proton
Tutorial ii   proyectos en basic protonTutorial ii   proyectos en basic proton
Tutorial ii proyectos en basic proton
 

Similar a Control digital equilibrador

Similar a Control digital equilibrador (20)

Conectores
ConectoresConectores
Conectores
 
Puertos de entrada/salida
Puertos de entrada/salidaPuertos de entrada/salida
Puertos de entrada/salida
 
Puertos de entrada diapositivas
Puertos de entrada diapositivasPuertos de entrada diapositivas
Puertos de entrada diapositivas
 
Convertidor morontes trejo
Convertidor morontes trejoConvertidor morontes trejo
Convertidor morontes trejo
 
Micro2 tema 5
Micro2 tema 5Micro2 tema 5
Micro2 tema 5
 
Usart
UsartUsart
Usart
 
Trabajo n° 1 electronica digital ii
Trabajo n° 1 electronica digital iiTrabajo n° 1 electronica digital ii
Trabajo n° 1 electronica digital ii
 
El club de Programación de microcontroladores PIC
El club de Programación de microcontroladores PIC El club de Programación de microcontroladores PIC
El club de Programación de microcontroladores PIC
 
28683892 Practica1 1
28683892 Practica1 128683892 Practica1 1
28683892 Practica1 1
 
Puerto paralelo
Puerto paraleloPuerto paralelo
Puerto paralelo
 
Puerto paralelo
Puerto paraleloPuerto paralelo
Puerto paralelo
 
474472707-ADC-PIC-pptx porocesadores.pptx
474472707-ADC-PIC-pptx porocesadores.pptx474472707-ADC-PIC-pptx porocesadores.pptx
474472707-ADC-PIC-pptx porocesadores.pptx
 
Niple diapopsitiva
Niple   diapopsitivaNiple   diapopsitiva
Niple diapopsitiva
 
Niple diapopsitiva
Niple   diapopsitivaNiple   diapopsitiva
Niple diapopsitiva
 
Niple diapopsitiva
Niple   diapopsitivaNiple   diapopsitiva
Niple diapopsitiva
 
Txusart
TxusartTxusart
Txusart
 
Puerto Paralelo.ppt
Puerto Paralelo.pptPuerto Paralelo.ppt
Puerto Paralelo.ppt
 
28812521 Practica1 1
28812521 Practica1 128812521 Practica1 1
28812521 Practica1 1
 
Redes y Sistemas Distribuidos - Cuestiones de repaso y problemas
Redes y Sistemas Distribuidos - Cuestiones de repaso y problemasRedes y Sistemas Distribuidos - Cuestiones de repaso y problemas
Redes y Sistemas Distribuidos - Cuestiones de repaso y problemas
 
Comunicación RS-232
Comunicación RS-232Comunicación RS-232
Comunicación RS-232
 

Más de Castillo'S Legal Solutions

Más de Castillo'S Legal Solutions (20)

El Abogado del Estado y Fiscal ante el tribunal de tierras en Rep. Dominicana
El Abogado del Estado y Fiscal ante el tribunal de tierras en Rep. DominicanaEl Abogado del Estado y Fiscal ante el tribunal de tierras en Rep. Dominicana
El Abogado del Estado y Fiscal ante el tribunal de tierras en Rep. Dominicana
 
El abogado del estado ante la jurisdicción inmobiliaria en Rep. Dominicana
El abogado del estado ante la jurisdicción inmobiliaria en Rep. DominicanaEl abogado del estado ante la jurisdicción inmobiliaria en Rep. Dominicana
El abogado del estado ante la jurisdicción inmobiliaria en Rep. Dominicana
 
Análisis sobre las constituciones de Francia y dominicana
Análisis sobre las constituciones de Francia y dominicanaAnálisis sobre las constituciones de Francia y dominicana
Análisis sobre las constituciones de Francia y dominicana
 
Análisis constitucional tanto a la constitución de Francia y la constitución...
Análisis constitucional  tanto a la constitución de Francia y la constitución...Análisis constitucional  tanto a la constitución de Francia y la constitución...
Análisis constitucional tanto a la constitución de Francia y la constitución...
 
Análisis comparativo entre la constitución nicaragüense y la dominicana
Análisis comparativo entre la constitución nicaragüense y la dominicanaAnálisis comparativo entre la constitución nicaragüense y la dominicana
Análisis comparativo entre la constitución nicaragüense y la dominicana
 
Chicanas versus la Ética del Abogado
Chicanas versus la Ética del AbogadoChicanas versus la Ética del Abogado
Chicanas versus la Ética del Abogado
 
Implementación de estrategias innovadoras para el desarrollo de la motricidad...
Implementación de estrategias innovadoras para el desarrollo de la motricidad...Implementación de estrategias innovadoras para el desarrollo de la motricidad...
Implementación de estrategias innovadoras para el desarrollo de la motricidad...
 
Derechos de protección a la victima
Derechos de protección a la victimaDerechos de protección a la victima
Derechos de protección a la victima
 
Derechos humanos y los principios del código procesal penal
Derechos humanos y los principios del código procesal penalDerechos humanos y los principios del código procesal penal
Derechos humanos y los principios del código procesal penal
 
Como hacer un plan de negocio (cabañas turísticas placerex)
Como hacer un plan de negocio (cabañas turísticas placerex)Como hacer un plan de negocio (cabañas turísticas placerex)
Como hacer un plan de negocio (cabañas turísticas placerex)
 
Constitucionalizacion del proceso penal
Constitucionalizacion del proceso penalConstitucionalizacion del proceso penal
Constitucionalizacion del proceso penal
 
Como postular en la audiencia para conocer medida de coerción
Como postular en la audiencia para conocer medida de coerciónComo postular en la audiencia para conocer medida de coerción
Como postular en la audiencia para conocer medida de coerción
 
Código procesal penal
Código procesal penalCódigo procesal penal
Código procesal penal
 
Evaluacion de los aprendizajes en el nivel inicial
Evaluacion de los aprendizajes en el nivel inicialEvaluacion de los aprendizajes en el nivel inicial
Evaluacion de los aprendizajes en el nivel inicial
 
Adaptación de la estrategia a la situación
Adaptación de la estrategia a la situaciónAdaptación de la estrategia a la situación
Adaptación de la estrategia a la situación
 
Actualización curricular bases y diseño del nivel primario
Actualización curricular bases y diseño del nivel primarioActualización curricular bases y diseño del nivel primario
Actualización curricular bases y diseño del nivel primario
 
Actividades iniciales y diligencias preliminares
Actividades iniciales y diligencias preliminaresActividades iniciales y diligencias preliminares
Actividades iniciales y diligencias preliminares
 
Actividades iniciales y diligencias preliminares
Actividades iniciales y diligencias preliminaresActividades iniciales y diligencias preliminares
Actividades iniciales y diligencias preliminares
 
Actitudes y requisitos para el ejercicio de la abogacía
Actitudes y requisitos para el ejercicio de la abogacíaActitudes y requisitos para el ejercicio de la abogacía
Actitudes y requisitos para el ejercicio de la abogacía
 
Abusos sexuales infantiles
Abusos sexuales infantilesAbusos sexuales infantiles
Abusos sexuales infantiles
 

Último

La empresa sostenible: Principales Características, Barreras para su Avance y...
La empresa sostenible: Principales Características, Barreras para su Avance y...La empresa sostenible: Principales Características, Barreras para su Avance y...
La empresa sostenible: Principales Características, Barreras para su Avance y...
JonathanCovena1
 
FORTI-MAYO 2024.pdf.CIENCIA,EDUCACION,CULTURA
FORTI-MAYO 2024.pdf.CIENCIA,EDUCACION,CULTURAFORTI-MAYO 2024.pdf.CIENCIA,EDUCACION,CULTURA
FORTI-MAYO 2024.pdf.CIENCIA,EDUCACION,CULTURA
El Fortí
 
PLAN DE REFUERZO ESCOLAR primaria (1).docx
PLAN DE REFUERZO ESCOLAR primaria (1).docxPLAN DE REFUERZO ESCOLAR primaria (1).docx
PLAN DE REFUERZO ESCOLAR primaria (1).docx
lupitavic
 
6.-Como-Atraer-El-Amor-01-Lain-Garcia-Calvo.pdf
6.-Como-Atraer-El-Amor-01-Lain-Garcia-Calvo.pdf6.-Como-Atraer-El-Amor-01-Lain-Garcia-Calvo.pdf
6.-Como-Atraer-El-Amor-01-Lain-Garcia-Calvo.pdf
MiNeyi1
 
2 REGLAMENTO RM 0912-2024 DE MODALIDADES DE GRADUACIÓN_.pptx
2 REGLAMENTO RM 0912-2024 DE MODALIDADES DE GRADUACIÓN_.pptx2 REGLAMENTO RM 0912-2024 DE MODALIDADES DE GRADUACIÓN_.pptx
2 REGLAMENTO RM 0912-2024 DE MODALIDADES DE GRADUACIÓN_.pptx
RigoTito
 

Último (20)

Abril 2024 - Maestra Jardinera Ediba.pdf
Abril 2024 -  Maestra Jardinera Ediba.pdfAbril 2024 -  Maestra Jardinera Ediba.pdf
Abril 2024 - Maestra Jardinera Ediba.pdf
 
LABERINTOS DE DISCIPLINAS DEL PENTATLÓN OLÍMPICO MODERNO. Por JAVIER SOLIS NO...
LABERINTOS DE DISCIPLINAS DEL PENTATLÓN OLÍMPICO MODERNO. Por JAVIER SOLIS NO...LABERINTOS DE DISCIPLINAS DEL PENTATLÓN OLÍMPICO MODERNO. Por JAVIER SOLIS NO...
LABERINTOS DE DISCIPLINAS DEL PENTATLÓN OLÍMPICO MODERNO. Por JAVIER SOLIS NO...
 
Unidad 3 | Metodología de la Investigación
Unidad 3 | Metodología de la InvestigaciónUnidad 3 | Metodología de la Investigación
Unidad 3 | Metodología de la Investigación
 
Sesión de clase: Fe contra todo pronóstico
Sesión de clase: Fe contra todo pronósticoSesión de clase: Fe contra todo pronóstico
Sesión de clase: Fe contra todo pronóstico
 
Supuestos_prácticos_funciones.docx
Supuestos_prácticos_funciones.docxSupuestos_prácticos_funciones.docx
Supuestos_prácticos_funciones.docx
 
La empresa sostenible: Principales Características, Barreras para su Avance y...
La empresa sostenible: Principales Características, Barreras para su Avance y...La empresa sostenible: Principales Características, Barreras para su Avance y...
La empresa sostenible: Principales Características, Barreras para su Avance y...
 
BIOMETANO SÍ, PERO NO ASÍ. LA NUEVA BURBUJA ENERGÉTICA
BIOMETANO SÍ, PERO NO ASÍ. LA NUEVA BURBUJA ENERGÉTICABIOMETANO SÍ, PERO NO ASÍ. LA NUEVA BURBUJA ENERGÉTICA
BIOMETANO SÍ, PERO NO ASÍ. LA NUEVA BURBUJA ENERGÉTICA
 
FORTI-MAYO 2024.pdf.CIENCIA,EDUCACION,CULTURA
FORTI-MAYO 2024.pdf.CIENCIA,EDUCACION,CULTURAFORTI-MAYO 2024.pdf.CIENCIA,EDUCACION,CULTURA
FORTI-MAYO 2024.pdf.CIENCIA,EDUCACION,CULTURA
 
Estrategia de prompts, primeras ideas para su construcción
Estrategia de prompts, primeras ideas para su construcciónEstrategia de prompts, primeras ideas para su construcción
Estrategia de prompts, primeras ideas para su construcción
 
Lecciones 05 Esc. Sabática. Fe contra todo pronóstico.
Lecciones 05 Esc. Sabática. Fe contra todo pronóstico.Lecciones 05 Esc. Sabática. Fe contra todo pronóstico.
Lecciones 05 Esc. Sabática. Fe contra todo pronóstico.
 
CALENDARIZACION DE MAYO / RESPONSABILIDAD
CALENDARIZACION DE MAYO / RESPONSABILIDADCALENDARIZACION DE MAYO / RESPONSABILIDAD
CALENDARIZACION DE MAYO / RESPONSABILIDAD
 
GUIA DE CIRCUNFERENCIA Y ELIPSE UNDÉCIMO 2024.pdf
GUIA DE CIRCUNFERENCIA Y ELIPSE UNDÉCIMO 2024.pdfGUIA DE CIRCUNFERENCIA Y ELIPSE UNDÉCIMO 2024.pdf
GUIA DE CIRCUNFERENCIA Y ELIPSE UNDÉCIMO 2024.pdf
 
Qué es la Inteligencia artificial generativa
Qué es la Inteligencia artificial generativaQué es la Inteligencia artificial generativa
Qué es la Inteligencia artificial generativa
 
OCTAVO SEGUNDO PERIODO. EMPRENDIEMIENTO VS
OCTAVO SEGUNDO PERIODO. EMPRENDIEMIENTO VSOCTAVO SEGUNDO PERIODO. EMPRENDIEMIENTO VS
OCTAVO SEGUNDO PERIODO. EMPRENDIEMIENTO VS
 
Caja de herramientas de inteligencia artificial para la academia y la investi...
Caja de herramientas de inteligencia artificial para la academia y la investi...Caja de herramientas de inteligencia artificial para la academia y la investi...
Caja de herramientas de inteligencia artificial para la academia y la investi...
 
PLAN DE REFUERZO ESCOLAR primaria (1).docx
PLAN DE REFUERZO ESCOLAR primaria (1).docxPLAN DE REFUERZO ESCOLAR primaria (1).docx
PLAN DE REFUERZO ESCOLAR primaria (1).docx
 
6.-Como-Atraer-El-Amor-01-Lain-Garcia-Calvo.pdf
6.-Como-Atraer-El-Amor-01-Lain-Garcia-Calvo.pdf6.-Como-Atraer-El-Amor-01-Lain-Garcia-Calvo.pdf
6.-Como-Atraer-El-Amor-01-Lain-Garcia-Calvo.pdf
 
Programacion Anual Matemática5 MPG 2024 Ccesa007.pdf
Programacion Anual Matemática5    MPG 2024  Ccesa007.pdfProgramacion Anual Matemática5    MPG 2024  Ccesa007.pdf
Programacion Anual Matemática5 MPG 2024 Ccesa007.pdf
 
2 REGLAMENTO RM 0912-2024 DE MODALIDADES DE GRADUACIÓN_.pptx
2 REGLAMENTO RM 0912-2024 DE MODALIDADES DE GRADUACIÓN_.pptx2 REGLAMENTO RM 0912-2024 DE MODALIDADES DE GRADUACIÓN_.pptx
2 REGLAMENTO RM 0912-2024 DE MODALIDADES DE GRADUACIÓN_.pptx
 
SELECCIÓN DE LA MUESTRA Y MUESTREO EN INVESTIGACIÓN CUALITATIVA.pdf
SELECCIÓN DE LA MUESTRA Y MUESTREO EN INVESTIGACIÓN CUALITATIVA.pdfSELECCIÓN DE LA MUESTRA Y MUESTREO EN INVESTIGACIÓN CUALITATIVA.pdf
SELECCIÓN DE LA MUESTRA Y MUESTREO EN INVESTIGACIÓN CUALITATIVA.pdf
 

Control digital equilibrador

  • 1. PROYECTO FINAL DE CONTROL DIGITAL “EQUILIBRADOR” POR SERGIO RICARDO MURGUIA SANTANA 1.- Descripción del proyecto. El proyecto consiste en equilibrar una varilla colocada en una base que se conecta a un potenciómetro. El potenciómetro a su vez está colocado en un carro sobre un riel. El objetivo es equilibrar verticalmente la varilla haciendo que el carro permanezca lo más cerca posible a un punto en el riel. La posición del carro también se mide con un potenciómetro. En la siguiente figura se muestra el diagrama. Los potenciómetros se conectan al microcontrolador M68hc908jk3 (de ahora en adelante llamado micro) a los pines pb0 y pb4 para realizar la conversión analógico-digital. Los datos de la conversión se mandan a una computadora, esta los procesa y regresa el voltaje que debe aplicarse al motor del carro. Entonces el micro manda esta información a un conversor digital- analógico conectado al puerto d. La salida de este conversor se conecta al motor del carro. Este es el diagrama a bloques del proyecto: En las siguientes secciones se describe el funcionamiento de la comunicación entre la computadora y el micro, el funcionamiento del programa del micro, el programa de la computadora,
  • 2. el conversor digital-analógico y por último, el diagrama completo del proyecto. El programa para la computadora fue hecho en C++ Builder de Borland y el del micro en el programador de P&E Micro. 2.- Comunicación entre la computadora y el micro. La comunicación entre la computadora y el micro se realiza a través del puerto paralelo de la computadora y 6 pines del puerto B del micro. La comunicación es bidireccional pero no al mismo tiempo, es decir, mientras la computadora transmite el micro recibe y mientras el micro transmite la computadora recibe pero no pueden transmitir y recibir al mismo tiempo, si esto se intenta ambas partes quedan en un ciclo esperando a que la otra parte responda el pedido de comunicación. El algoritmo de comunicación es igual en las dos partes (solo se cambian las conexiones). En el micro se tienen que configurar lo pines pb1, pb2 y pb3 como entradas y los pines pb5, pb6 y pb7 como salidas. Los pines pb0 y pb4 se configuran como entradas pues en estos se conectan los potenciómetros. Los pines pb3 y pb7 funcionan como bits de estado de recepción y transmisión respectivamente (BR y BT), los pines pb2 y pb1 funcionan como bits de datos de recepción (DR1 y DR2) y los pines pb6 y pb4 como bits de datos de transmisión (DT1 y DT2). En a computadora la configuración que se aplica al puerto paralelo es la que se muestra en el siguiente diagrama: El algoritmo para la transmisión de un byte es el siguiente: 1. Esperar a que empiece la transmisión (que se ponga 1 en BR) 2. Ya que hay un 1 en BR, se lee en DR1 y DR2 los dos bits menos significativos. 3. Poner un 1 en BT para indicar que se leyeron los primeros dos bits. 4. Esperar a que se ponga un 0 en BR. 5. Leer los siguientes dos bits de los pines D1 y D2. 6. Poner 0 en el BT para indicar que se recibió la información 7. Esperar a que se ponga un 1 en BR.
  • 3. 8. Leer los siguientes dos bits. 9. Poner 1 en el BT. 10. Esperar a que BR tenga un 0. 11. Leer los últimos dos bits. 12. Poner 0 en BT. 13. Fin de la recepción. La contraparte de este algoritmo es la transmisión de un bit: 1. Esperar a que BR esté en 0. 2. Poner en BT un 1 y en los DT1 y DT2 los bits menos significativos. 3. Esperar a que BR esté en 1. 4. Poner en 0 en BT y en DT1 y DT2 los siguientes dos bits. 5. Esperar a que haya un 0 en BR 6. Poner un 1 en BT y los siguientes dos bits en DT1 y DT2 7. Esperar hasta que en BR haya un 1. 8. Poner los dos bits más significativos en DT y colocar un 0 en BT. 9. Esperar hasta que en BR sea puesto un 0. 10. Fin de la recepción. El esperar a que se pongan unos o ceros en los bits de transmisión y recepción es lo que provoca que, al querer transmitir o recibir las dos partes al mismo tiempo, se trabe la comunicación cayendo en un ciclo. Aparte de las rutinas de transmisión y recepción es necesario tener una de inicialización, esta rutina manda y recibe de manera progresiva los números del 0 al 7 por BT, DT1 y DT2 y los recibe por BR, DR1 y DR2. Al final se vuelva a mandar y esperar un cero. El código para la comunicación en el micro es el siguiente: ;configuración inicial: lda #$E0 ;poner el puerto b los 5 bits menos significativos como sta ddrb ;entradas y los 3 mas como salidas ;iniciar la comunicación iniciacom lda #$00 ;cargar con 0 el acumulador ini2 sta salida ;colocar el valor del acumulador a en el PTB sta PTB ini1 lda PTB ;leer el puerto B and #$0E ;hacer una mascara para obtener BR, DR1 y DR2 lsla ;ajustar lsla lsla
  • 4. lsla cmpa salida ;comparar lo que se leyó con lo transmitido bne ini1 ;ir a ini1 si no son iguales add #$20 ;agregar uno a lo que se transmite cmpa #$00 ;verificar si no se han mandado todos los números del 0 al 7 bne ini2 ;ir a ini2 si aún faltan números sta PTB ;poner 0 en PTB ini3 lda PTB ;esperar a que la computadora ponga 0 en el puerto and #$0E cmpa #$00 bne ini3 lda #$00 sta PTB ;Poner nuevamente 0 en PTB rts ;Salir. ;Recepción: lee brclr 3,PTB,lee ;Esperar a que haya un uno en BR lda PTB and #$06 ;leer los dos bits menos significativos lsra sta entrada bset 7,PTB ;poner en uno a BT buclee brset 3,PTB,buclee;esperar un cero en BR lda PTB and #$06 ;Obtener los siguientes dos bits lsla add entrada sta entrada bclr 7,PTB ;poner 0 en BT buclee2 brclr 3,PTB,buclee2;Esperar un 1 en BR lda PTB and #$06 ;Obtener los siguientes dos bits lsla lsla lsla add entrada sta entrada bset 7,PTB ;Poner un uno en BT buclee3 brset 3,PTB,buclee3;esperar un cero en BR lda PTB and #$06 ;Leer los dos bits menos significativos lsla lsla lsla lsla lsla add entrada sta entrada bclr 7,PTB ;poner 0 en BT sallee rts ;Fin de la transmisión ;Transmisión escribe brset 3,PTB,escribe;esperar a que haya un 0 en BR lda salida and #$03 ;poner uno en BT y los dos bits menos significativos en DT lsla
  • 5. lsla lsla lsla lsla add #$80 sta PTB bucesc1 brclr 3,PTB,bucesc1;esperar un uno en BR lda salida and #$0C ;Poner 0 en BT y los siguientes dos bits en DT lsla lsla lsla sta PTB bucesc2 brset 3,PTB,bucesc2;Esperar un cero en BR lda salida and #$30 ;Poner un uno en BT y los siguientes dos bits en DT lsla add #$80 sta PTB bucesc3 brclr 3,PTB,bucesc3;Esperar un uno en BR lda salida and #$C0 ;Poner un cero en BT y los dos bits mas significativos en DT lsra and #$7f sta PTB bucesc4 brset 3,PTB,bucesc4;Esperar un cero en BR salesc rts ;Fin de la recepción El siguiente es el código de la computadora para las funciones descritas anteriormente. //--Esta función pone un byte (valor) en el puerto (puerto)-------------------- void salidapuerto(short int puerto,unsigned char valor) { asm{ mov dx,puerto mov al,valor out dx,al } } //--Esta función es el complemento de la anterior, lee un byte del puerto------ unsigned char entradapuerto(short int puerto) { unsigned char r; asm{ mov dx,puerto in al,dx shr al,03 mov r,al } if (r<16) //inverter el pin negado { r+=16; } else { r-=16; }
  • 6. return r; } //--Esta función es la que lee un byte del micro ------------------------------ void leepuerto(short int puerto,unsigned char &entrada) { unsigned char a; a=entradapuerto(puerto); while ((a&0x04)==0) a=entradapuerto(puerto); //esperar a que haya un uno en BR a=a&(0x03); //Leer DT entrada=a; salidapuerto(puerto-1,0x08); //Poner 1 en BT do { a=entradapuerto(puerto); }while ((a&(0x04))!=0); //esperar un 0 en BR a=a&(0x03); //leer DT a=a*4; entrada+=a; salidapuerto(puerto-1,0x00); //Poner 0 en BT do { a=entradapuerto(puerto); }while ((a&(0x04))==0); //Esperar un 1 en BR a=a&(0x03); //Leer DT a=a*16; entrada+=a; salidapuerto(puerto-1,0x08); //Poner 1 en BT do { a=entradapuerto(puerto); }while ((a&(0x04))!=0); //Esperar 0 en BR a=a&(0x03); //Leer DT a=a*64; entrada+=a; salidapuerto(puerto-1,0x00); //Poner 0 en BT } //Fin de Recepción //--Esta función es la que transmite un byte al micro-------------------------- void escribepuerto(short int puerto,unsigned char salida) { unsigned char a; a=entradapuerto(puerto+1); while((a&0x04)!=0) a=entradapuerto(puerto+1); //Esperar a que haya un 0 en BR a=salida&(0x03); //Poner 1 en BT y los dos bits menos significativos en DT a=a*2; a=a+8; salidapuerto(puerto,a); do { a=entradapuerto(puerto+1); }while ((a&(0x04))==0); //Esperar a que haya un uno en BR salida=salida/4; a=salida&(0x03); //Poner los siguientes dos bits en DT y un 0 en BT a=a*2; salidapuerto(puerto,a);
  • 7. do { a=entradapuerto(puerto+1); }while ((a&(0x04))!=0); //Esperar un cero en BR salida=salida/4; a=salida&(0x03); //Poner 1 en BT y los siguientes bits en DT a=a*2; a=a+8; salidapuerto(puerto,a); do { a=entradapuerto(puerto+1); }while ((a&(0x04))==0); //Esperar un uno en BR salida=salida/4; a=salida&(0x03); //Poner 0 en BT y los dos bits más significativos en DT a=a*2; salidapuerto(puerto,a); do { a=entradapuerto(puerto+1); }while ((a&(0x04))!=0); //Esperar un 0 en BR } //Fin de Transmisión //--Esta función inicia la comunicación con el micro-------------------------- void iniciapuerto(short int puerto) { bool ya[8],todos=false; int i; unsigned char nuevo; for (i=0;i<8;i++) //Limpiar las banderas { ya[i]=false; } do { nuevo=entradapuerto(puerto+1)&0x07;//Leer un número ya[nuevo]=true; //Activar la bandera de ese número salidapuerto(puerto,nuevo*2); //Regresar el número leido todos=true; for (i=0;i<8;i++) todos=todos&&ya[i]; //Ver si hace falta algún número }while (!todos); //Seguir leyendo si aún faltan números if (nuevo!=0) //Si el último no fue cero, esperar a que se mande un cero { while (nuevo!=0) { nuevo=entradapuerto(puerto+1)&0x07;//Leer el número salidapuerto(puerto,nuevo*2); //Regresar el número } } } La conexión entre los dos puertos se hace se hace al enchufar los pines de transmisión con los de recepción, es decir, BT con BR, DR1 con DT1 y DR2 con DT2, la siguiente figura ilustra la conexión:
  • 8. 3.- Microcontrolador. El programa del microcontrolador inicia configurando los puertos y el prescalador para la conversión analógico-digital. Básicamente el programa se divide en 2 partes, en la primera se configuran los puertos y el prescalador y se inicia la comunicación; en la segunda parte el programa ejecuta un ciclo en el que lee el valor de los potenciómetros, los manda a la computadora y recibe y manda al conversor el voltaje que debe aplicar al motor del carro. Este es el diagrama de flujo del programa del microcontrolador: Las rutinas para la transmisión de la posición y el ángulo, y para la recepción del voltaje ya se describieron en la sección anterior. El código siguiente es el que corresponde al diagrama anterior. inicio lda #$01 sta config1 ;desactivar el watchdog lda #$ff ;poner el puerto d como salidas sta ddrd
  • 9. lda #$E0 ;poner el puerto b los 5 bits menos sig como sta ddrb ;entradas y los 3 mas como salidas lda #$40 ;ajustar las propiedades del reloj sta adclk ;del cad mov #$7F,ptd ;detener el carro jsr iniciacom ;iniciar la comunicación por el puerto b y el paralelo de la ;computadora bucle lda #$00 ;puerto pb0 con conversión uno sola vez para convertir el jsr cad ; valor del potenciómetro de la posición lda pos sta salida bsr escribe ;transmitir la posición lda #$04 ;puerto pb4 con conversión una sola vez para convertir el jsr cad ; valor del potenciómetro del ángulo lda pos sta salida bsr escribe ;transmitir el ángulo lda #$00 bsr lee ;Recibir el voltaje lda entrada sta ptd ;Mandar el voltaje al conversor digital-analógico. lda #$00 bsr pausa bra bucle ;Repetir desde la conversión del potenciómetro de la posición pausa deca bne pausa rts ;rutina para hacer una conversión analógico-digital cad sta adscr ;poner el puerto que se pide cad1 brclr 7,adscr,cad1;espera a que se termine la conversión lda adr sta pos ;guardar en pos el resultado de la conversióm rts ;salir 4.- Computadora. El programa de la computadora está hecho en C++ Builder 5 de Borland. Este programa inicia la comunicación con el micro, después de iniciarla se queda en un ciclo en el que recibe la posición del carro y el ángulo de la varilla, calcula el voltaje que se le debe aplicar al motor y se lo manda al micro, por último, actualiza las gráficas. El siguiente diagrama de flujo ilustra el programa.
  • 10. Este es el código del programa de la computadora, no se incluyen las funciones de comunicación porque están el la sección 2. La iniciación de la comunicación se realiza en el constructor de la forma de la aplicación. En el ciclo principal hay una parte en la que se mandan datos a un algoritmo genético, esta parte se tiene que activar si se quiere entrenar para conseguir los valores de las constantes k1, k2, k3 y k4. //--Este es el ciclo principal del programa---------------------------------- void __fastcall TForm1::bucle(TObject *Sender, bool &Done) { unsigned char voltaje,ayuda,pos2; double posl,posdes,velocidad,pendulo,velopen,uno,dos,tres; int tiempo=tiempopasadosinlimpiar(); //leer el tiempo para calcular lasvelocidades Tregreso r; TColor cuno,cdos,ctres; //lectura de datos y cálculo del voltaje cont++; //leer posicion leepuerto(0x379,ayuda); agregaapos(ayuda); posl=promediopos(); posdes=double(TrackBar2->Position)/10.0;//convertir a cm //calcular velocidad del carro velocidad=promedioposvel(tiempo); //leer pendulo leepuerto(0x379,ayuda); agregaapen(ayuda); pendulo=promediopen(); //calcular velocidad del péndulo velopen=promediopenvel(tiempo); //mandar datos al ag (cuando se está entrenando)/* enfitness=true; CheckBoxmover->Checked=trabajando; CheckBoxpendulo->Checked=enfitness; if (enfitness&&trabajando)
  • 11. { TrackBar2->Position=400; k1=poblacion[voy].k1; k2=poblacion[voy].k2; k3=poblacion[voy].k3; k4=poblacion[voy].k4; Editk1->Text=FloatToStr(k1); Editk2->Text=FloatToStr(k2); Editk3->Text=FloatToStr(k3); Editk4->Text=FloatToStr(k4); } variable[0].valor=posl-posdes; variable[1].valor=pendulo; if (trabajando) { r=f.evalua(); } else { r.valor=0; } if (trabajando) { ag(r.valor,tiempo); Caption=IntToStr(generacion)+", "+IntToStr(voy)+", "+FloatToStr(double(tiempoind)/1000.0)+", "+FloatToStr(poblacion[0].fitness)+", "+FloatToStr(poblacion[voy].fitness); }*/ //calcular y enviar voltaje if (CheckBoxpendulo->Checked) { voltaje=calculavoltajeconpendulo(posdes,posl,velocidad,pendulo,velopen); } else { voltaje=calculavoltajesinpendulo(posdes,posl,velocidad); } Sleep(5); if (CheckBoxmover->Checked) { escribepuerto(0x378,voltaje); } else { escribepuerto(0x378,0x7f); } //actualizar informacion de graficas y etiquetas Edit4->Text=FloatToStr(pendulo); pos2=int(posl); Edit3->Text=FloatToStr(posdes); Edit1->Text=FloatToStr(posl); Edit2->Text=Edit2->Text.IntToHex(voltaje,2); TrackBar1->Position=voltaje; TrackBar3->Position=posl*10; posl=posl*2.5; velocidad=velocidad*2.5+127; pendulo=pendulo*15+127;
  • 12. if (posl<pendulo) { if (posl<velocidad) { tres=posl; ctres=clRed; if (pendulo<velocidad) { dos=pendulo; cdos=clGreen; uno=velocidad; cuno=clWhite; } else { dos=velocidad; cdos=clWhite; uno=pendulo; cuno=clGreen; } } else { tres=velocidad; ctres=clWhite; dos=posl; cdos=clRed; uno=pendulo; cuno=clGreen; } } else { if (posl<velocidad) { tres=pendulo; ctres=clGreen; dos=posl; cdos=clRed; uno=velocidad; cuno=clWhite; } else { uno=posl; cuno=clRed; if (pendulo<velocidad) { tres=pendulo; ctres=clGreen; dos=velocidad; cdos=clWhite; } else { tres=velocidad;
  • 13. ctres=clWhite; dos=pendulo; cdos=clGreen; } } } Image1->Canvas->MoveTo(voygraf,0); Image1->Canvas->Pen->Color=clBlack; Image1->Canvas->LineTo(voygraf,255-uno); Image1->Canvas->Pen->Color=cuno; Image1->Canvas->LineTo(voygraf,255-dos); Image1->Canvas->Pen->Color=cdos; Image1->Canvas->LineTo(voygraf,255-tres); Image1->Canvas->Pen->Color=ctres; Image1->Canvas->LineTo(voygraf,255); voygraf=(voygraf+1)%Image1->Width; Image1->Canvas->MoveTo(voygraf,0); Image1->Canvas->Pen->Color=clWhite; Image1->Canvas->LineTo(voygraf,256); if (pos2%2==0) { CheckBox16->Checked=false; } else { CheckBox16->Checked=true; } pos2=pos2/2; if (pos2%2==0) { CheckBox15->Checked=false; } else { CheckBox15->Checked=true; } pos2=pos2/2; if (pos2%2==0) { CheckBox14->Checked=false; } else { CheckBox14->Checked=true; } pos2=pos2/2; if (pos2%2==0) { CheckBox13->Checked=false; } else { CheckBox13->Checked=true; } pos2=pos2/2; if (pos2%2==0)
  • 14. { CheckBox12->Checked=false; } else { CheckBox12->Checked=true; } pos2=pos2/2; if (pos2%2==0) { CheckBox11->Checked=false; } else { CheckBox11->Checked=true; } pos2=pos2/2; if (pos2%2==0) { CheckBox10->Checked=false; } else { CheckBox10->Checked=true; } pos2=pos2/2; if (pos2%2==0) { CheckBox9->Checked=false; } else { CheckBox9->Checked=true; } Done=false; } //--Agrega el valor de v en las posiciones----------------------------------- void TForm1::agregaapos(unsigned char v) { voypos=(voypos+1)%5; pos[voypos]=v; } //--Regresa el promedio de la posición (quitar un poco de ruido-------------- double TForm1::promediopos(void) { double suma=0; int i; for (i=0;i<5;i++) { suma=suma+equivalencias[pos[i]]; } return suma=suma/50; //regresa en centimteros } //--Regresa el promedio de la velocidad del carro---------------------------- double TForm1::promedioposvel(double tiempo) {
  • 15. if (tiempo!=0) { tiempoi=tiempof; velante=100*(equivalencias[pos[voypos]]-equivalencias[pos[(voypos+4)%5]])/tiempo; return velante;//regresa centimetros/s } return velante; } //--Agrega un valor a los ángulos-------------------------------------------- void TForm1::agregaapen(unsigned char v) { voypen=(voypen+1)%5; pen[voypen]=v; } //--Regresa el promedio del ángulo------------------------------------------- double TForm1::promediopen(void) { double suma=0; int i; for (i=0;i<5;i++) { suma+=pen[i]; } suma=(189.9-suma/5)*1.523076923; return suma;//en grados } //--Regresa la velocidad del ángulo------------------------------------------ double TForm1::promediopenvel(double tiempo) { if (tiempo!=0) { tiempoi=tiempof; velantepen=-1523.076923*(pen[voypen]-pen[(voypen+4)%5])/tiempo; } return velantepen; } //--Calcula el voltaje que debe mandarse al carro sin considerar el péndulo-- unsigned char TForm1::calculavoltajesinpendulo(double xd,double x,double vel) { unsigned char r; double calc=kp*(xd-x)-kd*vel; if (calc>0) { calc=min(calc,maxvol); } else { calc=max(-maxvol,calc); } calc=127+12.7*calc; r=int(calc); return r; } //--Calcula el votaje considerando el péndulo-------------------------------- unsigned char TForm1::calculavoltajeconpendulo(double xd,double x,double vel,double alfa,double velalfa)
  • 16. { unsigned char r; double calc=k1*(xd-x)-k3*vel-k2*alfa-k4*velalfa; if (calc>0) { calc=min(calc,maxvol); } else { calc=max(-maxvol,calc); } calc=127+12.7*calc; r=int(calc); return r; } Algoritmo Genético La manera de calcular el voltaje cuando se considera el péndulo es la siguiente fórmula:   4321 )( kxkkxxkV d  Donde x es la posición del carro en centímetros y alfa el ángulo de la varilla en grados. El problema es encontrar los valores del vector K=(k1,k2,k3,k4) que hagan que funcione de manera correcta el sistema. Para obtener estos valores utilice un algoritmo genético, en este, los individuos son vectores de cuatro dimensiones que representan los valores que se le asignan a K; la manera de evaluar cada individuo es dejar que trate de equilibrar la varilla minimizando la integral de alguna función, la función utilizada fue:       2 , dxxxF La primera generación se inicia con valores cercanos a los recomendados en un manual (modificados con ruido uniforme). La cruza se hizo con dos padres, se daba un volado por cada valor del vector, es decir se obtenía un número aleatorio entre 0 y 1, si este era mayor que 0.5 se le asignaba el valor de un padre y en caso contrario el del otro padre. Para la mutación se aplicó una pequeña perturbación a los valores del vector, esta se hizo con ruido uniforme. El siguiente es el código del algoritmo genético: //--Función para calcular un número con distribución uniforme en el intervalo [0,1] double uniforme(void) { return double(random(123456))/123455.0; } //--Esta es la estructura que tiene cada individuo struct Tindividuo { double k1,k2,k3,k4,fitness; }; //--Este apuntador es el que guardara la población completa Tindividuo *poblacion; //Esta función realiza una mutación en un individuo.
  • 17. void mutaindividuo(Tindividuo &ind) { if (uniforme()>=pm) { ind.k1=ind.k1+(uniforme()-0.5)/2; } if (uniforme()>=pm) { ind.k2=ind.k2+(uniforme()-0.5); } if (uniforme()>=pm) { ind.k3=ind.k3+(uniforme()-0.5)/2; } if (uniforme()>=pm) { ind.k4=ind.k4+(uniforme()-0.5)/2; } } //--Esta función toma dos individuos p y m y genera uno nuevo a partir de estos void cruzapareja(Tindividuo &p,Tindividuo &m,Tindividuo &h) { h=p; if (uniforme()>=0.5) { h.k1=m.k1; } if (uniforme()>=0.5) { h.k2=m.k2; } if (uniforme()>=0.5) { h.k3=m.k3; } if (uniforme()>=0.5) { h.k4=m.k4; } } //--Esta function es auxiliar, sirve como parámetro de la función qsort int comparaindividuos(const void *ae, const void *be) { Tindividuo *a=(Tindividuo *)ae, *b=(Tindividuo *)be; if (a->fitness<b->fitness)return -1; if (a->fitness==b->fitness)return 0; return 1; } //--La selección solamente ordena los individuos por el fitness void seleccion(void) { qsort(poblacion,mu+lambda,sizeof(Tindividuo),comparaindividuos); } //--Esta función genera lambda individuos nuevos mediante cruza y después los muta void cruzaymuta(void)
  • 18. { for (int i=mu;i<mu+lambda;i++) { cruzapareja(poblacion[random(mu)],poblacion[random(mu)],poblacion[i]); mutaindividuo(poblacion[i]); poblacion[i].fitness=0; } } //--Esta es la función principal del algoritmo genético, es una modificación pues esta //--ontiene el fitness dentro de otra función (el ciclo principal del programa) void ag(double aumento,int tiempo) { if (trabajando) { if (enfitness) { if (tiempo>(tiempodeprueba-tiempoind)) { tiempo=(tiempodeprueba-tiempoind); } poblacion[voy].fitness+=aumento*double(tiempo)/1000.0; tiempoind+=tiempo; if (tiempoind>=tiempodeprueba) { voy++; tiempoind=0; enfitness=false; } if (voy==(mu+lambda)) { seleccion(); cruzaymuta(); voy=mu; if (generacion%generacionesentreguardadas==0) { guardageneracion(); } generacion++; } } } } //--Esta función genera la población inicial void generapoblacioninicial(void) { poblacion=new Tindividuo[mu+lambda]; for (int i=0;i<mu+lambda;i++) { poblacion[i].k1=0.26+uniforme()/2; poblacion[i].k2=1.85+uniforme(); poblacion[i].k3=0.29+uniforme()/2; poblacion[i].k4=0.19+uniforme()/2; poblacion[i].fitness=0; } }
  • 19. Después de 50 generaciones y con una población de 20+10 y evaluar 10 segundos cada caso, se obtuvo un individuo con un fitness de 25.05, este logra equilibrar la varilla colocando al carro no muy lejos del punto en el que se quiere que permanezca. Manualmente se exploraron algunos de los individuos de esta generación, el que mas me gusto fue este: individuo 5: k1=1.059460 k2=0.430551 k3=0.330167 k4=0.112087 fitness=28.277874 5.- Convertidor Digital-Analógico. El convertidor digital-analógico está hecho con dos circuitos integrado: el DAC0800 y el . Tiene una respuesta de -10 a +10 voltios. El diagrama del convertidor es el siguiente:
  • 20. 6.- Diagrama. Este es el diagrama completo del proyecto: PROYECTO FINAL DE CONTROL DIGITAL “EQUILIBRADOR” POR SERGIO RICARDO MURGUIA SANTANA Enviado por: Ing.+Lic. Yunior Andrés Castillo S. “NO A LA CULTURA DEL SECRETO, SI A LA LIBERTAD DE INFORMACION”® www.monografias.com/usuario/perfiles/ing_lic_yunior_andra_s_castillo_s/monografias Página Web: yuniorandrescastillo.galeon.com Correo: yuniorcastillo@yahoo.com yuniorandrescastillosilverio@facebook.com Twitter: @yuniorcastillos Instagran:yuniorandrescastillo Celular: 1-829-725-8571 Santiago de los Caballeros, República Dominicana, 2016. “DIOS, JUAN PABLO DUARTE, JUAN BOSCH Y ANDRÉS CASTILLO DE LEÓN – POR SIEMPRE”®