• //#include <DHT.h>
    #include <TinyGPS.h>             // http://arduiniana.org/libraries/tinygpsplus/
    #include <SD.h>


    //SoftwareSerial  SerialGPS(9,10); // RX, TX
    TinyGPS gps; // create a TinyGPS object
    //#define DHTPIN 3 
    //#define DHTTYPE DHT22

    int chipSelect=4;
    int LED=7;
    unsigned long t1, fix_age;
    float lat, lon, alti, vitesse;
    int annee,fix,i;
    byte c,mois, jour, seconde, minute, heure, centiemes;
    String date ="";


    void setup()
    {
      Serial.begin(9600);
      Serial1.begin(9600); // GPS devices frequently operate at 4800 baud
      Serial.println("Initialisation...");
      pinMode(chipSelect, OUTPUT);
      pinMode(5,OUTPUT);
      pinMode(10,OUTPUT); // Carte Ethernet
      digitalWrite(chipSelect,LOW);
      digitalWrite(5,HIGH);
      digitalWrite(10,HIGH);  // désactiver Carte SD
      pinMode(LED,OUTPUT);
      if (!SD.begin(chipSelect)) Serial.println("Erreur carte SD"); else Serial.println("Carte presente");
      t1=millis();
     }
    void loop()
    {
      while (Serial1.available()&&millis()-t1>4000)
      { 
        c = Serial1.read();
        Serial.write(c);
        if (gps.encode(c)&&millis()-t1>5000) lireGPS();     // tempo pour lire une trame RMC
      
        if (millis()-t1>6000) {                              // Attente du Fix  
             fix++;
             Serial.println();
             Serial.println("Attente du FIX... ");
             Serial.print(6*fix); Serial.println(" s");
             t1=millis();}
      }
     
    }

    void lireGPS()
    {
          gps.f_get_position(&lat, &lon);              // Fonction de la bibliothèque TinyGPS
          gps.crack_datetime(&annee, &mois, &jour, &heure, &minute, &seconde, ¢iemes, &fix_age);
          date =String(jour) + "/" + String(mois) + "/" + String(annee) + " "+ String (heure+1) + ":" + String (minute) + ":" + String (seconde);
          Serial.println();
          Serial.println(date);
          Serial.print("Mesure ");Serial.println(i);
          Serial.print("Latitude = ");Serial.println(lat,5);
          Serial.print("Longitude = ");Serial.println(lon,5);
          alti = gps.f_altitude(); // +/- altitude in meters
          Serial.print("Altitude = ");Serial.print(alti,1);Serial.println(" m");
          vitesse = gps.f_speed_mps();
          Serial.print("Vitesse = ");Serial.print(vitesse,1);Serial.println(" m/s");
          Serial.print(lat,5);Serial.print(",");Serial.println(lon,5);
          Serial.println();
          digitalWrite(LED,1);
          if (i==0) entete();
          ecritureSD();     
          digitalWrite(LED,0); 
          t1=millis();
          i++;
          fix=0;
        }
       
       
    void entete(){                  // Pour utiliser Google table de fusion séparateur
       File GPStab = SD.open("GPS_Tab.csv", FILE_WRITE);
          if (GPStab) {
            GPStab.print("date");
            GPStab.print(";");
            GPStab.print("latitude");
            GPStab.print(";");
            GPStab.print("longitude");
            GPStab.print(";");
            GPStab.print("Altitude");
            GPStab.print(";");
            GPStab.println("Mesure");       
            GPStab.close();
          }
    }
         
    void ecritureSD() {
          File GPStab = SD.open("GPS_Tab.csv", FILE_WRITE);
          if (GPStab) {
            GPStab.print(date);
            GPStab.print(";");
            GPStab.print(lat,5);
            GPStab.print(";");
            GPStab.print(lon,5);
            GPStab.print(";");
            GPStab.print(alti,1);
            GPStab.print(";");
            GPStab.println(i);       
            GPStab.close();
            }
          else  {
             Serial.print("Erreur GPS_Tab.csv");}

    }

    ---------------------------------------------------------------------------

    Cette fois, c'est au tour du GPS, ce programme devrait permettre de le tester. Je ne l'ai pas encore programmé, mais

    je vous le soumet pour le tester. Si vous voulez le fichier .ino pour ce programme ou pour les autres,

    ainsi que les librairies, je peux vous les faire parvenir par mail, mais sans garantie si non testé.

    J'aurai l'occasion de commenter dans un article, ce que vous pouvez récupérer avec votre GPS. En gros, vous pouvez

    obtenir dans l'ordre :

    la date, l'heure, la latitude, la longitude, et l'altitude.

    Si votre GPS ne convient pas pour les vols sur un ballon haute altitude, l'indication d'altitude sera bloquée en vol, en

    général vers 18 km.

    Merci pour votre participation et vos commentaires.

    Alain F6AGV - BHAF -  f6agv (@) free.fr   Ballons Haute Altitude France


    votre commentaire
  • /* test RTTY BEACON du module NTX2B
    */
    //définir la pin de sortie vers NTX2B
    #define RADIOPIN 9
    //définir les bibliothèques
    #include <string.h>
    #include <util/crc16.h>
    //définir la taille du texte à transmettre en balise
    char datastring[80];

    void setup(){
      pinMode(RADIOPIN,OUTPUT);
      Serial.begin(9600);
    }

    void loop(){
      snprintf(datastring,80,"$$$$$F6AGV-11,RTTY,TEST,BEACON"); //placer le texte dans datastring
      unsigned int CHECKSUM=gps_CRC16_checksum(datastring); //calcul du checksum pour ce texte
      char checksum_str[6];
      sprintf(checksum_str,"*%04X\n",CHECKSUM);
      strcat(datastring,checksum_str);
      rtty_txstring(datastring);
      
      }

    void rtty_txstring(char*string){
      //envoyer des caractéres d'un octet de 8 bits (byte)
     
      char c;
      c=*string++;
     
      while (c !='\0'){
        rtty_txbyte(c);
        c=*string++;
        }
        }
      
     void rtty_txbyte(char c){
       //envoyer chaque bit d'un caractére
       //le LSB est transmit en premier
       //chaque octet est précédé d'un zéro (start)
       //chaque octet est suivi d'un ou deux un (stop)
       int i;
       rtty_txbit(0);  //start bit
       //envoyer les bits avec LSB en premier
      
       for (i=0;i<7;i++) { //
       if(c&1) rtty_txbit(1);
       else rtty_txbit(0);
      
       c = c>>1;
       }
       rtty_txbit(1); //stop bit
       rtty_txbit(1); //stop bit
      
       }
      
       void rtty_txbit (int bit) {
         if (bit) { 
           // high
           analogWrite(RADIOPIN,110);
          }
         else {
           // low
           analogWrite(RADIOPIN,100);
          }
         
          delayMicroseconds(10000);
          delayMicroseconds(10150);
          /* pour 300 bauds (3370)
          pour 50 bauds (20150)
          */
          }
         
          uint16_t gps_CRC16_checksum (char*string){
            size_t i;
            uint16_t crc;
            uint8_t c;
         
          crc = 0xFFFF;
          //calcul du checksum les deux premiers $$ ne comptent pas
          for(i=2; i <strlen(string);i++) {
            c=string[i];
            crc=_crc_xmodem_update (crc, c);
           }
          
           return crc;
          }
         

    ------------------------------------------------------------

    Petit commentaire :  ce programme écrit par Anthony M0UPU, vous permettra de tester votre émetteur NTX2 ou NTX2B.

    Ainsi que la réception du message "$$$$$F6AGV-11,TEST,RTTY,BEACON". Pour recevoir, cette émission, il vous faut

    un récepteur UHF sur la bande 434 MHz en USB, une antenne verticale quart d'onde (ou 7 éléments pour recevoir des

    émissions de ballons plus lointains). Il vous faut un ordinateur avec le logiciel DL-FLDIGI   HAB ou normal. 

    Ce logiciel vous permet de recevoir d'autres modes numériques utilisés par les ballons haute altitude.

    Je recommande une interface d'isolement entre le PC et le récepteur UHF. Si vous n'en avez pas encore, il suffit

    d'alimenter le récepteur avec une batterie 12 volts. La configuration à placer sur DL-FLDIGI pour recevoir ces trames

    de test en mode balise est  RTTY ---> custom ---> 50 bauds  7 bits ascii  none et 2 bits de stop.

    Ce programme a été testé avec succès, si vous avez une erreur à cause d'une mauvaise librairie, je pourrai vous

    faire parvenir les miennes qui sont dans le programme.

    Merci pour votre participation et vos commentaires.

    Alain F6AGV :   f6agv (@) free.fr

     

     


    votre commentaire
  • #include <NewSoftSerial.h>
    #include <TinyGPS.h>
    #include <SD.h>
    #include <OneWire.h>
    #include <util/crc16.h>

    //capteur de temperature
    #define DS18B20 0x28    
    OneWire ds(5);
    OneWire ds2(6);
    int temperature_val_ext=0;
    int temperature_val=0;

    //GPS
    TinyGPS gps;
    NewSoftSerial mySerial(2, 3);
    char msg[80];
    int count = 1;
    long lat, lon;
    unsigned long time;

    //carte memoire
    File theFile;

    //radio
    char datastring[80];
    #define RADIOPIN 8

    //variable globale
    int pression_val=0;
    int altitude_val=0;


    void setup()
    {
     
     
      Serial.begin(115200);
      mySerial.begin(9600);

      pinMode(10, OUTPUT);

      if (!SD.begin(10))
      {
        Serial.println(" Card failed, or not present");
        return;
      }
     
      pinMode(RADIOPIN,OUTPUT);
    }



    ////////////////////////////////////////////////////////////////////////////////////////////RADIO
    void rtty_txstring (char * string)
    {
      /* Simple function to sent a char at a time to
           ** rtty_txbyte function.
           ** NB Each char is one byte (8 Bits)
           */
      char c;
      c = *string++;
      while ( c != '\0')
      {
        rtty_txbyte (c);
        c = *string++;
      }
    }
     
     
    void rtty_txbyte (char c)
    {
      /* Simple function to sent each bit of a char to
           ** rtty_txbit function.
           ** NB The bits are sent Least Significant Bit first
           **
           ** All chars should be preceded with a 0 and
           ** proceded with a 1. 0 = Start bit; 1 = Stop bit
           **
           */
      int i;
      rtty_txbit (0); // Start bit
      // Send bits for for char LSB first   
      for (i=0;i<7;i++) // Change this here 7 or 8 for ASCII-7 / ASCII-8
      {
        if (c & 1) rtty_txbit(1);
        else rtty_txbit(0);     
        c = c >> 1;
      }
     
      rtty_txbit (1); // Stop bit
      rtty_txbit (1); // Stop bit
    }
     
    void rtty_txbit (int bit)
    {
      if (bit)
      {
        // high
        digitalWrite(RADIOPIN, HIGH);
      }
      else
      {
        // low
        digitalWrite(RADIOPIN, LOW);
      }
     
      //                  delayMicroseconds(3370); // 300 baud
      delayMicroseconds(10000); // For 50 Baud uncomment this and the line below.
      delayMicroseconds(10150); // You can't do 20150 it just doesn't work as the
                                // largest value that will produce an accurate delay is 16383
                                // See : http://arduino.cc/en/Reference/DelayMicroseconds
    }
     
    uint16_t gps_CRC16_checksum (char *string)
    {
      size_t i;
      uint16_t crc;
      uint8_t c;
      crc = 0xFFFF;
      // Calculate checksum ignoring the first two $s
      for (i = 2; i < strlen(string); i++)
      {
        c = string[i];
        crc = _crc_xmodem_update (crc, c);
      }
      return crc;
    }   


    ////////////////////////////////////////////////////////////////////////////////////////////TEMPERATURE
    boolean getTemperature(int *temperature_val){
      byte data[9], addr[8];

      if (!ds.search(addr)) {
        ds.reset_search();   
        return false;        
      } 
      if (OneWire::crc8(addr, 7) != addr[7])
        return false;                       
      if (addr[0] != DS18B20)
        return false;        

      ds.reset();            
      ds.select(addr);         
      ds.write(0x44, 1);     
      delay(800);            
      ds.reset();            
      ds.select(addr);       
      ds.write(0xBE);        

      for (byte i = 0; i < 9; i++)
        data[i] = ds.read();      
     
      // Calcul de la température en degré Celsius
      *temperature_val = ((data[1] << 8) | data[0]) * 0.0625; 
      return true;
    }
    ////////////////////////////////////////////////////////////////////////////////////////////TEMPERATURE EXTERIEUR
    boolean getTemperature_ext(int *temperature_val_ext){
      byte data[9], addr[8];
      if (!ds2.search(addr)) {
        ds2.reset_search();   
        return false;        
      } 
      if (OneWire::crc8(addr, 7) != addr[7])
        return false;                       
      if (addr[0] != DS18B20)
        return false;        

      ds2.reset();            
      ds2.select(addr);         
      ds2.write(0x44, 1);     
      delay(800);            
      ds2.reset();            
      ds2.select(addr);       
      ds2.write(0xBE);        

      for (byte i = 0; i < 9; i++)
        data[i] = ds2.read();      
     
      // Calcul de la température en degrée Celsius
      *temperature_val_ext = ((data[1] << 8) | data[0]) * 0.0625;  
      return true; 
    }
      


      
    ////////////////////////////////////////////////////////////////////////////////////////////CARTE MEMOIRE
    void sd(int temperature_val,int temperature_val_ext, int altitude_val, int pression_val, long lat, long lon, long altGPS)
    {
     
        File theFile = SD.open("fichier.txt", FILE_WRITE);
          theFile.print(lat);
          theFile.print(" ");
          theFile.print(lon);
          theFile.print(" ");
          theFile.print(altGPS);
          theFile.print(" "); 
          theFile.print(pression_val);
          theFile.print(" ");   
          theFile.print(altitude_val);
          theFile.print(" "); 
          theFile.print(temperature_val);
          theFile.print(" ");
          theFile.println(temperature_val_ext);
          theFile.close();
          Serial.println("carte sd ecrit !");
    }



    ////////////////////////////////////////////////////////////////////////////////////////////PRESSION
    float pression()
    {
      int val = analogRead(0);
      float tension = ((val-10)*0.0049);
      // Calcul de la pression réel
      int pression_val = (100.1-(((tension/5)-0.04) / 0.009))*10;
      return pression_val;
    }



    ////////////////////////////////////////////////////////////////////////////////////////////ALTITUDE
    int getAltitude(long pression_val)
    {
      pression_val=pression_val/0.01;
      // Pression au niveau de la mer (Pa)
      const float p0 = 101325;
      int altitude = (float)44330 * (1 - pow(((float) pression_val/p0), 0.190295))+230;
      return altitude;
    }



    ////////////////////////////////////////////////////////////////////////////////////////////GPS
    void GPS(){

    if (mySerial.available()) {
      
        if(!gps.encode(mySerial.read())) return;   

        gps.get_position(&lat, &lon, NULL);
        gps.get_datetime(NULL, &time, NULL);

        snprintf(msg, 80,
        "heure : %02li:%02li:%02li  lat/lon : %s%li.%05li,%s%li.%05li  altitude : %li",
        time / 1000000, time / 10000 % 100, time / 100 % 100,
        (lat >= 0 ? "" : "-"), labs(lat / 100000), labs(lat % 100000),
        (lon >= 0 ? "" : "-"), labs(lon / 100000), labs(lon % 100000),
        gps.altitude() / 100
        );
       
        Serial.println(msg);

        delay(1000);
      }
    }


    ////////////////////////////////////////////////////////////////////////////////////////////LOOP
    void loop()
    {

      for (unsigned long start = millis(); millis() - start < 1000;) 
        GPS();
     
      
      pression_val=pression();
      Serial.print("pression = ");
      Serial.println(pression_val);
     
      altitude_val=getAltitude(pression_val);
      Serial.print("altitude = ");
      Serial.println(altitude_val);
     
      getTemperature(&temperature_val);
      Serial.print("Temperature : ");
      Serial.println(temperature_val);
     
      getTemperature_ext(&temperature_val_ext);
      Serial.print("Temperature exterieur : ");
      Serial.println(temperature_val_ext);

      sd(temperature_val,temperature_val_ext, altitude_val, pression_val, lat, lon, gps.altitude());
     
      noInterrupts();
     
        snprintf(datastring, 250,
        "T : %02li:%02li:%02li  lat/lon : %s%li.%05li,%s%li.%05li  altGPS : %li  P = %dHpa  alt = %dm  temp = %d  tempext = %d",
        time / 1000000, time / 10000 % 100, time / 100 % 100,
        (lat >= 0 ? "" : "-"), labs(lat / 100000), labs(lat % 100000),
        (lon >= 0 ? "" : "-"), labs(lon / 100000), labs(lon % 100000),
        gps.altitude() / 100,
        pression_val,
        altitude_val,
        temperature_val,
        temperature_val_ext
        );
       
      unsigned int CHECKSUM = gps_CRC16_checksum(datastring); 
      char checksum_str[6];
     
      sprintf(checksum_str, "\n", CHECKSUM);
      strcat(datastring,checksum_str);
      rtty_txstring (datastring);
      interrupts();
     
     
       
      delay(5000); 
     
      asm volatile ("  jmp 0");
    }

    -----------------------------------------------------------------------------------

    Ce programme semble complet pour un vol de ballon, mais je ne l'ai pas encore testé !

    Je vous le livre quand même, et si vous pouvez le faire fonctionner sur un Arduino Uno ou un Méga,

    je serai très intéressé ainsi que les lecteurs de savoir si il fonctionne et quelques remarques.

    Merci pour votre participation. 

    Alain F6AGV - BHAF - Ballons Haute Altitude France - 7 avril 2016

     

     


    votre commentaire



    Suivre le flux RSS des articles
    Suivre le flux RSS des commentaires