0% encontró este documento útil (0 votos)
58 vistas39 páginas

PI3 Informe Final

Este documento presenta el informe final del proyecto CanSat de la Universidad UTEC. El CanSat es un microsatélite de bajo costo diseñado para monitorear la tala ilegal de madera en la Amazonía peruana mediante el uso de una cámara y sensores meteorológicos. El documento describe la estructura mecánica del CanSat, incluidos los diferentes niveles internos y la carcasa exterior, y los subsistemas como el módulo GPS, cámara, sensores y paracaídas. El objetivo general es desar
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
58 vistas39 páginas

PI3 Informe Final

Este documento presenta el informe final del proyecto CanSat de la Universidad UTEC. El CanSat es un microsatélite de bajo costo diseñado para monitorear la tala ilegal de madera en la Amazonía peruana mediante el uso de una cámara y sensores meteorológicos. El documento describe la estructura mecánica del CanSat, incluidos los diferentes niveles internos y la carcasa exterior, y los subsistemas como el módulo GPS, cámara, sensores y paracaídas. El objetivo general es desar
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
Está en la página 1/ 39

Informe Final de PI3: CanSat

Marcelo Contreras Cabrera1 , Walter Dı́az Ysla 1 , Mauricio Bernuy Geiser2 , Edward López
Tarazona1 , Avlaro Palero Ramı́rez1 y Marko Puchuri López1

1
Universidad UTEC. Facultad de Ingenierı́a. Ingenierı́a Mecatrónica
2
Universidad UTEC. Facultad de Ingenierı́a. Ciencias de la computación

Resumen

Palabras clave: Microsatélite, Arduino, Sensores, Amazonı́a Peruana, Estación meteorológica

1. Introducción
El Perú tiene aproximadamente 74 millones de hectáreas con bosques [1] donde la mayor parte son bosques
tropicales que se encuentran en la Amazonia Peruana [2]. Estos bosques son aprovechados frecuentemente para
la extracción de madera [3]. Para la mayorı́a de las familias que habitan en las zonas rurales de la Amazonia
Peruana, la venta de madera es un ingreso importante para ellos [4]. El OSINFOR (Organismo de supervisión
de los Recursos Forestales y de Fauna Silvestre) menciona que el Perú enfrenta muchos desafı́os entre las cuales
se encuentra la tala y el tráfico ilegal de la madera [5]. Por ello, el Estado peruano ha fijado este problema como
una medida urgente la cual se debe de afrontar. De por sı́, existen diferentes soluciones para poder luchar contra
esta problemática como el monitoreo constante y localización de los puntos donde la tala este más concentrado.
La solución propuesta en este trabajo es usar un microsatélite de bajo costo y fácil de operar para poder
realizar dicha función mediante una cámara, además, de cumplir con la función de una estación meteorológica.
Este dispositivo es lanzado con un globo de helio hacia el exterior la cual le ayuda a conseguir una altura y
amplia vista para el monitoreo. Asimismo, el globo de helio le da cualidad de pasar desapercibido lo cual evita
sospechas de los traficantes. Este proyecto tiene una escalabilidad amplia y también se puede enfocar no solo en
el tráfico ilegal de madera sino en la minerı́a ilegal, incendios forestales, caza de animales en peligro de extinción,
narcotráfico y entre otros sectores donde se requiera el monitoreo aéreo.

2. Estructura mecánica del Cansat


En cuanto al diseño de la estructura mecánica, se hizo uso del programa de modelado paramétrico de sólidos
en 3D: Autodesk Inventor. Los diseños fueron posteriormente impresos en 3D. El proceso de diseño y creación
de la parte mecánica partió de bocetos e ideas que derivaron a un modelo preliminar. La estructura se puede
dividir en 2 partes: La estructura interior y la estructura exterior.

1
2.1. Estructura interior

Figura 1: Vista superior izquierda del ensamblaje de la estructura interior del CanSat.

La estructura interior tiene la función primordial de sostener, fijar y vincular mecánicamente los diferentes
componentes electrónicos y electromecánicos del CanSat. Para ello, se ha proyectado un sistema integrado
por niveles sencillo de montar y desmontar, estos niveles se unen mediante columnas que son posteriormente
asegurados por compresión. Estos niveles son:

El 1er nivel o piso de la cámara.

El 2do nivel o piso de sensores y baterı́a.


El 3er nivel o pisos de PCBs.
El 4to nivel o piso del paracaı́das.

2.1.1. 1er nivel (Cámara)

Figura 2: Vista isométrica del nivel 1.

El primer nivel es la pieza en la que se sitúa la cámara junto a su propio PCB. Posee una abertura inferior
para la salida del objetivo de la cámara. Tiene una hendidura adaptada a las dimensiones de la cámara OV7670,
de la misma manera que los agujeros para su atornillado en la estructura. Posee la altura suficiente para el encaje
del PCB, el arduino mini y la cámara. La estructura posee 4 columnas huecas cuyo patrón se repetirá en los
pisos siguientes. En este piso, las columnas poseen un agujero transversal en la base, las cuales sirven para
asegurar la barra que se incrustará a lo largo de todas las columnas huecas de los distintos niveles.

2
2.1.2. 2do nivel (Sensores y baterı́a)

Figura 3: Vista frontal superior del nivel 2.

El segundo nivel es la pieza que agrupa a todos los sensores del CanSat (excluyendo la cámara) junto a
la baterı́a. El espacio se ha optimizado para que todos estos componentes puedan ajustarse sin problemas.
Tomando como referencia la Figura 3, la parte derecha de la mitad más próxima a la pantalla (o documento)
corresponde al sensor de CO2 (módulo MQ-7), el cual es atornillado en la cara externa; mientras que la parte
izquierda corresponde al sensor de humedad y temperatura digital (módulo DHT11) tambien atornillado en la
cara exterior. En cuanto a la mitad más alejada de la pantalla (o documento), la parte izquierda corresponde
al sensor de calidad de aire (módulo MQ-135) atornillado en la cara externa; y la parte derecha corresponde
al sensor de presión, temperatura y humedad (módulo BME280) atornillado en la cara interna, dado que es
importante proteger el pequeño orificio del sensor de la obstrucción y tambien con el fin de medir la temperatura
interna del CanSat. El diseño del nivel 2 tambien considera la inserción de la baterı́a, por lo que tiene una pequeña
base de soporte en la mitad de la estructura.

2.1.3. 3er nivel (PCBs)

Figura 4: Vista isométrica del nivel 3.

El tercer nivel corresponde al espacio designado para la colocación de los PCBs, en los que se colocarán la
electrónica principal del CanSat. Dos de las columnas han sido parcialmente cortadas para optimizar el área
útil del PCB. Posee 4 agujeros en la base para atornillar el PCB. La base de esta estructura es hueca, esto por
la necesidad de interconexion de los PCBs y sensores mediante cables. Se debe mencionar que el 4to nivel se
puede duplicar o triplicar en caso se necesite más espacio para la electrónica del CanSat.

3
2.1.4. 4to nivel (Paracaı́das)

Figura 5: Vista frontal superior del nivel 4.

El 4to nivel es la estructura concerniente al paracaı́das del CanSat. Está conformado por dos piezas: La
estructura principal y la tapa del paracaı́das. Esta estructura se ha pensado para que pueda contener tanto al
servomotor de giro continuo, como al paracaı́das. Tiene un pequeño recipiente donde el paracaı́das irá plegado. Al
centro de la pieza, dentro del recipiente, hay un pequeño gancho del cual se amarrarán los hilos del paracaı́das. La
estructura tambien posee otros ganchos en la parte interna superior del recipiente; en esos ganchos se amarrarán
las ligas que, una vez abierta la tapa, impulsarán al paracaı́das a salir del recipiente.

Figura 6: Vista frontal superior de la tapa del paracaı́das.

La tapa es la estructura que evita la eyección del paracaı́das antes de tiempo. La tapa tiene un eje que
funciona como una bisagra, este eje se acopla por presión en la estructura principal del paracaı́das. La tapa
tiene tambien un gancho de seguro que evita que se abra; este gancho es asegurado mediante un hilo cotrolado
por el servomotor. La tapa tambien tiene un sistema que asegura que una vez que se haya abierto, permanezca
de ese modo gracias a un gancho cerca del eje; a ese gancho se le amarra una liga cuyo segundo extremo se
amarra al gancho de la base de la estructura principal del paracaı́das; este mecanismo hace que la liga ejerza
un torque constante a favor de la abertura de la tapa.

2.2. Estructura exterior


La estructura exterior, tambien conocida como carcasa, fue diseñada con el objetivo de proteger los com-
ponentes.Está divida en dos secciones laterales, siendo cortado longitudinalmente. Además cuenta con orificios
que permiten a los sensores MQ-7, DHT11 y MQ-135 tener contacto con el exterior. Para el caso de la cámara,
se busca que el lente no sobresalga, debido a que en caso contrario podrı́a dañarse por el aterrizaje. En la parte
superior se cubre el servomotor y se deja una espacio para que la tapa del paracaı́das cumpla su función. El

4
sistema de cierre consiste en atornillar los cuatro extremos sobresalientes que cuentan con un orificio roscado,
donde pasaron los tornillos.

Figura 7: Carcasa del CanSat

3. Subsistemas del CanSat


En esta sección, se va a explicar los sensores que se han implementado en el CanSat. Estos dispositivos
tienen la función de reportar los parámetros deseados para este estudio la cuales se analizarán por un tercero.

3.1. Módulo GPS


El módulo GPS escogido es el NEO-M8N-0-01 Ublox. Este módulo GPS ofrece un alto rendimiento también
con bajos niveles de consumo de energı́a [6]. También, este puede rastrear hasta 22 satélites en 50 canales y
alcanza el nivel más alto de sensibilidad de la industria . Asimismo, el NEO-M8N-0-01 Ublox viene equipado en
el PCB, una EEPROM con configuración de fábrica, una pila de botón para mantener los datos de configuración
en la memoria EEPROM, un indicador LED y una antena cerámica. Estos dispositivos le dan caracterı́sticas
particulares:
La antena de cerámica proporciona una señal muy fuerte.

La velocidad en baudios predeterminada: 9600.


Cuenta con una baterı́a de respaldo de datos.
La EEPROM guarda los datos de los parámetros de configuración cuando se apaga.
Detección y eliminación de CW activa anti-jamming.

Filtro de paso de banda SAW adicional a bordo.


En la siguiente figura se muestra el esquemático del módulo GPS implementado en el Arduino Uno.

5
Figura 8: Esquemático del Modulo GPS NEO-M8N-0-01 Ublox

El código desarrollado para el módulo GPS no se ha usado la librerı́a que interpreta por completo la infor-
macion de la trama de datos. Por lo cual, los datos que recibimos en nuestro módulo GPS siguen el protocolo
NMEA (National Marine Electronics Asociation). La sentencia que se uso en este proyecto es ”$GPRMC”, la cual
tiene la siguiente estructura:”$GPRMC,044235.000,A,4322.0289,N,00824.5210,W,0.39,65.46,020615,,,A*44”. Si
analizamos la trama mostrada se determinar las siguientes variables según el protocolo NMEA:
044235.000 representa la hora GMT (04:42:35)
A” es la indicación de que el dato de posición está fijado y es correcto. “V” serı́a no válido
4322.0289 representa la longitud (43º 22.0289´)
N representa el Norte
00824.5210 representa la latitud (8º 24.5210´)
W representa el Oeste
0.39 representa la velocidad en nudos
65.46 representa la orientación en grados
020615 representa la fecha (2 de Junio del 2015)
Ya explicado la trama, el código que se implemento es el siguiente:

1 #include <SoftwareSerial.h>
2 SoftwareSerial gps(4,3);
3 char dato=' ';
4 void setup()
5 {
6 Serial.begin(115200);
7 gps.begin(9600);
8 }
9 void loop()
10 {
11 if(gps.available())
12 {
13 dato=gps.read();
14 Serial.print(dato);
15 }
16 }

6
3.2. Telemetrı́a variada
3.2.1. Presión, temperatura y humedad
Para estos parámetros se utilizaron dos sensores: El sensor DHT11 y el sensor BME280. Primero, el sensor
DHT11 tiene como función medir la temperatura y humedad del exterior para poder hacer un estudio del
ambiente donde se encuentra sobrevolando el CanSat. Este dispositivo utiliza un sensor de humedad capacitivo
y un termistor para medir el aire circundante, y entrega una señal digital en el pin de datos [7]. Las caracterı́sticas
técnicas de este sensor son :
Se alimenta con un voltaje de 3.5V a 5V.

Consume 2.5mA.
La señal de salida es Digital.
La medición de temperatura tiene un rango de 0°C a 50°C y una precisión de 25°C± 2°C.

La medición de humedad tiene un rango de 20 %RH a 90 %RH y una precisión entre 0°C a 50°C ± 5 %
RH.
Por ello, fue escogido debido a que es un sensor digital por lo cual está más protegido frente al ruido y a la
baja potencia que consumec[7]. Asimismo, fue elegido debido a su bajo costo y su simplicidad al momento de
realizar la programación y las conexiones de pines. En la siguiente figura se muestra el esquemático de este
sensor usando el Arduino uno.

Figura 9: Esquemático del DHT11

En la sección de programación [7], la trama de datos es de 40 bits correspondiente a la humedad y tem-


peratura. Los primeros 8 bits son la parte entera de la humedad y el siguiente grupo de 8 bits es la parte
decimal de la humedad. El tercer grupo y cuarto grupo de 8 bits es la parte entera y decimal de la temperatura,
respectivamente. El último grupo de 8 bits son los bits de paridad que son usados para confirmar que no hay
datos corruptos. Estos bits de paridad lo único que hacen es asegurarnos de que la trama datos entregados sea
la correcta. Esto se comprueba sumando los 4 primero grupos de 8-bit, esta suma debe ser igual a los bits de
paridad. Sin embargo, existe una librerı́a llamada DHT que analiza esta trama y lo muestra como entero. El
código usado en esta ocasión es la siguiente:

1 // Incluimos librerı́a
2 #include <DHT.h>
3 // Definimos el pin digital donde se conecta el sensor
4 #define DHTPIN 8
5 // Dependiendo del tipo de sensor
6 #define DHTTYPE DHT11
7 // Inicializamos el sensor DHT11
8 DHT dht(DHTPIN, DHTTYPE);
9 void setup() {
10 // Inicializamos comunicación serie
11 Serial.begin(9600);
12 // Comenzamos el sensor DHT

7
13 dht.begin();
14 }
15 void loop() {
16 // Esperamos 5 segundos entre medidas
17 delay(5000);
18 // Leemos la humedad relativa
19 float h = dht.readHumidity();
20 // Leemos la temperatura en grados centı́grados (por defecto)
21 float t = dht.readTemperature();
22 // Leemos la temperatura en grados Fahreheit
23 float f = dht.readTemperature(true);
24 // Comprobamos si ha habido algún error en la lectura
25 if (isnan(h) || isnan(t) || isnan(f)) {
26 Serial.println("Error obteniendo los datos del sensor DHT11");
27 return;
28 }
29 // Calcular el ı́ndice de calor en Fahreheit
30 float hif = dht.computeHeatIndex(f, h);
31 // Calcular el ı́ndice de calor en grados centı́grados
32 float hic = dht.computeHeatIndex(t, h, false);
33 Serial.print("Humedad: ");
34 Serial.print(h);
35 Serial.print(" %\t");
36 Serial.print("Temperatura: ");
37 Serial.print(t);
38 Serial.print(" *C ");
39 Serial.print(f);
40 Serial.print(" *F\t");
41 Serial.print("Índice de calor: ");
42 Serial.print(hic);
43 Serial.print(" *C ");
44 Serial.print(hif);
45 Serial.println(" *F");
46 }

Segundo, el sensor BME280 tiene como función medir la temperatura, humedad y presión interna del CanSat.
Esto se puede usar como modo de precaución por si se ocasiona un corto circuito y analizar el interior del Cansat.
También, para comprobar los valores de la temperatura y humedad del exterior. Este sensor mide la presión
barométrica, la temperatura y la humedad. Debido a que la presión cambia con la altitud, también puede
estimar la altitud sobre el nivel del mar [8]. Este dispositivo combina termómetro, barómetro e higrómetro en
un único dispositivo que podemos emplear junto a un procesador como Arduino. Las caracterı́sticas técnicas de
este sensor son:
El rango de temperatura es de -40 a + 85 °C con una precisión de ±1 °C y resolución 0,01 °C.
El rango para la presión es de 300-1100 hPa, precisión de ±1 Pa, y resolución de 0,18 Pa.

El rango de la humedad relativa es de 0 %RH a 100 %RH.


Consume 2.7 µA para mediciones a 1Hz.
El BME280 incorpora comunicación I2C y SPI, por lo que es muy sencillo conectarlo a un procesador
como Arduino.

Asimismo, este sensor es el indicado debido a su bajo costo y el tamaño diminuto que posee lo cual ayuda a
optimizar el espacio dentro del CanSat. En la siguiente imagen se muestra el esquemático de este sensor usando
Arduino Uno usando comunicación I2C.

8
Figura 10: Esquemático del BME280

Para la sección de programación se usaron librerion que facilitaron la interpretaciond de los datos del sensor.
Estas librerias son .Adafruit Sensor .Adafruit BME280 ”. El código usado es el siguiente:
2

1 #include <Wire.h>
2 #include <Adafruit_Sensor.h>
3 #include <Adafruit_BME280.h>
4 #define SEALEVELPRESSURE_HPA (1013.25)
5 Adafruit_BME280 bme;
6 void setup() {
7 Serial.begin(9600);
8 if (!bme.begin(0x76)) {
9 Serial.println("Could not find a valid BME280 sensor, check wiring!");
10 while (1);
11 }
12 }
13 void loop() {
14 Serial.print("Temperature = ");
15 Serial.print(bme.readTemperature());
16 Serial.println("*C");
17 Serial.print("Pressure = ");
18 Serial.print(bme.readPressure() / 100.0F);
19 Serial.println("hPa");
20 Serial.print("Approx. Altitude = ");
21 Serial.print(bme.readAltitude(SEALEVELPRESSURE_HPA));
22 Serial.println("m");
23 Serial.print("Humidity = ");
24 Serial.print(bme.readHumidity());
25 Serial.println("%");
26 Serial.println();
27 delay(5000);
28 }

9
3.2.2. Calidad de aire
El sensor de aire es un sensor determinante en la detección de contaminación en el medio ambiente, que es
lo que principalmente encontramos en lo que es la tala ilegal de árboles. Los componentes tóxicos que pueden
encontrar pueden ser detectados por este sensor y enviar una señal a la estación terrena. Claramente al ser
una señal digital permite una salida de 0 u 1, donde 1 representa la contaminación del entorno. Precisar que se
pueden encontrar para gases especı́ficos como el Amoniaco, sulfuro y benceno. Sin embargo, para hacer estas
pruebas se requiere de la calibración del sensor hacia el gas en especı́fico, que no se ha podido establecer en
este código. En este código se detecta cualquiera de los gases mencionados anteriormente sin mencionar su
concentración dentro del ambiente.

Figura 11: Esquemático del MQ135

int pin_mq = 2;

void setup() {
Serial.begin(9600);
pinMode(pin_mq, INPUT);
}

void loop() {

boolean mq_estado = digitalRead(pin_mq);//Leemos el sensor


if(mq_estado) //si la salida del sensor es 1
{
Serial.println("Sin Contaminacion");
}
else //si la salida del sensor es 0
{
Serial.println("Ambiente contaminado");
}
delay(100);
}

Algunas caracterı́sticas de este sensor para tener en consideración para una futura implementación, sea para
una implementación analógica o digital son.
Voltaje de alimentación 5V.
Potencia de consumo 800mW.
Detección de partes por millón: 10ppm-1000ppm.
Rango de temperatura para operar: -20°C-70°C

3.2.3. Acelerómetro
El sensor escogido para detectar la aceleración del dispositivo es el MPU6050 que tiene como caracterı́stica
no ser únicamente un acelerómetro sino también un giroscopio. El MPU6050 es un IMU (Inertial Measurment

10
Units) que tiene 6 grados de libertad repartidos equitativamente entre el acelerómetro y el giroscopio. El uso
de este sensor en este proyecto ha sido utilizando el acelerómetro y no el giroscopio, sin embargo, se puede
implementar más adelante para ver la estabilidad del cansat y como parte de un sistema de navegación más
avanzado.

Figura 12: Esquemático del MPU6050

El acelerómetro nos mide las componentes Y,X,Z de la aceleración , hay que tener en cuenta la posición del
acelerómetro para evitar las errores en la medición de la aceleración y también el giroscopio con las lecturas que
nos pueda brindar.

Figura 13: Orientación de ejes del MPU6050

Mediante el código que se ha implementado determinar valores iniciales, pero de ser necesario se pueden
predefinir valores iniciales llamados offsets también estos pueden ser predefinidos mediante una calibración
del dispositivo ya que puede variar en distintos sensores. Este sensor se ha implementado con el protocolo
de comunicación I2C mayormente usado por estos sensores digitales ya que nos permite la conexión de varios
dispositivos al mismo bus. En primera instancia este dispositivo fue implementado con Arduino UNO, y como se
mencionó anteriormente solo se usó la lectura del acelerómetro, sin embargo, no es únicamente parte del sistema
de telemetrı́a, sino que también forma parte del sistema de apertura del paracaı́das detallado en la siguiente
sección. En esta sección, a continuación, únicamente se expondrá el código que se usó para la lectura de datos
del acelerómetro.

1 #include "Simple_MPU6050.h"
2 #define MPU6050_ADDRESS_AD0_LOW 0x68
3 #define MPU6050_ADDRESS_AD0_HIGH 0x69
4 #define MPU6050_DEFAULT_ADDRESS MPU6050_ADDRESS_AD0_LOW
5
6 Simple_MPU6050 mpu;
7 ENABLE_MPU_OVERFLOW_PROTECTION();
8
9 #define spamtimer(t) for (static uint32_t SpamTimer; (uint32_t)(millis() - SpamTimer) >= (t); SpamTimer = millis())
10
11 #define printfloatx(Name,Variable,Spaces,Precision,EndTxt)print(Name);{char S[(Spaces+Precision+3)];Serial.print(F(" "));Serial.print(dtostrf((float)Variable,Spaces,Precision,S));}Serial.print(EndTxt);
12
13 int PrintAllValues(int16_t *gyro, int16_t *accel, int32_t *quat, uint16_t SpamDelay = 100) {
14 Quaternion q;
15 VectorFloat gravity;
16 float ypr[3] = { 0, 0, 0 };
17 float xyz[3] = { 0, 0, 0 };
18 spamtimer(SpamDelay) {
19 mpu.GetQuaternion(&q, quat);

11
20 mpu.GetGravity(&gravity, &q);
21 mpu.GetYawPitchRoll(ypr, &q, &gravity);
22 mpu.ConvertToDegrees(ypr, xyz);
23 Serial.printfloatx(F("Yaw") , xyz[0], 9, 4, F(", "));
24 Serial.printfloatx(F("Pitch"), xyz[1], 9, 4, F(", "));
25 Serial.printfloatx(F("Roll") , xyz[2], 9, 4, F(", "));
26
27 Serial.printfloatx(F("ax") , accel[0], 5, 0, F(", "));
28 Serial.printfloatx(F("ay") , accel[1], 5, 0, F(", "));
29 Serial.printfloatx(F("az") , accel[2], 5, 0, F(", "));
30 Serial.printfloatx(F("gx") , gyro[0], 5, 0, F(", "));
31 Serial.printfloatx(F("gy") , gyro[1], 5, 0, F(", "));
32 Serial.printfloatx(F("gz") , gyro[2], 5, 0, F("\n"));
33
34 Serial.println();
35 }
36 }
37 \
38 void print_Values (int16_t *gyro, int16_t *accel, int32_t *quat, uint32_t *timestamp) {
39 uint8_t Spam_Delay = 100;
40
41 PrintAllValues(gyro, accel, quat, Spam_Delay);
42 }
43 void setup() {
44 uint8_t val;
45
46 #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
47 Wire.begin();
48 Wire.setClock(400000);
49 #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
50 Fastwire::setup(400, true);
51 #endif
52 // initialize serial communication
53 Serial.begin(115200);
54 while (!Serial);
55 Serial.println(F("Start:"));
56 #ifdef OFFSETS
57 Serial.println(F("Using Offsets"));
58 mpu.SetAddress(MPU6050_DEFAULT_ADDRESS).load_DMP_Image(OFFSETS); // Does it all for you
59 #else
60 Serial.println(F(" Mantenga en posicion estacionaria el MPU\n"
61 " Para establecer automaticamente offsetts\n\n"
62 " \t\t\t[Presionar cualquier tecla]"));
63 while (Serial.available() && Serial.read()); // empty buffer
64 while (!Serial.available()); // wait for data
65 while (Serial.available() && Serial.read()); // empty buffer again
66 mpu.SetAddress(MPU6050_DEFAULT_ADDRESS).CalibrateMPU().load_DMP_Image();
67 #endif
68 mpu.on_FIFO(print_Values);
69 }
70 void loop() {
71 mpu.dmp_read_fifo();// Must be in loop
72 }

3.3. Sistema de apertura del paracaidas


En el caso del sistema de apertura, consta de 2 principales componentes, el servomotor y el acelerómetro. Los
detalles del acelerómetro fueron visto en la sección anterior. El servomotor escogido es el MG90S Tower Pro, un
catalogado micro servo de giro continuo que tiene un torque de reposo de 2.2kg*cm(4,8V),2.5kg*cm(6V) con una
velocidad 0.1seg/60 grados. Este sistema se encarga de la apertura del paracaı́das dentro de un contenedor visto
en la sección de la estructura mecánica del sistema, el servomotor es alojado en un pequeño compartimiento
exterior al cansat. Este sistema su función es detectar una predeterminada aceleración a través del MPU6050
y al detectar el sensor esa aceleración se active el servomotor durante un breve periodo de tiempo para que ası́
termine de abrir el compartimiento del paracaı́das por completo.
Para implementar este sistema hay que tener en consideración la fuerza que va a soportar el servomotor ya
que a mayor fuerza mayor voltaje consumirá, por lo que es recomendable apoyarse de una fuente externa de
energı́a para evitar posibles fallos en la tarjeta. Destacar que en este caso fue usado directamente en la tarjeta
Arduino UNO para ver el funcionamiento, al no estar sometido a ninguna carga no habrı́a peligro de que pase
mayores inconvenientes en su implementación.
La implementación fue con arduino UNO y combina 2 librerı́as de arduino, Servo.h y SimpleMPU visto en
el código del acelerómetro.

MPU6050 y Servo Arduino UNO


VCC (MPU) 5V
GND (MPU) GND
SCL (MPU) A5
SDA (MPU) A4
Int (MPU) PIN 2
VCC (SERVO) 5V
GND (SERVO) GND
Int (SERVO) PIN 5

12
1 #include "Simple_MPU6050.h" // incluye libreria Simple_MPU6050
2 #define MPU6050_ADDRESS_AD0_LOW 0x68 // direccion I2C con AD0 en LOW o sin conexion
3 #define MPU6050_ADDRESS_AD0_HIGH 0x69 // direccion I2C con AD0 en HIGH
4 #define MPU6050_DEFAULT_ADDRESS MPU6050_ADDRESS_AD0_LOW // por defecto AD0 en LOW
5 #include <Servo.h>
6
7 Simple_MPU6050 mpu; // crea objeto con nombre mpu
8 ENABLE_MPU_OVERFLOW_PROTECTION(); // activa proteccion
9
10
11 // #define OFFSETS -5114, 484, 1030, 46, -14, 6 // Colocar valores personalizados
12 Servo ServoX;
13
14 #define spamtimer(t) for (static uint32_t SpamTimer; (uint32_t)(millis() - SpamTimer) >= (t); SpamTimer = millis())
15 // spamtimer funcion para generar demora al escribir en monitor serie sin usar delay()
16
17 ##define printfloatx(Name,Variable,Spaces,Precision,EndTxt)print(Name);{char S[(Spaces+Precision+3)];Serial.print(F(" "));Serial.print(dtostrf((float)Variable,Spaces,Precision,S));}Serial.print(EndTxt);
18 // printfloatx funcion para mostrar en monitor serie datos para evitar el uso se multiples print()
19
20 // mostrar_valores funcion que es llamada cada vez que hay datos disponibles desde el sensor
21 void mostrar_valores (int16_t *gyro, int16_t *accel, int32_t *quat, uint32_t *timestamp) {
22 uint8_t SpamDelay = 100; // demora para escribir en monitor serie de 100 mseg
23 Quaternion q; // variable necesaria para calculos posteriores
24 VectorFloat gravity; // variable necesaria para calculos posteriores
25 float ypr[3] = { 0, 0, 0 }; // array para almacenar valores de yaw, pitch, roll
26 float xyz[3] = { 0, 0, 0 }; // array para almacenar valores convertidos a grados de yaw, pitch, roll
27 spamtimer(SpamDelay) { // si han transcurrido al menos 100 mseg entonces proceder
28 mpu.GetQuaternion(&q, quat); // funcion para obtener valor para calculo posterior
29 mpu.GetGravity(&gravity, &q); // funcion para obtener valor para calculo posterior
30 mpu.GetYawPitchRoll(ypr, &q, &gravity); // funcion obtiene valores de yaw, ptich, roll
31 mpu.ConvertToDegrees(ypr, xyz); // funcion convierte a grados sexagesimales
32 Serial.printfloatx(F("Yaw") , xyz[0], 9, 4, F(", ")); // muestra en monitor serie rotacion de eje Z, yaw
33 Serial.printfloatx(F("Pitch"), xyz[1], 9, 4, F(", ")); // muestra en monitor serie rotacion de eje Y, pitch
34 Serial.printfloatx(F("Roll") , xyz[2], 9, 4, F(", ")); // muestra en monitor serie rotacion de eje X, roll
35 Serial.println(); // salto de linea
36 if ( xyz[0] > abs(30.0) ){ // si el pitch es mayor a 10 grados
37 ServoX.write(180); // muestra texto
38 delay(5000);
39 ServoX.write(90);
40 }
41 if ( xyz[1] > abs(30.0)){ // si el pitch es menor a -10 grados
42 ServoX.write(180); // muestra texto
43 delay(5000);
44 ServoX.write(90);
45 }
46 else if(xyz[2]> abs(30.0)){
47 ServoX.write(180);
48 delay(5000);
49 ServoX.write(90);
50 }
51 }
52 }
53
54
55
56 void setup() {
57 ServoX.attach(5,625,2400);
58 ServoX.write(90);
59 uint8_t val;
60 #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE //
61 Wire.begin();
62 Wire.setClock(400000);
63 #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
64 Fastwire::setup(400, true);
65 #endif
66
67 Serial.begin(115200);
68 while (!Serial);
69 Serial.println(F("Inicio:"));
70 #ifdef OFFSETS
71 Serial.println(F("Usando Offsets predefinidos")); // texto estatico
72 mpu.SetAddress(MPU6050_ADDRESS_AD0_LOW).load_DMP_Image(OFFSETS); // inicializacion de sensor
73
74 #else // sin no existen OFFSETS
75 Serial.println(F(" No se establecieron Offsets, haremos unos nuevos.\n" // muestra texto estatico
76 " Colocar el sensor en un superficie plana y esperar unos segundos\n"
77 " Colocar los nuevos Offsets en #define OFFSETS\n"
78 " para saltar la calibracion inicial \n"
79 " \t\tPresionar cualquier tecla y ENTER"));
80 while (Serial.available() && Serial.read());
81 while (!Serial.available());
82 while (Serial.available() && Serial.read());
83 mpu.SetAddress(MPU6050_ADDRESS_AD0_LOW).CalibrateMPU().load_DMP_Image();
84 #endif
85 mpu.on_FIFO(mostrar_valores);
86 }
87
88
89
90 void loop() {
91 mpu.dmp_read_fifo();
92 }

Establecido el código hay que detallar algunas cosas importantes del mismo, en primer lugar, el tiempo en el que
se recogen las muestras, para no sobrecargar la salida de datos se ha propuesto un ”Spamtimer”determinado a
tener el tiempo de recolección de datos, en este ejemplo es de 100 ms. La activación del servomotor depende de

13
la lectura entonces es recomendable que reduzcamos el tiempo de muestreo para activar adecuadamente y en
el momento preciso el servomotor. Además, considerar que los datos están sujetos a variabilidad dependiendo
del dispositivo como por ejemplo los offsett del acelerómetro y el ancho de impulso del servomotor (mı́nimo y
máximo).

3.4. Módulo de Cámara OV7670


El módulo de cámara escogido es el de la empresa Omnivision OV7670 con unas dimensiones de 3.3 cm x
3.3 cm con total de 18 conexiones. El dispositivo puede manejar hasta resoluciones VGA de 480 x360 pixeles
a una tasa de fotogramas de 30 fps. Adicionalmente, permite el uso de filtros de preprocesamiento, manejo de
escala RGB y YCbCr. Todos estos ajustes se encuentran detallados en el datasheet y se puede acceder a las
diferencias combinaciones de ellos modificando los registros asociados a cada caracterı́stica. Este módulo al igual
que muchos otros de la empresa Omnivision utiliza el protocolo de comunicación SCCB (Serial Camera Control
Bus) que también se encuentra detallado en profundidad dentro del datasheet.

Si bien se utilizan 17 de los 18 pines, la gran mayorı́a sirven para enviar información sobre la foto como escala,
resolución, paleta de colores, sincronización vertical y horizontal. No se debe pensar que se está trabajando en
forma paralela porque solo un pin envı́a el archivo de la imagen, los demás son de parámetros. Cabe resaltarse
que se ha utilizado el modelo sin memoria FIFO de manera que necesita enviar todos los datos a través de los
pines hacia la computadora porque el Arduino no puede almacenar la foto por su limitada memoria que tiene
como función principal solo almacenar el script. Esto también repercute en la complejidad del código a utilizar
porque la memoria FIFO tiene muchas funciones implementadas de fábrica que no necesitan declararse en un
script, reduciendo considerablemente la cantidad de lı́neas de código. Su única desventaja es un costo mucho
mayor.

Figura 14: Cámara OV7670 de OmniVision

Para una primera implementación se utilizó la tarjeta Arduino Mini Original y se trabajó con una con-
figuración de 160 x 120 con 115200 baudios para transmisión de datos. Es importante que dependiendo de
la frecuencia de reloj del procesador se pueden utilizar resoluciones y velocidades de comunicación mayores.
Múltiples usuarios que han utilizado la OV7670 destacan que el Arduino Uno Original no puede trabajar para
velocidades mayores a los 115200 baudios. Otras tarjetas si pueden acceder a este grupo de opciones como
Arduino Mini, Micro o tarjetas ESP32.

A continuación se detalla el procedimiento de instalación del módulo y puesta en funcionamiento.


1. Las conexiones a realizar entre la cámara OV7670 y el Arduino se muestran a continuación dividas en
dos grupos. Conexiones con asterisco necesitan una resistencia adicional como las del clock. Para más
información observar el esquemático adjunto

14
OV7670 Arduino Mini
VSYNC (1) PIN 2
XCLCK (1) PIN 3
PCLCK (2) PIN12
SIOD (1) A4*
SIOC (1) A5*
D0-D3 (2) A0-A3*
D4-D7 (2) PIN4-PIN7*
3.3V (1) 3.3V
RESET (1) 3.3V
GND (1) GND
PWDN (1) GND

Figura 15: Esquemático del módulo de OV7670 y Arduino Mini

2. El primer grupo en amarillo son conexiones que se encargan de establecer sincronización con el clock y
la fase de alimentación. Con el primer grupo de conexiones ya se puede realizar una primera prueba de
comunicación entre el Arduino y la computadora.
3. El código a utilizar para la comunicación entre dispositivos pertenece al repositorio de [9]. Dentro del
repositorio se encuentran las instrucciones de instalación de librerı́as adicionales y el source code compuesto
de 9 archivos. Los dos más importantes son setup.h y ExampleUart.cpp porque definen el modo de
operación de la cámara. Los demás archivos son listas de registros ya inicializados para trabajar en
determinados ajustes como escala de grises a 10 fps con 320p de resolución o imagen a color completo
para la misma resolución y tasa de frames. En ambos casos se debe verificar una lı́nea de código: para
setup.h la lı́nea 31 (#define EXAMPLE X) debe tener el valor 3 para fijar una comunicación entre Arduino
con su puerto COM32 hacia la computadora y en ExampleUart.cpp la lı́nea 31 (#define UARTMODE)
debe estar con el valor 4 porque el Arduino Uno original no puede trabajar fuera de los 115200 baudios.
Los códigos presentados solo incluyen las lı́neas de comando de interés para este proyecto.

1 // Setup.h
2 // Created by indrek on 1.05.2016.
3 //
4

5 #ifndef LIVEOV7670_SETUP_H
6 #define LIVEOV7670_SETUP_H

15
7

9 /*
10 * EXAMPLE = 1
11 * Use LiveOV7670Library class that reads line into buffer and
12 * sends data to TFT over SPI during blank lines.
13 *
14 * EXAMPLE = 2
15 * Use LiveOV7670Library class that processes data pixel by pixel
16 * sends data to TFT during each pixel reading loop.
17 * VGA can not be used with line buffer since there is no
18 * time (no blank lines) to do something useful with a buffered line
19 *
20 * EXAMPLE = 3
21 * Reads data from LiveOV7670Library and send it over UART to computer
22 * Java application for receiving picture from UART
23 * https://github.com/indrekluuk/ArduinoImageCapture
24 *
25 * EXAMPLE = 4
26 * Gray scale image @20Hz. Interlaced image.
27 *
28 */
29 #define EXAMPLE 3

1 // ExampleUart.cpp
2 // Created by indrek on 1.05.2016.
3 //
4

5 // set EXAMPLE to EXAMPLE_UART in setup.h to activate


6 #include "setup.h"
7 #if EXAMPLE == 3
8

10 #include "Arduino.h"
11 #include "CameraOV7670.h"
12

13 static const uint8_t COMMAND_NEW_FRAME = 0x01;


14 static const uint8_t COMMAND_END_OF_LINE = 0x02;
15 static const uint8_t COMMAND_DEBUG_DATA = 0x03;
16

17 static const uint16_t COLOR_GREEN = 0x07E0;


18 static const uint16_t COLOR_RED = 0xF800;
19

20 static const uint16_t UART_PIXEL_FORMAT_RGB565 = 1;


21 static const uint16_t UART_PIXEL_FORMAT_GRAYSCALE = 2;
22

23 // select resolution and communication speed:


24 // 1 - 320x240 with 2M baud (may be unreliable!)
25 // 2 - 320x240 with 1M baud
26 // 3 - 160x120 with 1M baud
27 // 4 - 160x120 with 115200 baud
28 // 5 - 320x240 grayscale with 1M baud
29 // 6 - 160x120 grayscale with 1M baud
30 // 7 - 640x480 grayscale with 1M baud (very unreliable)

16
31 #define UART_MODE 4

4. Luego de descargar el source code del arduino, se debe descargar la terminal serial donde se visualizará la
imagen y también puede definir una carpeta en donde almacenar las imágenes capturadas. En esta terminal
está desarrollada en lenguaje JAVA y se descarga desde [10]. Puede ser ejecutada desde el terminal por
lı́nea de comando o desde el IDE de preferencia.
5. Después de hacer el primer grupo de conexiones, subir el código al arduino y ejecutar el serial port reader,
se probará la sincronización con el clock. Dentro de serial port saldrá el botón de establecer conexión y se
debe fijar la cantidad de baudios a 115200. A partir de aquı́ tres resultados se pueden obtener.

Pantalla roja sin distorsión: Existe un problema de conexión con los puertos SIOD y SIOC. Revisar
conexiones y resistencias.

Figura 16: Pantalla roja sin distorsión

Pantalla roja con distorsión: Existe un problema con los puertos SIOD, SIOC y XCLCK. Revisar
conexiones y resistencias

Figura 17: Pantalla roja con distorsión

Pantalla verde: Todas las conexiones se hicieron bien.

17
Figura 18: Pantalla verde

6. Una vez se obtenga la pantalla verde en el serial port reader, se puede continuar con el resto de conexiones.
En la segunda prueba, la transmisión de imágenes empezará con un recuadro verde durante unos segundos
y luego comenzará a emitir las capturas de la cámara en tiempo real. Dentro de la terminal del compilador
Java que se utilizó aparecerá una lı́nea por cada imagen que se transmite y muestra en el serial port reader.
Si la configuración básica fue implementada con éxito se pueden probar otras como escala de grises.
Si bien se han hecho una primera ronda de pruebas con un módulo OV7670 en un Arduino Uno, se pla-
nea optimizar el espacio utilizando un Arduino Mini 3.3V. Con este cambio de plataforma se debe considerar
comprar un adaptador Serial(TTL) a USB porque Arduino Mini no incluye este tipo de puerto. Existe una al-
ternativa para guardar los scripts en el Arduino Mini y es utilizar un Arduino Uno como medio de comunicación
al retirarle su chip AtMega. No se recomienda este método porque la señal de las imágenes tendrı́a que pasar
por los componentes del Arduino Uno retrasando ası́ la comunicación, un problema que no se tendrı́a con el
adaptador.

En general las conexiones se pueden mantener aunque probablemente se tenga que modificar los valores
de las resistencias de los puertos SIOD y SIOC asociados al clock porque el Arduino Mini trabaja en otras
frecuencias de reloj. Ası́ mismo, considerar hacer pruebas de consumo de potencia del módulo OV7670 y el
Arduino Mini, ya que no fueron realizadas.
Finalmente, se ha desarrollado un prototipo de PCB para el Arduino Mini con un módulo OV7670 respetando
las dimensiones del diseño mecánico propuesto en la sección anterior. Las conexiones y resistores del Arduino
Uno no han sido modificados. Además, posee 4 agujeros para ser fijada la placa dentro de la estructura mecánica.
Este diseño fue creado en la plataforma EasyEDA y es exportable a Altium y Eagle.

Figura 19: Diagrama de PCB con conexiones entre OV7670 y Arduino Mini

18
3.5. Módulo de comunicación
Para el módulo de comunicación se usó el transceptor NRF24L01. Este dispositivo se comunica sin nece-
sidad de un cableado mediante radio frecuencia (RF). Se puede enviar y recibir datos simultáneamente. El
NRF24L01 tiene un solo chip que opera en 2.4 - 2.5 GHz (banda ISM) con soporte para velocidades de datos
de 250kbps, 1Mbps y 2Mbps[12]. Este módulo consta de un sintetizador de frecuencia totalmente integrado,
un amplificador de potencia, un oscilador de cristal, un demodulador, un modulador y un motor de protocolo
ShockBurs mejorado. La potencia de salida, los canales de frecuencia y la configuración del protocolo se pueden
programar fácilmente a través de una interfaz SPI con un microcontrolador. Asimismo, el rango de voltaje de
funcionamiento de este módulo transceptor es de 1,9 V a 3,6 V. Tiene modos de apagado y espera integrados
que hacen que ahorre energı́a y sea fácil de realizar. Esta caracterı́stica produce que consuma menor energı́a
de la baterı́a. En la siguiente imagen se muestra un esquemático del NRF24L01 con un potenciómetro la cual
consta en enviar el voltaje de este [13].

Figura 20: Conexiones Receptor NRF24L01 con potenciómetro para la transmisión de datos y sin potenciómetro
para el recibo de datos

Para la parte de programación de este ejemplo se necesita dos microcontroladores uno para el envió de datos
y el otro para la recepción. El siguiente Código es el envió de datos, es decir el emisor:

1 #include <SPI.h>
2 #include <nRF24L01.h>
3 #include <RF24.h>
4 //Declaremos los pines CE y el CSN
5 #define CE_PIN 9
6 #define CSN_PIN 10
7 //Variable con la dirección del canal por donde se va a transmitir
8 byte direccion[5] ={'c','a','n','a','l'};
9 //creamos el objeto radio (NRF24L01)
10 RF24 radio(CE_PIN, CSN_PIN);
11 //vector con los datos a enviar
12 float datos[3];
13 void setup()
14 {
15 //inicializamos el NRF24L01
16 radio.begin();
17 //inicializamos el puerto serie
18 Serial.begin(9600);
19

20 //Abrimos un canal de escritura


21 radio.openWritingPipe(direccion);
22

23 }
24 void loop()
25 {

19
26 //cargamos los datos en la variable datos[]
27 datos[0]=analogRead(0)* (5.0 / 1023.0);;
28 datos[1]=millis();
29 datos[2]=3.14;
30 //enviamos los datos
31 bool ok = radio.write(datos, sizeof(datos));
32 //reportamos por el puerto serial los datos enviados
33 if(ok)
34 {
35 Serial.print("Datos enviados: ");
36 Serial.print(datos[0]);
37 Serial.print(" , ");
38 Serial.print(datos[1]);
39 Serial.print(" , ");
40 Serial.println(datos[2]);
41 }
42 else
43 {
44 Serial.println("no se ha podido enviar");
45 }
46 delay(1000);
47 }

Este siguiente código programa al microcontrolador como el receptor de datos y lo imprime para verificar.

1 #include <SPI.h>
2 #include <nRF24L01.h>
3 #include <RF24.h>
4 //Declaremos los pines CE y el CSN
5 #define CE_PIN 9
6 #define CSN_PIN 10
7 //Variable con la dirección del canal que se va a leer
8 byte direccion[5] ={'c','a','n','a','l'};
9 //creamos el objeto radio (NRF24L01)
10 RF24 radio(CE_PIN, CSN_PIN);
11 //vector para los datos recibidos
12 float datos[3];
13 void setup()
14 {
15 //inicializamos el NRF24L01
16 radio.begin();
17 //inicializamos el puerto serie
18 Serial.begin(9600);
19

20 //Abrimos el canal de Lectura


21 radio.openReadingPipe(1, direccion);
22

23 //empezamos a escuchar por el canal


24 radio.startListening();
25 }
26 void loop() {
27 uint8_t numero_canal;
28 //if ( radio.available(&numero_canal) )
29 if ( radio.available() )
30 {

20
31 //Leemos los datos y los guardamos en la variable datos[]
32 radio.read(datos,sizeof(datos));
33

34 //reportamos por el puerto serial los datos recibidos


35 Serial.print("Dato0= " );
36 Serial.print(datos[0]);
37 Serial.print(" V, ");
38 Serial.print("Dato1= " );
39 Serial.print(datos[1]);
40 Serial.print(" ms, ");
41 Serial.print("Dato2= " );
42 Serial.println(datos[2]);
43 }
44 else
45 {
46 Serial.println("No hay datos de radio disponibles");
47 }
48 delay(1000);
49 }

Para este proyecto, se usaron dos transceiver NRF24l01, uno tiene la función de la transmisión de datos de
la temperatura, humedad, calidad de aire, altitud, ubicación, el ángulo del motor y las imágenes capturadas de
la cámara, y el control del paracaı́das mediante una señal transmitida de la estación terrena. Este está ubicado
dentro del CanSat ya que debe estar conectado con todos los sensores. El otro está en la estación terrena, este
recibe todos los datos mencionados y también envı́a la señal de movimiento para el paracaı́das.
Con el fin de poder realizar una correcta transmisión de datos, se debe armar una trama en base a los valores
calculados previamente. Una encodificación a enviar por el módulo NRF24L01 consiste de un arreglo de floats,
el cual definiremos de la siguiente manera.

Trama[index] Almacenar
0 Longitude
1 Latitude
2 Speed(knots)
3 Temp(C)
4 Pressure
5 Height
6 Humidity( %)
7 Yaw
8 Pitch
9 Roll
10 ax(m/s2 )
11 ay(m/s2 )
12 az(m/s2 )
13 parachute status
14 camera connection
15 1

Esta trama será entonces enviada desde el transmisor del CanSat y recibida por el receptor conectado a la
estación terrsestre, tomando esta trama, decodificando sus valores y mostrándolos en una interfaz de usuario.
Para el caso de envı́o de imágenes se necesitaria crear una trama diferente, exclusiva para este propósito.
Dada la complejidad de un sistema de este tipo, esta modalidad aun se encuentra en desarrollo.

3.6. Estación terrestre


Con el fin de recibir la data transmitida por el NRF24L01, un segundo NRF24L01 servirá como su antena
receptora, esta vez conectado a un Arduino Uno, conectado a su vez mediante USB a una laptop o computadora
capaz de correr programas escritos en Python.
El código cargado a este Arduino sigue nuevamente la estructura dada por la guı́a [13].

21
El Arduino receptor recibirá la trama definida previamente, la cual se transmitirá por comunicación serial
a una Laptop u otro dispositivo capaz de correr Python, mostrando la data en una interfaz gráfica construida
especificamente para visualizar los datos del CanSat.

Figura 21: Interfaz de usuario PyQt5

La interfaz de usuario está basada en el UI base Ground station GUI [14], la cual fue modificada para
poder mostrar y leer los datos encodificados en la trama que definimos, añadiendo funcionalidades extra como
la visualización y almacenamiento de los datos transmitidos por el GPS en tiempo real.

3.6.1. Recepción de la trama


La trama es leı́da a través de comunicación serial mediante un puerto definido al lanzar el programa. Con
el fin de poder realizar pruebas sin tener los dispositivos disponibles, también se genera una trama de ejemplo,
siguiendo el formato de trama previamente propuesto, para poder comprobar la visualizacion correcta de los
datos.

1 class Communication:
2 baudrate = ''
3 portName = ''
4 dummyPlug = False
5 ports = serial.tools.list_ports.comports()
6 ser = serial.Serial()
7 startlat = -12.135400
8 startlon = -77.022095
9 increase = 0.000500
10

11

12 def __init__(self):
13 self.baudrate = 9600
14 print("the available ports are (if none appear, press any letter): ")
15 for port in sorted(self.ports):
16 # obtener la lista de puertos: https://stackoverflow.com/a/52809180
17 print(("{}".format(port)))

22
18 if(self.dummyMode == False):
19 self.portName = input("write serial port name (ex: /dev/ttyUSB0): ")
20 try:
21 self.ser = serial.Serial(self.portName, self.baudrate)
22 except serial.serialutil.SerialException:
23 print("Can't open : ", self.portName)
24 self.dummyPlug = True
25 print("Dummy mode activated")
26

27 def close(self):
28 if(self.ser.isOpen()):
29 self.ser.close()
30 else:
31 print(self.portName, " it's already closed")
32

33 def getData(self):
34 value = self.ser.readline() # read line (single value) from the serial port
35 decoded_bytes = str(value[0:len(value) - 2].decode("utf-8"))
36 value_chain = decoded_bytes.split(",")
37 print(value_chain)
38 else:
39 # lon lat vel
40 value_chain = [self.startlon] + [self.startlat] + [random.random()*(3-0) + 0]
41 # height temp press
42 + [random.random()*(38-16) + 16] + random.sample(range(280, 300), 1) + [random.random()*(12-5) + 5]
43 # hum yawpitchroll/ax ay az para cam trans
44 + random.sample(range(80, 100), 1) + random.sample(range(0, 20), 6) + [0] + [1] + [1]
45 self.startlat = self.startlat + self.increase
46 self.startlon = self.startlon + self.increase
47 print(value_chain)
48 return value_chain
49

50 def isOpen(self):
51 return self.ser.isOpen()
52

53 def dummyMode(self):
54 return self.dummyPlug

3.6.2. Almacenamiento de los datos


Se adaptó la funcionalidad de almacenamiento de datos para poder almacenar la trama completa proveniente
del CanSat, con el fin de tener los datos disponibles para su posterior análisis.

1 import time
2 import csv
3

5 class data_base():
6 def __init__(self):
7 self.state = False
8

9 def guardar(self, data):


10 if self.state == True:
11 data.append(time.asctime())
12 with open("flight_data.csv", "a") as f:

23
13 writer = csv.writer(f, delimiter=",")
14 writer.writerow(data)
15

16 def start(self):
17 self.state = True
18 print('starting storage in csv')
19

20 def stop(self):
21 self.state = False
22 print('stopping storage in csv')

Figura 22: Almacenamiento de la trama en flight data.csv

Figura 23: Almacenamiento del recorrido del CanSat en trayectoria.html

3.6.3. Ploteo y Updating de las gráficas


Updating
Para poder actualizar todas las gráficas, se define una función de update() que lee la siguiente lı́nea disponible
de la trama y envı́a los datos leı́dos al las funciones de updating de cada una de las gráficas.

1 def update():
2 try:
3 value_chain = []

24
4 value_chain = ser.getData()
5 update_altitude(value_chain)
6 update_vel(value_chain)
7 update_acc(value_chain)
8 update_gyro(value_chain)
9 update_humidity(value_chain)
10 update_pressure(value_chain)
11 update_temp(value_chain)
12 update_parachute(value_chain)
13 update_camera(value_chain)
14 update_transmitter(value_chain)
15 update_MAP(value_chain)
16 update_altitude(value_chain)
17

18 data_base.guardar(value_chain)
19 except IndexError:
20 print('starting, please wait a moment')

Con esto, ahora se procede a definir los plots y las funciones de actualización de cada métrica analizada.

GPS
Se parsean los datos de value chain de latitud y longitud del NEO-M8N-0-01 Ublox para la visualización
GPS, utilizando la librerı́a Folium para graficar y almacenar el trayecto en un archivo de mapa. Se escribe una
trayectoria marcada en rojo, además de marcadores los cuales denotan las coordenadas, la fecha y la hora en
que fueron recibidas.

1 coordinate = (-12.135400, -77.022095) # STARTING ADDRESS #(37.819859404476425, -122.47855046471037)


2

3 m = folium.Map(
4 title='cansat',
5 zoom_start=18,
6 location=coordinate
7 )
8

9 data = io.BytesIO()
10 m.save(data, close_file=False)
11 webView = QWebEngineView()
12 webView.setHtml(data.getvalue().decode())
13

14 proxy3 = QtGui.QGraphicsProxyWidget()
15 proxy3.setWidget(webView)
16 proxy3.update()
17 count = 0
18

19 W3 = l11.addItem(proxy3)
20 lat = 0
21 lon = 0
22

23 def update_MAP(value_chain):
24 global proxy3,m,data,W3,webView,l11,data,count,lat,lon
25

26 loc = []
27 if (lat == 0):
28 loc = [ (float(value_chain[1]), float(value_chain[0])),
29 (float(value_chain[1]), float(value_chain[0]))]

25
30 else:
31 loc = [ (lat, lon),
32 (float(value_chain[1]), float(value_chain[0]))]
33 lat = float(value_chain[1])
34 lon = float(value_chain[0])
35 m.location = (lat,lon)
36

37

38 folium.PolyLine(loc,
39 color='red',
40 weight=15,
41 opacity=0.8).add_to(m)
42

43 if count == 20:
44 now = datetime.now()
45 dt_string = now.strftime("%d/%m/%Y %H:%M:%S")
46

47 folium.Marker(
48 [float(value_chain[1]), float(value_chain[0])],
49 popup = str(float(value_chain[1])) + ',' + str(float(value_chain[0])) + '\n' + dt_string,
50 icon=folium.Icon(color='blue',icon="fab fa-fly",prefix='fa'),
51 tooltip="GPS SIGNAL"
52 ).add_to(m)
53

54 data2 = io.BytesIO()
55 m.save(data2, close_file=False)
56 m.save('trayectoria.html')
57 if count == 20:
58 webView.setHtml(data2.getvalue().decode())
59 count = 0
60 else:
61 count+=1
62 print(count)

Velocidad
Se grafica el dato de velocidad en nudos obtenido del NEO-M8N-0-01 Ublox.

1 # Speed graph
2 p2 = l11.addPlot(title="Speed (knots)")
3 vel_plot = p2.plot(pen=(29, 185, 84))
4 vel_data = np.linspace(0, 0, 30)
5 ptr6 = 0
6 vel = 0
7

9 def update_vel(value_chain):
10 global vel_plot, vel_data, ptr6, vel
11 vel = value_chain[2]
12 vel_data[:-1] = vel_data[1:]
13 vel_data[-1] = vel
14 ptr6 += 1
15 vel_plot.setData(vel_data)
16 vel_plot.setPos(ptr6, 0)

Temperatura

26
Se grafica la temperatura en grados del DHT11.

1 # Temperature graph
2 graf_temp = l12.addPlot(title="Temperature (ºc)")
3 temp_plot = graf_temp.plot(pen=(29, 185, 84))
4 temp_data = np.linspace(0, 0, 30)
5 ptr5 = 0
6

8 def update_temp(value_chain):
9 global temp_plot, temp_data, ptr5
10 temp_data[:-1] = temp_data[1:]
11 temp_data[-1] = float(value_chain[3])
12 ptr5 += 1
13 temp_plot.setData(temp_data)
14 temp_plot.setPos(ptr5, 0)

Altitud
Se grafica altura extrapolada en msnm del BME280.

1 # Altitude graph
2 l1 = Layout.addLayout(colspan=20, rowspan=2)
3 l11 = l1.addLayout(rowspan=1, border=(83, 83, 83))
4 p1 = l11.addPlot(title="Altitude (m)")
5 altitude_plot = p1.plot(pen=(29, 185, 84))
6 altitude_data = np.linspace(0, 0, 30)
7 ptr1 = 0
8

10 def update_altitude(value_chain):
11 global altitude_plot, altitude_data, ptr1
12 altitude_data[:-1] = altitude_data[1:]
13 altitude_data[-1] = float(value_chain[4])
14 ptr1 += 1
15 altitude_plot.setData(altitude_data)
16 altitude_plot.setPos(ptr1, 0)

Presión
Se grafica la presión atmosférica en hPa del BME280.

1 # Pressure Graph
2 pressure_graph = l12.addPlot(title="Barometric pressure")
3 pressure_plot = pressure_graph.plot(pen=(102, 252, 241))
4 pressure_data = np.linspace(0, 0, 30)
5 ptr4 = 0
6

7 def update_pressure(value_chain):
8 global pressure_plot, pressure_data, ptr4
9 pressure_data[:-1] = pressure_data[1:]
10 pressure_data[-1] = float(value_chain[5])
11 ptr4 += 1
12 pressure_plot.setData(pressure_data)
13 pressure_plot.setPos(ptr4, 0)

27
Humedad
Se grafica el porcentaje de humedad del DHT11.

1 # Humidity Graph
2 humidity_graph = l12.addPlot(title="Humidity")
3 humidity_plot = humidity_graph.plot(pen=(102, 252, 241))
4 humidity_data = np.linspace(0, 0, 100)
5 ptr5 = 0
6

7 def update_humidity(value_chain):
8 global humidity_plot, humidity_data, ptr5
9 humidity_data[:-1] = humidity_data[1:]
10 humidity_data[-1] = float(value_chain[6])
11 ptr5 += 1
12 humidity_plot.setData(humidity_data)
13 humidity_plot.setPos(ptr5, 0)

Giroscopio
Se grafica los datos de Yaw, Pitch y Roll del MPU6050.

1 # Gyro graph
2 gyro_graph = l12.addPlot(title="Gyro")
3 gyro_graph.hideAxis('bottom')
4 # adding legend
5 gyro_graph.addLegend()
6 pitch_plot = gyro_graph.plot(pen=(102, 252, 241), name="Pitch")
7 roll_plot = gyro_graph.plot(pen=(29, 185, 84), name="Roll")
8 yaw_plot = gyro_graph.plot(pen=(203, 45, 111), name="Yaw")
9

10 pitch_data = np.linspace(0, 0)
11 roll_data = np.linspace(0, 0)
12 yaw_data = np.linspace(0, 0)
13 ptr3 = 0
14

15

16 def update_gyro(value_chain):
17 global pitch_plot, roll_plot, yaw_plot, pitch_data, roll_data, yaw_data, ptr3
18 pitch_data[:-1] = pitch_data[1:]
19 roll_data[:-1] = roll_data[1:]
20 yaw_data[:-1] = yaw_data[1:]
21

22 pitch_data[-1] = float(value_chain[7])
23 roll_data[-1] = float(value_chain[8])
24 yaw_data[-1] = float(value_chain[9])
25

26 ptr3 += 1
27

28 pitch_plot.setData(pitch_data)
29 roll_plot.setData(roll_data)
30 yaw_plot.setData(yaw_data)
31

32 pitch_plot.setPos(ptr3, 0)
33 roll_plot.setPos(ptr3, 0)
34 yaw_plot.setPos(ptr3, 0)

28
Aceleración
Se grafica los datos de aceleración x,y,z en m/s2 del MPU6050.

1 # Acceleration graph
2 acc_graph = l12.addPlot(title="Accelerations (m/s²)")
3 # adding legend
4 acc_graph.addLegend()
5 acc_graph.hideAxis('bottom')
6 accX_plot = acc_graph.plot(pen=(102, 252, 241), name="X")
7 accY_plot = acc_graph.plot(pen=(29, 185, 84), name="Y")
8 accZ_plot = acc_graph.plot(pen=(203, 45, 111), name="Z")
9

10 accX_data = np.linspace(0, 0)
11 accY_data = np.linspace(0, 0)
12 accZ_data = np.linspace(0, 0)
13 ptr2 = 0
14

15

16 def update_acc(value_chain):
17 global accX_plot, accY_plot, accZ_plot, accX_data, accY_data, accZ_data, ptr2
18 accX_data[:-1] = accX_data[1:]
19 accY_data[:-1] = accY_data[1:]
20 accZ_data[:-1] = accZ_data[1:]
21

22 accX_data[-1] = float(value_chain[10])
23 accY_data[-1] = float(value_chain[11])
24 accZ_data[-1] = float(value_chain[12])
25 ptr2 += 1
26

27 accX_plot.setData(accX_data)
28 accY_plot.setData(accY_data)
29 accZ_plot.setData(accZ_data)
30

31 accX_plot.setPos(ptr2, 0)
32 accY_plot.setPos(ptr2, 0)
33 accZ_plot.setPos(ptr2, 0)

Status Paracaı́das
Se escribe el status del paracaı́da, Yes si fue abierto y No en caso contrario.

1 parachute_status_graph = l2.addPlot(title="Parachute deployed")


2 parachute_status_graph.hideAxis('bottom')
3 parachute_status_graph.hideAxis('left')
4

5 def update_parachute(value_chain):
6 global parachute_status_graph
7 if(value_chain[13] == 0):
8 parachute_status_text1 = pg.TextItem("NO", anchor=(0.5, 0.5), color="r")
9 parachute_status_text1.setFont(font)
10 parachute_status_graph.addItem(parachute_status_text1)
11 else:
12 parachute_status_text1 = pg.TextItem("Yes", anchor=(0.5, 0.5), color="g")
13 parachute_status_text1.setFont(font)
14 parachute_status_graph.addItem(parachute_status_text1)

29
Status Cámara
Se grafica el status de conexión del OV7670 PASS si es correcta y FAIL en caso contrario.

1 # camera graph
2 camera_graph = l2.addPlot(title="Camera satus")
3 camera_graph.hideAxis('bottom')
4 camera_graph.hideAxis('left')
5

6 def update_camera(value_chain):
7 global camera_graph
8 if value_chain[14] == 1:
9 camera_text1= pg.TextItem("PASS", anchor=(0.5, 0.5), color="g")
10 camera_text1.setFont(font)
11 camera_graph.addItem(camera_text1)
12 else:
13 camera_text1= pg.TextItem("FAIL", anchor=(0.5, 0.5), color="r")
14 camera_text1.setFont(font)
15 camera_graph.addItem(camera_text1)

Status Conexión
Se grafica el status de conexion del módulo NRF24L01 CONNECTED si esta recibiendo y NO SIGNAL en caso
contrario.

1 # transmitter graph
2 transmitter_graph = l2.addPlot(title="Transmitter satus")
3 transmitter_graph.hideAxis('bottom')
4 transmitter_graph.hideAxis('left')
5

6 def update_transmitter(value_chain):
7 global transmitter_graph
8 if value_chain[15] == 1:
9 transmitter_text1 = pg.TextItem("CONNECTED", anchor=(0.5, 0.5), color="g")
10 transmitter_text1.setFont(font)
11 transmitter_graph.addItem(transmitter_text1)
12 else:
13 transmitter_text1 = pg.TextItem("NO SIGNAL", anchor=(0.5, 0.5), color="r")
14 transmitter_text1.setFont(font)
15 transmitter_graph.addItem(transmitter_text1)

4. Conclusión
Durante este proyecto PI3 se desarrolló un microsatélite de pequeñas dimensiones conocido como CanSat
para ejercer un monitoreo constante de la selva peruana en búsqueda de áreas donde se realice tala ilegal
de madera. El dispositivo tiene una gran variedad de funciones como la toma de fotografı́as de ecosistemas,
mediciones de la temperatura, presión, humedad, nivel de CO2 etc. Si bien existen otras soluciones que pueden
tener funciones similares como un dron, este proyecto presenta varias ventajas como un menor coste, un manejo
optimizado de la energı́a, facilidad para aumentar las funciones disponibles y el CanSat no genera sonido porque
se desplaza por su propio peso con un paracaı́das. Sin duda, esta tecnologı́a es escalable y pueda abarcar otras
problemáticas donde se necesite del monitoreo aéreo. Algunas propuestas de mejoras o testeos para futuros
grupos que sigan este proyecto son establecer comunicación entre los distintos Arduinos, implementar el modulo
OV7670 con un Arduino Mini, testeo de consumo de corriente y ensamblaje de la estructura mecánica-eléctrica.
Los scripts del proyecto están en un repositorio de GitHub la cual se puede descargar libremente. [18].

30
Referencias
[1] Food and Agriculture Organization of the United Nations, FAO (2015) Evaluación de los Recursos Forestales
Mundiales 2015.
[2] Mejı́a, E and Cano, W and de Jong, W and Pacheco, P and Tapia, S and Morocho,
J (2015) Actores, aprovechamiento de madera y mercados en la Amazonı́a peruana. [book]
https://play.google.com/books/reader?id=eJ1pCwAAQBAJ&pg=GBS.PA32&hl=es
[3] Ministerio del Ambiente (2011) El Perú de los Bosques.
[4] Porro, Roberto and Lopez-Feldman, Alejandro and Vela-Alvarado, Jorge W and Quiñonez-Ruı́z, Lourdes
and Seijas-Cardenas, Zully P and Vásquez-Macedo, Miguel and Salazar-Arista, Clemente and Núñez-Paredes,
Vladimir I and Cardenas-Ruiz, Jefferson (2014) Forest use and agriculture in Ucayali, Peruvian Amazon:
Interactions among livelihood strategies, income and environmental outcomes.
[5] Organismo de supervisión de los Recursos Forestales y de Fauna Silvestre, ONSIFOR (2020) Tala Ilegal [Web
Site]https://www.osinfor.gob.pe/tala-ilegal/
[6] Neo-M8 u-blox M8 concurrent GNSS modules data sheet. [source] https://www.u-blox.com/en/product/neo-
m8-series
[7] DHT11 - Humidity and Temperature Sensor data sheet. [source] https://www.robocraft.ru/files/datasheet/DHT11.pdf
[8] BME Combined humidity and pressure sensor data sheet. [source] https://www.bosch-
sensortec.com/media/boschsensortec/downloads/datasheets/bst-bme280-ds002.pdf

[9] Luuk,I. (2020) Live OV7670. [source code] https://github.com/indrekluuk/LiveOV7670.


[10] Luuk,I. (2020) ArduinoImageCapture. [source code] https://github.com/indrekluuk/ArduinoImageCapture
[11] OV7670 Camera Module with Arduino: Color Image To PC (Step-By-Step Guide). (2018, December 2). [Vi-
deo]. YouTube. https://www.youtube.com/watch?v=L9DTW1ulsT0&t=404s nRF24L01 Single Chip 2.4GHz
Transceiver

[12] nRF24L01 Single Chip 2.4GHz Transceiver.


source
https://cdn.sparkfun.com/datasheets/Wireless/Nordic/nRF24L01 Product Specification v2 0.pdf

[13] (2016) TUTORIAL BÁSICO NRF24L01 CON ARDUINO. [Blog post]


https://naylampmechatronics.com/blog/16 tutorial-basico-nrf24l01-con-arduino.html
[14] Rodriguez,D. (2020) CanSat Ground station. [source code] https://github.com/el-NASA/CanSat-Ground-
station

[15] TUTORIAL SENSORES DE GAS MQ2, MQ3, MQ7 Y MQ135 MQ135 [Web Site]
https://naylampmechatronics.com/blog/42-tutorial-sensores-de-gas-mq2-mq3-mq7-y-mq135.html
[16] Arduino control Servo with MPU6050 (2018, October 20). [Video]. YouTube.
https://www.youtube.com/watch?v=I45XLjE14DQ
[17] Th-Havy (2017) Simple-MPU6050-Arduino. [source code] https://github.com/Th-Havy/Simple-MPU6050-
Arduino
[18] Marcelo Contreras Cabrera, Walter D ıaz Ysla, Mauricio Bernuy Geiser,Edward López, Alvaro Palero
Ramiréz, Marko Puchuri López (2021) CanSat. [source ] https://github.com/markopuch/cansat utec

31
5. Anexos
A. Plano del ensablaje de la estructura interna - CanSat

6 5 4 3 2 1

D D

C C
175,00

B B

64,00

A Dise o de Revisado por Aprobado por Fecha Fecha


A
Usuario 9/08/2021

Edici n Hoja
Ensamblaje v2 CANSAT 1/1
6 5 4 3 2 1

Figura 24: Plano del ensamblaje de la estructura interna

32
B. Plano de la estructura del nivel 1 (Cámara)

6 5 4 3 2 1

35,16
3,5 ,00
D 0 64 D

20,00 10,29
34,29

5,50
C C
0

A A-A ( 1 : 1 )
2 ,0

1,00
32,00
35,00

34,00
1,00
2,00
4,00

A
B B
,00
6,00 R2 4,00
28,69

7,00

5,00

9,00
2,80

A 2,80
Dise o de Revisado por Aprobado por Fecha Fecha
A
Usuario 7/08/2021
48,00

Edici n Hoja
Pieza Base v2 1/1
6 5 4 3 2 1

Figura 25: Plano estructural del nivel 1.

33
C. Plano de la estructura del nivel 2 (Sensores y baterı́a)

6 5 4 3 2 1

Vista superior E-E ( 1 : 1 )


C(1:1)
D D
D B 2,97
0
2,
R2

R32,0

13
00 8,40
,0

,0

2,00
0
0

10,00
17
2,00

,0
0
2,00 2,00 2,00
7,00

3,50
5,00
9,00

2,00
E
F-F ( 1 : 1 ) 20,50

38,00
57,00

11,90
00
2,50 2, 50
9,

2,60
C E ,5
0 1,00 C
12 1,00
0
,5
18
A 6,00 4,00 C

B(1:1) D(1:1) A(1:1)


2,
00 8,40
Vista inferior

0
B B

3,0
3,50
0
F R2,0 10,60
8,00 4,00 0
4,00 21,0
38,00

3,00
6,00 F
20,00
14,77

11,90
5,00

7,00

2,60

2,00

1,00
13,00
2,00 0
,0
17
0
,0
19
4,

A Dise o de Revisado por Aprobado por Fecha Fecha


A
97

Usuario 7/08/2021

Edici n Hoja
Pieza 2 Sensores v2 1/1
6 5 4 3 2 1

Figura 26: Plano estructural del nivel 2.

34
D. Plano de la estructura del nivel 3 (PCBs)

6 5 4 3 2 1

Vista frontal
D D
60,00
A-A ( 1 : 1 )

1,00

4,00
A
19,00

2,00
1,00
A 1,50

C C

Vista inferior
R2
Vista superior 4 ,0
0 ,50
R4
,00 ,00
R2 64
4,00
4,50

7,00

5,00
B B
9,00

2,00 3,00

4,00
2,00
4,00

5,00

7,00

A Dise o de Revisado por Aprobado por Fecha Fecha


A
Usuario 9/08/2021

Edici n Hoja
Pieza 3 - PCBs v2 1/1
6 5 4 3 2 1

Figura 27: Plano estructural del nivel 3.

35
E. Plano de la estructura del nivel 4 (Paracaı́das)

6 5 4 3 2 1

0
2 ,0
A

0
,0
R3
A(1:1)

12

0
00 B(1:1)

R3
,0
D 5, D

0
1,
00

0 32,50
2,0 2,00
2,00
C
6,

00
00

2,
00
9, 5,00 5,00

21,00
6,00 17,00
16
,6
2

1,00
C
32

1,00
,6
2

C B C
22,50 2,00

C-C ( 1 : 1 )
3,00
7,00 ,00
R2 R1

00
,4
2,
0 2,13
4,00

2,00

2,00
2,50

5,00 R1
,00
00
8,
00
B 6,00 2, B
R2

,50
,0

R1
0
8,00

6,00
5,

R1
,50
00

,5
0
R1

5,96

A Dise o de Revisado por Aprobado por Fecha Fecha


A
Usuario 9/08/2021

Edici n Hoja
Pieza 4 - Paraca das v2 1/1
6 5 4 3 2 1

Figura 28: Plano estructural del nivel 4.

36
F. Plano de la tapa del paracaı́das

6 5 4 3 2 1

D D

18
,0
0
9,
7
,7

00
37
3,
00

C C
A B
B(1:1)
A(1:1)

2,00
12,50
1,50
R3

2,

0
,0
00
2,0

2,00
R3
0

6,00
2,00
6,00
B 6,00 3,00 B
9,00
34,00

2
,6
18
0
00 ,0
2, 14

2
,6
A 32 Dise o de Revisado por Aprobado por Fecha Fecha
A
Usuario 9/08/2021

Edici n Hoja
Tapa Paracaidas 1/1
6 5 4 3 2 1

Figura 29: Plano estructural de la tapa del paracaı́das.

37
G. Plano del lado derecho de la carcasa

1 2 3 4 5 6 7 8 9 10 11 12

A A

.75
R8

R8.75
B B

3
3
Ø4.8

C C

D D

1
Ø2
183.5

7.5
Ø1

E E
15.5

Ø25
59.9

10
45°

F F

64

38.27
R3
.0 5
G 1 R3 G

Dept. Technical reference Created by Approved by

Usuario 10/08/2021
3

Document type Document status


6.5

13.85 Title DWG No.


H
Carcasa H

Rev. Date of issue Sheet

1/1
1 2 3 4 5 6 7 8 9 10 11 12

Figura 30: Plano del lado derecho de la carcasa.

38
H. Plano del lado izquierdo de la carcasa

1 2 3 4 5 6 7 8 9 10 11 12

R1
A A

.75
0.
75

R8
R35

B B

83
4.
Ø
10

C C

D D
20
Ø

183.5
6.5
Ø1
15.5

E E
59.9
45°

F F

12.49

3.01
3.02

R3
G 5 G

Dept. Technical reference Created by Approved by

Usuario 10/08/2021
Document type Document status
6.5

Title DWG No.


H
Carcasa H

Rev. Date of issue Sheet

1/1
1 2 3 4 5 6 7 8 9 10 11 12

Figura 31: Plano del lado izquierdo de la carcasa.

39

También podría gustarte