{"id":447,"date":"2016-09-18T21:53:16","date_gmt":"2016-09-18T11:53:16","guid":{"rendered":"http:\/\/leederville.net\/rocket\/?p=447"},"modified":"2016-09-18T21:54:27","modified_gmt":"2016-09-18T11:54:27","slug":"small-air-pressure-sensor","status":"publish","type":"post","link":"https:\/\/leederville.net\/rocket\/index.php\/2016\/09\/18\/small-air-pressure-sensor\/","title":{"rendered":"Small Air-Pressure Sensor"},"content":{"rendered":"<p>I put together a small air-pressure sensor that could fit inside a Junior Model rocket nose cone. The components used were:-<\/p>\n<ul>\n<li>3.3v Mini Trinket<\/li>\n<li>BMP180 GY-68 sensor<\/li>\n<li>50mAH Lithium Ion Battery<\/li>\n<li>A lot of hardcore programming to get it to fit in 5k of space!<\/li>\n<\/ul>\n<p>Some pictures of this are shown below.<\/p>\n<p>&nbsp;<\/p>\n<figure id=\"attachment_449\" aria-describedby=\"caption-attachment-449\" style=\"width: 300px\" class=\"wp-caption alignnone\"><a href=\"http:\/\/leederville.net\/rocket\/wp-content\/uploads\/2016\/09\/sml_IMG_1306.jpg\"><img loading=\"lazy\" class=\"size-medium wp-image-449\" src=\"http:\/\/leederville.net\/rocket\/wp-content\/uploads\/2016\/09\/sml_IMG_1306-300x225.jpg\" alt=\"Everything together.\" width=\"300\" height=\"225\" srcset=\"https:\/\/leederville.net\/rocket\/wp-content\/uploads\/2016\/09\/sml_IMG_1306-300x225.jpg 300w, https:\/\/leederville.net\/rocket\/wp-content\/uploads\/2016\/09\/sml_IMG_1306.jpg 320w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><figcaption id=\"caption-attachment-449\" class=\"wp-caption-text\">Everything together.<\/figcaption><\/figure>\n<figure id=\"attachment_450\" aria-describedby=\"caption-attachment-450\" style=\"width: 300px\" class=\"wp-caption alignnone\"><a href=\"http:\/\/leederville.net\/rocket\/wp-content\/uploads\/2016\/09\/sml_IMG_1307.jpg\"><img loading=\"lazy\" class=\"size-medium wp-image-450\" src=\"http:\/\/leederville.net\/rocket\/wp-content\/uploads\/2016\/09\/sml_IMG_1307-300x225.jpg\" alt=\"Glued string to interior of the Nose cone. This string then is thread through cap and tied to it. This keeps everything together.\" width=\"300\" height=\"225\" srcset=\"https:\/\/leederville.net\/rocket\/wp-content\/uploads\/2016\/09\/sml_IMG_1307-300x225.jpg 300w, https:\/\/leederville.net\/rocket\/wp-content\/uploads\/2016\/09\/sml_IMG_1307.jpg 320w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><figcaption id=\"caption-attachment-450\" class=\"wp-caption-text\">Glued string to interior of the Nose cone. This string then is thread through cap and tied to it. This keeps everything together.<\/figcaption><\/figure>\n<p><strong>NOTE<\/strong>: We had a very small hole drilled into the side of the Nose Cone to allow air pressure to equalise.<\/p>\n<figure id=\"attachment_451\" aria-describedby=\"caption-attachment-451\" style=\"width: 300px\" class=\"wp-caption alignnone\"><a href=\"http:\/\/leederville.net\/rocket\/wp-content\/uploads\/2016\/09\/sml_IMG_1304.jpg\"><img loading=\"lazy\" class=\"size-medium wp-image-451\" src=\"http:\/\/leederville.net\/rocket\/wp-content\/uploads\/2016\/09\/sml_IMG_1304-300x225.jpg\" alt=\"Top view of sensor unit. Battery is glued to the Veraboard pcb. Wires that you see connect to the Air pressure sensor on top\" width=\"300\" height=\"225\" srcset=\"https:\/\/leederville.net\/rocket\/wp-content\/uploads\/2016\/09\/sml_IMG_1304-300x225.jpg 300w, https:\/\/leederville.net\/rocket\/wp-content\/uploads\/2016\/09\/sml_IMG_1304.jpg 320w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><figcaption id=\"caption-attachment-451\" class=\"wp-caption-text\">Top view of sensor unit. Battery is glued to the Veraboard pcb. Wires that you see connect to the Air pressure sensor on top<\/figcaption><\/figure>\n<figure id=\"attachment_452\" aria-describedby=\"caption-attachment-452\" style=\"width: 300px\" class=\"wp-caption alignnone\"><a href=\"http:\/\/leederville.net\/rocket\/wp-content\/uploads\/2016\/09\/sml_IMG_1305.jpg\"><img loading=\"lazy\" class=\"size-medium wp-image-452\" src=\"http:\/\/leederville.net\/rocket\/wp-content\/uploads\/2016\/09\/sml_IMG_1305-300x225.jpg\" alt=\"Underside of sensor device. On\/Off switch is at top. Three pin header at bottom of for Serial Connection.\" width=\"300\" height=\"225\" srcset=\"https:\/\/leederville.net\/rocket\/wp-content\/uploads\/2016\/09\/sml_IMG_1305-300x225.jpg 300w, https:\/\/leederville.net\/rocket\/wp-content\/uploads\/2016\/09\/sml_IMG_1305.jpg 320w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><figcaption id=\"caption-attachment-452\" class=\"wp-caption-text\">Underside of sensor device. On\/Off switch is at top. Three pin header at bottom of for Serial Connection.<\/figcaption><\/figure>\n<p>&nbsp;<\/p>\n<p>The code had to be able to detect a reduction in Air Pressure, to sense that the rocket flight had started. Then it had to record the last 10 measurements plus another 40 measurements inside the EPROM of the Arduino. We had a measurement taking place every 0.2 seconds, so we got 10 seconds of measurements.<\/p>\n<p>And it worked quite well! Below is a plot of points for maiden flight.<\/p>\n<p>&nbsp;<\/p>\n<figure id=\"attachment_453\" aria-describedby=\"caption-attachment-453\" style=\"width: 300px\" class=\"wp-caption alignnone\"><a href=\"http:\/\/leederville.net\/rocket\/wp-content\/uploads\/2016\/09\/picture_of_pressure_over_flight.jpg\"><img loading=\"lazy\" class=\"size-medium wp-image-453\" src=\"http:\/\/leederville.net\/rocket\/wp-content\/uploads\/2016\/09\/picture_of_pressure_over_flight-300x180.jpg\" alt=\"Air Pressure vs time\" width=\"300\" height=\"180\" srcset=\"https:\/\/leederville.net\/rocket\/wp-content\/uploads\/2016\/09\/picture_of_pressure_over_flight-300x180.jpg 300w, https:\/\/leederville.net\/rocket\/wp-content\/uploads\/2016\/09\/picture_of_pressure_over_flight.jpg 614w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><figcaption id=\"caption-attachment-453\" class=\"wp-caption-text\">Air Pressure vs time<\/figcaption><\/figure>\n<p>Below is the code I used. Please note, that I have not included a cut-down version of SoftwareSerial. Essentially the Trinket never needs to receive data on its software Serial link, so I commented out code in the library. This allows the program to JUST fit inside the 5310 Bytes.<\/p>\n<p>&nbsp;<\/p>\n<pre>#include &lt;TinyWireM.h&gt;\r\n#include &lt;SoftwareSerial.h&gt;\r\n#include &lt;EEPROM.h&gt;\r\n\r\n\/\/ Uncomment following line, recompile and upload to\r\n\/\/ read results. This is because we don't have enough\r\n\/\/ space to have READ and WRITE functionality co-existing.\r\n\/\/ #define READ\r\n\r\nSoftwareSerial mySerial(4, 3); \/\/ RX, TX\r\n\r\nint addr = 0; \/\/ EEPROM memory\r\n\r\n#define BMP180_ADDRESS 0x77 \/\/ I2C address of BMP180 \r\n\/\/ define calibration data for temperature:\r\nint ac1;\r\nint ac2; \r\nint ac3; \r\nunsigned int ac4;\r\nunsigned int ac5;\r\nunsigned int ac6;\r\nint b1; \r\nint b2;\r\nint mb;\r\nint mc;\r\nint md;\r\nlong b5; \r\n\/\/define variables for pressure and temperature calculation\r\nlong x1,x2;\r\n\/\/define variables for pressure calculation\r\nlong x3,b3,b6,p;\r\nunsigned long b4,b7;\r\n\/\/define variables for temperature and pressure reading\r\n\r\nlong p_avg = 0;\r\nbyte iter = 0;\r\nint p_threshold = 200;\r\nint p_threshold_count_required = 3;\r\nint p_threshold_count = 0;\r\nboolean launch_detected = false;\r\nboolean information_saved = false;\r\nlong rawpressure;\r\n\r\n\r\nlong hist_measurements[10];\r\nlong measurements[40];\r\nshort hist_measurement_index = 0;\r\nshort measurement_index = 0;\r\n\r\n\r\nconst unsigned char OSS = 3; \/\/ Oversampling Setting\r\n\/* blz 12 Datasheet\r\nOSS=0 ultra Low Power Setting, 1 sample, 4.5 ms 3uA\r\nOSS=1 Standard Power Setting, 2 samples, 7.5 ms 5uA\r\nOSS=2 High Resolution, 4 samples, 13.5 ms 7uA\r\nOSS=3 Ultra High Resolution, 2 samples, 25.5 ms 12uA\r\n*\/\r\n\r\n\r\nvoid setup() {\r\n\r\n pinMode(1, OUTPUT);\r\n digitalWrite(1, HIGH);\r\n \r\n \r\n TinyWireM.begin();\r\n delay(5000);\r\n \r\n \/\/ First read calibration data from EEPROM\r\n ac1 = bmp180ReadInt(0xAA);\r\n ac2 = bmp180ReadInt(0xAC);\r\n ac3 = bmp180ReadInt(0xAE);\r\n ac4 = bmp180ReadInt(0xB0);\r\n ac5 = bmp180ReadInt(0xB2);\r\n ac6 = bmp180ReadInt(0xB4);\r\n b1 = bmp180ReadInt(0xB6);\r\n b2 = bmp180ReadInt(0xB8);\r\n mb = bmp180ReadInt(0xBA);\r\n mc = bmp180ReadInt(0xBC);\r\n md = bmp180ReadInt(0xBE);\r\n\r\n\r\n delay(5000);\r\n mySerial.begin(9600);\r\n \/\/ mySerial.println(\"S\");\r\n digitalWrite(1, LOW);\r\n\r\n#ifdef READ\r\n \/\/ uncomment this and comment out the writeResults below when wanting to read values.\r\n readResults();\r\n#endif \r\n \r\n}\r\n\r\nvoid loop() {\r\n \/\/ first, read uncompensated temperature\r\n \/\/temperature = bmp180ReadUT();\r\n \/\/and then calculate calibrated temperature\r\n unsigned int rawtemp = bmp180ReadUT();\r\n b5 = computeB5 (rawtemp);\r\n \/\/ temperature = bmp180CorrectTemperature(bmp180ReadUT());\r\n \/\/ then , read uncompensated pressure\r\n rawpressure = bmp180ReadUP();\r\n\r\n b6 = b5 - 4000;\r\n \/\/ Calculate B3\r\n x1 = (b2 * (b6 * b6)&gt;&gt;12)&gt;&gt;11;\r\n x2 = (ac2 * b6)&gt;&gt;11;\r\n x3 = x1 + x2;\r\n b3 = (((((long)ac1)*4 + x3)&lt;&lt;OSS) + 2)&gt;&gt;2;\r\n \r\n \/\/ Calculate B4\r\n x1 = (ac3 * b6)&gt;&gt;13;\r\n x2 = (b1 * ((b6 * b6)&gt;&gt;12))&gt;&gt;16;\r\n x3 = ((x1 + x2) + 2)&gt;&gt;2;\r\n b4 = (ac4 * (unsigned long)(x3 + 32768))&gt;&gt;15;\r\n \r\n b7 = ((unsigned long)(rawpressure - b3) * (50000&gt;&gt;OSS));\r\n if (b7 &lt; 0x80000000) {\r\n p = (b7&lt;&lt;1)\/b4;\r\n } else {\r\n p = (b7\/b4)&lt;&lt;1; \r\n }\r\n x1 = (p&gt;&gt;8) * (p&gt;&gt;8);\r\n x1 = (x1 * 3038)&gt;&gt;16;\r\n x2 = (-7357 * p)&gt;&gt;16;\r\n p += (x1 + x2 + 3791)&gt;&gt;4;\r\n \r\n\r\n\/\/ Debugging \r\n\/\/ mySerial.println(p);\r\n\r\n if (iter &lt; 10) {\r\n p_avg = (iter * p_avg + p)\/(iter+1);\r\n iter++; \r\n\r\n\r\n\/\/ Debugging\r\n\/*\r\n if (iter == 10) {\r\n mySerial.print(\"a\"); \r\n mySerial.println(p_avg);\r\n\r\n mySerial.println(((p_avg &gt;&gt; 32) &amp; 0xff), HEX);\r\n mySerial.println(((p_avg &gt;&gt; 16) &amp; 0xff), HEX);\r\n mySerial.println(((p_avg &gt;&gt; 8) &amp; 0xff), HEX);\r\n mySerial.println((p_avg &amp; 0xff), HEX);\r\n\r\n delay(120);\r\n }\r\n*\/\r\n \r\n }\r\n\r\n if ( p_avg - p &gt; p_threshold) {\r\n p_threshold_count++;\r\n } else {\r\n p_threshold_count = 0;\r\n }\r\n\r\n if (p_threshold_count &gt;= p_threshold_count_required) {\r\n launch_detected = true;\r\n }\r\n\r\n \r\n#ifndef READ\r\n if (launch_detected) {\r\n digitalWrite(1, HIGH);\r\n measurements[measurement_index] = p;\r\n measurement_index++;\r\n if (measurement_index &gt; 40) {\r\n measurement_index = 0; \r\n if (! information_saved) {\r\n information_saved = true;\r\n writeResults (p_avg, hist_measurement_index);\r\n }\r\n }\r\n \r\n } else {\r\n hist_measurements[hist_measurement_index] = p;\r\n hist_measurement_index++;\r\n if (hist_measurement_index &gt; 9) hist_measurement_index = 0;\r\n }\r\n#endif\r\n \r\n \/\/ mySerial.println(rawtemp);\r\n \/\/ mySerial.println(temperature);\r\n \/\/ mySerial.println(b5);\r\n delay(200);\r\n}\r\n\r\n\r\n\r\nint bmp180ReadInt(unsigned char address)\r\n{\r\n unsigned char msb, lsb;\r\n TinyWireM.beginTransmission(BMP180_ADDRESS);\r\n TinyWireM.send(address);\r\n TinyWireM.endTransmission();\r\n TinyWireM.requestFrom(BMP180_ADDRESS, 2);\r\n while(TinyWireM.available()&lt;2);\r\n msb = TinyWireM.receive();\r\n lsb = TinyWireM.receive();\r\n return (int) msb&lt;&lt;8 | lsb;\r\n}\r\n\r\nunsigned int bmp180ReadUT()\r\n{\r\n unsigned int ut;\r\n \r\n \/\/ Write 0x2E into Register 0xF4 and wait at least 4.5mS\r\n \/\/ This requests a temperature reading \r\n \/\/ with results in 0xF6 and 0xF7\r\n TinyWireM.beginTransmission(BMP180_ADDRESS);\r\n TinyWireM.send(0xF4);\r\n TinyWireM.send(0x2E);\r\n TinyWireM.endTransmission();\r\n \r\n \/\/ Wait at least 4.5ms\r\n delay(10);\r\n \r\n \/\/ Then read two bytes from registers 0xF6 (MSB) and 0xF7 (LSB)\r\n \/\/ and combine as unsigned integer\r\n ut = bmp180ReadInt(0xF6);\r\n return ut;\r\n}\r\n\r\n\/*\r\ndouble bmp180CorrectTemperature(unsigned int ut)\r\n{\r\n x1 = (((long)ut - (long)ac6)*(long)ac5) &gt;&gt; 15;\r\n x2 = ((long)mc &lt;&lt; 11)\/(x1 + md); \r\n b5 = x1 + x2; \r\n return (((b5 + 8)&gt;&gt;4)); \r\n}\r\n*\/\r\n\r\n\r\n\/\/ Read the uncompensated pressure value\r\nunsigned long bmp180ReadUP()\r\n{\r\n unsigned char msb, lsb, xlsb;\r\n unsigned long up = 0;\r\n \r\n \/\/ Write 0x34+(OSS&lt;&lt;6) into register 0xF4\r\n \/\/ Request a pressure reading w\/ oversampling setting\r\n TinyWireM.beginTransmission(BMP180_ADDRESS);\r\n TinyWireM.send(0xF4);\r\n TinyWireM.send(0x34 + (OSS&lt;&lt;6));\r\n TinyWireM.endTransmission();\r\n \r\n \/\/ Wait for conversion, delay time dependent on OSS\r\n \/\/ delay(5 + (5*OSS));\r\n delay(26);\r\n \r\n \/\/ Read register 0xF6 (MSB), 0xF7 (LSB), and 0xF8 (XLSB)\r\n TinyWireM.beginTransmission(BMP180_ADDRESS);\r\n TinyWireM.send(0xF6);\r\n TinyWireM.endTransmission();\r\n TinyWireM.requestFrom(BMP180_ADDRESS, 3);\r\n \r\n \/\/ Wait for data to become available\r\n while(TinyWireM.available() &lt; 3)\r\n ;\r\n msb = TinyWireM.receive();\r\n lsb = TinyWireM.receive();\r\n xlsb = TinyWireM.receive();\r\n \r\n up = (((unsigned long) msb &lt;&lt; 16) | ((unsigned long) lsb &lt;&lt; 8) | (unsigned long) xlsb) &gt;&gt; (8-OSS);\r\n \r\n return up;\r\n}\r\n\r\n\r\ndouble bmp180CorrectPressure(unsigned long up)\r\n{ \r\n b6 = b5 - 4000;\r\n \/\/ Calculate B3\r\n x1 = (b2 * (b6 * b6)&gt;&gt;12)&gt;&gt;11;\r\n x2 = (ac2 * b6)&gt;&gt;11;\r\n x3 = x1 + x2;\r\n b3 = (((((long)ac1)*4 + x3)&lt;&lt;OSS) + 2)&gt;&gt;2;\r\n \r\n \/\/ Calculate B4\r\n x1 = (ac3 * b6)&gt;&gt;13;\r\n x2 = (b1 * ((b6 * b6)&gt;&gt;12))&gt;&gt;16;\r\n x3 = ((x1 + x2) + 2)&gt;&gt;2;\r\n b4 = (ac4 * (unsigned long)(x3 + 32768))&gt;&gt;15;\r\n \r\n b7 = ((unsigned long)(up - b3) * (50000&gt;&gt;OSS));\r\n if (b7 &lt; 0x80000000) {\r\n p = (b7&lt;&lt;1)\/b4;\r\n } else {\r\n p = (b7\/b4)&lt;&lt;1; \r\n }\r\n x1 = (p&gt;&gt;8) * (p&gt;&gt;8);\r\n x1 = (x1 * 3038)&gt;&gt;16;\r\n x2 = (-7357 * p)&gt;&gt;16;\r\n p += (x1 + x2 + 3791)&gt;&gt;4;\r\n \r\n return p;\r\n}\r\n\r\n\r\nint32_t computeB5(int32_t UT) {\r\n int32_t X1 = (UT - (int32_t)ac6) * ((int32_t)ac5) &gt;&gt; 15;\r\n int32_t X2 = ((int32_t)mc &lt;&lt; 11) \/ (X1+(int32_t)md);\r\n return X1 + X2;\r\n}\r\n\r\n\r\n\/\/ avg_pressure = 32-bit measurement of air pressure - AVERAGE\r\n\/\/ hist_index = where we are up to in the histortical measurements...the place of the last value\r\n\/\/ This helps us know where the start\/end numbers are in the historical data...when we go to \r\n\/\/ put all the data back together again.\r\n\/\/ historical_measurements = pointer to where the historical measurements are\r\n\/\/ measurements = pointer to post launch test results are stored.\r\nvoid writeResults(long avg_pressure, short hist_index)\r\n{\r\n \/\/ Save the Average value\r\n EEPROM.write(addr, ((avg_pressure &gt;&gt; 16) &amp; 0xff));\r\n addr++;\r\n EEPROM.write(addr, ((avg_pressure &gt;&gt; 8) &amp; 0xff));\r\n addr++;\r\n EEPROM.write(addr, (avg_pressure &amp; 0xff));\r\n addr++;\r\n\r\n EEPROM.write(addr, hist_index);\r\n addr++;\r\n for (int i = 0; i &lt; 10; i++) {\r\n EEPROM.write(addr, ((hist_measurements[i] &gt;&gt; 16) &amp; 0xff));\r\n addr++;\r\n EEPROM.write(addr, ((hist_measurements[i] &gt;&gt; 8) &amp; 0xff));\r\n addr++;\r\n EEPROM.write(addr, (hist_measurements[i] &amp; 0xff)); \r\n addr++;\r\n }\r\n\r\n for (int i = 0; i &lt; 40; i++) {\r\n EEPROM.write(addr, ((measurements[i] &gt;&gt; 16) &amp; 0xff));\r\n addr++;\r\n EEPROM.write(addr, ((measurements[i] &gt;&gt; 8) &amp; 0xff));\r\n addr++;\r\n EEPROM.write(addr, (measurements[i] &amp; 0xff)); \r\n addr++;\r\n }\r\n\r\n int i = 0;\r\n while (i &lt; 100) {\r\n digitalWrite(1, HIGH);\r\n delay(50);\r\n digitalWrite(1, LOW);\r\n delay(150);\r\n i++;\r\n }\r\n}\r\n\r\n\r\nvoid readResults()\r\n{\r\n byte val;\r\n for (int i = 0; i &lt; 154; i++) {\r\n val = EEPROM.read(i);\r\n mySerial.println(val, HEX);\r\n }\r\n\r\n while(1);\r\n}\r\n\r\n\r\n\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p>Then I needed to write a PERL script to interrogate these data from the Serial Port and put in a CSV File.<\/p>\n<p>&nbsp;<\/p>\n<pre>#!\/usr\/bin\/perl\r\n\r\n$pressure_file = \"data.txt\";\r\nmy $data_index = 1;\r\n\r\nopen(my $fh, \"&lt;\", $pressure_file)\r\n or die \"cannot open &lt; \" . $pressure_file . \": $!\";\r\n\r\nmy $line_number = 1;\r\nwhile ($line = &lt;$fh&gt;)\r\n{\r\n #print \"Processing: \" . $line;\r\n if ($line_number &lt;= 3 ){\r\n $val = hex($line);\r\n $avg = $avg + 256**(3 - $line_number) * $val;\r\n# print \"Line: \" . $line;\r\n# print \"Line Number: \" . $line_number . \"\\n\";\r\n# print \"AVG: \" . $avg . \"\\n\";\r\n }\r\n \r\n if ($line_number == 3) {\r\n print \"Avg Pressure: \" . $avg . \"\\n\";\r\n }\r\n\r\n # Find Starting point in historical data\r\n if ($line_number == 4) {\r\n $start_point = $line + 1;\r\n if ($start_point == 11) {\r\n $start_point = 1;\r\n }\r\n print \"Starting Point: \" . $start_point . \"\\n\";\r\n }\r\n\r\n if ($line_number &gt; 4) {\r\n $v_data_idx_mod = ($line_number - 5) % 3;\r\n# print \"MOD: \" . $v_data_idx_mod . \"\\n\";\r\n $val = hex($line);\r\n $v_data = $v_data + 256 ** (2 - $v_data_idx_mod) * $val;\r\n# print $val . \" - \" . $v_data_idx_mod . \"\\n\";\r\n\r\n if ($v_data_idx_mod == 2) {\r\n # print \"Reading: \" . $v_data . \"\\n\";\r\n if ($data_index &lt;= 10) {\r\n $historical_data[$data_index] = $v_data;\r\n } else {\r\n $measurement_index = $data_index - 10;\r\n $measurement[$measurement_index] = $v_data;\r\n }\r\n# print $v_data . \"\\n\";\r\n $v_data = \"\";\r\n $data_index++; \r\n }\r\n \r\n\r\n\r\n\r\n }\r\n\r\n $line_number++;\r\n}\r\n\r\nclose $fh;\r\n\r\n\r\n$historical_index = $start_point;\r\nprint \"STARTING POINT: $historical_index \\n\";\r\n$i = 1;\r\n\r\nwhile ($i &lt;= 10) {\r\n$v_final[$i] = $historical_data[$historical_index];\r\n\r\n$historical_index = $historical_index + 1;\r\nif ($historical_index &gt; 10) {\r\n $historical_index = 1;\r\n}\r\n$i++;\r\n}\r\n\r\n$i = 1;\r\n$measurement_index = 11;\r\nwhile ($i &lt;= 40) {\r\n$v_final[$measurement_index] = $measurement[$i];\r\n\r\n$measurement_index++;\r\n$i++;\r\n}\r\n\r\n\r\n\r\n# Cycle through data and print it out\r\n$i = 1;\r\nwhile ($i &lt;= 50) {\r\n$time = 0.2 * $i;\r\nprint \"$time,\" . $v_final[$i] . \"\\n\";\r\n$i++;\r\n}<\/pre>\n<p>&nbsp;<\/p>\n<p>It all seems quite desperate, but this is what you need to do if you want to make it small and fit inside the Nose Cone!<\/p>\n<p>&nbsp;<\/p>\n<p>The total weight of this unit was 5 grams.<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I put together a small air-pressure sensor that could fit inside a Junior Model rocket nose cone. The components used were:- 3.3v Mini Trinket BMP180 GY-68 sensor 50mAH Lithium Ion Battery A lot of hardcore programming to get it to fit in 5k of space! Some pictures of this are shown below. &nbsp; NOTE: We &hellip; <a href=\"https:\/\/leederville.net\/rocket\/index.php\/2016\/09\/18\/small-air-pressure-sensor\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Small Air-Pressure Sensor<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[1],"tags":[],"_links":{"self":[{"href":"https:\/\/leederville.net\/rocket\/index.php\/wp-json\/wp\/v2\/posts\/447"}],"collection":[{"href":"https:\/\/leederville.net\/rocket\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/leederville.net\/rocket\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/leederville.net\/rocket\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/leederville.net\/rocket\/index.php\/wp-json\/wp\/v2\/comments?post=447"}],"version-history":[{"count":4,"href":"https:\/\/leederville.net\/rocket\/index.php\/wp-json\/wp\/v2\/posts\/447\/revisions"}],"predecessor-version":[{"id":456,"href":"https:\/\/leederville.net\/rocket\/index.php\/wp-json\/wp\/v2\/posts\/447\/revisions\/456"}],"wp:attachment":[{"href":"https:\/\/leederville.net\/rocket\/index.php\/wp-json\/wp\/v2\/media?parent=447"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/leederville.net\/rocket\/index.php\/wp-json\/wp\/v2\/categories?post=447"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/leederville.net\/rocket\/index.php\/wp-json\/wp\/v2\/tags?post=447"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}