Shop OBEX P1 Docs P2 Docs Learn Events
Results from MS5607 & DHT22 on High Altitude Balloon to over 115,000 ft — Parallax Forums

Results from MS5607 & DHT22 on High Altitude Balloon to over 115,000 ft

aparis1983aparis1983 Posts: 22
edited 2015-06-10 11:45 in Accessories
This past Memorial Day Weekend I launched a high altitude balloon over South Florida. I used a 3000 gram Hwoyee latex balloon filled with 190 cubic feet of hydrogen (I don't advise using hydrogen if it's you're first launch, use Helium). My payload included two Arduino Megas running an MS5607 barometric pressure sensor (from Parallax), a DHT22 temperature/humidity sensor, and an Adafruit Ultimate GPS Logger Shield.

Additionally I had a SPOT personal tracker inside of a gimbal as a separate payload, and a mini GPS GSM tracker atop the main capsule. I had two GoPro cameras aboard and a Canon Powershot SD880 IS (hacked with CHDK). Unfortunately, one of the GoPros snapped off after a mainline tangle during descent, and the other one simply malfunctioned and didn't record a second of footage. The Canon took upwards of 250 pictures. I used a 3-feet parachute, which was perfect for the 5.5 lbs payload.

My brother, who's hobby is astrophotography, brought his 12" dobsonian telescope with which we were able to track and record the entire flight up to the moment the balloon burst at 115,922 feet. This is the youtube video I made about the whole thing (including 80 amazing pictures shot by the Canon camera):
https://www.youtube.com/watch?v=tI6alFMD79I

Here's a link with a few of the better pictures taken by the camera:
http://imgur.com/a/8XT3S#0

Here's a link with the Datalog from the temperature/humidity sensor, and the barometric pressure sensor:
https://docs.google.com/spreadsheets/d/18CsiDvMkIqPbno0cTT1M5il6tEtVtS4pdaZjk4rj84E/edit#gid=1735956087

I have columns for outside temperature and humidity, and inside temperature with pressure. I also logged the raw data for temperature and pressure. I added some columns post-flight for altitude calculations (using the troposphere and stratospere formulas provided in here: http://www.jameco.com/jameco/products/prodds/2150230.pdf).

You'll notice I added a column for ascent and descent rate; curiously the ascent and descent rate increases dramatically and inexplicably at higher altitudes which makes me think the resolution of the sensor is some nominal rather than proportional value (the highest amount of turbulence should be from 20km to just over 25km, not above that). The datalog file has a second tab with lots of graphs for all of the data.

On top of that, I think the DHT22 sensor may have needed some compensations. The temperature at launch was correct, and then it reached it lower limit of -55 Celsius, but then it climbs up to roughly 20 C at the flight's apogee (which is impossible). Temperature does increase above the ozone layer due to UV radiation, but not up to 20 Celsius.

Here's the arduino based code I used for this datalog:
#include <Wire.h>
#include <DHT.h>
#include <SPI.h>
#include <SD.h>
#include "LiquidCrystal.h"

#define DHTPIN 2     // what pin we're connected to

// Uncomment whatever type you're using!
//#define DHTTYPE DHT11   // DHT 11 
#define DHTTYPE DHT22   // DHT 22  (AM2302)
//#define DHTTYPE DHT21   // DHT 21 (AM2301)

// Connect pin 1 (on the left) of the sensor to +5V
// Connect pin 2 of the sensor to whatever your DHTPIN is
// Connect pin 4 (on the right) of the sensor to GROUND
// Connect a 10K resistor from pin 2 (data) to pin 1 (power) of the sensor

DHT dht(DHTPIN, DHTTYPE);

#define ADDRESS 0x76 //0x77

uint32_t D1 = 0;
uint32_t D2 = 0;
int64_t dT = 0;
int32_t TEMP = 0;
int64_t OFF = 0; 
int64_t SENS = 0; 
int32_t P = 0;
uint16_t C[7];
const int chipSelect = 4;

float Temperature;
float Pressure;
LiquidCrystal lcd(4, 3, 5);
#define visualPin 6
int ledState = LOW;             // ledState used to set the LED
long previousMillis = 0; 
long interval = 10000; 
long intervalShort = 150; 



void setup() {
// Disable internal pullups, 10Kohms are on the breakout
PORTC |= (1 << 4);
PORTC |= (1 << 5);

 Wire.begin();
 Serial.begin(9600); //9600 changed 'cos of timing?
 delay(100);
  Serial.println("DHT22 with SD Logging!");
  pinMode(10, OUTPUT);
  pinMode(visualPin, OUTPUT);  
  if (!SD.begin(chipSelect)) {
  Serial.println("Card failed, or not present");
  return;
  }
    Serial.println("card initialized.");

  delay(2000);
  dht.begin();
  #define LED 13
 
 initial(ADDRESS);
   lcd.begin(16, 2);
     lcd.print("AETHER II");
  }

void loop()
{  
   unsigned long currentMillis = millis();
   File dataFile = SD.open("datalog.csv", FILE_WRITE);
  // Wait a few seconds between measurements.
  delay(4850);
  float h = dht.readHumidity();
  // Read temperature as Celsius
  float t = dht.readTemperature();
  // Read temperature as Fahrenheit
  float f = dht.readTemperature(true);
    if (isnan(h) || isnan(t) || isnan(f)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }

  
  Serial.print("Humidity: "); 
  Serial.print(h);
  Serial.print(" %\t");
  Serial.print("Temperature: "); 
  Serial.print(t);
  Serial.print(" *C ");
  Serial.print(f);
  Serial.print(" *F\%");
 D1 = getVal(ADDRESS, 0x48); // Pressure raw
 D2 = getVal(ADDRESS, 0x58);// Temperature raw

 dT   = D2 - (uint32_t)C[5] *pow(2,8);
 OFF  = (int64_t)C[2] * pow(2,17) + ((dT * C[4])/pow(2,6));
 SENS = (int32_t)C[1] *pow(2,16) + ((dT * C[3])/pow(2,7));

 TEMP = ((int64_t)dT * (int64_t)C[6] / 8388608) + 2000;

 if(TEMP < 2000) // if temperature lower than 20 Celsius 
 {
   int32_t T1    = 0;
   int64_t OFF1  = 0;
   int64_t SENS1 = 0;

   T1    = pow(dT, 2) / 2147483648;
   OFF1  = 61 * pow((TEMP - 2000), 2) / 16;
   SENS1 = 2 * pow((TEMP - 2000), 2);
   
   if(TEMP < -1500) // if temperature lower than -15 Celsius 
   {
     OFF1  = OFF1 + 15 * pow((TEMP + 1500), 2); 
     SENS1 = SENS1 + 8 * pow((TEMP + 1500), 2);
   }
   
   TEMP -= T1;
   OFF -= OFF1; 
   SENS -= SENS1;
 }


 Temperature = (float)TEMP / 100; 
 
 P  = ((int64_t)D1 * SENS / 2097152 - OFF) / 32768;

 Pressure = (float)P / 100;
 
 Serial.print("     Actual TEMP= ");
 Serial.print(Temperature);
 Serial.print("      Actual PRESSURE= ");
 Serial.print(Pressure);

 Serial.println();  
 Serial.print(" RAW Temp D2=  ");
 Serial.print(D2);
 Serial.print(" RAW Pressure D1=  ");
 Serial.println(D1);
 Serial.println();

//  Serial.print(" dT=  ");
//  Serial.println(dT); can't print int64_t size values
 Serial.println();
 Serial.print(" C1 = ");
 Serial.println(C[1]);
 Serial.print(" C2 = ");
 Serial.println(C[2]); 
 Serial.print(" C3 = ");
 Serial.println(C[3]); 
 Serial.print(" C4 = ");
 Serial.println(C[4]); 
 Serial.print(" C5 = ");
 Serial.println(C[5]); 
 Serial.print(" C6 = ");
 Serial.println(C[6]); 
//  Serial.print(" C7 = ");
//  Serial.println(C[7]);
 Serial.println();
 
lcd.setCursor(0, 0);
lcd.print("mBar: ");
lcd.setCursor(7,0);
lcd.print(Pressure);
lcd.setCursor(0,1);
lcd.print("Cels: ");
lcd.setCursor(6,1);
lcd.print(Temperature);

  if(dataFile){
  String dataString = String(h) + ", " + String(t) + ", " + String(f) + "," + String(Pressure) + "," + String(Temperature) + "," + String(D1)+ "," + String (D2);
  dataFile.println(dataString);
  dataFile.close();
  if(t && Pressure && currentMillis - previousMillis > interval) {
    // save the last time you blinked the LED 
    previousMillis = currentMillis;   

digitalWrite(visualPin,HIGH);}
delay(150);
digitalWrite(visualPin,LOW);
}
  else{Serial.println("Couldn't access file");}

}

long getVal(int address, byte code)
{
 unsigned long ret = 0;
 Wire.beginTransmission(address);
 Wire.write(code);
 Wire.endTransmission();
 delay(10);
 // start read sequence
 Wire.beginTransmission(address);
 Wire.write((byte) 0x00);
 Wire.endTransmission();
 Wire.beginTransmission(address);
 Wire.requestFrom(address, (int)3);
 if (Wire.available() >= 3)
 {
   ret = Wire.read() * (unsigned long)65536 + Wire.read() * (unsigned long)256 + Wire.read();
 }
 else {
   ret = -1;
 }
 Wire.endTransmission();
 return ret;
}

void initial(uint8_t address)
{

 Serial.println();
 Serial.println("PROM COEFFICIENTS");

 Wire.beginTransmission(address);
 Wire.write(0x1E); // reset
 Wire.endTransmission();
 delay(10);


 for (int i=0; i<6  ; i++) {

   Wire.beginTransmission(address);
   Wire.write(0xA2 + (i * 2));
   Wire.endTransmission();

   Wire.beginTransmission(address);
   Wire.requestFrom(address, (uint8_t) 6);
   delay(1);
   if(Wire.available())
   {
      C[i+1] = Wire.read() << 8 | Wire.read();
   }
   else {
     Serial.println("Error reading PROM 1"); // error reading the PROM or communicating with the device
   }
   Serial.println(C[i+1]);
 }
 Serial.println();
}

Comments

  • Duane DegnDuane Degn Posts: 10,588
    edited 2015-06-03 16:25
    That's fantastic. Those clouds look amazing.

    I don't think it's seen a video which has shown the balloon burst before. Very cool.

    Thanks for letting us know about this.
  • xanaduxanadu Posts: 3,347
    edited 2015-06-03 20:34
    Awesome! Glad you used something other than a GoPro for the stills, looks really nice!
  • ercoerco Posts: 20,256
    edited 2015-06-06 06:34
    Outstanding job and results! Glad you got your package back safely...no lakes, swamps or gators! How many miles away did it land?
  • aparis1983aparis1983 Posts: 22
    edited 2015-06-08 08:31
    erco wrote: »
    Outstanding job and results! Glad you got your package back safely...no lakes, swamps or gators! How many miles away did it land?

    Hi, thanks!
    That day we had ideal conditions for launching a balloon. The winds were relatively calm and, on top of that, we had several complete 180 degree wind-direction changes at different altitudes,which means our balloon zig-zagged its way up in roughly the same area. It landed just 7 miles southeast of us in the middle of a field. Last year's balloon landed 15 miles away and about 40 feet up on a tree canopy. Florida launches are difficult in that if you miscalculate, you might end up chasing a balloon a few miles into the Atlantic as happened with this guy: https://www.youtube.com/watch?v=gc82-pHSyd4

    Andres
  • JDatJDat Posts: 103
    edited 2015-06-09 15:51
    Hey! Greetings from Europe!

    Sounds like Zinoo-2 launch: https://www.youtube.com/watch?v=JzSZuEBGmns
    That was real fun! :)
  • LevLev Posts: 182
    edited 2015-06-10 05:39
    Good job.

    We have seen substantial self-heating of electronics at high altitudes, where conductive and convective heat transfer is limited by the rarified atmosphere. Our ICs seem to stay toasty warm. Could that explain the temperature measured by the DHT22?
  • aparis1983aparis1983 Posts: 22
    edited 2015-06-10 06:42
    It could be although my confusion is worsened by the fact that the internal temperature seemed spot on (measured by the MS5607). However, the outside and inside temperature were measured by two different sensors so maybe the DHT22 is simply more prone to self-heating in thin air than the MS5607.

    It would be great to have a formula for pressure-compensated temperature, but short of finding a vacuum chamber inside of a cryogenic freezer looks like it'll remain unknown.... oh well
  • JDatJDat Posts: 103
    edited 2015-06-10 11:45
    It's important to have heat source and heat accumulator. Bulky rechargeable cells works fine as heat accumulator. 0.5W video transmitter from RC FPV works as heater. Main purpose is to get live video from 60 KM distance, but at the same time Batteries should be kept in warm environment. So FPV transmitter becomes pretty hot. You know it. Why not to use this side product (heat) for battery heating? No atmosphere? No problem. Actually it is better. Neatly all heat will go to batteries. Heat conduction is the answer! These small things for ear space ballooning are really interesting while constructing electronics and mechanical support.
Sign In or Register to comment.