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.
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.
* 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.
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:
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:
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); } }