User Tools

Site Tools


Writing /var/lib/dokuwiki/data/meta/teaching/ie0117/proyectos/2015/i/proyecto_1/puesta_en_funcionamiento_de_paparazzi_en_un_stm32f3.meta failed
teaching:ie0117:proyectos:2015:i:proyecto_1:puesta_en_funcionamiento_de_paparazzi_en_un_stm32f3

Puesta en funcionamiento de Paparazzi en un STM32f3

Integrantes: Daniel García Vaglio (B42781), y Esteban Zamora Alvarado (B47769)

Primera Parte

Descripción

Este proyecto consiste en implementar un sistema de estabilización avanzado en un multicóptero para esto se utilizará paparazzi. Este coptero utilizará un STM32f3, que es un controlador de bajo costo y alto desempeño.

Objetivos

Objetivo general

Hacer funcionar un multicóptero por medio de Paparazzi con el microcontrolador STM32f3.

Objetivos específicos

Parte 1:

Daniel Garcia Vaglio:

  • Configurar el airframe para el multicóptero en Paparazzi.
  • Lograr la comunicación tierra-aire entre el multicóptero y una computadora.

Esteban Zamora Alvarado:

  • Compilar el airframe del multicóptero e instalarlo en el STM32f3 para describir el estado actual del programa en el microcontrolador.
  • Diseñar una tarjeta de adaptación entre STM32f3 y los motores.
  • Crear el tutorial para la instalación de Paparazzi en el STM32f3.

Parte 2:

Daniel Garcia Vaglio:

  • Implementar el mapeo de pines en el STM32f3 para el funcionamiento de Paparazzi en el microcontrolador.
  • Construcción del fuselaje para adaptarse al STM32f3.
  • Configurar el plan de vuelo del multicóptero.
  • Configurar el GPS y magnetómetro para lograr la estabilización del mismo por medio de Paparazzi.

Esteban Zamora Alvarado:

  • Configurar los acelerómetro, giroscopio y motores del multicóptero para lograr la estabilización del mismo por medio de Paparazzi.
  • Crear el tutorial para la configuración de los sensores y el vuelo del multicóptero por medio de Paparazzi.

Primera parte del Proyecto

Instalación

El primer paso fue descargar, compilar e instalar el programa Paparazzi en una computadora. Para el caso específico de este proyecto se utilizó una computadora con Debian. En el ARCOS-lab ya existía un tutorial para instalar Paparazzi sin embargo este no incluye las modificaciones para funcionar con el STM32f3. Entonces se utilizaron los branchs del git del ARCOS (disponibles Aqui). Existen tres branches: stm32f3discovery, stm32f3discovery-fede, stm32f3_memo.

El branch correcto es stm32f3_fede, que fue el único que compiló correctamente (Se descargaron los tres y se trató de compilar cada uno). En todos los casos, se presentaron errores con las dependencias:

    unable to locate boa

Esto se resolvió utilizando aptitude en lugar de apt-get

    
CC test_sdl_stick.o
In file included from test_sdl_stick.c:31:0:
sdl_stick.h:30:21: fatal error: SDL/SDL.h: No such file or directory
 #include <SDL/SDL.h>
	             ^
compilation terminated.
Makefile:85: recipe for target 'test_sdl_stick.o' failed
make[1]: *** [test_sdl_stick.o] Error 1
Makefile:147: recipe for target 'joystick' failed
make: *** [joystick] Error 2
""

Se resolvió con:

      sudo apt-get install libsdl1.2-dev python-yaml
      

También había otro error en el último paso de la compilación de stm32f3_fede. Esto era con luftboot:

   luftboot.c:486:26: error: 'STK_CTRL_CLKSOURCE_AHB_DIV8' undeclared (first use in this function)
   systick_set_clocksource(STK_CTRL_CLKSOURCE_AHB_DIV8);  
   

Se buscó en los archivos de paparazzi_master para encontrar la declaración de la variable. Se esncontró en el siguiente archivo: /local/src/paparazzi/paparazzi_master/sw/ext/libopencm3/include/libopencm3/cm3/systick.h. Luego se buscó el mismo archivo pero relativo en el branch stm32f3_fede, y no existe la declaración de la variable. En _fede estaban las mismas variables pero en lugar de STK_CTRL_CLKSOURCE_AHB_DIV8 se encontró STK_CSR_CLKSOURCE_AHB_DIV8. Entonces se cambió la referencia en luftboot a la variable correcta y paparazzi compiló correctamente.

Luego se tomó el tutorial existente para instalar paparazi y se modificó para instalar el paparazzi que funciona con el stm32f3. El mismo puede ser encontrado en: STM32f3 discovery with Paparazzi

Airframe

En el branch stm32f3_fede existe una configuración para el stm32f3 (en la carpeta ~HOME/local/src/paparazzi/paparazzi_fede/conf/airframes/examples/). Se estudió la documentación de paparazzi para determinar si estaba correcta la configuración actual. No se encontraron errores. La configuración actual es de un cóptero en T, entonces se comienza la transformación a un cuadracóptero en X. Para esto fue necesario cambiar las configuraciones en los comandos. Si adicionalmente se desearan agregar más motores, se deben definir en la configuración. En el tutorial se explican los pasos para hacer una configuración determinada.

Existen 4 comandos: pitch, roll, yaw, y thrust. Paparazzi define los valores positivos para cada comando. El valor postivo de pitch es subir la parte del frontal, el valor positivo de Roll es subir la parte izquierda, el yaw positivo es girar en contra de las manecillas del reloj, y el trhust positivo es aumentar la altura.

Lo que se debe definir entonces para cada comando es el comportamiento de cada motor. A esto se le llama “motor mixing”. En la documentación de paparazzi se proporcionan algunas configuraciones usuales, sin embargo no abarcaban todas las configuraciones de cópteros en el ARCOS-lab (específicamente el hexacóptero en Y). Para desarrollar motor mixing completamente nuevos se debió estudiar el sistema del cóptero en cada comando.

Paparazzi asume que los motores consecutivos tienen direcciones de rotación contrarias, esto para evitar un torque neto no nulo que provoque un giro indeseado del cóptero. Entonces el primer motor definido gira en contra del las manecillas del reloj, el segundo a favor, y así sucesivamente. Entonces para el comando YAW, se debe aumentar la velocidad de los motores de manera intercalada. Entocnes los motores impares aumentan su velocidad para generar un yaw positivo.

Thrust se logra aumentando la velocidad de todos los motores por igual.

Pitch y Roll son comandos especiales, ya que existen configuraciones en las que estos comandos no son simétricos. Si se define un eje de rotación para Roll o Pitch, y se tiene una diferente cantidad de motores en cada lado del eje entonces se debe encontrar un motor mixing específico para este caso. Lo primero que se debe tomar en consideración es que se pretende hacer girar el cóptero a una determinada velocidad angular, y que por tanto cada motor debe moverse a la misma velocidad angular. Por tanto los motores lejanos al eje deben rotar más rápido, y los cercanos más lento.

Sea x uno de los lados (frente, atrás, izquierda o derecha). Y sea Cx el vector de posición, con respecto al centro del cóptero, del motor más lejano al eje de rotación. Entonces de define el valor de este motor en motormixing como vx. Entonces vx=256.Ya que por ser el más lejano, entoncestiene el mayor valor de rotación. Ahora como todos los motores deben moverse a la misma velocidad rotacional entonces se obtiene la siguiente expresión:

Donde vi es el valor de cada motor, a y b es la cantidad de motores en cada lado, x la cantidad de motores en el lado que corresponde al motor en cuestión. Ca el ángulo que forma el vector de posición del motor más lejano al eje, y ci el ángulo de cada motor. En el tutorial se puede tener un desarrollo más completo del tema.

Una vez configurado el airframe se procede a subir el programa a la tarjeta. Para esto se leyó la documentación de paparazzi sobre GCS (la interfaz gráfica de paparazzi) y se logró sin problemas. En el tutorial se describe el proceso para hacerlo.

Luego se procedió a trabajar en la comunicación entre la computadora y el STM32f3. Libopencm3, que es la librería que se utiliza para programar el stm32f3, no tiene soporte para comunicación por usb. Entonces se utilizó la comunicación UART, y se emppleó un convertidor UART-USB ( UMFT234XF). La comunicación entre la computadora y la tarjeta se llevó acabo por medio de telemetría. Buscando en boardconfiguration (HOME/local/src/paparazzi/paparazzi_fede/sw/airborne/boards/stm32f3_discovery.h) se determinaron los pines correctos para conectar el convertidor,los cuales son PC4 y PC5 (UART1). Una vez conectado el convertidor se siguió la documentación de paparazzi y se logró realizar la comunicación. Para poder hacerlo en el caso específico del STM32f3 se puede seguir el tutorial.

Además, a continuación se presentan muchos airframe configurations útiles y comunes. Todos estos archivos fueron compilados y probados. La configuración de motores se garantiza que funciona, sin embargo los sensores aún no están calibrados.

P QuadCopter

 <!DOCTYPE airframe SYSTEM "../airframe.dtd">
<!-- this is a quadrotor frame equiped with
     * Autopilot:   Lisa/M 2.0             http://paparazzi.enac.fr/wiki/Lisa/M_v20
     * IMU:         Aspirin 2.1            http://paparazzi.enac.fr/wiki/AspirinIMU
     * Actuators:   PWM motor controllershttp://paparazzi.enac.fr/wiki/Subsystem/actuators#PWM_Supervision
     * GPS:         Ublox                  http://paparazzi.enac.fr/wiki/Subsystem/gps
     * RC:          two Spektrum sats      http://paparazzi.enac.fr/wiki/Subsystem/radio_control#Spektrum
-->
<airframe name="Quadrotor stm32f3_discovery pwm ppm">
  <firmware name="rotorcraft">
    <target name="ap" board="stm32f3_discovery">
      <subsystem name="radio_control" type="spektrum"> <!-- Check this!! -->
	<define name="RADIO_MODE" value="RADIO_AUX1"/>
	<!-- <configure name="USE_SECONDARY_PPM_RECEIVER" value="1"/> <\!-- Check this!! -\-> -->
      </subsystem>
      <!-- MPU6000 is configured to output data at 2kHz, but polled at 512Hz PERIODIC_FREQUENCY -->
      <define name="STM32F3_DISCOVERY_I2C1_FOR_LSM303DLHC"/>
      <define name="STM32F3_DISCOVERY_SPI1_FOR_L3GD20"/>
      <configure name="FLASH_MODE" value="STLINK" />
      <configure name="STLINK" value="y" />
      <configure name="NO_LUFTBOOT" value="1" />
      <define name="LUFTBOOT" value="0" />
    <!-- <define name="I2C1_CLOCK_SPEED" value="100000"/> -->
    </target>
    <target name="nps" board="pc">
      <subsystem name="fdm" type="jsbsim"/>
      <subsystem name="radio_control" type="ppm"/>
    </target>
    <subsystem name="motor_mixing"/>
    <subsystem name="actuators"     type="pwm">
      <define name="SERVO_HZ" value="400"/>
      <!-- <define name="USE_SERVOS_7AND8"/> -->
    </subsystem>
    <subsystem name="telemetry"     type="transparent"/>
    <subsystem name="imu"           type="stm32f3_discoveryimu"/>
    <subsystem name="gps"           type="ublox"/>
    <subsystem name="stabilization" type="int_quat"/>
    <subsystem name="ahrs"          type="int_cmpl_quat">
      <define name="AHRS_GRAVITY_UPDATE_NORM_HEURISTIC" value="TRUE"/>
    </subsystem>
    <subsystem name="ins"/>
    <!--define name="KILL_ON_GROUND_DETECT" value="TRUE"/-->
    <define name="PRINT_CONFIG"/>
  </firmware>
          
  <servos driver="Pwm">
    <servo name="FRONT"   no="0" min="1000" neutral="1100" max="1900"/>
    <servo name="BACK"    no="1" min="1000" neutral="1100" max="1900"/>
    <servo name="RIGHT"   no="2" min="1000" neutral="1100" max="1900"/>
    <servo name="LEFT"    no="3" min="1000" neutral="1100" max="1900"/>
  </servos>
         
  <commands>
    <axis name="ROLL"   failsafe_value="0"/>
    <axis name="PITCH"  failsafe_value="0"/>
    <axis name="YAW"    failsafe_value="0"/>
    <axis name="THRUST" failsafe_value="0"/>
  </commands>
        
  <section name="MIXING" prefix="MOTOR_MIXING_">
    <define name="TRIM_ROLL" value="0"/>
    <define name="TRIM_PITCH" value="0"/>
    <define name="TRIM_YAW" value="0"/>
    <define name="NB_MOTOR" value="4"/>
    <define name="SCALE" value="256"/>
    <!-- front/back turning CW, right/left CCW -->
    <define name="ROLL_COEF"   value="{    0,    0, -256,  256 }"/>
    <define name="PITCH_COEF"  value="{  256, -256,    0,    0 }"/>
    <define name="YAW_COEF"    value="{ -256, -256,  256,  256 }"/>
    <define name="THRUST_COEF" value="{  256,  256,  256,  256 }"/>
  </section>
         
  <command_laws>
    <call fun="motor_mixing_run(autopilot_motors_on,FALSE,values)"/>
    <set servo="FRONT"  value="motor_mixing.commands[SERVO_FRONT]"/>
    <set servo="BACK"   value="motor_mixing.commands[SERVO_BACK]"/>
    <set servo="RIGHT"  value="motor_mixing.commands[SERVO_RIGHT]"/>
    <set servo="LEFT"   value="motor_mixing.commands[SERVO_LEFT]"/>
  </command_laws>
         
  <section name="IMU" prefix="IMU_">
    <define name="ACCEL_X_NEUTRAL" value="11"/>
    <define name="ACCEL_Y_NEUTRAL" value="11"/>
    <define name="ACCEL_Z_NEUTRAL" value="-25"/>
    <!-- replace this with your own calibration -->
    <define name="MAG_X_NEUTRAL" value="-179"/>
    <define name="MAG_Y_NEUTRAL" value="-21"/>
    <define name="MAG_Z_NEUTRAL" value="79"/>
    <define name="MAG_X_SENS" value="4.17334785618" integer="16"/>
    <define name="MAG_Y_SENS" value="3.98885954135" integer="16"/>
    <define name="MAG_Z_SENS" value="4.40442339014" integer="16"/>
    <define name="BODY_TO_IMU_PHI"   value="0." unit="deg"/>
    <define name="BODY_TO_IMU_THETA" value="0." unit="deg"/>
    <define name="BODY_TO_IMU_PSI"   value="0." unit="deg"/>
  </section>
          
  <section name="AHRS" prefix="AHRS_">
    <define name="H_X" value="0.3770441"/>
    <define name="H_Y" value="0.0193986"/>
    <define name="H_Z" value="0.9259921"/>
  </section>
          
  <section name="INS" prefix="INS_">
    <define name="BARO_SENS" value="22.3" integer="16"/>
  </section>
          
  <section name="STABILIZATION_RATE" prefix="STABILIZATION_RATE_">
    <!-- setpoints -->
    <define name="SP_MAX_P" value="10000"/>
    <define name="SP_MAX_Q" value="10000"/>
    <define name="SP_MAX_R" value="10000"/>
    <define name="DEADBAND_P" value="20"/>
    <define name="DEADBAND_Q" value="20"/>
    <define name="DEADBAND_R" value="200"/>
    <define name="REF_TAU" value="4"/>
    <!-- feedback -->
    <define name="GAIN_P" value="400"/>
    <define name="GAIN_Q" value="400"/>
    <define name="GAIN_R" value="350"/>
    <define name="IGAIN_P" value="75"/>
    <define name="IGAIN_Q" value="75"/>
    <define name="IGAIN_R" value="50"/>
    <!-- feedforward -->
    <define name="DDGAIN_P" value="300"/>
    <define name="DDGAIN_Q" value="300"/>
    <define name="DDGAIN_R" value="300"/>
  </section>
     
 
  <section name="STABILIZATION_ATTITUDE" prefix="STABILIZATION_ATTITUDE_">
    <!-- setpoints -->
    <define name="SP_MAX_PHI"     value="45." unit="deg"/>
    <define name="SP_MAX_THETA"   value="45." unit="deg"/>
    <define name="SP_MAX_R"       value="90." unit="deg/s"/>
    <define name="DEADBAND_A"     value="0"/>
    <define name="DEADBAND_E"     value="0"/>
    <define name="DEADBAND_R"     value="250"/>
    <!-- reference -->
    <define name="REF_OMEGA_P"  value="800" unit="deg/s"/>
    <define name="REF_ZETA_P"   value="0.85"/>
    <define name="REF_MAX_P"    value="400." unit="deg/s"/>
    <define name="REF_MAX_PDOT" value="RadOfDeg(8000.)"/>
    <define name="REF_OMEGA_Q"  value="800" unit="deg/s"/>
    <define name="REF_ZETA_Q"   value="0.85"/>
    <define name="REF_MAX_Q"    value="400." unit="deg/s"/>
    <define name="REF_MAX_QDOT" value="RadOfDeg(8000.)"/>
    <define name="REF_OMEGA_R"  value="500" unit="deg/s"/>
    <define name="REF_ZETA_R"   value="0.85"/>
    <define name="REF_MAX_R"    value="180." unit="deg/s"/>
    <define name="REF_MAX_RDOT" value="RadOfDeg(1800.)"/>
    <!-- feedback -->
    <define name="PHI_PGAIN"  value="1000"/>
    <define name="PHI_DGAIN"  value="400"/>
    <define name="PHI_IGAIN"  value="200"/>
    <define name="THETA_PGAIN"  value="1000"/>
    <define name="THETA_DGAIN"  value="400"/>
    <define name="THETA_IGAIN"  value="200"/>
    <define name="PSI_PGAIN"  value="500"/>
    <define name="PSI_DGAIN"  value="300"/>
    <define name="PSI_IGAIN"  value="10"/>
    <!-- feedforward -->
    <define name="PHI_DDGAIN"   value="300"/>
    <define name="THETA_DDGAIN" value="300"/>
    <define name="PSI_DDGAIN"   value="300"/>
  </section>
         
  <section name="GUIDANCE_V" prefix="GUIDANCE_V_">
    <define name="MIN_ERR_Z"   value="POS_BFP_OF_REAL(-10.)"/>
    <define name="MAX_ERR_Z"   value="POS_BFP_OF_REAL( 10.)"/>
    <define name="MIN_ERR_ZD"  value="SPEED_BFP_OF_REAL(-10.)"/>
    <define name="MAX_ERR_ZD"  value="SPEED_BFP_OF_REAL( 10.)"/>
    <define name="MAX_SUM_ERR" value="2000000"/>
    <define name="HOVER_KP"    value="150"/>
    <define name="HOVER_KD"    value="80"/>
    <define name="HOVER_KI"    value="20"/>
    <!-- 1.5m/s for full stick : BOOZ_SPEED_I_OF_F(1.5) / (MAX_PPRZ/2) -->
    <define name="RC_CLIMB_COEF" value ="163"/>
    <!-- BOOZ_SPEED_I_OF_F(1.5) * 20% -->
    <define name="RC_CLIMB_DEAD_BAND" value ="160000"/>
    <define name="NOMINAL_HOVER_THROTTLE" value="0.5"/>
    <define name="ADAPT_THROTTLE_ENABLED" value="TRUE"/>
  </section>
           
  <section name="GUIDANCE_H" prefix="GUIDANCE_H_">
    <define name="MAX_BANK" value="20" unit="deg"/>
    <define name="PGAIN" value="50"/>
    <define name="DGAIN" value="100"/>
    <define name="AGAIN" value="100"/>
    <define name="IGAIN" value="20"/>
  </section>
        
  <section name="SIMULATOR" prefix="NPS_">
    <define name="ACTUATOR_NAMES"  value="{&quot;front_motor&quot;, &quot;back_motor&quot;, &quot;right_motor&quot;, &quot;left_motor&quot;}"/>
    <define name="JSBSIM_INIT" value="&quot;reset00&quot;"/>
    <define name="SENSORS_PARAMS" value="&quot;nps_sensors_params_default.h&quot;"/>
    <!-- mode switch on joystick channel 5 (axis numbering starting at zero) -->
    <define name="JS_AXIS_MODE" value="4"/>
  </section>
         
  <section name="AUTOPILOT">
    <define name="MODE_MANUAL" value="AP_MODE_ATTITUDE_DIRECT"/>
    <define name="MODE_AUTO1"  value="AP_MODE_HOVER_Z_HOLD"/>
    <define name="MODE_AUTO2"  value="AP_MODE_NAV"/>
  </section>
         

</airframe>

X Quadcopter

      <!DOCTYPE airframe SYSTEM "../airframe.dtd">
        
<!-- this is a quadrotor frame equiped with
     * Autopilot:   Lisa/M 2.0             http://paparazzi.enac.fr/wiki/Lisa/M_v20
     * IMU:         Aspirin 2.1            http://paparazzi.enac.fr/wiki/AspirinIMU
     * Actuators:   PWM motor controllers  http://paparazzi.enac.fr/wiki/Subsystem/actuators#PWM_Supervision
     * GPS:         Ublox                  http://paparazzi.enac.fr/wiki/Subsystem/gps
     * RC:          two Spektrum sats      http://paparazzi.enac.fr/wiki/Subsystem/radio_control#Spektrum
-->
       
<airframe name="Quadrotor stm32f3_discovery pwm ppm">
        
  <firmware name="rotorcraft">
    <target name="ap" board="stm32f3_discovery">
      <subsystem name="radio_control" type="spektrum"> <!-- Check this!! -->
	<define name="RADIO_MODE" value="RADIO_AUX1"/>
	<!-- <configure name="USE_SECONDARY_PPM_RECEIVER" value="1"/> <\!-- Check this!! -\-> -->
      </subsystem>
      <!-- MPU6000 is configured to output data at 2kHz, but polled at 512Hz PERIODIC_FREQUENCY -->
      <define name="STM32F3_DISCOVERY_I2C1_FOR_LSM303DLHC"/>
      <define name="STM32F3_DISCOVERY_SPI1_FOR_L3GD20"/>
      <configure name="FLASH_MODE" value="STLINK" />
      <configure name="STLINK" value="y" />
      <configure name="NO_LUFTBOOT" value="1" />
      <define name="LUFTBOOT" value="0" />
    <!-- <define name="I2C1_CLOCK_SPEED" value="100000"/> -->
    </target>
           
    <target name="nps" board="pc">
      <subsystem name="fdm" type="jsbsim"/>
      <subsystem name="radio_control" type="ppm"/>
    </target>
            
    <subsystem name="motor_mixing"/>
    <subsystem name="actuators"     type="pwm">
      <define name="SERVO_HZ" value="400"/>
      <!-- <define name="USE_SERVOS_7AND8"/> -->
    </subsystem>
           
    <subsystem name="telemetry"     type="transparent"/>
    <subsystem name="imu"           type="stm32f3_discoveryimu"/>
    <subsystem name="gps"           type="ublox"/>
    <subsystem name="stabilization" type="int_quat"/>
    <subsystem name="ahrs"          type="int_cmpl_quat">
      <define name="AHRS_GRAVITY_UPDATE_NORM_HEURISTIC" value="TRUE"/>
    </subsystem>
    <subsystem name="ins"/>
           
    <!--define name="KILL_ON_GROUND_DETECT" value="TRUE"/-->
    <define name="PRINT_CONFIG"/>
  </firmware>
         
  <servos driver="Pwm">
    <servo name="NE"    no="0" min="1000" neutral="1100" max="1900"/>
    <servo name="SE"    no="1" min="1000" neutral="1100" max="1900"/>
    <servo name="SW"    no="2" min="1000" neutral="1100" max="1900"/>
    <servo name="NW"    no="3" min="1000" neutral="1100" max="1900"/>
  </servos>
         
  <commands>
    <axis name="ROLL"   failsafe_value="0"/>
    <axis name="PITCH"  failsafe_value="0"/>
    <axis name="YAW"    failsafe_value="0"/>
    <axis name="THRUST" failsafe_value="0"/>
  </commands>
         
  <section name="MIXING" prefix="MOTOR_MIXING_">
    <define name="TRIM_ROLL" value="0"/>
    <define name="TRIM_PITCH" value="0"/>
    <define name="TRIM_YAW" value="0"/>
    <define name="NB_MOTOR" value="4"/>
    <define name="SCALE" value="256"/>
    <!-- front/back turning CW, right/left CCW -->
    <define name="ROLL_COEF"   value="{ -256, -256,  256,  256 }"/>
    <define name="PITCH_COEF"  value="{  256, -256, -256,  256 }"/>
    <define name="YAW_COEF"    value="{ -256,  256, -256,  256 }"/>
    <define name="THRUST_COEF" value="{  256,  256,  256,  256 }"/>
  </section>
         
  
  <command_laws>
    <call fun="motor_mixing_run(autopilot_motors_on,FALSE,values)"/>
    <set servo="NE"   value="motor_mixing.commands[0]"/>
    <set servo="SE"   value="motor_mixing.commands[1]"/>
    <set servo="SW"   value="motor_mixing.commands[2]"/>
    <set servo="NW"   value="motor_mixing.commands[3]"/>
  </command_laws>
         
  <section name="IMU" prefix="IMU_">
    <define name="ACCEL_X_NEUTRAL" value="11"/>
    <define name="ACCEL_Y_NEUTRAL" value="11"/>
    <define name="ACCEL_Z_NEUTRAL" value="-25"/>
    <!-- replace this with your own calibration -->
    <define name="MAG_X_NEUTRAL" value="-179"/>
    <define name="MAG_Y_NEUTRAL" value="-21"/>
    <define name="MAG_Z_NEUTRAL" value="79"/>
    <define name="MAG_X_SENS" value="4.17334785618" integer="16"/>
    <define name="MAG_Y_SENS" value="3.98885954135" integer="16"/>
    <define name="MAG_Z_SENS" value="4.40442339014" integer="16"/>
          
    <define name="BODY_TO_IMU_PHI"   value="0." unit="deg"/>
    <define name="BODY_TO_IMU_THETA" value="0." unit="deg"/>
    <define name="BODY_TO_IMU_PSI"   value="0." unit="deg"/>
  </section>
          
  <section name="AHRS" prefix="AHRS_">
    <define name="H_X" value="0.3770441"/>
    <define name="H_Y" value="0.0193986"/>
    <define name="H_Z" value="0.9259921"/>
  </section>
        
  <section name="INS" prefix="INS_">
    <define name="BARO_SENS" value="22.3" integer="16"/>
  </section>
          
  <section name="STABILIZATION_RATE" prefix="STABILIZATION_RATE_">
    <!-- setpoints -->
    <define name="SP_MAX_P" value="10000"/>
    <define name="SP_MAX_Q" value="10000"/>
    <define name="SP_MAX_R" value="10000"/>
    <define name="DEADBAND_P" value="20"/>
    <define name="DEADBAND_Q" value="20"/>
    <define name="DEADBAND_R" value="200"/>
    <define name="REF_TAU" value="4"/>
           
    <define name="GAIN_P" value="400"/>
    <define name="GAIN_Q" value="400"/>
    <define name="GAIN_R" value="350"/>
           
    <define name="IGAIN_P" value="75"/>
    <define name="IGAIN_Q" value="75"/>
    <define name="IGAIN_R" value="50"/>
            
    <define name="DDGAIN_P" value="300"/>
    <define name="DDGAIN_Q" value="300"/>
    <define name="DDGAIN_R" value="300"/>
  </section>
          
        
  <section name="STABILIZATION_ATTITUDE" prefix="STABILIZATION_ATTITUDE_">
    <!-- setpoints -->
    <define name="SP_MAX_PHI"     value="45." unit="deg"/>
    <define name="SP_MAX_THETA"   value="45." unit="deg"/>
    <define name="SP_MAX_R"       value="90." unit="deg/s"/>
    <define name="DEADBAND_A"     value="0"/>
    <define name="DEADBAND_E"     value="0"/>
    <define name="DEADBAND_R"     value="250"/>
             
    <!-- reference -->
    <define name="REF_OMEGA_P"  value="800" unit="deg/s"/>
    <define name="REF_ZETA_P"   value="0.85"/>
    <define name="REF_MAX_P"    value="400." unit="deg/s"/>
    <define name="REF_MAX_PDOT" value="RadOfDeg(8000.)"/>
          
    <define name="REF_OMEGA_Q"  value="800" unit="deg/s"/>
    <define name="REF_ZETA_Q"   value="0.85"/>
    <define name="REF_MAX_Q"    value="400." unit="deg/s"/>
    <define name="REF_MAX_QDOT" value="RadOfDeg(8000.)"/>
           
    <define name="REF_OMEGA_R"  value="500" unit="deg/s"/>
    <define name="REF_ZETA_R"   value="0.85"/>
    <define name="REF_MAX_R"    value="180." unit="deg/s"/>
    <define name="REF_MAX_RDOT" value="RadOfDeg(1800.)"/>
          
    <!-- feedback -->
    <define name="PHI_PGAIN"  value="1000"/>
    <define name="PHI_DGAIN"  value="400"/>
    <define name="PHI_IGAIN"  value="200"/>
            
    <define name="THETA_PGAIN"  value="1000"/>
    <define name="THETA_DGAIN"  value="400"/>
    <define name="THETA_IGAIN"  value="200"/>
           
    <define name="PSI_PGAIN"  value="500"/>
    <define name="PSI_DGAIN"  value="300"/>
    <define name="PSI_IGAIN"  value="10"/>
            
    <!-- feedforward -->
    <define name="PHI_DDGAIN"   value="300"/>
    <define name="THETA_DDGAIN" value="300"/>
    <define name="PSI_DDGAIN"   value="300"/>
  </section>
          
  <section name="GUIDANCE_V" prefix="GUIDANCE_V_">
    <define name="MIN_ERR_Z"   value="POS_BFP_OF_REAL(-10.)"/>
    <define name="MAX_ERR_Z"   value="POS_BFP_OF_REAL( 10.)"/>
    <define name="MIN_ERR_ZD"  value="SPEED_BFP_OF_REAL(-10.)"/>
    <define name="MAX_ERR_ZD"  value="SPEED_BFP_OF_REAL( 10.)"/>
    <define name="MAX_SUM_ERR" value="2000000"/>
    <define name="HOVER_KP"    value="150"/>
    <define name="HOVER_KD"    value="80"/>
    <define name="HOVER_KI"    value="20"/> 
    <define name="RC_CLIMB_COEF" value ="163"/>
    <define name="RC_CLIMB_DEAD_BAND" value ="160000"/>
    <define name="NOMINAL_HOVER_THROTTLE" value="0.5"/>
    <define name="ADAPT_THROTTLE_ENABLED" value="TRUE"/>
  </section>
        
  <section name="GUIDANCE_H" prefix="GUIDANCE_H_">
    <define name="MAX_BANK" value="20" unit="deg"/>
    <define name="PGAIN" value="50"/>
    <define name="DGAIN" value="100"/>
    <define name="AGAIN" value="100"/>
    <define name="IGAIN" value="20"/>
  </section>
          
  <section name="SIMULATOR" prefix="NPS_">
    <define name="ACTUATOR_NAMES"  value="{&quot;ne_motor&quot;, &quot;se_motor&quot;, &quot;sw_motor&quot;, &quot;nw_motor&quot;}"/>
    <define name="JSBSIM_INIT" value="&quot;reset00&quot;"/>
    <define name="SENSORS_PARAMS" value="&quot;nps_sensors_params_default.h&quot;"/>
    <!-- mode switch on joystick channel 5 (axis numbering starting at zero) -->
    <define name="JS_AXIS_MODE" value="4"/>
  </section>
         
  <section name="AUTOPILOT">
    <define name="MODE_MANUAL" value="AP_MODE_ATTITUDE_DIRECT"/>
    <define name="MODE_AUTO1"  value="AP_MODE_HOVER_Z_HOLD"/>
    <define name="MODE_AUTO2"  value="AP_MODE_NAV"/>
  </section>

</airframe>

HexaCopter Y

      <!DOCTYPE airframe SYSTEM "../airframe.dtd">
       
<!-- this is a quadrotor frame equiped with
     * Autopilot:   Lisa/M 2.0             http://paparazzi.enac.fr/wiki/Lisa/M_v20
     * IMU:         Aspirin 2.1            http://paparazzi.enac.fr/wiki/AspirinIMU
     * Actuators:   PWM motor controllers  http://paparazzi.enac.fr/wiki/Subsystem/actuators#PWM_Supervision
     * GPS:         Ublox                  http://paparazzi.enac.fr/wiki/Subsystem/gps
     * RC:          two Spektrum sats      http://paparazzi.enac.fr/wiki/Subsystem/radio_control#Spektrum
-->
        
<airframe name="Quadrotor stm32f3_discovery pwm ppm">
          
  <firmware name="rotorcraft">
    <target name="ap" board="stm32f3_discovery">
      <subsystem name="radio_control" type="spektrum"> <!-- Check this!! -->
	<define name="RADIO_MODE" value="RADIO_AUX1"/>
	<!-- <configure name="USE_SECONDARY_PPM_RECEIVER" value="1"/> <\!-- Check this!! -\-> -->
      </subsystem>
      <!-- MPU6000 is configured to output data at 2kHz, but polled at 512Hz PERIODIC_FREQUENCY -->
      <define name="STM32F3_DISCOVERY_I2C1_FOR_LSM303DLHC"/>
      <define name="STM32F3_DISCOVERY_SPI1_FOR_L3GD20"/>
      <configure name="FLASH_MODE" value="STLINK" />
      <configure name="STLINK" value="y" />
      <configure name="NO_LUFTBOOT" value="1" />
      <define name="LUFTBOOT" value="0" />
    <!-- <define name="I2C1_CLOCK_SPEED" value="100000"/> -->
    </target>
           
    <target name="nps" board="pc">
      <subsystem name="fdm" type="jsbsim"/>
      <subsystem name="radio_control" type="ppm"/>
    </target>
            
    <subsystem name="motor_mixing"/>
    <subsystem name="actuators"     type="pwm">
      <define name="SERVO_HZ" value="400"/>
      <!-- <define name="USE_SERVOS_7AND8"/> -->
    </subsystem>
            
    <subsystem name="telemetry"     type="transparent"/>
    <subsystem name="imu"           type="stm32f3_discoveryimu"/>
    <subsystem name="gps"           type="ublox"/>
    <subsystem name="stabilization" type="int_quat"/>
    <subsystem name="ahrs"          type="int_cmpl_quat">
      <define name="AHRS_GRAVITY_UPDATE_NORM_HEURISTIC" value="TRUE"/>
    </subsystem>
    <subsystem name="ins"/>
            
    <!--define name="KILL_ON_GROUND_DETECT" value="TRUE"/-->
    <define name="PRINT_CONFIG"/>
  </firmware>
         
  <servos driver="Pwm">
    <servo name="LEFT_UP"    no="0" min="1000" neutral="1100" max="1900"/>
    <servo name="RIGHT_UP"    no="1" min="1000" neutral="1100" max="1900"/>
    <servo name="BACK_UP"    no="2" min="1000" neutral="1100" max="1900"/>
    <servo name="LEFT_DW"    no="3" min="1000" neutral="1100" max="1900"/>
    <servo name="RIGHT_DW"    no="4" min="1000" neutral="1100" max="1900"/>
    <servo name="BACK_DW"    no="5" min="1000" neutral="1100" max="1900"/>
  </servos>
         
  <commands>
    <axis name="ROLL"   failsafe_value="0"/>
    <axis name="PITCH"  failsafe_value="0"/>
    <axis name="YAW"    failsafe_value="0"/>
    <axis name="THRUST" failsafe_value="0"/>
  </commands>
         
  <section name="MIXING" prefix="MOTOR_MIXING_">
    <define name="TRIM_ROLL" value="0"/>
    <define name="TRIM_PITCH" value="0"/>
    <define name="TRIM_YAW" value="0"/>
    <define name="NB_MOTOR" value="6"/>
    <define name="SCALE" value="256"/>
    <!-- front/back turning CW, right/left CCW -->
    
    <define name="ROLL_COEF" value="{256, -256, 0, 256, -256, 0}"/>
    <define name="PITCH_COEF" value="{128, 128, -256, 128, 128, -256}"/>
    <define name="YAW_COEF" value="{-256, 256, -256, 256, -259, 256}"/>
    <define name="THRUST_COEF" value="{256, 256, 256, 256, 256, 256}"/>	
  </section>
   
  <command_laws>
    <call fun="motor_mixing_run(autopilot_motors_on,FALSE,values)"/>
    <set servo="LEFT_UP"   value="motor_mixing.commands[0]"/>
    <set servo="RIGHT_UP"   value="motor_mixing.commands[1]"/>
    <set servo="BACK_UP"   value="motor_mixing.commands[2]"/>
    <set servo="LEFT_DW"   value="motor_mixing.commands[3]"/>
    <set servo="RIGHT_DW"   value="motor_mixing.commands[4]"/>
    <set servo="BACK_DW"   value="motor_mixing.commands[5]"/>
  </command_laws>
         
  <section name="IMU" prefix="IMU_">
    <define name="ACCEL_X_NEUTRAL" value="11"/>
    <define name="ACCEL_Y_NEUTRAL" value="11"/>
    <define name="ACCEL_Z_NEUTRAL" value="-25"/>
           
    <!-- replace this with your own calibration -->
    <define name="MAG_X_NEUTRAL" value="-179"/>
    <define name="MAG_Y_NEUTRAL" value="-21"/>
    <define name="MAG_Z_NEUTRAL" value="79"/>
    <define name="MAG_X_SENS" value="4.17334785618" integer="16"/>
    <define name="MAG_Y_SENS" value="3.98885954135" integer="16"/>
    <define name="MAG_Z_SENS" value="4.40442339014" integer="16"/>
            
    <define name="BODY_TO_IMU_PHI"   value="0." unit="deg"/>
    <define name="BODY_TO_IMU_THETA" value="0." unit="deg"/>
    <define name="BODY_TO_IMU_PSI"   value="0." unit="deg"/>
  </section>
        
  <section name="AHRS" prefix="AHRS_">
    <define name="H_X" value="0.3770441"/>
    <define name="H_Y" value="0.0193986"/>
    <define name="H_Z" value="0.9259921"/>
  </section>
         
  <section name="INS" prefix="INS_">
    <define name="BARO_SENS" value="22.3" integer="16"/>
  </section>
          
  <section name="STABILIZATION_RATE" prefix="STABILIZATION_RATE_">
    <!-- setpoints -->
    <define name="SP_MAX_P" value="10000"/>
    <define name="SP_MAX_Q" value="10000"/>
    <define name="SP_MAX_R" value="10000"/>
    <define name="DEADBAND_P" value="20"/>
    <define name="DEADBAND_Q" value="20"/>
    <define name="DEADBAND_R" value="200"/>
    <define name="REF_TAU" value="4"/>
           
    <!-- feedback -->
    <define name="GAIN_P" value="400"/>
    <define name="GAIN_Q" value="400"/>
    <define name="GAIN_R" value="350"/>
           
    <define name="IGAIN_P" value="75"/>
    <define name="IGAIN_Q" value="75"/>
    <define name="IGAIN_R" value="50"/>
            
    <!-- feedforward -->
    <define name="DDGAIN_P" value="300"/>
    <define name="DDGAIN_Q" value="300"/>
    <define name="DDGAIN_R" value="300"/>
  </section>
            
         
  <section name="STABILIZATION_ATTITUDE" prefix="STABILIZATION_ATTITUDE_">
    <!-- setpoints -->
    <define name="SP_MAX_PHI"     value="45." unit="deg"/>
    <define name="SP_MAX_THETA"   value="45." unit="deg"/>
    <define name="SP_MAX_R"       value="90." unit="deg/s"/>
    <define name="DEADBAND_A"     value="0"/>
    <define name="DEADBAND_E"     value="0"/>
    <define name="DEADBAND_R"     value="250"/>
            
    <!-- reference -->
    <define name="REF_OMEGA_P"  value="800" unit="deg/s"/>
    <define name="REF_ZETA_P"   value="0.85"/>
    <define name="REF_MAX_P"    value="400." unit="deg/s"/>
    <define name="REF_MAX_PDOT" value="RadOfDeg(8000.)"/>
           
    <define name="REF_OMEGA_Q"  value="800" unit="deg/s"/>
    <define name="REF_ZETA_Q"   value="0.85"/>
    <define name="REF_MAX_Q"    value="400." unit="deg/s"/>
    <define name="REF_MAX_QDOT" value="RadOfDeg(8000.)"/>
           
    <define name="REF_OMEGA_R"  value="500" unit="deg/s"/>
    <define name="REF_ZETA_R"   value="0.85"/>
    <define name="REF_MAX_R"    value="180." unit="deg/s"/>
    <define name="REF_MAX_RDOT" value="RadOfDeg(1800.)"/>
          
    <!-- feedback -->
    <define name="PHI_PGAIN"  value="1000"/>
    <define name="PHI_DGAIN"  value="400"/>
    <define name="PHI_IGAIN"  value="200"/>
        
    <define name="THETA_PGAIN"  value="1000"/>
    <define name="THETA_DGAIN"  value="400"/>
    <define name="THETA_IGAIN"  value="200"/>
           
    <define name="PSI_PGAIN"  value="500"/>
    <define name="PSI_DGAIN"  value="300"/>
    <define name="PSI_IGAIN"  value="10"/>
                 
    <!-- feedforward -->
    <define name="PHI_DDGAIN"   value="300"/>
    <define name="THETA_DDGAIN" value="300"/>
    <define name="PSI_DDGAIN"   value="300"/>
  </section>
      
  <section name="GUIDANCE_V" prefix="GUIDANCE_V_">
    <define name="MIN_ERR_Z"   value="POS_BFP_OF_REAL(-10.)"/>
    <define name="MAX_ERR_Z"   value="POS_BFP_OF_REAL( 10.)"/>
    <define name="MIN_ERR_ZD"  value="SPEED_BFP_OF_REAL(-10.)"/>
    <define name="MAX_ERR_ZD"  value="SPEED_BFP_OF_REAL( 10.)"/>
    <define name="MAX_SUM_ERR" value="2000000"/>
    <define name="HOVER_KP"    value="150"/>
    <define name="HOVER_KD"    value="80"/>
    <define name="HOVER_KI"    value="20"/>
    <!-- 1.5m/s for full stick : BOOZ_SPEED_I_OF_F(1.5) / (MAX_PPRZ/2) -->
    <define name="RC_CLIMB_COEF" value ="163"/>
    <!-- BOOZ_SPEED_I_OF_F(1.5) * 20% -->
    <define name="RC_CLIMB_DEAD_BAND" value ="160000"/>
    <define name="NOMINAL_HOVER_THROTTLE" value="0.5"/>
    <define name="ADAPT_THROTTLE_ENABLED" value="TRUE"/>
  </section>
         
  <section name="GUIDANCE_H" prefix="GUIDANCE_H_">
    <define name="MAX_BANK" value="20" unit="deg"/>
    <define name="PGAIN" value="50"/>
    <define name="DGAIN" value="100"/>
    <define name="AGAIN" value="100"/>
    <define name="IGAIN" value="20"/>
  </section>
        
  <section name="SIMULATOR" prefix="NPS_">
    <define name="ACTUATOR_NAMES"  value="{&quot;left_up_motor&quot;, &quot;right_up_motor&quot;, &quot;back_up_motor&quot;, &quot;left_up_motor&quot;, &quot;right_up_motor&quot;, &quot;back_up_motor&quot;}"/>
    <define name="JSBSIM_INIT" value="&quot;reset00&quot;"/>
    <define name="SENSORS_PARAMS" value="&quot;nps_sensors_params_default.h&quot;"/>
    <!-- mode switch on joystick channel 5 (axis numbering starting at zero) -->
    <define name="JS_AXIS_MODE" value="4"/>
  </section>
       
  <section name="AUTOPILOT">
    <define name="MODE_MANUAL" value="AP_MODE_ATTITUDE_DIRECT"/>
    <define name="MODE_AUTO1"  value="AP_MODE_HOVER_Z_HOLD"/>
    <define name="MODE_AUTO2"  value="AP_MODE_NAV"/>
  </section>
      
 
       
</airframe>

Tarjeta PCB de adaptación

El objetivo inicial era hacer una tarjeta de adaptación para los motores, sin embargo, debido a las necesidades del ARCOS-lab, se decidió incluir conectores extra: 2 salidas de UART1 (telemetría), una es para el convertidor uart usb y otro para el xbee. Una salida UART2 para el gps, 8 salidas PWM para motores, 1 salida UART3, 4 salidas SPI y 2 salidas I2C.

La primera etapa para diseñar la tarjeta de adaptación consistió en identificar los pines del STM32F3 y cómo estos eran utilizados en Paparazzi. Esto se encontró por medio de dos fuentes. La primera fue la hoja del fabricante del STM32F3 y la segunda fueron los documentos referentes a la definición del microcontrolador (STM32F3) en Paparazzi. Estas definiciones se encuentran en: /HOME/local/src/paparazzi/paparazzi/sw/airborne/boards/stm32f3_discovery.h.

La configuración de pines que se tenía al momento de terminar la primera parte del proyecto es la siguiente:

PA5  = SPI1 SCK if STM32F3_DISCOVERY_SPI1_FOR_L3GD20,              pp: SPI1 SCK
PA6  = SPI1 MISO if STM32F3_DISCOVERY_SPI1_FOR_L3GD20,             pp: SPI1 MISO
PA7  = SPI1 MOSI if STM32F3_DISCOVERY_SPI1_FOR_L3GD20,             pp: SPI1 MOSI
 * PA13 = SWDIO (FREE?),                                           pp: TIM4  CH3
 * PA14 = SWCLK (FREE?),                                           pp: UART2 TX, pp: I2C1 SDA, pp: TIM8  CH2
 * PB3  = SWO (FREE?),                                             pp: UART2 TX, pp: SPI1 SCK, SPI3 SCK, pp: TIM2  CH2
PB6  = I2C1 SCL if STM32F3_DISCOVERY_I2C1_FOR_LSM303DLHC,          pp: I2C1 SCL
PB7  = I2C1 SDA if STM32F3_DISCOVERY_I2C1_FOR_LSM303DLHC,          pp: I2C1 SDA
PC14 = OSC32_IN
PC15 = OSC32_OUT
PE0  = INT1 if STM32F3_DISCOVERY_SPI1_FOR_L3GD20
PE1  = DRDY/INT2 if STM32F3_DISCOVERY_SPI1_FOR_L3GD20
PE2  = DRDY if STM32F3_DISCOVERY_I2C1_FOR_LSM303DLHC
PE3  = CS_I2C/SPI if STM32F3_DISCOVERY_SPI1_FOR_L3GD20
PE4  = INT1 if STM32F3_DISCOVERY_I2C1_FOR_LSM303DLHC
PE5  = INT2 if STM32F3_DISCOVERY_I2C1_FOR_LSM303DLHC
PE8  = LD4/BLUE, pp: LED_4
PE9  = LD3/RED, pp: LED_3,                                          pp: TIM1  CH1
PE10 = LD5/ORANGE, pp: LED_5
PE11 = LD7/GREEN, pp: LED_7,                                        pp: TIM1  CH2
PE12 = LD9/BLUE, pp: LED_9
PE13 = LD10/RED, pp: LED_10,                                        pp: TIM1  CH3
PE14 = LD8/ORANGE, pp: LED_8,                                       pp: TIM1  CH4
PE15 = LD6/GREEN, pp: LED_6, pp: UART3 RX
PF0  = OSC_IN
PF1  = OSC_OUT

PC6=PWM0

PC7=PWM1
PC8=PWM2
PC9=PWM3
PD3=PWM4
PD4=PWM5
PD6=PWM6
PD7=PWM7
PD12=PWM8
PD13=PWM9
PD14=PWM10
PD15=PWM11

Luego de esto, se procedió a llevar acabo el diseño de la tarjeta de adaptación tomando en cuenta las definiciones que se acaban de describir. Para esto se utilizó el software Kicad, el cual permite el diseño de estos circuitos mediante un entorno de software libre.

Para esto, se creó el proyecto mediante el administrador de proyectos de Kicad, después de lo cual se empleó el programa de Kicad denominado eeschema para diseñar el circuito esquemático de la PCB. A continuación se muestra una imagen del esquemático realizado mediante este programa:

En esta imagen se puede notar la disposición de los headers del STM32F3, así como los conectores para las interfaces UART, SPI, I2C y PWM(motores), las cuales se encuentran conectadas a los pines del STM32F3 indicados previamente.

A continuación, se creó por medio de eeschema el archivo netlist del esquemático, el cual utiliza Kicad para asociar los diferentes componentes del circuito, y este se empleó para asociar los componentes (en este caso conectores) a los footprints que se utilizaron en la etapa final del diseño.

Esto se realizó mediante el programa de Kicad CvPcb. A continuación se muestra una imagen del programa CvPcb con la asociación de los footprints realizada:

Finalmente se procedió a importar los archivos Tarjeta Interfaz.net y Tarjeta Interfaz.cmp, creadas con eeschema y CvPcb al programa PcbNew, el cual contiene las herramientas necesarias para el diseño real de la tarjeta PCB. De esta manera, se procedió a realizar un primer diseño de la tarjeta PCB, ordenando los componentes del diseño dentro de un espacio de 11x11cm, tomando en cuenta la separación exacta de los headers del STM32F3 Discovery y de los componentes de telemetría UART y Xbee.

Estos conectores y los correspondientes a los SPI, I2C y PWM, se colocaron a conveniencia dentro del espacio disponible, el cual se determinó a partir de las dimensiones del frame del cóptero que se va a utilizar.

Sin embargo, debido a la gran cantidad de pistas necesarias para conectar correctamente todos los componentes, fue necesario incluir en el diseño una gran cantidad de “jumpers” o saltos por debajo de la tarjeta, los cuales se propuso llevar acabo mediante cables dispuestos manualmente en el diseño físico de la tarjeta.

Debido a la gran cantidad de saltos necesaria para construir la tarjeta a partir de este diseño (49 en total), se determinó que esto era no viable, por lo que se procedió a realizar un segundo diseño. A continuación se muestra una imagen del primer diseño de la tarjeta PCB en PcbNew:

El segundo diseño de la tarjeta PCB fue realizado a dos capas, lo cual permitía conectar los componentes del circuito de una manera mucho más ordenada y eficiente, incluso permitiendo disminuir el tamaño total que ocupaban la conexiones en la tarjeta. Esto además permitía que no fuera necesario realizar conexiones tipo jumper por medio de cables, ya que todo se pudo conectar mediante pistas de cobre.

Es importante mencionar que las conexiones entre los componentes se llevó acabo siguiendo las disposiciones del ARCOS-lab para la dimensiones de las pistas y pads de la tarjeta, las cuales toman en cuenta los requerimentos de la cortadora laser.

En seguida se muestra una imagen del diseño final de la tarjeta PCB en PcbNew:

Segunda Parte

teaching/ie0117/proyectos/2015/i/proyecto_1/puesta_en_funcionamiento_de_paparazzi_en_un_stm32f3.txt · Last modified: 2022/09/20 00:08 (external edit)