Timer
Pendant la construction d'une fusée avec le club SpaceCampus de l'Université de Bordeaux, j'ai été amené à concevoir et assembler un petit circuit gérant l'ouverture de la trappe à parachute.
Le but de ce circuit est de déployer le parachute au bon moment, c'est-à-dire quand la fusée atteint l'apogée.
Pour ce faire, j'ai choisi d'utiliser un petit micro-contrôleur appelé PIC12F683. Il détecte quand la fusée décolle grâce à un câble jack attaché au pas-de-tir qui se déconnecte de la carte à ce moment-là. Ensuite, la puce lance un compte à rebours de 5.3 secondes avant de commander l'ouverture de la trappe à parachute. Cette durée de 5.3 secondes a été calculée à l'aide d'une simulation (Stabtraj).
Voici à quoi ressemble la carte une fois imprimée et une fois les composants soudés :
Vous aurez remarqué plusieurs connecteurs. Comme vous pouvez le voir sur le schéma ci-dessous, chacun est labellisé d'une lettre :
Voici la signification des lettres :
L
: LED (L'indicateur lumineux donnant l'état du programme est raccordé ici.)A
: Alimentation (L'alimentation 5V est raccordée ici.)S
: Servomotor (Le servomoteur agissant de loquet pour la trappe à parachute est raccordé ici.)T
: Trigger (La fiche jack accessible sur la paroi de la fusée est raccordée ici.)
Quant au code, le voici ci-dessous. Il est assez court, mais pas pour autant inintéressant. En effet, il manipule directement certains registres bas niveau de la puce.
#include <xc.h>
#include <pic12f683.h>
#define _XTAL_FREQ 125000
// CONF
#pragma config FOSC = INTOSCIO // Oscillator Selection bits (INTOSCIO oscillator: I/O function on RA4/OSC2/CLKOUT pin, I/O function on RA5/OSC1/CLKIN)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = OFF // MCLR Pin Function Select bit (MCLR pin function is digital input, MCLR internally tied to VDD)
#pragma config CP = OFF // Code Protection bit (Program memory code protection is disabled)
#pragma config CPD = OFF // Data Code Protection bit (Data memory code protection is disabled)
#pragma config BOREN = OFF // Brown Out Detect (BOR disabled)
#pragma config IESO = OFF // Internal External Switchover bit (Internal External Switchover mode is disabled)
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is disabled)
const unsigned char DUTY_CYCLE_START_VALUE = 31;
const unsigned char DUTY_CYCLE_END_VALUE = 62;
void setAngle(int angle) {
int value = (int) ((angle + 90) / 180.0 * (DUTY_CYCLE_END_VALUE - DUTY_CYCLE_START_VALUE)) + DUTY_CYCLE_START_VALUE;
CCPR1L = value >> 2;
CCP1CON = (CCP1CON & 0b11001111) | ((value & 0b00000011) << 4);
}
void main(void) {
INTCON = 0b00000000; // disable interrupts
IOC = 0b00000000; // disable GPIO interrupts on change
PIE1 = 0b00000000; // disable various interrupts
OPTION_REG = 0b00001111; // weak pullups global enable,
WPU = 0b00110111; // individual weak pullups enabled
OSCCON = 0b00010001; // select internal oscillator and set it to 125Khz
T1CON = 0b10110111; // enable timer1 and set prescaler div. by 1
T2CON = 0b00000101; // enable timer2 and set prescaler div. by 4 and postscaler div. by 1
CCP1CON = 0b00001100; // Set PWM mode, active high
ADCON0 = 0b00000000; // disable A/D converter
ANSEL = 0b00000000; // Disable analog assignment to pins
CMCON0 = 0b00010111; // Disable comparator, use internal reference, invert output.
CMCON1 = 0b00000000; // comparator gating timer 1 asynchronously
VRCON = 0b00100001; // Disable internal comparator Vref, use low range, set Vref to 0.15V
WDTCON = 0b00010100; // Assign the right prescaler value to the watchdog timer. Keep WTD off for now.
GPIO = 0b00110000; // Set output pins initially before enabling them.
TRISIO = 0b00011011; // GPIO first disabled, but assigned as follows
PR2 = 155;
// Close the parachute hatch.
setAngle(30);
// Turn the LED off.
GP5 = 0;
// If no jack is detected...
if (!GP4) {
// ...flicker the LED to signal the problem.
while (1) {
GP5 = 1;
__delay_ms(150);
GP5 = 0;
__delay_ms(150);
}
}
// Turn the LED on to signal that everything is good so far.
GP5 = 1;
while (1) {
// If the jack was unplugged (rocket lifted off)...
if (!GP4) {
// ...wait 5.3 sec and then open the parachute hatch.
__delay_ms(5300);
setAngle(-150);
exit(0);
}
__delay_ms(100);
}
}
Enfin, lors du lancement, le circuit a fonctionné à merveille et le parachute s'est déployé à temps, permettant un atterrissage en douceur et sans dégât.