• ARDUINO UNO nos (et vos) premières applications pour ballons haute altitude

    #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

     

     


  • Commentaires

    Aucun commentaire pour le moment

    Suivre le flux RSS des commentaires


    Ajouter un commentaire

    Nom / Pseudo :

    E-mail (facultatif) :

    Site Web (facultatif) :

    Commentaire :