You are on page 1of 46

Bitácora realizada para el Proyecto Integral de Tercer Semestre

Bitácora del Proyecto Integral de Tecnologías Digitales.

Lunes 4 de Agosto de 2008º


Anoto: Rick L. Swenson

Resumen de la reunión:
• Primer día de clase.
• Se les platico a los estudiantes de que consiste la materia de Proyecto Integral de Tecnologías
Digitales.
• La materia consta de realizar un proyecto que involucre conocimientos de materias de sus 3
primeros semestres:
○ Matemáticas, Física, Organización computacional, Diseño de Sistemas Digitales y
lenguaje ANSI C de programación.
• Se les explico a los educandos la estructura general de su carrera ITE que comprende 9
semestres, que pueden ser vistos como 3 bloques de tres semestres cada uno:
○ Semestre 1,2 y 3. Materias de ciencias básicas y primer contacto con materias de su
carrera. Al final de este bloque habrá el primer proyecto integral de tecnologías
digitales.
○ Semestre 4,5 y 6. Materias fundamentales de electrónica que crearan los cimientos de
su formación. Al final de este bloque habrá el segundo proyecto integral de
tecnologías digitales.
○ Semestre 7,8 y 9. Materias de modalidad y especialidad. Al final de este bloque habrá
el tercer proyecto integral de tecnologías digitales.

Compromisos para la siguiente reunión:


• Cada miembro del equipo debe traer una presentación de dos filminas aproximadamente. En
ella debe traer una propuesta de un proyecto que consideren que cubra todos los
requerimientos que se piden en el programa analítico.
• Se seleccionaran estudiantes para que pasen a explicar al equipo sus propuestas.
• Lo mejor de cada presentación será considerado para la decisión del proyecto final.

Jueves 7 de Agosto de 2008


Anoto: Omar Mejía Arnaud

Resumen de la reunión:
• Planteamiento de la bitácora
Se habló sobre los turnos según la lista y sobre el formato
• Se mostró en que directorio de Calypso se encuentra el material de apoyo( de c ) y conceptos
generales [ Calypso login: ProyDig password:ProyDig]
• Se habló sobre el otorgamiento de permisos para alterar los archivos en la carpeta de
contribuciones (tareas)
• Se presentaron las primeras propuestas de proyecto:
○ Un robot que según el reconocimiento de imágenes por una computadora imite el
movimiento de una persona
○ El bastón inteligente para personas de visión débil , con sensores de proximidad y
comandos por voz, el uso de terminales en lugares de interés para precargar rutas
○ Un excavador automatizado para la búsqueda de minas, minerales o personas en caso
de siniestro
○ Un robot controlado a través del control del wii con distintas aplicaciones
○ Un diagnosticador y reparador de problemas con la computadora
○ Un Helicóptero con una cámara integrada programable.

Compromisos para la siguiente reunión:


• Un análisis de la carta que será enviada por el maestro sobre un proyecto y que tan lejos se
cree poder llegar en el mismo

Lunes 11 de Agosto de 2008


Anoto: José Luis Loyola Larrondo

Resumen de la reunión:
• Se habló sobre el nuevo formato del servidor de tareas y contribuciones
• Se analizó la carta de la NASA
Esta carta habla sobre la historia de la NASA y sus misiones más importantes, como
por ejemplo el primer hombre en la luna, el “Space Shuttle” .
La petición que hacen es crear un prototipo de “Mars Pathfinder” que pueda ser
probado en la tierra.

Características:
– El vehículo debe ser capaz de comunicarse inalámbricamente con una
computadora.
– El vehículo debe reportar su posición en latitud y longitud en todo momento a la
computadora.
– La computadora debe ser capaz de controlar el vehículo en dos modos:
A) Manualmente: controlando su dirección y velocidad.
B) Autónoma: la computadora le transmitirá varios puntos al vehículo y este
debe seguir la ruta trazada.
– El vehículo debe estar programado en ANSI C para que sea compatible con las
computadoras de la NASA.
• Analizamos que tan viable era el proyecto realizando preguntas como:
– ¿Alcance?
– ¿Frecuencia?
– ¿Peso?
– ¿Dimensiones?
– ¿Velocidad?
– ¿Diseño?
• Estudiamos que materiales necesitamos para realizar el proyecto:
– Antenas
– GPS
– Motores
– Fuentes de Poder
– PC
• Aprendimos a usar el programa Mind Manager.
Compromisos para la siguiente reunión:
• Utilizar el Mind Manager para poder terminar la lluvia de ideas para el proyecto.

Jueves 14 de Agosto de 2008


Anotó: Roberto Sierra Alvarez

Resumen de la reunión:
• Se habló acerca del Mind Manager y de la experiencia que tuvimos al utilizarlo.
• Se presentaron algunas “lluvias de ideas” para describir las necesidades de aprendizaje que
tenemos para llevar a cabo el proyecto
• Algunos de los conceptos que necesitamos son los siguientes
– Lenguaje C
– Protocolos de comunicación inalámbrica
– GPS
 Funcionamiento
– Control del vehículo
 Mecánica
• Motores
– Tarjetas impresas
• Se habló acerca de la calendarización de los temas haciendo uso del Mind Manager y se
inició el trabajo en el mismo
Compromisos para la siguiente reunión:
• Escoger los mejores extras entre los proyectos y enumerarlos en 1,2 y 3.
• Ponerle nombre a nuestros equipos
• Hacer una lista de preguntas con base en la lluvia de ideas para preguntarle a la NASA
• Completar la calendarización que se inició haciendo uso del JCVGantt Pro 3
• Rick
○ Generar diagrama con base en las lluvias de ideas
○ Planear el curso con base en nuestras calendarización
○ Responder preguntas tomando la postura de la NASA

Lunes 18 de Agosto de 2008


Anotó: Juan Carlos Lara

Resumen de la reunión:
• El tema central fue el funcionamiento de GPS
• Se comenzó con una conferencia sobre las formas de ubicar puntos geográficos sobre la
tierra: latitud y longitud.
○ Un poco de reseña histórica sobre el surgimiento de los meridianos y paralelos
○ Meridiano de Greenwich
○ Trópicos de Cáncer y Capricornio
○ Husos horarios
• Se habló de diversos métodos históricos para ubicarse geográficamente
○ Empírico (sin instrumentación)
 Constelaciones
 Migraciones de algunas especies animales como mariposas o aves
○ Con instrumentos
 Brújula
 Astrolabio
 Ejemplo de calcular la distancia radial de algún individuo usando un reloj y la
velocidad del sonido
• Dos polos distintos: magnético y geográfico
○ Se habló que el Polo Norte está conformado por casquetes de hielo móviles que
hacen de su exploración una tarea frustrante.
• Breve reseña sobre el funcionamiento de los GPS: relojes atómicos.

Compromisos para la siguiente reunión:


• Investigar el funcionamiento de un reloj atómico
• Investigar cómo el GPS puede tomar un precio accesible aún con la presencia de un reloj
atómico de más de $100,000.

Jueves 21 de Agosto de 2008


Anotó: Gonzalo Pacheco

Resumen de la reunión:
Se comenzó a platicar de los GPS
Algunas marcas : Garmin , Magellan, Trimble, TomTom.
Evolución de los GPS
• Hoy en día se puede a través de un GPS pedir las coordenadas de otro GPS.
De esta forma se puede localizar incluso a una persona que este inconsciente.
• Se habló de los compañeros virtuales que puedes tener a partir de los GPS, en
esté puedes programar la condición del compañero virtual.
• Se comento del DOG TRAKING SYSTEM, pequeños transmisores que se
pueden añadir a perros y todos transmiten a un mismo GPS, los cuales pueden
decir la localización de cada uno de los perros, incluyendo si están detenidos;
es decir si encontraron algo.
• También se mencionaron los GPS en los automóviles, etc.
• Tractores guiados por GPS

Comenzamos a ver la presentación de GPSLecture_Burgess


Vimos otras características de los satélites.
Los 24 satélites existentes saben donde están por una triangulación con torres en la
tierra. Estos a su vez con triangulación te dicen dónde estás.
Vuelta a la tierra cada 12 h
Se hablo un poco de PPS, anterior al GPS, sin embargo estos solamente eran usados por la
milicia.
También se hablo del SPS, el cual ya no era sólo militar, ya también había para usuarios. A
pesar de que este era más exacto que el pasado (21m) lo hicieron menos exacto 100m de
inexactitud.
Hoy en día el GPS tiene un rango de error de tan sólo 6m.

Como funciona:
Un satélite transmite a la tierra donde esta, las computadoras aquí en la tierra, les retransmite
una señal corregida. El satélite después transmite a los usuarios su posición, al mandar su tiempo y
posición, el GPS realiza el cálculo según 4 señales de los satélites. El cuarto es para corrección del
lugar y también del tiempo. (Reloj)

Se comentó como se midió la velocidad de la luz.

Del GPS a nuestro Proyecto


Se mostro que es lo que manda en GPS a la PC cuando se conecta.

Compromisos para la siguiente reunión:

Investigar que nos manda el GPS


Escribir un Reporte de cómo hacerlo
FORMATO NMEA-0183

Lunes 25 de Agosto de 2008


Anotó: Fco. Javier López

Resumen de la reunión:

Se comenzó a analizar la información que manda el GPS cada segundo, para esto se conectó
el GPS a la computadora por el puerto serial.

El formato del GPS es el NMEA-0183 el cual fue creado por la marina y como varios le
entendían al formato, entonces fue adoptado por los creadores del GPS (los que tienen “Sentences”
como extra).

Se señaló que todos los GPS soportan el NMEA-0183 y algunos otros como el GARMIN
utilizan otro generado por su creador. Se mencionó que era requerido realizar un Tokenizer
utilizando la experiencia en JAVA para ir recordando la lógica para poder manejar el vehículo
(ROVER) por medio de los comandos en C.

Comenzamos a ver el formato del NMEA-0183 en el que es como el siguiente:


$GPRMC donde la sentencia comienza con $, la GPorigina la sentencia y el RMC dice el tipo
de sentencia.

Rick nos dijo dónde obtener el archivo en donde dice como tener la transmisión de un
Garmin para obtener la información que vamos a utilizar para mover y recibir información del
ROVER.
RMC (separado por comas)
Hh/min/seg militar
A => Active V => Void
Latitude N (norte) S (sur) {número máximo = 90.00.000° (siempre 2 dígitos y los demás de
minutos) (polo Norte)}
Longitud (3 dígitos) W (oeste) E (este) máximo = 180.00.000
Después de la longitud y si dice W o E dice 3 dígitos que viene en nudos/hrs = 1.85km/hrs.
Trank angle: 000.0 = N; 090.0 : E; 280.0 : S ; 270.0 : W; 359.9 Casi Norte;
Date: 230394 (dd/mm/año)
Declinación Magnética: (si es al este, se suma; si es al oeste se resta) tiene 3 dígitos
Checksum: hace cálculos con los que se puede saber si es correcto o no los datos que llegaron.

Se vio que la capa terrestre llamada Ionósfera, es importante para conocer la posición exacta
ya que dentro de ella, la señal rebota tarda más tiempo en llegar al satélite generando un margen de
error. Lo mismo sucede con las construcciones, además de que hay una forma de corregirlo
poniendo estaciones que transmiten donde están, esto se llama “Differential GPS”. Con estas
estaciones el margen de error puede reducirse a +- 5 cm.

Compromisos para la siguiente reunión:

De un archivo de texto, buscar la oración: $GPRMC


Desplegar la long, lat, en formato (grados°/minutos’/ segundos”), la hora de qro., el checksum y si
es activo o void.
Para sacar el Checksum revisar documento notepad del Material del Proyecto – Contribuciones
equipo- 05GPS-04Obtención del Checksum.

Jueves 28 de Agosto de 2008


Anotó: María Guadalupe Cervantes Pérez

Resumen de la reunión:
Comentamos que todos teníamos duda al momento de determinar el cheksum, a los que
hicimos el trabajo nos da 10 cuando debe de dar 07. Proyectamos y analizamos el
código de un compañero, pero varios no hicieron la conversión de las decimales de
minuto a segundo, se debe multiplicar *60.
Realizamos otro ejercicio a mano (que complicado…) donde el cheksum da 37 para ver
en qué teníamos el error, pero varios de los códigos realizados no estaban validando
que fuese V. Vicente propuso que podríamos analizar el numero de comas para analizar
el cheksum, pues con comas y sin comas debería de dar lo mismo si es par el numero de
comas. Sin embargo si es impar da distinto. Para comprobar lo de las comas analizamos
otro a mano y oh sorpresa… el cheksum si da pero debemos incluir las comas. La
pregunta es: ¿por qué no da en los códigos desarrollados?
Se encontró la posible fuente de error, el que nos envió Rick tenia datos no reales,
pues en el código de un compañero se realizo otro y ahora si funciona correctamente.
Analizamos el RMB (recommended mínimum navigation information) que trabaja cuando
ya se esta en movimiento pues con el RMC sólo sabemos donde esta el vehículo, cuando
esta estático. Por medio de programación en C debemos hacer cálculos matemáticos
para analizar desde donde está a donde tiene que ir para hacer determinado grado de
giro.
Heading: hacia donde se tiene que mover (a donde tiene que llegar).
Bearing: hacia donde se está moviendo.
Para el proyecto tenemos que hacer medidas muy exactas, pues la longitud y magnitud
nos da un vector.

Analizaremos con nuestro asesor varios tipos de GPS pero nosotros debemos
seleccionar lo que nos sirve o no.
RMB -
$GPRMB,A,0.66,L,003,004,4917.24,N,12309.57,W,001.3,052.5,000.5,V*20
donde:
RMB Recommended minimum navigation information
A Data status A = OK, V = Void (warning).

Caunto te has desviado de tu ruta y hacia donde tienes que girar:


0.66,L Cross-track error (nautical miles, 9.99 max),
steer Left to correct (or R = right).

Entre que waypoint estas de tu trayecto:


003 Origin waypoint ID (origen).
004 Destination waypoint ID (destino).
4917.24,N Destination waypoint latitude 49 deg. 17.24 min. N (latitud del
destino).

12309.57,W Destination waypoint longitude 123 deg. 09.57 min. W (longitud


del destino).

001.3 Range to destination, nautical miles(999.9 max). (a que distacia


estamos de donde queremos llegar).

052.5 True bearing to destination (para que estemos en el destino debe


decir este ángulo nuestro aparato).
000.5 Velocity towards destination, knots. (Velocidad a la que se va
desplazando, no a la que te vas moviendo).

V Arrival alarm A = arrived, V = not arrived (puede enviar una señal de


alarma cuando es A es que ya llegaste).

*20 checksum

Compromiso para la siguiente clase:


Checar nuestro código y el que había de tarea a mano para checar el posible error.
Terminar de leer el documento analizado en clase, respecto a GPS.
Lenguaje de programación en C.

Jueves 01 de Septiembre de 2008


Anotó: Nora Edith Angeles Lira

Resumen de la reunión:
Acordamos que para la evaluación del parcial será necesario traer las herramientas necesarias para
trabajar en java y prepararnos con lo elemental del NMEA 0183($gp) y sistema GPS.
El parcial tendrá un valor mínimo del 10%.
Recordamos que es un waypoint, track y route.
Waypoint: Los waypoints son coordenadas para ubicar puntos de referencia tridimensionales
utilizados en la navegación fundamentada en GPS En realidad se emplean para trazar rutas mediante
agregación secuencial de puntos.
Track: waypoints temporales que se generan a base de tiempo y distancia, es decir cada medio
minuto o cada 100 metros.
Marcas como waypiont tu inicio y tu final existe una función llamada Trackback es para que
regreses exactamente la ruta por la que venias.
Introducción al lenguaje C.

“Un diseñador sabe que ha alcanzado la perfección no cuando ya no tiene nada que agregar si no
cuando ya no tiene nada que quitarle”
Usaremos el C estándar , el ANSI C, esto es porque los dispositivos lógicos están programados en C
(micro-controladores, DSP, NPU). El
nivel mas bajo de programación es con ceros y unos. El
nivel medio seria o fue, Minemonisc, Mov, ADD, SHL, Ensamblador. Nivel
medio/alto. Basic, fortan-77, COBOL, RPG/Pascal. Nivel alto:
Modula II , C evolucuono en C++ y actualmente C#
¿Por qué no ha desaparecido C? porque toda la gente lo usa pues se siente más familiarizada con
este.
Existe una versión para especificar hardware (dispositivos lógicos programables) utilizando C
“SystemC” .
Compiladores gratuitos en la red: Borland 4.5 (win), Turbo C (DOS), Dev C++ 4.95, Eclipse,
Watcom C (el más poderoso)
Compiladores no gratuitos: Borland, Micosoft Net (C#) , Visual C,, national Instruments Windows
CVI.
*Bajamos e instalamos el compilador Dev C++ 4.95
Trabajamos con el programita hello world:
Las dos librerías básicas en C : include stdio.h , include stdlib.h.
Para dejar comentarios es el mismo mecanismo de java.
Printf: para escribir en pantalla.
Void: no recibe parámetros.
Para declaración de variables siempre pones primero el tipo d evariable que quieres pones y
después el nombre, de igual manera las puedes inicializar.
Fue unprograma sencillo pero una muy buena introducción a C.

Lunes 8 de septiembre de 2008


Anotó: Vicente Estebes González

Resumen de la reunión:

○ Lo primero que se hizo en el día fue establecer cuál de los programas calculadores de
distancia es el que más exactitud tenia.

○ Se propuso una fórmula para calcular la exactitud de distancia y de ángulo, donde


dividíamos el valor más pequeño entre el resultado y la respuesta correcta, después el
resultado lo multiplicamos por 100.

○ Se estableció que el programa que tuviera mayor exactitud, es el que se va a utilizar


como modelo para traducirlo a lenguaje C.

○ Se dibujo una tabla con todos los compañeros de grupo y el número de pruebas que
se hicieron con localización de dos puntos sacados del google Earth.

○ Los programas de prueba se hicieron para calcular en distancia y ángulo entre dos
puntos: uno en el hemisferio Norte y otro en el hemisferio Sur, para ver cuál es la
exactitud, tomando cuando en cuenta que hay latitud Norte y latitud Sur.
○ Los programas más exactos fueron los de: Lupita (con promedio aproximado de
99.8 ), Omar(con un promedio aproximado de 99.3) e Israel (con un promedio
aproximado de 99.7).

○ Se hizo una prueba, calculando una distancia en el google earth de 40mts. En el


actual estacionamiento del tec, después se hicieron cálculos en los programas de cada
uno para ver la exactitud en el cálculo de distancias cortas.

○ Se pregunto a la mayoría de los compañeros que métodos utilizaron, los más


comunes fueron el Haversine, trigonometría, ley de senos y cosenos.

○ Se estableció que para la siguiente clase hay que traer corregido el programa.

Resultados de programas realizados por el equipo de diseño. Programas realizados en Java. Los
resultados especifican el margen de error de acuerdo a porcentaje ((valor menor / valor mayor) *
100). La comparación se realiza con el valor obtenido en el programa del equipo, contra los valores
obtenidos del GPS.

• C1
• Punto A: El edifico del CIE del ITESM – Campus Querétaro
○ Latitud: 20 grados 36 minutos 52.31 segundos Norte
○ Longitud: 100 grados 24 minutos 11.41 segundos Oeste
• Punto B: Iglesia en el centro de Bernal, Querétaro
○ Latitud: 20 grados 44 minutos 26.70 segundos Norte
○ Longitud: 99 grados 56 minutos 28.06 segundos Oeste
• Solución para ir de Punto A al Punto B
○ Distancia entre Punto A y Punto B: 50,071.51 metros
○ Dirección de navegación del Punto A al Punto B: 74 grados True
• C2
• Punto A: El centro del estadio de futbol Cuauhtémoc de Puebla, Puebla
○ Latitud: 19 grados 04 minutos 40.95 segundos Norte
○ Longitud: 98 grados 09 minutos 51.80 segundos Oeste
• Punto B: El centro del estadio de futbol La Corregidora de Querétaro, Querétaro
○ Latitud: 20 grados 34 minutos 39.58 segundos Norte
○ Longitud: 100 grados 21 minutos 59.54 segundos Oeste
• Solución para ir de Punto A al Punto B
○ Distancia entre Punto A y Punto B: 284,000 metros
○ Dirección de navegación del Punto A al Punto B: 306 grados True
• C3
• Punto A: El auditorio Josefa Ortiz de Domínguez de Querétaro, Querétaro.
○ Latitud: 20 grados 35 minutos 10.03 segundos Norte
○ Longitud: 100 grados 22 minutos 41.24 segundos Oeste
• Punto B: El auditorio Tres Guerras de Celaya, Guanajuato
○ Latitud: 20 grados 32 minutos 09.25 segundos Norte
○ Longitud: 100 grados 49 minutos 42.93 segundos Oeste
• Solución para ir de Punto A al Punto B
○ Distancia entre Punto A y Punto B: 47, 300 metros
○ Dirección de navegación del Punto A al Punto B: 263 grados True
• C4
• Punto A: La cima del volcán activo, más alto del mundo, Cotopaxi (5894 mts.
Altura) en Ecuador.
○ Latitud: 00 grados 51 minutos 30.50 segundos Sur
○ Longitud: 78 grados 54 minutos 06.32 segundos Oeste
• Punto B: La cima de volcán activo Popocatepetl (5426 mts. Altura) en México.
○ Latitud: 19 grados 01 minutos 48.58 segundos Norte
○ Longitud: 98 grados 37 minutos 26.73 segundos Oeste
• Solución para ir de Punto A al Punto B
○ Distancia entre Punto A y Punto B: 3,080,000 metros
○ Dirección de navegación del Punto A al Punto B: 317 grados True
• C5
• Punto A: Un punto origen en el estacionamiento conocido como Disney del
ITESM-Campus Qro.
○ Latitud: 20 grados 36 minutos 50.18 segundos Norte
○ Longitud: 100 grados 24 minutos 23.90 segundos Oeste
• Punto B: Un punto destino en el estacionamiento conocido como Disney del
ITESM-Campus Qro.
○ Latitud: 20 grados 36 minutos 50.16 segundos Norte
○ Longitud: 100 grados 24 minutos 22.52 segundos Oeste
• Solución para ir de Punto A al Punto B
○ Distancia entre Punto A y Punto B: 40 metros
○ Dirección de navegación del Punto A al Punto B: 91 grados True
Resultados de las pruebas realizadas en Java para obtener D (distancia) y G (grados). Los valores
están expresados en porcentaje. C1, C2, C3, C4 y C5 son los casos tomados del GPS.

Jueves 11 de septiembre de 2008


Anotó: Samuel Isaac Delgado Durón

Resumen de la reunión:

Lo que hicimos en esta clase fue ingresar el código que anteriormente habíamos hecho en java ahora
a C++, Rick nos ayudo a transcribirlo dándonos inicialmente una serie de ecuaciones (las
ecuaciones principales) que teníamos que ingresar en código a C++.
Las siguientes funciones son las que Rick nos aportó:

• dlon= lon2 - lon1


• dlat = lat2 – lat1
• a=[sin (dlat/2)]2+ cos (lat1)+ cos (lat2)+[sin (dlong/2)]2
• c=2x atan2 (√a, √1-a)
• dist= c * R Radio de la tierra

Inmediatamente comenzamos a escribir el código en C++ en la comenzamos con la


declaración de constantes, en este caso el valor de π. Lo definimos de la siguiente
manera:
#define pi= 3.14159265358979323846.
Después declaramos la función de determinará la distancia entre lat1, lon1 con lat2,
lon2 la cual la declaramos como un double por que éste tipo de dato nos regresa
valores con decimales, los cuales necesitamos para tener una mayor precisión en
nuestros resultados.

Al terminar de escribir el código quedó de la siguiente forma:

#include <iostream.h>
#include <stdlib.h>
#include <math.h>
#include <stdio.h>

#define pi = 3.141559

//funcion que determina la distancia entre dos puntos


double DistLatLong (double lat1, double lon1, double lat2, double lon2, char
unidades){
//variables locales
double dlon, dlat; //delta longitud y latidud
double a,c; //variables para claculos intermedios
double rad; //Para convertir de grados a radianes
double R;

//Algotirmo Haversin
dlon = lon2 - lon1;
dlat = lat2 - lat1;

//constante para convertir a radianes


rad= 3.141559/180;
a = pow(sin(dlat/2*rad),2) + (cos (lat1*rad) * cos(lat2*rad) *
pow(sin(dlon/2*rad),2));
c = 2 * atan2 (sqrt (a),sqrt (1-a));
//R (radio de la tierra)
switch (unidades)
{
case 'M': //millas
R = 3956.0;
break;
case 'N': //millas náuticas
R = 3437.7;
break;
case 'K' : //Kilómetros
R = 6367.0;
break;
}

//Salir de la funcion regresando el valor de la distancia


return (R*c);
}

int main(void)
{
double distancia; //valor de la distancia entre dos puntos

//coordenadas del edificio CIE del tec campus qro


double lat1 = 20.61453056;
double lon1 = 100.4031694;
//coordenadas del centro de Bernal
double lat2 = 20.74075;
double lon2 = 99.94112778;

distancia = DistLatLong (lat1,lon1,lat2,lon2,'K');

printf("La distancia entre las dos coordenadas dades es: %f\n",distancia);


system("PAUSE");
return 0;
}

Quedo pendiente terminar el programa para que funcione similar al programado


anteriormente en java

Jueves 18 de septiembre de 2008


Anotó: Araceli Carolina Govea Buendía

Resumen de la reunión:

 Revisamos el programa de C ++ en el que estaba la respuesta a la tarea, checando las funciones


que se necesitaban para transformar de grados a minutos y segundos y nos dijo Rick que al escribir
%f , C se encargaba de leer datos en punto flotante.

Hicimos los siguientes ejercicios corriéndolo desde el programa que estábamos checando en
clase.
• Lat 20° 35’ 10.03’’ N
Lon 100° 22’ 41.24’’W
Respuestas:
Lat20.58619
Long100.378122

• Lat 20° 32’ 9.25’’ N


Long 100° 49’ 42.93’’ W
Respuestas:
Lat20.535903
Long20.586119

Lo que hacia el programa era convertir de grados, minutos y segundos a decimales, te regresa el
valor de la longitud y la latitud en decimal.

Se discutió la manera en la que se pudiera sacar el ángulo, tomando en cuenta los posibles errores
que tuvieron compañeros al querer sacar el ángulo con la tangente inversa.

Se utilizó un programa escrito por nuestros compañeros (el equipo de Israel Olvera) , sólo la
parte que calcula el ángulo con respecto al Norte Geográfico, y recibe como parámetros la longitud
[1 y 2], latitud [1 y 2] y h (todos los parámetros son double), y se compiló para verificar que no
tuviera ningún error.
Al correr el programa nos percatamos que no nos quedaba el ángulo por que no le pusimos el
nombre correcto al dato que nos tenía que devolver, al corregirle el nombre el ángulo dio
perfectamente.

Comenzamos a ver cómo es que C++ lee memorias.

MEMORIA (RAM)

int

Hicimos varios documentos dentro de C con la finalidad de hacer distintos Test para leer memorias

1er programa

int main (void){

short int num;


printf(“El numero de bytes que ocupa num en memoria son: %i\n”, sizeof (num));
printf(“La localidad de memoria en donde quedo num almacenado:” %i\n”, sizeof (num));
printf(“El valor que tiene num es: %i\n”, num);

system(“PAUSE”);
return (0);
}

2do programa

int main (void){

short int num= 32767;


printf(“El numero de bytes que ocupa num en memoria son: %i\n”, sizeof (num));
printf(“La localidad de memoria en donde quedo num almacenado:” %i\n”, &num);
num += 4;
printf(“El valor que tiene num es: %i\n”, num);

system(“PAUSE”);
return (0);
}

El programa anterior nos desplegará una respuesta de : -32765

3er programa

int main (void){

short int num;


char car = ‘A’;

num car
printf(“El numero de bytes que ocupa num en memoria son: %i\n”, sizeof (num));
printf(“La localidad de memoria en donde quedo num almacenado:” %i\n”, &num)
printf(“El valor que tiene num es: %i\n”, num);
system(“PAUSE”);
return (0);
}

El programa anterior nos desplegará una respuesta de : 65 (te da el núm. de carácter de A)

Rick nos mostró un archivo donde nos ayuda diciéndonos los siguientes datos (dentro de Material
de Clase):
Tipos de datos en C (su descripción)
Palabras reservadas en C
Declaración de constantes.
Operaciones aritméticas que se pueden realizar en C y como se escriben.
Niveles de jerarquía entre operaciones.
Operadores de incremento u decremento (++ y – respectivamente)
Operadores Lógicos y su jerarquía
Caracteres de control y su explicación
Formato de escritura de las variables.
Modificaciones al símbolo %

Nos mostró una presentación de Power Point , donde viene la estructura de de los
condicionales(if, if-else, switch, etc,) .

Compromisos para la siguiente sesión:

-Tratar de ver los ejemplos (el que recibe oraciones y los tokeniza –el tokenizer-)

Jueves 22 de septiembre de 2008


Anotó: Jonathan Iván Candedo Justo

Funciones, Procedimientos y Parámetros.

Resumen de la reunión:

La reunión de este día trato sobre las funciones, procedimientos y parámetros en un


programa de C++ en donde Rick explicó las diferencias entre variables con el mismo nombre, las
variables estáticas, la diferencia entre un procedimiento y una función además de las diferentes
formas de declaración que pueden tener. Para poder explicar lo anterior, usamos 12 programas con
casos diferentes en donde analizábamos cada uno para poder llegar al resultado e ir pudiendo ver los
objetivos de la clase. A continuación se encuentran los 6 primeros programas analizados:

Programa 1: En este programa Rick mostró una variable global, un prototipo de función la
cual se diferencia de un procedimiento porque devuelve un valor. Ej- (int cubo(void);) el cual
no recibe parámetros. Este programa eleva al cubo a los 10 primeros números naturales por
medio de un ciclo for, el cual aprendimos a hacer. Las variables globales se pueden utilizar
en cualquier función.

#include <stdio.h>
#include <stdlib.h>
/* Cubo-1.
El programa calcula el cubo de los 10 primeros números naturales con la ayuda de una
función.
En la solución del problema se utiliza una variable global, aunque esto, como veremos más
adelante, no es muy recomendable. */
int cubo(void); /* Prototipo de funcion. */
int I; /* Variable global. */

int main(void)
{
int CUB;
for (I = 1; I <= 10; I++)
{
CUB = cubo(); /* Llamada a la funcion cubo. */
printf("\nEl cubo de %d es: %d", I, CUB);
}
printf("\n");
system("PAUSE");
return 0;
}

int cubo(void) /* Declaracion de la funcion. */


/* La funcion calcula el cubo de la variable global I. */
{
return (I*I*I);
}

Programa 2: Este programa puede parecer parecido al primero pero tiene una gran
diferencia y esta es que se usan 2 variables con el mismo nombre. Primero está declarada la variable
global como en el anterior, pero luego en la función “cubo” se declara otra variable con el mismo
nombre que la global y esta inicializada en 2. Esta función regresa el cubo de esa variable, porque en
C la variable que se usa es la más recientemente declarada. El resultado siempre va a ser 8.

#include <stdio.h>
#include <stdlib.h>
/* Cubo-2.
El programa calcula el cubo de los 10 primeros numeros naturales con la
ayuda de una funcion. */
int cubo(void); /* Prototipo de funcion. */
int I; /* Variable global. */

int main(void)
{
int CUB;
for (I=1; I <= 10; I++)
{
CUB = cubo(); /* Llamada a la funcion cubo. */
printf("\nEl cubo de %d es: %d", I, CUB);
}
system(" PAUSE");
return 0;
}

int cubo(void) /* Declaracion de la funcion. */


/* La funcion calcula el cubo de la variable local I. */
{
int I=2; /* Variable local entera I con el mismo nombre que la variable global. */
return (I*I*I);
}

Programa 3: Este programa es casi igual al anterior, solamente cambia en el hecho de que se
usa un procedimiento void f1(void); que no regresa un valor, también en que nos dice cómo usar 2
variables con un mismo nombre , para la variable local se queda intacta pero para la global se tiene
que usar :: variable para poder usarla en conjunto con la local como se muestra en el programa.

#include <stdio.h>
#include <stdlib.h>
/* Conflicto de variables con el mismo nombre. */
void f1(void); /* Prototipo de funcion. */
int K = 5; /* Variable global. */

int main (void)


{
int I;
for (I=1; I <= 3; I++)
f1();

system(" PAUSE");
return 0;
}
void f1(void)
/* La funcion utiliza tanto la variable local I como la variable •global I. */
{
int K = 2; /* Variable local. */
K += K;
printf("\n\nEl valor de la variable local es: %d", K);
::K = ::K + K; /* Uso de ambas variables. */
printf("\nEl valor de la variable global es: %d", ::K);
}

Programa 4:En este programa por fin podemos ver la diferencia entre los diferentes modos de
declarar una variable. Se encuentra la variable global, una variable local, y una variable estática
que se reparten en 4 funciones diferentes.
• La función 1 utiliza la variable global la cual se modifica con cada llamada a la función.
• La función 2 no cambia porque cada vez que se llama a la función la variable vuelve a ser
inicializada con el valor establecido.
• La función 3 utiliza la variable static la cual conserva el valor al acabar la función y cada vez
que se llama a la función sigue cambiando su valor, nunca vuelve a inicializarse con su
primer valor.
• Por último la función 4 es una combinación de variables. Utiliza la variable local y la global,
la global se modifica cada vez en la función 1.

#include <stdio.h>
#include <stdlib.h>
/* Prueba de variables globales, locales y estaticas.
El programa utiliza funciones en las que se usan diferentes tipos de
variables. */

int f1(void);
int f2(void);
int f3(void); /* Prototipos de funciones. */
int f4(void);
int K = 3; /* Variable global. */
int main(void)
{
int I;
for (I = 1; I <= 3; I++)
{
printf("\n\nEl resultado de la funcion f1 es: %d", f1());
printf("\nEl resultado de la funcion f2 es: %d", f2());
printf("\nEl resultado de la funcion f3 es: %d", f3());
printf("\nEl resultado de la funcion f4 es: %d \n", f4());
}
system(" PAUSE");
return 0;
}

int f1(void)
/* La funcion f1 utiliza la variable global. */
{
K += K;
return (K);
}
int f2(void)
/* La funcion f2 utiliza la variable local. */
{
int K = 1;
K++;
return (K);
}
int f3(void)
/* La funcion f3 utiliza la variable estatica. */
{
static int K = 8;
K += 2;
return (K);
}

int f4(void)
/* La funcion f4 utiliza dos variables con el mismo nombre: local y global. */
{
int K = 5;
K = K + ::K; /* Uso de la variable local (K) y global (::K) */
return (K);
}

Programa 5: En este programa se implementan las funciones con parámetros por valor donde la
función “cubo” recibe como parámetro la variable K. Al llamar el método con el ciclo “for”, I ocupa
el parámetro de esta y el resultado final es el cubo de los primeros 10 números.

#include <stdio.h>
#include <stdlib.h>
/* Cubo-3.
El programs calcula el cubo de los 10 primeros numeros naturales con la
ayuda de una funcion y utilizando parametros por valor.
int cubo(int); /* Prototipo de funcion. El parametro es de tipo entero. */

int cubo(int K) /* K es un parametro por valor de tipo entero. */


/* La funcion calcula el cubo del parametro K. */
{
return (K*K*K);
}

int main(void)
{
int I;
for(I = 1; I <= 10; I++)
printf("\nEl cubo de I es:%d", cubo(I));
/* Llamada a la funcion cubo. El paso del parametro es por valor. */
system(" PAUSE");
return 0;
}

Programa 6: En este programa se emplea una función que recibe un parámetro por referencia el
cual se diferencia al del valor por la cualidad de poder leer una localidad de memoria. Cuando se
recibe un parámetro por valor a este se le saca una copia al contrario de por referencia en el cual se
sabe nada mas la localidad de memoria y su valor. Para usar el valor de la localidad de memoria se
usa el signo “*” antes de la variable. Para saber su dirección en memoria se usa el “&”. En el
programa primero se le hace un pre-incremento a la variable, después despliega el resultado.

#include <stdio.h>
#include <stdlib.h>

/* Prueba de parametros por referencia. */


void f1(int *);
/* Prototipo de funcion. El parametro es de tipo entero y por referencia
—observa el uso del operador de indireccion. */
int main(void)
{
int I, K = 4;
for (I = 1; I <= 3; I++)
{
printf("\n\nValor de K antes de llamar a la funcion: %d", ++K);
printf("\nValor de K despues de llamar a la funcion: %d", f1(&K));
/* Llamada a la funcion f1. Se pasa la direccion de la variable K, */
/* por medio del operador de direccion: &. */
}
system(" PAUSE");
return 0;
}

void f1(int *R)


/* La funcion f1 recibe un parametro por referencia. Cada vez que el
parametro se utiliza en la funcion debe ir precedido por el operador de indireccion. */
{
*R += *R;
}

Jueves de septiembre de 2008


Anotó: Luis Alberto González

Introducción a apuntadores.

Resumen de la reunión:
Se comenzó la clase con una breve introducción hacia los distintos métodos de acceder a los
valores de una variable, ya sea dejan sola (valor directo), con un “&” al principio de la variable (lo
que nos da la localidad en donde se encuentra guardada la variable “apuntador directo”) o con un
“*” al principio (te da la localidad donde se guarda el número de la localidad de la variable
“apuntador indirecto”
Durante el proceso de la clase se fueron realizando diversos programas para ver las
diferencias en comportamiento y diferentes aplicaciones de cada uno.
Problema 1
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
int locker = 2;
int *locker1;
printf("\n El contenido del locker es %d", locker);
printf("\n\nel locker tiene la siguiente direccion:%d", &locker);

locker1 = &locker;
printf("\n El contenido del locker es %d", locker1);
printf("\n\nel locker tiene la siguiente direccion:%d", *locker1);
printf("\n");

system(" PAUSE");
}
Con el problema anterior se nos explica las diferentes posibilidades, en el primer printf, lo que se
imprime en pantalla es el valor del número, en cambio, en el segundo printf, donde se le ha puesto el
símbolo “&” antes del nombre de la variable, lo que se imprime en pantalla es la dirección donde se
encuentra la variable, por último, en los últimos dos printf(donde se pretende desplegar una variable
que tiene un asterisco enfrente, lo que la hace una variable “almacenadora de direcciones”) donde al
poner el asterisco, nos regresa la variable, con un “&” nos da la localidad donde se encuentra él, y
cuando no tiene nada enfrente, nos da la localidad de la localidad.
Después de ese ejemplo, se pasó a los problemas vistos en la clase anterior (checar
anotaciones anteriores) y se nos explico de manera más amplia lo hecho en dicha clase.
Pro ultimo se presento problemas nuevos que fueron analizados para reforzar los temas
vistos hasta este punto:

Problema 2

Con este problema se realizó manualmente las posibles respuestas del programa, para poder
analizar las fallas o aciertos en los conocimientos obtenidos al día de hoy.

#include <stdio.h>
#include <stdlib.h>
/* Combinación de variables globales y locales, y parámetros por valor *» y por referencia. */
int a, b, c, d; /* Variables globales. */
void funcion1(int *, int *);
/* Prototipo de función. Observa que los dos parámetros son por
*» referencia. */
int funcion2(int, int *);
/* En este prototipo el primer parámetro es por valor y el segundo por
*• referencia. */
int main(void)
{
int a; /* Nota que a es una variable local. */
a = 1; /* Se asigna un valor a la variable local a. */
b = 2; /* Se asignan valores a las variables globales b, c y d. */
c = 3;
d = 4;
printf("\n%d %d %d %d", a, b, c, d);
funcion1 (&b, &c);
printf("\n%d %d %d %d", a, b, c, d);
a = funcion2(c, &d);
printf("\n%d %d %d %d", a, b, c, d);

system(" PAUSE");
return 0;
}

void funcion1 (int *b, int *c)


{
int d;
a = 5; /* Observa que se hace referencia a la variable global a. */
d = 3; /* Nota que se hace referencia a la variable local d. */
(*b)++;
(*c) += 2;
printf("\n%d %d %d %d", a, *b, *c, d);
}

int funcion2(int c, int *d)


{
int b;
a++;
b = 7;
c += 3;
(*d) += 2;
printf("\n%d %d %d %d", a, b, c, *d);
return (c);
}

Problema 3

En este problema se nos presento un “truco” de C en el cual una función llama a otra
función, como por ejemplo aquí con diversos procesos aritméticos.

#include <stdio.h>
#include <stdlib.h>
/* Paso de una función como parámetro por referencia. */
int Suma(int X, int Y)
/* La función Suma regresa la suma de los parámetros de tipo entero
*• X y Y. */
{
return (X+Y);
}
int Resta(int X, int Y)
/* Esta función regresa la resta de los parámetros de tipo entero
|- X y Y. */
{
return (X-Y);
}
int Control(int (*apf) (int, int), int X, int Y)
/* Esta función recibe como parámetro 3tra función —la dirección — y
*» Dependiendo de cuál sea esta, llama a la función Suma o Resta. */
{
int RES;
RES = (*apf) (X, Y); /* Se llama a la funcion Suma o Resta. */
return (RES);
}

int main(void)
{
int R1, R2;
R1 = Control(Suma, 15, 5); /* Se pasa como parámetro la funcion Suma. */
R2 = Control(Resta, 10, 4); /* Se pasa como parámetro la función Resta.*/
printf("\nResultado 1: %d",R1);
printf (" \nResultado 2: %d",R2);

system(" PAUSE");
return 0;
}
Lunes 30 de septiembre de 2008
Anotó: Jorge Raigosa
Programas Necesarios para el curso:

-Calculo de una distancia y angulo entre 2 puntos

-Tokenizer

-Control de vehiculo desde el teclado


Problemas : Brincar la seguridad de Windows XP
Plus : Manejo con control de Wii
-Manejo de Archivos

Objetivo de la clase: Sacar un campo del GPS.


Tema del día: Arreglos en C

Arreglos Unidimensionales:
Ejemplo 1:
Manejo de arreglo con entero
#include <stdio.h>
#include <stdlib.h>

/* Cuenta-numeros.
El programa, al recibir como datos un arreglo unidimensional de tipo *»
entero y un numero entero, determina cuantas veces se encuentra el
*»numero en el arreglo. */
int main(void)
{
int I, NUM, CUE = 0;
int ARRE[10]; /* Declaracion del arreglo */
for (I=0; I<10; I++)
{
printf("Ingrese el elemento %d del arreglo: ", I+1);
scanf("%d", &ARRE[I]); /* Lectura -asignacion— del arreglo */
}
printf("\n\nlngrese el numero que se va a buscar en el arreglo: ");
scanf("%d", &NUM);
for (I=0; I<10; I++)
if (ARRE[I] == NUM)
/* Comparacion del numero con los elementos del arreglo */
CUE++;
printf("\n\nEl %d se encuentra %d veces en el arreglo", NUM, CUE);
system(" PAUSE");
return 0;
}

Ejemplo 2:
#include <stdio.h>
#include <stdlib.h>

/* Eleccion.
El programa almacena los votos emitidos en una eleccion en la que hubo cinco
»»candidatos e imprime el total de votos que obtuvo cada uno de ellos . */
int main (void)
{
int ELE[5]= {0}; /* Declaracion del arreglo entero ELE de cinco
•elementos. Todos sus elementos se inicializan en 0. */
int I, VOT;
printf ("Ingresa el primer voto (0 -Para terminar): ");
scanf("%d", &VOT);
while (VOT)
{
if ((VOT > 0) && (VOT < 6)) /* Se verifica que el voto sea
*correcto. */
ELE[VOT-1]++; /* Los votos se almacenan en el arreglo. •Recuerda que la primera posicion
del arreglo es 0, por esa razon a la •variable VOT se le descuenta 1. Los votos del primer candidato
se •almacenan en la posicion 0. */
else
printf("\nEl voto ingresado es incorrecto.\n");
printf("Ingresa el siguiente voto (0 - Para terminar): ");
scanf("%d", &VOT);
}
printf("\n\nResultados de la Eleccion\n");
for (I=0; I <= 4; I++)
printf("\nCandidato %d: %d", I+1, ELE[I]);
system(" PAUSE");
return 0;
}

Ejemplo 3:
El programa engloba todos los temas vistos apuntadores , variables y arreglos.
Primero predecimos lo que nos va a dar la variable final para repasar el conocimiento luego
corremos el programa para ver si estamos bien .

#include <stdio.h>
#include <stdlib.h>

/* Eleccion.
El programa almacena los votos emitidos en una eleccion en la que hubo cinco
»»candidatos e imprime el total de votos que obtuvo cada uno de ellos . */
int main (void)
{
int ELE[5]= {0}; /* Declaracion del arreglo entero ELE de cinco
•elementos. Todos sus elementos se inicializan en 0. */
int I, VOT;
printf ("Ingresa el primer voto (0 -Para terminar): ");
scanf("%d", &VOT);
while (VOT)
{
if ((VOT > 0) && (VOT < 6)) /* Se verifica que el voto sea
*correcto. */
ELE[VOT-1]++; /* Los votos se almacenan en el arreglo. •Recuerda que la primera posicion
del arreglo es 0, por esa razon a la •variable VOT se le descuenta 1. Los votos del primer candidato
se •almacenan en la posicion 0. */
else
printf("\nEl voto ingresado es incorrecto.\n");
printf("Ingresa el siguiente voto (0 - Para terminar): ");
scanf("%d", &VOT);
}
printf("\n\nResultados de la Eleccion\n");
for (I=0; I <= 4; I++)
printf("\nCandidato %d: %d", I+1, ELE[I]);

system(" PAUSE");
return 0;
}

Ejemplo 4:
Paso de parámetros con arreglos, los arreglos unidimensionales se pasan por referencia.
#include <stdio.h>
#include <stdlib.h>
/* Producto de vectores.
El programa calcula el producto de dos vectores y almacena el resultado
»en otro arreglo unidimensional */

const int MAX = 10; /* Se define una constante para el tamaño de los
*arreglos. */
void Lectura(int VEC[], int T);
void Imprime(int VEC[], int T); /* Prototipos de funciones. */
void Producto(int *X, int *Y, int *Z, int T); /* Observa que en los
•parametros, para indicar que lo que se recibe es un arreglo, se puede escribir
VEC[] o *VEC. */

int main(void)
{
int VE1[MAX], VE2[MAX], VE3[MAX];
/* Se declaran tres arreglos de tipo entero de 10 elementos. */
Lectura(VE1, MAX);
/* Se llama a la funcion Lectura. Observa que el paso del arreglo a la funcion
•»es por referenda. Solo se debe incluir el nombre del arreglo. */
Lectura(VE2, MAX);
Producto(VE1, VE2, VE3, MAX);
/* Se llama a la funcion Producto. Se pasan los nombres de los tres arreglos. */
printf("\nProducto de los Vectores");
Imprime(VE3, MAX);

system(" PAUSE");
return 0;
}

void Lectura(int VEC[], int T)


/* La funcion Lectura se utiliza para leer un arreglo unidimensional de T
^elementos de tipo entero. */
{
int I;
printf("\n");
for(I=0; I<T; I++)
{
printf("Ingrese el elemento %d: ", I+1);
scanf("%d", &VEC[I]);
}
}
void Imprime(int VEC[], int T)
/* La funcion Imprime se utiliza para imprimir un arreglo unidimensional de T >
»elementos de tipo entero. */
{
int I;
for (I=0; I <T; I++)
printf("\nVEC[%d]: %d", I+1, VEC[I]);
}
void Producto(int *X, int *Y, int *Z, int T)
/* Esta funcion se utiliza para calcular el producto de dos arreglos
>»unidimensionales de T elementos de tipo entero. */
{
int I;
for(I=0; I<T; I++)
//Z[I] = X[I] * Y[I];
//apuntadores
// *(Z+I) = *(X+I) * *(Y+I);
*Z+I = *X++ * *Y++;

Ejemplo 5 : Contiene Errores para practicar.


Ejemplo 6 :
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
/* Suma-cuadrados.
El programa calcula la suma del cuadrado de los elementos de un arreglo
^•unidimensional de 100 elementos de tipo real. */

const int MAX =10;


/* MAX se utiliza para reservar el espacio maximo que podra ocupar el arreglo. */

void Lectura(float *, int); /* Prototipos de funciones. */


double Suma(float *, int);

int main(void)
{
float VEC[MAX];
double RES;
Lectura(VEC, MAX);
RES = Suma(VEC, MAX);
/* Se llama a la funcion Suma y se almacena el resultado en la variable RES. */
printf("\n\nSuma del arreglo: %.21f", RES);
system(" PAUSE");
return 0;
}

void Lectura(float A[], int T)


/* La funcion Lectura se utiliza para leer un arreglo unidimensional de T
^elementos de tipo real. */
{
int I;
for (I=0; I<T; I++)
{
printf("Ingrese el elemento %d: ", I+1);
scanf("%f",&A[I]);
}
}

double Suma(float A[], int T)


/* La funcion Suma se utiliza para calcular la suma del cuadrado de los
*»componentes de un arreglo unidimensional de T elementos de tipo real. */
{
int I;
double AUX = 0.0;
for (I=0; I<T; I++)
AUX += pow(A[I], 2);
return(AUX);
}
TOKENIZER EN C!!!!!!!!!!!!!:
Ejemplo para recibir arreglo de caracteres donde vamos a tokenizar en c y hay que incluir la librería
string.h
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char rollo[]= "Jorge,Gonzalo,Rick,Caro,Isaac";
char *Token;
char *delimitador =",";
//printf("\nRollo ocupa: %d bytes de memria\n", sizeof(rollo));
//printf("\nRollo : %s\n", rollo);

//TOKENIZER
Token= strtok(rollo,",");
printf("\nToken : %s\n", Token);

system("PAUSE");
return 0;

CompromisoS: Comprender el tokenizer y estudiar para el examen de la próxima clase.


Lunes 6 de Octubre de 2008
Anotó: Israel Olvera Lozano

Resumen de la reunión:

Se habló de los avances hasta el momento:

✔ CRC NMEA 0183


Programa que calcula el checksum de una línea NMEA 0183
✔ HAVERSINE + NMEA 0183 TOKENIZER (estático)
Programa que calcula las distancia entre un punto de origen y uno de destino dados por dos
líneas NMEA 0183
También se comentó que faltan otros dos temas muy importantes por ver en C necesarios para
realizar el proyecto:

• Apuntadores
• Manejo de archivos
A corto plazo, lo que se debe hacer para seguir en tiempo con el proyecto es lo siguiente:

• Cambiar los programas que ya hicimos para que funcionen de forma dinámica en
coordinación con un GPS.
• Escribir un programa en C que controle el vehículo

Posteriormente se revisaron las soluciones del examen parcial del jueves anterior. Lo siguiente fue lo
que se aprendió con la revisión:

• En un printf, con %x se despliega un entero en forma hexadecimal.


• En ocasiones es posible que no lleguen CRC´s del GPS si la transmisión se detiene o falla.
Por ello es necesario tener las validaciones necesarias para que el programa no truene o se
cicle esperando algo.
• El hevrsine funciona correctamente aunque los dos puntos no estén en el mismo
“cuadrante”, únicamente haciendo las siguientes consideraciones respecto al signo:
N+ E+
S - W-

EL problema que muchos tuvimos al tratar de unir los dos programas durante el examen, fue que el
GPS manda sus latitudes o longitudes con el siguiente formato:

GGMM.MMMM (Latitud)
GGGMM.MMMM (Longitud)

Una forma de hacerlo es:

1. Convertir el token de longitud o latitud a float con la función atof()


2. Guardar en una variable entera el resultado de dividir el numero que regresó atof() entre 100.
3. Guardar en una variable double el resultado de la resta del numero que regresó atof() menos
el que se guardo en el paso anterior multiplicado por 100.
4. Meter estos valores a la función que ya teníamos considerando segundos igual a 0.

APUNTADORES

• Un apuntador es una variable en C cuyo valor es la dirección de otra variable.


• Para declarar un apuntador se utiliza el *.
• Al inicializar se puedeapuntar algo que ya existe o a algo que está a punto de existir
(memoria dinámica).
• En Cse va creando memoria conforme se va necesitando y destruyendo lo que ya se ocupó.
• Los apuntadores permiten un código más compacto pero un poco más complejo de entender.
• Existe el riesgo de accesar y modificar lugares de memoria RAM o incluso deldisco duro
que pueden afectar a la computadora.

Se checaron los programas 1 y 2 de la carpeta “Apuntadores”.

Compromisos para la siguiente reunión:

Tarea

I. Traer cable USB-Serial

II. Unir todos los programas que tenemos hasta el momento con ciertas modificaciones:

1. CRC
• Comparando el checksum calculado con el de la línea leída.
• Considerando que la línea puede llegar incompleta (para que el programa truene ni se
cicle).
2. HAVERSINE
• Considerando puntos en con diferentes latitudes y/o longitudes.
3. TOKENIZER
• Creando una función que haga la transformación del formato GGMM.MMMM.

Durante la sesión

• Hacer los programas ya acabados de forma dinámica.


• Salir con las lap-top´s y un GPS para checar longitudes y latitudes de distintos puntos y
calcular distancias.
• Interactuar con hardware.
• Checar los programas de Queue estática y Queue dinámica

Jueves 9 de Octubre de 2008


Anotó: Diego Rafael Torres Lafuente

Resumen de la reunión:

• Se habló sobre las dificultades en compilar los programas dejados de tarea.

• Se introdujo el método para brincar las seguridades de el sistema operativo Windows XP


para comunicarse con los puertos de salida de la computadora.

• Comentó Rick que en anteriores versiones del sistema operativo era mucho más sencillo
comunicarse con los puertos, con una simple instruccion en una aplicación en C se podía
comunicar con los puertos serial y paralelo, solamente entregando la dirección y el dato a
transmitir.

• La manera de saltar las seguridades del sistema operativo es hacer que C tome al puerto
paralelo o serial como un archivo (handles y threads), mediante sus sentencias de código
para abrir y manipularlos se puede lograr una comunicación.

• Los GPS – RS232:


• Baud Rate = 4800 bps
• Datos = 8 bits
• Parity = None
• Stop bits = 1

• Para recibir los datos transmitidos por el GPS mediante el puerto serial se usa el programa
Hyper Terminal, al iniciar una sesión hay que agregar una conexión nueva, en donde el
puerto serial si es físico, es decir viene construido en la máquina, será generalmente COM1.

• El trabajo que se deberá hacer con las transmiciones del GPS será hacer que C lea la línea de
código GPRMC, es decir cuando lo detecte concatene todos los caracteres de esa línea para
construirla y luego tokenizarla para aislar la posición del vehículo.

• Vimos la estructura del puerto Serial DB-9, sus líneas de entrada de las cuales las más
importantes son TxD (transmición), RxD (recepción) y GND(tierra), el resto de los pines
eran usados para la comunicación con un módem.

• Los puertos seriales envían voltajes para 0's y 1's lógicos llamados de Mark y Space, es decir
un 0 lógico tiene un voltaje de -15V y un 1 lógico tiene un voltaje de +15V, por lo tanto hace
falta un circuito extra que convierta los 1's y 0's a tal voltaje, este es el MAX232.
/*********************************************
Biblioteca para habilitar comunicación serial.
M.C. Luis Ricardo Salgado Garza.
Interfaces y Equipo Periférico, ITESM, C.MTY.
**********************************************/
#include <stdio.h>
#include <string.h>
#include <conio.h>
#include <windows.h>

DCB oldConfig,newConfig;
DWORD error;

//************************************************************************
HANDLE serini(char *portName, DCB config, COMMTIMEOUTS timeOuts) {
HANDLE hSerial; //"handle" hacia el puerto serial
int state;

//Crea el "handle" para manejar el puerto
hSerial=CreateFile(portName,GENERIC_WRITE | 
GENERIC_READ,0,NULL,OPEN_EXISTING,
  FILE_ATTRIBUTE_NORMAL,NULL);

if (hSerial==INVALID_HANDLE_VALUE){ //Si hay algún error al iniciar la 
configuración
printf("Error en CreateFile\n");// del puerto ==> salir marcando el 
error.
error=GetLastError();
printf("Error %d\n",error);
return(0);
}

state=GetCommState(hSerial,&oldConfig); //Se obtiene la configuracion 
original
if (state==0){ // para al final 
reponerla al terminar.
error=GetLastError();
printf("Error en GetCommState\n");
printf("Error %d\n",error);
return(0);
}

state=GetCommState(hSerial,&newConfig); //obtiene la configuracion
if (state==0){
error=GetLastError(); //para modificarla
printf("Error en GetCommState\n");
printf("Error %d\n",error);
return(0);
}
newConfig.BaudRate=config.BaudRate; //configuracion del puerto 
serial
newConfig.fParity=config.fParity;
newConfig.Parity=config.Parity;
newConfig.ByteSize=config.ByteSize;
newConfig.StopBits=config.StopBits;

state=SetCommState(hSerial,&newConfig); //aplica la nueva configuracion
if (state==0){
error=GetLastError();
printf("Error en SetCommState\n");
printf("Error %d\n",error);
return(0);
}

state=SetCommTimeouts(hSerial,&timeOuts); //aplica los timeouts al puerto
if (state==0){
error=GetLastError();
printf("Error en SetCommTimeouts\n");
printf("Error %d\n",error);
return(0);
}
return(hSerial);
//SERIAL
}
//************************************************************************
void serclose(HANDLE hSerial)
{
int state;
state=SetCommState(hSerial,&oldConfig); //aplica la configuracion 
original
if (state==0){
error=GetLastError();
printf("Error en SetCommState(oldConfig)\n");
printf("Error %d\n",error);
}
CloseHandle(hSerial); //cierra el FILE, el handle
}
//************************************************************************
void limpia_buff(unsigned char * buffer,int longitud)
{
int x;
for (x=0;x<longitud;x++) //limpia el buffer
buffer[x]='\0';
}
//************************************************************************
void sndserial(HANDLE hSerial,unsigned char * buffer,unsigned long longitud)
{
int state;
unsigned long totalWritten;
state=WriteFile(hSerial,(char *)buffer,1,&totalWritten,NULL);
state=WriteFile(hSerial,(char *)buffer+1,longitud­1,&totalWritten,NULL);
// state=WriteFile(hSerial,(char *)buffer,longitud,&totalWritten,NULL);
if (state==0){
error=GetLastError();
printf("Error en WriteFile\n");
printf("Error %d\n",error);
}
}
//************************************************************************
unsigned long rcvserial(HANDLE hSerial,unsigned char * buffer,int longitud)
{
int state;
unsigned long totalRead;
state=ReadFile(hSerial,(char *)buffer,longitud,&totalRead,NULL);
if (state==0){
error=GetLastError();
printf("Error en ReadFile\n");
printf("Error %d\n",error);
}
return totalRead;
}

• Este fue el programa de habilitación del puerto serial desde Windows XP, a continuación se
presenta el programa que lee la información enviada por el GPS usando el código anterior
como una clase en ANSI C.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
#include "serial.c"

char portName[]="COM1";
HANDLE pSerial;
DCB config;
COMMTIMEOUTS touts;

unsigned char datosTsm[]={0x0D};
unsigned char datosRcv[100];
int contadorRcv=0;

int main() {
char chr=0;
int i;

config.BaudRate=CBR_9600; //Configuracion del puerto 
serial
config.fParity=FALSE;
config.Parity=NOPARITY;
config.ByteSize=8;
config.StopBits=ONESTOPBIT;

touts.ReadIntervalTimeout=0; //Tiempo entre char y char en ms
touts.ReadTotalTimeoutMultiplier=0;
touts.ReadTotalTimeoutConstant=100; //Tiempo const. (maximo) de recibir en 
ms
touts.WriteTotalTimeoutMultiplier=0;
touts.WriteTotalTimeoutConstant=100;//Tiempo const. (maximo) de enviar en 
ms

    if (pSerial=serini(portName, config, touts)) {
        while(chr!=27) {
if (chr==13)
sndserial(pSerial,datosTsm,1);
chr=0;
if (!(kbhit())) {
contadorRcv=rcvserial(pSerial,datosRcv,1);
if (contadorRcv!=0) {
printf("%d bytes: ",contadorRcv);
for (i=0;i<contadorRcv;i++) {
printf("%02x ",datosRcv[i]);
}
printf("\n");
}
} else
chr=getch();
}
printf("FIN!!!");
serclose(pSerial);
    } else {
        printf("Oops!");
    }
    system("PAUSE");
    return 0;
}

• Se modificó el programa anterior para que lea desde el puerto serial y lo despliegue de igual
forma que el Hyperterminal.

Compromisos para la siguiente reunión:

Tarea

1. Integrar los programas de ANSI C para que despliegue solo la longitud y latitud basados
en la información entregada por el GPS.
Lunes 13 de Octubre de 2008
Anotó: Omar Mejía Arnaud

Resumen de la reunión:

• Se mostró el material disponible en el laboratorio (GPS, cables).


• Se revisó el programa para la transferencia serial de la información del GPS a la
computadora. El programa es el siguiente y fue aportado por Lupita:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <cstring>
#include <iostream>
#include <windows.h>
#include "serial.c"
#include <math.h>
#include <conio.h>
#include <time.h>
using namespace std;

char portName[]="COM5";
HANDLE pSerial;
DCB config;
COMMTIMEOUTS touts;

unsigned char datosTsm[]={0x0D};


unsigned char datosRcv[100];
int contadorRcv=0;

const double pi = 3.14159265358979323846;

//Variables para el control del checksum


string checksum;
int checkAux;
char *cuadLat;
char *cuadLon;
char Header[6];
char lugar[100];

//Seccion de prototipos de funciones y procedimientos


string hexadecimal(int valor);
int cuentaTokens(char *, char*);
char *Tokenizer(char *, char *, int);
int calcChecksum(char *, char *);
double GradosDecimales(float grados,float min,float seg);

string hexadecimal(int valor){ //funcion para obtener el checksum en hexadecimal


int aux = valor;
int residuo = 0;
string str = "";
string suma = ""; //apuntador que guardara el checksum en formato hexadecimal

while(aux>0){
residuo = aux%16; //para obtener residuo
aux = aux/16;

switch(residuo){ //dependera del residuo para hacer una u otra opcion


//el valor correspondiete al residuo se copia en un arreglo
//lo que ya tenga en suma se le concatenara al arreglo
//lo que hay en el arreglo se manda a suma
case 0: str = "0"; suma = str + suma; break;
case 1: str = "1"; suma = str + suma; break;
case 2: str = "2"; suma = str + suma; break;
case 3: str = "3"; suma = str + suma; break;
case 4: str = "4"; suma = str + suma; break;
case 5: str = "5"; suma = str + suma; break;
case 6: str = "6"; suma = str + suma; break;
case 7: str = "7"; suma = str + suma; break;
case 8: str = "8"; suma = str + suma; break;
case 9: str = "9"; suma = str + suma; break;
case 10: str = "A"; suma = str + suma; break;
case 11: str = "B"; suma = str + suma; break;
case 12: str = "C"; suma = str + suma; break;
case 13: str = "D"; suma = str + suma; break;
case 14: str = "E"; suma = str + suma; break;
case 15: str = "F"; suma = str + suma; break;

}
}
return suma;//regresa el hexadecimal
}

//Funcion que convierte de grados, minutos, segundos a grados decimales


double GradosDecimales(float grados,float min,float seg){
return(grados + (min / 60) + (seg / 3600));
} //Final de la funcion GradosDecimales

//calcular el checksum
int calcChecksum(char *texto, char *del){

int cont = 0;
int sum = 0;
char *tok;
tok = strtok(texto,del); //tokenizamos la oracion del GPS tomando la coma como
delimitador

while(tok != NULL){ //mientras haya mas tokens entrara al ciclo


if( strchr(tok,'*') != NULL ){ //si el token contiene un * significa que este es el ultimo
token
char *tokenFin1; //se crea un apuntador para manejar la primer parte del ultimo
token
tokenFin1 = strtok(tok, "*"); //se le asigna la primera parte del ultimo token, lo que
esta antes del asterisco
//para tomarlo en cuenta para el xor.
checksum = strtok(NULL, "*"); // la segunda parte del token se asigna a
cheksum1(lo q esta despues del asterisco)
int k;
for (k = 0; k<strlen(tokenFin1); k++){//recorre el token que llame
sum = (sum^tok[k]); // realizo el xor de cada elemento del token
}
}else{
int k;
for (k = 0; k<strlen(tok); k++){ //recorro el token que llame
sum = (sum^tok[k]); //realizo el xor de cada elemento del token
}
sum = (sum^','); //se toman en cuenta las comas
}
tok = strtok(NULL,","); //Se llama el siguente token
cont++;
if(cont==4){
cuadLat = tok;
} else if(cont==6){
cuadLon = tok;
}
}
return sum; //regresa el checksum en valor decimal
}

//Funcion que regresa el numero de Token deseado, sino existe


//regresa un NULL
char *Tokenizer(char *texto, char *delimitador, int pos){
char *tok;
int cont = 0;

tok = strtok(texto,delimitador);
while(tok != NULL && cont < pos){ //mientras el token sea diferente de nulo
tok = strtok(NULL,delimitador); //Para obtener el símbolo siguiente en la cadena
original
cont++;
}
return tok;
}

int cuentaTokens(char *texto, char *del){


char *tok;
int cont = 0;
tok = strtok(texto,del);
while (tok != NULL && cont < 3){
if(cont == 1 || cont == 2){
int igual = strcmp(tok,"V");
if(igual==0){
return 0;
}
}
tok = strtok(NULL,del);
cont++;
}
return 1;
}
int main() {
char chr=0;
int i;

config.BaudRate=CBR_4800; //Configuracion del puerto serial


config.fParity=FALSE;
config.Parity=NOPARITY;
config.ByteSize=8;
config.StopBits=ONESTOPBIT;

touts.ReadIntervalTimeout=0; //Tiempo entre char y char en ms


touts.ReadTotalTimeoutMultiplier=0;
touts.ReadTotalTimeoutConstant=100; //Tiempo const. (maximo) de recibir en
ms
touts.WriteTotalTimeoutMultiplier=0;
touts.WriteTotalTimeoutConstant=100;//Tiempo const. (maximo) de enviar en ms

if (pSerial=serini(portName, config, touts)) {


while(chr!=27) {
chr=0;
if (!(kbhit())) {
contadorRcv=rcvserial(pSerial,datosRcv,1);
if (contadorRcv!=0) {
if (datosRcv[0] == '$'){

i = 0;
do{
Header[i] = datosRcv[0];
i++;
contadorRcv=rcvserial(pSerial,datosRcv,1);
}while((i<=5)&&(contadorRcv!=0));

int igual = strcmp(Header, "$GPRMC");

if(igual==0){
strcpy(lugar,Header);
while((lugar[i++]=datosRcv[0])!=10){
contadorRcv = rcvserial(pSerial,datosRcv,1);
}

printf("%s", lugar);
char *token;
char *delimitador = ",";
char *delimitador2 = "$,";
int numtoken;

// crear respaldos
char respaldo[strlen(lugar)]; //respaldo para distancia y angul0
char respCheck[strlen(lugar)]; //respaldo para checksum
char respContTokens[strlen(lugar)];//respaldo para verificar mensaje valido

//Coordenadas del punto 1


double lat;
double lon;

float grados,min,seg;
//se crea la copia de respaldo
strcpy (respContTokens,lugar);
//se verifica si los mensaje son válidos
if(cuentaTokens(respContTokens,delimitador2)){

//se crea la copia de los respaldos


strcpy (respCheck,lugar);

//Se implementa el metodo de calcular el checksum en decimal


checkAux=calcChecksum(respCheck,delimitador2);//punto 1

string checkTmp;
checkTmp = "";
checkTmp = hexadecimal(checkAux);
if(checkTmp.length()==1){
checkTmp = "0"+checkTmp;
}
//modificar para checksum
if(checksum.compare(checkTmp)==0){
//se hace la copia de los puntos al respaldo
strcpy (respaldo,lugar);

lat = atof(Tokenizer(respaldo,delimitador,3));
grados = (int)(lat / 100); min = (lat - (grados * 100)); seg = 0.0;
lat = GradosDecimales(grados,min,seg);

if(strcmp(cuadLat,"S")==0){
lat*=(-1.0);
}

//Nota: De momento este programa considera que ambas latitudes son


N
// y ambas longitudes son W !!!!!
lon = atof(Tokenizer(lugar,delimitador,5));
grados = (int)(lon / 100); min = (lon - (grados * 100)); seg = 0.0;
lon = GradosDecimales(grados,min,seg);

if(strcmp(cuadLon,"W")==0){
lon*=(-1.0);
}

printf("\nLat = %f ", lat);


printf("Lon = %f \n\n", lon);
}else{
cout << "\nError en el checksum. " << endl;
cout << "Calculada: " << checkTmp << " Recibida: " << checksum <<
endl;
printf("\n\n");
//se comprueba si el checksum 1 obtenido y el de la cadena concuerdan
}
//serraria la validacion para el checksum
}else{
printf("\nHay error en la informacion dada. Imposible realizar
calculos\n\n");
}
}
}
}
} else
chr=getch();
}
printf("FIN!!!");
serclose(pSerial);
} else {
printf("Oops!");
}
system("PAUSE");
return 0;
}

• Se salió un momento del laboratorio para probar con recepción en el GPS


• Se comprobó que el programa funciona, se utilizó otro GPS para
corroborar los datos enviados por el programa
• Se explico el algoritmo para sacar el GPRMC del los datos enviados por el
GPS; Se lee un carácter del puerto serial, se checaba si el carácter era un
signo “$”. Después se leen 5 caracteres siguientes pasándolo a una
variable auxiliar. Esa se comparaba con un GPRMC al ser igual se leen los
caracteres hasta encontrar un “*” guardándose en otra variable, los
siguientes dos caracteres del “*” se guardaban como checksum
directamente del puerto serial. Se hacían las validaciones necesarias al
checksum. Tras esto se usaba el tokenizer para extraer el lugar y después
desplegarlo.
• Se planteo el problema de la falta de conexión y que se cicle el programa
Tarea:
• Pensar cómo hacer para saber si esta ciclado
• Dejar terminado el programa
• Se verá cómo hacer la comunicación inalámbrica
Jueves 16 de Octubre de 2008
Anotó: Emmanuel Chio

Resumen de la reunión:

PC /lap tokenizer,
crc checker,
aislar “$GPRMC…”
validacion.

GPS
CHEQUEO D

EL FUNCIONAMIENTO DEL PROGRAMA EN LAS AFUERAS DEL EDIFICIO DEL CIE

RADIO-MODEM GPS ROVER


Telecomunicaciones Interfaz
RS232 serial

INTERFAZ
Serial

Lunes 20 de Octubre de 2008


Anoto: José Luis Loyola Larrondo

Resumen de la reunión:
• Analizamos la presentación “Alternativas de diseño del Mars Rover”

– El vehículo debe ser de tipo “Off-Road” debido a las características del terreno.
– El vehículo debe tener un motor eléctrico ya que en Marte no se puede estar
recargando de nitro metano.
– Kits, Prebuilt, o RTR
– Tipos de control:
A) 2-Stick Radios
B) Pistol-Grip Radios
- Motor Servo: son motores que se ajustan a cierto ángulo sin seguir girando.
- Frecuencia para vehículos terrestres 75 MHz.
- Cristales: AM, FM, PCM.
A) AM: Se crean ondas senoidales a determinada frecuencia y se ajustan las
amplitudes en una frecuencia fija.
B) FM: Se crean ondas senoidales a determinada amplitud y se ajustan las
frecuencias en una amplitud fija.
C) PCM: La señal que se manda son pulsos cuadrados, es la señal más exacta ya
que es digital.
Compromisos para la siguiente reunión:
• Resumen de Radio Modems.

Jueves 23 de Octubre de 2008


Anotó: Roberto Sierra Alvarez

Resumen de la reunión:
• Se plantearon los objetivos de la reunión
○ Demo del servo
○ Puerto Paralelo
• Puerto Paralelo
○ Características del control remoto
• Tres cables. Uno es el centro, otro la derecha y otro la izquierda.
Igualmente se tienen tres para ir adelante o atrás.
○ Tarjetas impresas
• Son necesarias para controlar las señales del control remoto y
conectar después al puerto paralelo
• Programación de GAL en VHDL
○ Servirá para traducir los comandos que mande el puerto paralelo.
○ También para validar que no se manden comandos izquierda-derecha o
adelante-abajo para evitar quemar el control remoto.
• Programa en C para controlar el Rover
○ Teclas que se van a usar (sólo se aprieta una vez)
• Q – adelante e izquierda
• W – adelante
• E – adelante y derecha
• A – izquierda (no mueve el vehículo)
• S – stop (y se centra la dirección)
• D – derecha (no mueve el vehículo)
• Z – atrás e izquierda
• X – atrás
• C – atrás y derecha
• Notas
1. Los comandos no se van acumulando, al apretar una tecla, el
comando anterior se olvida
2. Hay que validar en el programa el cambio entre cruces (W a
X, Q a Z, E a C). Cuando pase esto, hay que pasar por S.
• Demostración Servo
○ Tres líneas de control, una 5V, GND y control.
○ A la línea de control entran pulsos que determinan el ángulo al cual gira el
servo (Duty Cycle)
○ Duty Cycle – duración del pulso/tiempo entre pulsos *100

Compromisos para la siguiente reunión:


• Escribir programa en C que pueda controlar al vehículo mediante el puerto
paralelo. (Ver Notas)