Skip to content

Commit

Permalink
deploy: 7cdd568
Browse files Browse the repository at this point in the history
  • Loading branch information
bytecod3 committed Aug 6, 2024
1 parent 7807852 commit ac3b25b
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 49 deletions.
2 changes: 1 addition & 1 deletion class_data_logger.html
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@
<table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pub-methods" name="pub-methods"></a>
Public Member Functions</h2></td></tr>
<tr class="memitem:a9ddfc501b4bd4f004f11854c3552d574" id="r_a9ddfc501b4bd4f004f11854c3552d574"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="#a9ddfc501b4bd4f004f11854c3552d574">DataLogger</a> (uint8_t <a class="el" href="src_2main_8cpp.html#aed65b23a4e5c39c4267c5730833e70db">cs_pin</a>, uint8_t led_pin, char *<a class="el" href="src_2main_8cpp.html#a6c2affe0788e6ba12dce7a51e1bd35c3">filename</a>, SerialFlashFile <a class="el" href="src_2main_8cpp.html#ada14cbbf98490eb3cb49b5d1cb0c0056">file</a>, uint32_t filesize)</td></tr>
<tr class="memitem:a9ddfc501b4bd4f004f11854c3552d574" id="r_a9ddfc501b4bd4f004f11854c3552d574"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="#a9ddfc501b4bd4f004f11854c3552d574">DataLogger</a> (uint8_t cs_pin, uint8_t led_pin, char *<a class="el" href="src_2main_8cpp.html#a6c2affe0788e6ba12dce7a51e1bd35c3">filename</a>, SerialFlashFile <a class="el" href="src_2main_8cpp.html#ada14cbbf98490eb3cb49b5d1cb0c0056">file</a>, uint32_t filesize)</td></tr>
<tr class="memdesc:a9ddfc501b4bd4f004f11854c3552d574"><td class="mdescLeft">&#160;</td><td class="mdescRight">class constructor pass the chip select pin as a parameter for that class instance <br /></td></tr>
<tr class="separator:a9ddfc501b4bd4f004f11854c3552d574"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a0cf2853582b7f2194eb0024d3d6d4944" id="r_a0cf2853582b7f2194eb0024d3d6d4944"><td class="memItemLeft" align="right" valign="top">bool&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="#a0cf2853582b7f2194eb0024d3d6d4944">loggerInit</a> ()</td></tr>
Expand Down
2 changes: 1 addition & 1 deletion class_m_p_u6050.html
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ <h2 class="memtitle"><span class="permalink"><a href="#a63bb7b9f83eca4c2debdd0df
</tr>
</table>
</div><div class="memdoc">
<p>Read X axix acceleration </p>
<p>Read X axiS acceleration </p>

</div>
</div>
Expand Down
95 changes: 48 additions & 47 deletions md__r_e_a_d_m_e.html
Original file line number Diff line number Diff line change
Expand Up @@ -88,65 +88,65 @@
<div class="headertitle"><div class="title">N4 Flight Software Documentation</div></div>
</div><!--header-->
<div class="contents">
<div class="textblock"><p><a class="anchor" id="autotoc_md0"></a><img src="https://img.shields.io/badge/Version-N4-blue" alt="Static Badge" class="inline"/> <img src="https://img.shields.io/badge/License-MIT-red" alt="Static Badge" class="inline"/> <img src="https://img.shields.io/badge/Status-development-orange" alt="Static Badge" class="inline"/></p>
<h2><a class="anchor" id="autotoc_md1"></a>
<div class="textblock"><p><a class="anchor" id="autotoc_md16"></a><img src="https://img.shields.io/badge/Version-N4-blue" alt="Static Badge" class="inline"/> <img src="https://img.shields.io/badge/License-MIT-red" alt="Static Badge" class="inline"/> <img src="https://img.shields.io/badge/Status-development-orange" alt="Static Badge" class="inline"/></p>
<h2><a class="anchor" id="autotoc_md17"></a>
Code documentation</h2>
<p>The complete code documentation can be found here ()[]</p>
<h2><a class="anchor" id="autotoc_md2"></a>
<h2><a class="anchor" id="autotoc_md18"></a>
N4 Flight software requirements</h2>
<hr />
<h3><a class="anchor" id="autotoc_md4"></a>
<h3><a class="anchor" id="autotoc_md20"></a>
1. Rocket kinematics (acceleration, velocity)</h3>
<p>a) Perform accurate calculation of acceleration and velocity from sensor data</p>
<p>b) Perform data filtering to get close to ideal simulated data</p>
<h3><a class="anchor" id="autotoc_md5"></a>
<h3><a class="anchor" id="autotoc_md21"></a>
2. Rocket altitude above ground level (AGL)</h3>
<p>a) Determine the rocket's instantaneous AGL during flight</p>
<h3><a class="anchor" id="autotoc_md6"></a>
<h3><a class="anchor" id="autotoc_md22"></a>
3. Flight state transitions</h3>
<p>a) Accurately switch to the corresponding flight state based on evaluated sensor data</p>
<h3><a class="anchor" id="autotoc_md7"></a>
<h3><a class="anchor" id="autotoc_md23"></a>
4. Data logging and storage</h3>
<p>a) Collect and aggregate all sensor data and store it in an external flash memory for post-flight data recovery</p>
<p>b) Perform onboard system logging to indicate all events that occur during flight and store this in a separate system log file</p>
<h3><a class="anchor" id="autotoc_md8"></a>
<h3><a class="anchor" id="autotoc_md24"></a>
5. Onboard systems diagnostics</h3>
<p>a) Troubleshoot onboard subsystems such as the sensors, batteries etc. and log to the system file</p>
<p>b) Package the system diagnostics results into telemetry packets for transmission to ground</p>
<h3><a class="anchor" id="autotoc_md9"></a>
<h3><a class="anchor" id="autotoc_md25"></a>
6. GPS location</h3>
<p>a) Accurately determine the latitude, longitude and timestamp of the rocket using GPS for post flight recovery</p>
<h3><a class="anchor" id="autotoc_md10"></a>
<h3><a class="anchor" id="autotoc_md26"></a>
7. Rocket attitude (orientation ) determination</h3>
<p>a) Calculate the roll and pitch of the rocket in space during flight</p>
<h3><a class="anchor" id="autotoc_md11"></a>
<h3><a class="anchor" id="autotoc_md27"></a>
8. Command and data handling</h3>
<p>a) Receive commands sent from ground station</p>
<p>b) Decode commands sent from ground station</p>
<p>c) Acknowledge and perform command sent from the ground station</p>
<h3><a class="anchor" id="autotoc_md12"></a>
<h3><a class="anchor" id="autotoc_md28"></a>
9. Telemetry transmission</h3>
<p>a) Reliably transmit the rocket's data to the ground station</p>
<p>b) Perform error detection and correction on the telemetry packets</p>
<h3><a class="anchor" id="autotoc_md13"></a>
<h3><a class="anchor" id="autotoc_md29"></a>
10. Video capture and streaming**</h3>
<p>a) Capture video stream during flight</p>
<p>b) Record video stream to an onboard SD card for post-flight analysis</p>
<p>b) Transmit video stream to ground**</p>
<h2><a class="anchor" id="autotoc_md14"></a>
<h2><a class="anchor" id="autotoc_md30"></a>
Tasks and task creation</h2>
<hr />
<h2><a class="anchor" id="autotoc_md16"></a>
autotoc_md16</h2>
<h2><a class="anchor" id="autotoc_md17"></a>
<h2><a class="anchor" id="autotoc_md32"></a>
autotoc_md32</h2>
<h2><a class="anchor" id="autotoc_md33"></a>
Data queues and task communication</h2>
<hr />
<h2><a class="anchor" id="autotoc_md19"></a>
<h2><a class="anchor" id="autotoc_md35"></a>
Telemetry and transmission to ground</h2>
<hr />
<h3><a class="anchor" id="autotoc_md21"></a>
<h3><a class="anchor" id="autotoc_md37"></a>
Link budget calculation</h3>
<h3><a class="anchor" id="autotoc_md22"></a>
<h3><a class="anchor" id="autotoc_md38"></a>
Telemetry packet structure</h3>
<table class="markdownTable">
<tr class="markdownTableHead">
Expand Down Expand Up @@ -200,18 +200,18 @@ <h3><a class="anchor" id="autotoc_md22"></a>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyNone"><b>Total packet size</b> </td><td class="markdownTableBodyNone"></td><td class="markdownTableBodyNone"><b>74 BYTES</b> </td><td class="markdownTableBodyNone"></td></tr>
</table>
<h2><a class="anchor" id="autotoc_md23"></a>
<h2><a class="anchor" id="autotoc_md39"></a>
Data Logging and storage</h2>
<hr />
<p>For logging and storage, we use two methods to ensure redundancy.</p>
<p>One is logging to an external SPI flash memory during flight, the WINBOND W25Q32JVSIQ2135, which is a 32Mbits(4 MB) storage chip. For redundancy, we add a microSD card into which data is dumped from the external SPI flash memory POST-FLIGHT.</p>
<p>The logging flowchart is shown below:</p>
<p><img src="./imgs/logger-flowchart.png" alt="logger-flowchart" class="inline"/></p>
<h3><a class="anchor" id="autotoc_md25"></a>
<h3><a class="anchor" id="autotoc_md41"></a>
Flash chip hardware tests</h3>
<p>Using this library <a href="https://github.com/PaulStoffregen/SerialFlash/tree/master">SerialFlashLib</a>, we carried out flash chip hardware tests to make sure the MCU communicates as desired with the memory chip. The circuit diagram is shown below:</p>
<p><img src="./imgs/flash-mem.png" alt="flash-cct" class="inline"/></p>
<h3><a class="anchor" id="autotoc_md26"></a>
<h3><a class="anchor" id="autotoc_md42"></a>
PCB layout for the flash memory</h3>
<p>To ensure maximum reliability of the flash memory on the PCB, follow the following techniques during layout:</p>
<p>The following snapshot from serial monitor shows that ESP32 was able to recognize the chip over the SPI channel.</p>
Expand All @@ -223,7 +223,7 @@ <h3><a class="anchor" id="autotoc_md26"></a>
<p>Now, since we want to access the flash memory in a file-system kind of way, where we can read and write FILES, we use the <a href="https://github.com/PaulStoffregen/SerialFlash">SerialFlash Library</a>, even if the flash memory is not recognized by it. This will make it easier for us to access huge blocks of memory in chunks and avoid accessing the memory directly. In addition, we can erase files and use SD-like methods to access data.</p>
<p>The demonstration below received data from the serial monitor, and writes it to a file inside the flash memory.</p>
<p>First we test for file R/W.</p>
<h4><a class="anchor" id="autotoc_md27"></a>
<h4><a class="anchor" id="autotoc_md43"></a>
Known issue</h4>
<p>When using SPI protocol on breadboard, it might fail to communicate with the peripheral device. This is because SPI is high-speed and is expected to be used with short traces on PCB. When testing this part, I experienced errors before i realized this issue. To correct this, I reduced the SPI communication speed from 50MHz to 20MHz so that I could access the R/W functions using the breadboard. More details are in reference #8 below.</p>
<p>Note: Make sure you change the speed to 20MHz for your files to be created. Change the speed in the SerialFlashChip.cpp near the top of the file (SPICONFIG)</p>
Expand All @@ -234,15 +234,15 @@ <h4><a class="anchor" id="autotoc_md27"></a>
<li>I then appended this random data to the file, while checking the size being occupied by the file</li>
<li>Running the <code>flash_read.ino</code> file after data is done recording displays all the recorded data on the flash memory</li>
</ol>
<h3><a class="anchor" id="autotoc_md28"></a>
<h3><a class="anchor" id="autotoc_md44"></a>
How to recover the data</h3>
<p>Use <code>Nakuja Flight Data Recovery Tool</code> to dump the recorded data as follows:</p>
<p>The image below shows the response after I reduced the SPI speed: <img src="./imgs/file-ready.png" alt="flash" class="inline"/></p>
<h2><a class="anchor" id="autotoc_md29"></a>
<h2><a class="anchor" id="autotoc_md45"></a>
GPS Operations</h2>
<p>GPS is used to give us accurate location in terms of longitude, latitude, time and altitude. This data is useful for post-flight recovery and for apogee detection and verification. However, because of the low sample rate of GPS modules (1 Hz), we cannot use it reliably to log altitude data since rocketry is high speed.</p>
<p><img src="./imgs/GPS-MODULE.jfif" alt="gps" class="inline"/></p>
<h3><a class="anchor" id="autotoc_md30"></a>
<h3><a class="anchor" id="autotoc_md46"></a>
Reading GPS data algorithm</h3>
<p>We read GPS data using the <a href="https://github.com/mikalhart/TinyGPSPlus">TinyGPSPlus Library</a>. The data of interest is the latitude, longitude, time and altitude. The algorithm is as follows:</p>
<ol type="1">
Expand All @@ -252,40 +252,41 @@ <h3><a class="anchor" id="autotoc_md30"></a>
<li>Read the latitude, longitude, time and altitude into the <code>gps_type_t</code> variable</li>
<li>Send this data to <code>telemetry_queue</code></li>
</ol>
<h3><a class="anchor" id="autotoc_md31"></a>
<h3><a class="anchor" id="autotoc_md47"></a>
GPS fix time issues</h3>
<p>The start of GPS can be cold or warm. Cold start means the GPS is starting from scratch, no prior satellite data exists, and here it takes much time to lock satellites and download satellite data. Once you initially download satellite data, the following connections take less time, referred to as warm-starts.</p>
<p>When using GPS, you will find that the time it takes to acquire a fix to GPS satellites depends on the cloud cover. If the cloud cover is too high, it takes longer to acquire a signal and vice-versa. During one of the tests of the GPS, it took ~2 min at 45% cloud cover to acquire signal.</p>
<p>During launch, we do not want to wait for infinity to get a GPS lock, so we implement a timeout as follows:</p>
<div class="fragment"><div class="line">Consider the GPS_WAIT_TIME as 2 minutes (2000ms):</div>
<div class="line"> </div>
<div class="line">1. Initialize a timeout variable and a lock_acquired boolean value</div>
<div class="line">2. Check the value of the timeout_variable</div>
<div class="line">1. Initialize a timeout variable and a lock_acquired boolean <a class="code hl_variable" href="src_2main_8cpp.html#ac4f474c82e82cbb89ca7c36dd52be0ed">value</a></div>
<div class="line">2. Check the <a class="code hl_variable" href="src_2main_8cpp.html#ac4f474c82e82cbb89ca7c36dd52be0ed">value</a> of the timeout_variable</div>
<div class="line">3. Is it less than the GPS_WAIT_TIME?</div>
<div class="line">4. If less than the wait time, continue waiting for GPS fix, if more than the GPS_WAIT_TIME, stop waiting for fix and return false</div>
<div class="line">5. If the GPS data is available and successfully encoded via serial, set the lock_acquired booelan value to true</div>
<div class="line">5. If the GPS data is available and successfully encoded via serial, set the lock_acquired booelan <a class="code hl_variable" href="src_2main_8cpp.html#ac4f474c82e82cbb89ca7c36dd52be0ed">value</a> to true</div>
<div class="ttc" id="asrc_2main_8cpp_html_ac4f474c82e82cbb89ca7c36dd52be0ed"><div class="ttname"><a href="src_2main_8cpp.html#ac4f474c82e82cbb89ca7c36dd52be0ed">value</a></div><div class="ttdeci">int value</div><div class="ttdoc">Parse the received serial command if it is a string.</div><div class="ttdef"><b>Definition</b> main.cpp:388</div></div>
</div><!-- fragment --><p>This timeout will ensure we do not delay other sub-systems of the flight software from starting.</p>
<h4><a class="anchor" id="autotoc_md32"></a>
<h4><a class="anchor" id="autotoc_md48"></a>
Flowchart</h4>
<p><img src="./imgs/gps-lock-flow.png" alt="gps-flowchart" class="inline"/></p>
<h3><a class="anchor" id="autotoc_md33"></a>
<h3><a class="anchor" id="autotoc_md49"></a>
GPS tests</h3>
<p>The following screenshots show the results of GPS tests during development. In the image below, the raw GPS coordinates are read and printed on the serial debugger:</p>
<p><img src="./imgs/gps-test-altitude.png" alt="gps-data" class="inline"/></p>
<h2><a class="anchor" id="autotoc_md34"></a>
<h2><a class="anchor" id="autotoc_md50"></a>
State machine logic and operation</h2>
<hr />
<h3><a class="anchor" id="autotoc_md36"></a>
<h3><a class="anchor" id="autotoc_md52"></a>
States</h3>
<h3><a class="anchor" id="autotoc_md37"></a>
<h3><a class="anchor" id="autotoc_md53"></a>
State transition conditions</h3>
<h3><a class="anchor" id="autotoc_md38"></a>
<h3><a class="anchor" id="autotoc_md54"></a>
State functions handling</h3>
<h2><a class="anchor" id="autotoc_md39"></a>
<h2><a class="anchor" id="autotoc_md55"></a>
IMU</h2>
<h3><a class="anchor" id="autotoc_md40"></a>
<h3><a class="anchor" id="autotoc_md56"></a>
Calculating acceleration from accelerometer</h3>
<h3><a class="anchor" id="autotoc_md41"></a>
<h3><a class="anchor" id="autotoc_md57"></a>
Calculating velocity from accelerometer</h3>
<p>The initial idea is to use integration. Since velocity is the first integral of acceleration. From the equation: </p><div class="fragment"><div class="line">v = u + at </div>
</div><!-- fragment --><p>So what we do to calculate the velocity is keep track of time, acceleration in the requires axis and then update the initial velocity. Consider the X axis:</p>
Expand All @@ -297,29 +298,29 @@ <h3><a class="anchor" id="autotoc_md41"></a>
<p>However, after extensive research online, it was concluded that getting velocity from accelerometer is very innacurate and unreliable. Check out this reddit thread: <a href="https://www.reddit.com/r/embedded/comments/138jnhu/acceleration_velocity_with_mpu6050/">Acceleration &amp; velocity with MPU6050</a></p>
<p>Check this arduinoForum article too (ArduinForum) [<a href="https://forum.arduino.cc/t/integrating-acceleration-to-get-velocity/954731/8">https://forum.arduino.cc/t/integrating-acceleration-to-get-velocity/954731/8</a>]</p>
<p>Following this, we decide to keep the accelerometer for measuring the acceleration and the rocket orientation.</p>
<h2><a class="anchor" id="autotoc_md42"></a>
<h2><a class="anchor" id="autotoc_md58"></a>
Data Filtering</h2>
<hr />
<h3><a class="anchor" id="autotoc_md44"></a>
<h3><a class="anchor" id="autotoc_md60"></a>
Complementary filter</h3>
<h2><a class="anchor" id="autotoc_md45"></a>
<h2><a class="anchor" id="autotoc_md61"></a>
Utility scripts</h2>
<p>During development the following scripts might (and will) be useful.</p>
<h4><a class="anchor" id="autotoc_md46"></a>
<h4><a class="anchor" id="autotoc_md62"></a>
1. HEX converter</h4>
<p>Converts string to HEX string and back. Built with python </p>
<h5><a class="anchor" id="autotoc_md47"></a>
<h5><a class="anchor" id="autotoc_md63"></a>
Requirements</h5>
<ol type="1">
<li>Python &gt; 3.10</li>
</ol>
<p>The screenshot below shows the program running: <img src="./imgs/hex-converter.png" alt="hex-converter" class="inline"/></p>
<h5><a class="anchor" id="autotoc_md48"></a>
<h5><a class="anchor" id="autotoc_md64"></a>
Usage</h5>
<p>Open a terminal window in the folder containing the <code>hex-converter.py</code> file and run the following command:</p>
<div class="fragment"><div class="line">python hex-converter.py</div>
</div><!-- fragment --><p> The screenshot above appears. Select your option and proceed. The program will output your string in HEX format.</p>
<h2><a class="anchor" id="autotoc_md49"></a>
<h2><a class="anchor" id="autotoc_md65"></a>
References and Error fixes</h2>
<ol type="1">
<li>(Wire LIbrary Device Lock) <a href="https://github.com/espressif/arduino-esp32/issues/6616">Confusing overload of <code>Wire::begin</code> · Issue #6616 · espressif/arduino-esp32 · GitHub</a></li>
Expand Down
4 changes: 4 additions & 0 deletions search/pages_7.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
var searchData=
[
['readme_0',['README',['../md_n4-flight-software_2_r_e_a_d_m_e.html',1,'']]]
];
4 changes: 4 additions & 0 deletions search/pages_8.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
var searchData=
[
['software_20documentation_0',['N4 Flight Software Documentation',['../md__r_e_a_d_m_e.html',1,'']]]
];

0 comments on commit ac3b25b

Please sign in to comment.