Bitácora
Bitácora
Bitácora
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.
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.
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.
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
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.
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
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)
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.
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.
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).
*20 checksum
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.
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 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 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.
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ó:
#include <iostream.h>
#include <stdlib.h>
#include <math.h>
#include <stdio.h>
#define pi = 3.141559
//Algotirmo Haversin
dlon = lon2 - lon1;
dlat = lat2 - lat1;
int main(void)
{
double distancia; //valor de la distancia entre dos puntos
Resumen de la reunión:
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:
Lat20.58619
Long100.378122
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.
MEMORIA (RAM)
int
Hicimos varios documentos dentro de C con la finalidad de hacer distintos Test para leer memorias
1er programa
system(“PAUSE”);
return (0);
}
2do programa
system(“PAUSE”);
return (0);
}
3er programa
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);
}
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,) .
-Tratar de ver los ejemplos (el que recibe oraciones y los tokeniza –el tokenizer-)
Resumen de la reunión:
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;
}
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;
}
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. */
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 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>
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;
}
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:
-Tokenizer
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;
}
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;
}
//TOKENIZER
Token= strtok(rollo,",");
printf("\nToken : %s\n", Token);
system("PAUSE");
return 0;
Resumen de la reunión:
• 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:
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)
APUNTADORES
Tarea
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
Resumen de la reunión:
• 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.
• 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,longitud1,&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.
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:
#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;
while(aux>0){
residuo = aux%16; //para obtener residuo
aux = aux/16;
}
}
return suma;//regresa el hexadecimal
}
//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
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;
}
i = 0;
do{
Header[i] = datosRcv[0];
i++;
contadorRcv=rcvserial(pSerial,datosRcv,1);
}while((i<=5)&&(contadorRcv!=0));
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
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)){
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);
}
if(strcmp(cuadLon,"W")==0){
lon*=(-1.0);
}
Resumen de la reunión:
PC /lap tokenizer,
crc checker,
aislar “$GPRMC…”
validacion.
GPS
CHEQUEO D
INTERFAZ
Serial
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.
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