Højdemåler til faststof-raket

En letvægts-højdemåler baseret på trykmåleren BMP180. Tryk og temperatur måles og skrives på et SD-kort. Vægt og størrelse spiller en stor rolle. Diameteren på raketten er ca. 3 cm.

Af hensyn til vægten har jeg valgt en Arduino Nano. Og tre serieforbundne 3V knapcelle-batterier som strømforsyning. To er for lidt. Da der ikke er bevægelige dele, giver de tre netop nok spænding til at holde liv i systemet.

hojdemaaler
SD kortlæseren (Catalex) – Arduino:
VCC – 5V
GND – GND (ground)
MISO – Pin 12
MOSI – Pin 11
SCK – Pin 13
CS – Pin 10

BMP180 – Arduino
SDA – A4
SCL – A5
VCC – 3,3V
GND – GND

Desuden har jeg indsat en rød LED (og en 1 kOhm modstand) til fejlfinding og klarmelding. Her kunne jeg have brugt den indbyggede LED i Arduino-boarded, men den pin (D13) er optaget af SD-kortlæseren i dette setup. Den kunne formentligt frigøres.

Se koden nederst.

Nogle udfordringer har været:
* Højden over jorden har svinget med ca. 1 meters usikkerhed. Jeg har lagt et lille filter i koden (gennemsnit af 10 målinger) til at måle starttrykket, da det er afgørende for alle følgende bestemmelser af højden over jorden. Det filter giver ingen forbedring.
* Tænd/sluk kontakten SKAL sidde i enden af kredsløbet. Ligeledes skal SD-kortlæseren være der. Så det er muligt at betjene dem uden at tage al indmaden ud af raketten.

hojdemaaler2
* Lave en raketdel, som kan åbnes fx ved at den er tapet sammen. Jeg har brugt et lamineret A4, som materiale til payload kammeret (elev-ide).
* Kunne være fint med noget “padding” rundt om elektronikken. Det har der ikke været plads til.

Test#1:
Affyring med A6-4-motor (den mindste klasse jeg kan købe). Raketten fløj lodret til ca. 4 meters højde, vendte om og fløj mod jorden, som den borede sig 3 cm ned i. Derefter blev faldskærmen udløst. Glad for jeg ikke stod lige under.

wp_20160930_001

Selv om jeg har beskyttet lodningerne med lim fra limpistol, tror jeg ikke alle overlevede mødet med jorden. Kredsløbet så efterfølgende sådan ud:

unavngivet

SD-kortet, som var røget ud og lå for sig selv, indeholdt bl.a. følgende data:
Tid (s): 2 Tryk (Pa): 100619 Temp (gr,C): 19,84 Højde (m): -0,41
Tid (s): 3 Tryk (Pa): 100618 Temp (gr,C): 19,82 Højde (m): -0,32
Tid (s): 3 Tryk (Pa): 100621 Temp (gr,C): 19,82 Højde (m): -0,58
Tid (s): 3 Tryk (Pa): 100625 Temp (gr,C): 19,84 Højde (m): -0,92
Tid (s): 3 Tryk (Pa): 100618 Temp (gr,C): 19,82 Højde (m): -0,32
Tid (s): 4 Tryk (Pa): 100630 Temp (gr,C): 19,84 Højde (m): -1,35
Tid (s): 4 Tryk (Pa): 100628 Temp (gr,C): 19,84 Højde (m): -1,17
Tid (s): 4 Tryk (Pa): 100618 Temp (gr,C): 19,82 Højde (m): -0,32

Alle beregnede højder:
hoejdekurve

Hvad nu?
Alt i alt er der noget, der virker. Men raketten fløj mere end 2 meter op. Måske påvirker accelerationen den trykmåling der sker?
Brug en kraftigere motor, så den kommer højere op.
Kan jeg bruge noget sammen med elever? Selv fremstille motoren?

Kode (tilpasser codebender):

double pressure; //Variabel til tryk i Pascal (Pa)
double startpressure; //Variabel til tryk i Pascal (Pa)
double tempC;  //Variabel til temperatur i grader Celcius
//double starttempC;  //Variabel til temperatur i grader Celcius
double hojde; // variabel til højden i meter over havet
double tempK; //Variabel til temperaturen i Kelvin

const double gaskonstant = 8.31; // gaskonstanten i N*m/mol*K
const double tyngdeacceleration = 9.807; //tyngdeaccelerationen i m/s^2
const double molarmasse = 0.02896; //Molarmassen af luft i kg/mol
 
#include  <SD.h>// åbner biblioteker for at tale med SD-kortlæser og BMP180 chippen (I2C)
#include  <SPI.h>
#include "Wire.h"     
#include "Adafruit_BMP085.h" 
Adafruit_BMP085 mySensor;  // laver et objekt kaldet mySensor

int chipSelect = 4; // Pin til SD kortlæser?? Skal det være 10?
File mySensorData; // laver et fil-objekt, som kan gemme data

void setup(){
Serial.begin(9600); //åbner forbindelse til serial monitor
mySensor.begin();   // starter tryk-sensoren mySensor
//tempC = mySensor.readTemperature(); //  Måler STARTtemperaturen i grader C fra BMP180
for (int i=1; i <= 10; i++){
      pressure += mySensor.readPressure(); // Måler STARTtrykket i Pa 
//	Serial.println(i);
//		Serial.println(pressure);
      delay(100);
   } 
startpressure= pressure/10;
//Serial.println(startpressure);
//tempK = tempC + 273; // temperaturen i Kelvin

pinMode(3, OUTPUT); // Pin reserveres til LED.
pinMode(10, OUTPUT); // Pin 10 reserveres til SD kortlæseren.
SD.begin(10); // starter SD kortlæseren
  if (SD.exists("Hojde.txt")) // hvis filen "Hojde.txt" allerede findes på SD-kortet..
  {
  SD.remove("Hojde.txt"); // ..slet filen.
  for (int i=1; i <= 5; i++){
  digitalWrite(3, HIGH);   // sets the LED on
  delay(50);                  // waits for a second
  digitalWrite(3, LOW);    // sets the LED off
  delay(50);
  }
}
delay(1000);
}

void loop() {
tempC = mySensor.readTemperature(); //  Måler temperaturen i grader C fra BMP180
tempK = tempC + 273;
pressure=mySensor.readPressure(); // Måler trykket i Pa
hojde = -(tempK*gaskonstant/(molarmasse*tyngdeacceleration)) * log(pressure/startpressure);

mySensorData = SD.open("Hojde.txt", FILE_WRITE);  // åbn filen på SD-kortet
if (mySensorData) {
Serial.print("Tryk: ");
Serial.print(pressure);
Serial.println(" Pa");
Serial.print(" Højde: ");
Serial.print(hojde);
Serial.println(" meter");
//delay(250);   

//dataString = String("Tryk (Pa):") + String(pressure) + String(" ; ") + String("Temperatur (gr.C):") + String(tempC) + String(" ; ") + String("Højde (m):") + String(hojde);
mySensorData.print("Tid (s): ");  //skriv data til SD-kortet
mySensorData.print(millis()/1000);  //skriv data til SD-kortet
mySensorData.print(" ; Tryk (Pa): ");  //skriv data til SD-kortet
mySensorData.print(pressure);  //skriv data til SD-kortet
mySensorData.print(" ; Temp (gr.C): ");  //skriv data til SD-kortet
mySensorData.print(tempC);  //skriv data til SD-kortet
mySensorData.print(" ; Højde (m): ");  //skriv data til SD-kortet
mySensorData.println(hojde);  //skriv data til SD-kortet
mySensorData.close();           //luk filen på SD-kortet
digitalWrite(3, HIGH);   // sets the LED on
  delay(100);                  // waits for a second
  digitalWrite(3, LOW);    // sets the LED off
  delay(100);
}
}
Dette indlæg blev udgivet i Arduino. Bogmærk permalinket.