BTS Mesure BTS Mesure
Présentation2014CapteursModulationTyponsArduinoDémodulationApp InventorCourbesVidéos

PrésentationSimulationGSMGPSSDCapteursFinal

Pourquoi un programme simulation ?

Pour tester nos futurs réalisations nous avons réalisé un programme qui simule le comportement de notre carte Arduino le jour du lancement.

Pour rendre cette simulation plus réaliste, les équations de simulation sont celles établies par les courbes de tendance d'Excel (à partir des mesures réalisées en 2014).

La grande majorité de ce programme sera réutilisée pour le programme final : il suffira de remplacer la précédure simulation() par une nouvelle procédure mesure().

Algorithmes :

Le programme simulation :

Nous testons aussi avec ce programme simulation le module GSM SIM800L.


/* 1) Zone 1 : les déclarations */

// 1.b) Les Constantes et #define 
#define Sdebug Serial
#define Sballon Serial1
#define Sgsm Serial2
#define Sgps Serial3

#define numero "+336xxxxxxxx"    // Mettre ici le numéro que l'on souhaite appeler

// 1.c) Les variables globales
unsigned long t0;
float N,E,x;
float Tint,Text,Pext;
word N1,E1,Alti,n=0;
byte chk,voie,Pile;
byte Trame[11];
int FskOff=13;                // http://www.planete-sciences.org/espace/basedoc/Arduino_en_syst%C3%A9me_de_t%C3%A9l%C3%A9mesure_type_modulation_Kiwi
int RST=2;                    // Pour éteindre la carte GSM SIM800L

/* 2) Zone 2 : Initialisation (le setup) */
void setup() {
   Sdebug.begin(9600);
   Sballon.begin(600);
   Sgps.begin(9600);
   Sgsm.begin(9600);
   Trame[0]=255; // Synchro
   pinMode(FskOff,OUTPUT);              //  Mise de la capa à la masse pour désactiver la FSK
   digitalWrite(FskOff, LOW);
}

/* 3) Zone 3 : le Programme Principal */
void loop() {
  t0=millis();
  n++;
  CalculCoord();
  TrameOctets();
  TrameBallon();
  Debug(); 
  SMS();       
  while (millis()-t0<2000);
}


/* 4) Zone 4 : les sous programmes (ou fonctions) */
void CalculCoord() {
   x=2*n;
  if(x<6502) Alti=4.3931*x-9.172;  // Montée
  else {Alti=1.175994e-9*pow(x,4)-3.861926e-5*pow(x,3)+4.75801e-1*pow(x,2)-2.613544e3*x+5.421484e6;}
  N=2.42935e-16*pow(x,4)-5.40926e-12*pow(x,3)+4.04274e-8*pow(x,2)-1.001506e-4*x+43.6582;
  E=1.6529e-15*pow(x,4)-2.6505e-11*pow(x,3)+1.1255e-7*pow(x,2)+8.0558e-6*x+5.0179;
  if (x>9270) {
    Alti=654;
    E=5.69864;
    N=43.64283;}
  Tint=(7.424E-7*pow(x,2)- 0.01069*x + 33);
  Text=(2.03906E-07*pow(x,2)- 6.74602E-03*x + 25);
  Pext=(4.00474E-05*pow(x,2) - 3.87550E-01*x + 1000);    // en hPa
  N1=(N-40.0)*10000.0;
  /* word permet de coder un nombre entier jusqu'à 65535
   Pour cela nous allons enlever 40° à N et le multiplier par 10000 pour garder 4 chiffres après la vigule
   Ainsi nous pouvons coder N de 40° (N1=0) à 46,5535 (N1=65535)
   Ce qui couvre la zone probable de vol */
  E1=E*10000;
  /* De même pour E de 0° (E1=0) à 6,5535° */
  Pile=(9.723-2.8094e-4*2*n)*16-14;
   Sdebug.println();
   Sdebug.print(Tint,1);Sdebug.print(" C \t");
   Sdebug.print(Text,1);Sdebug.print(" C \t");
   Sdebug.print(Pext);Sdebug.print(" hPa \t");
   Sdebug.print(Alti);Sdebug.println(" m");
}


void TrameOctets() {
  Trame[1]=lowByte(Alti);
  Trame[2]=lowByte(E1); 
  Trame[3]=lowByte(N1);
  Trame[4]=0;
  Trame[5]=0;
  Trame[6]=(Tint+20)*4;
  Trame[7]=(Text+50)*3;
  Trame[8]=Pext/4; 
    // Pile
  switch (n%5){
       case 0:
         Trame[9] =254; break; 
       case 1:
         Trame[9] =highByte(N1); break;
       case 2:
         Trame[9] =highByte(E1); break;
       case 3:
         Trame[9] =highByte(Alti); break; 
       case 4:
         Trame[9] =Pile; break; 
        }    
}


void TrameBallon(){
    pinMode(FskOff,INPUT);                   //  Haute impédance pour activer la FSK
    delay(50);
    for (byte trame=0;trame<3;trame++) {
    chk=0;
      Sballon.write(Trame[0]);
    for (byte i=1;i<10;i++) {
      if (Trame[i]==255) Trame[i]=254;
      Sballon.write(Trame[i]);
      chk=chk+Trame[i];
    }
       chk=(chk)/2;
       Trame[10]=chk;
       Sballon.write(chk);
       Sballon.flush();
      delay(32);}
      
      pinMode(FskOff,OUTPUT);             //  Mise de la capa à la masse pour désactiver la FSK
      digitalWrite(FskOff, LOW);
}

void Debug() {
  Sdebug.print("Trame \t");Sdebug.print(n);Sdebug.print("\t");
      for (byte i=0;i<11;i++) {
      Sdebug.print(Trame[i]);
      Sdebug.print("\t");
      }
    Sdebug.println();
    while(Sgsm.available())
        Sdebug.write(Sgsm.read());
     if (n%60==12) {
      Sdebug.println();
      Sdebug.print(N,5);Sdebug.print(",");
      Sdebug.print(E,5);Sdebug.print("\t");
      Sdebug.print("Altitude = ");Sdebug.print(Alti);Sdebug.println(" m");
       }     
   }

void SMS() {
  int sms = n%60;              // Pour envoyer un SMS tout les 2*60 = 120s
  if (Alti>9000){              // Si Altitude >9000 m on éteint le GSM
      pinMode(RST,OUTPUT);
      digitalWrite(RST,LOW);
      return;}
  if (sms==1) {
      pinMode(RST,INPUT);      // On allume le GSM en mettant RST en haute impédance, attendre au moins 6s pour se connecter au réseau
      return;}
  if (sms==10) Sgsm.println("AT+CMGF=1");                             // Au bout de 20s sous tension on envoie le SMS
  if (sms==11) {                                                      // Composition n° au bout de 22s
      Sgsm.print("AT+CMGS=\""); Sgsm.print(numero); Sgsm.println("\"");
      }
  if (sms==12) {                                                   // Il est préférable d'attendre (ici 2s) avant d'envoyer le coprs du message
      Sgsm.print("Temps = "); Sgsm.print(2*n);Sgsm.print(" s");
      Sgsm.print(" : https://maps.google.fr/maps?q="); Sgsm.print(N,5); Sgsm.print(","); Sgsm.print(E,5);
      Sgsm.print(" Alti=");Sgsm.print(Alti);Sgsm.print(" m");
      Sgsm.print(" P= ");Sgsm.print(int(Pext));Sgsm.print(" hPa");
      Sgsm.print(" T= ");Sgsm.print(Text,1);Sgsm.print(" C");
      Sgsm.write(26); // Caractère de fin 26 <Ctrl-Z> 
      }
  if (sms==14) {               // Puis au bout de 28s on éteint le GSM
      pinMode(RST,OUTPUT);
      digitalWrite(RST,LOW); } 
}