{"id":8338,"date":"2023-11-09T16:59:09","date_gmt":"2023-11-09T15:59:09","guid":{"rendered":"https:\/\/dronesonen.usn.no\/?p=8338"},"modified":"2023-11-09T16:59:09","modified_gmt":"2023-11-09T15:59:09","slug":"turret-syndrome-week-11","status":"publish","type":"post","link":"https:\/\/dronesonen.usn.no\/?p=8338","title":{"rendered":"Turret Syndrome &#8211; Week 11"},"content":{"rendered":"\n<h2 class=\"has-text-align-center wp-block-heading\">Christopher Daffinrud<\/h2>\n\n\n\n<p><strong>On Monday <\/strong>when testing our system as a whole together with our software we encountered some issues when calling the motors for rotating the Turret. The turret rotated both clockwise and counterclockwise based on where the Detection Model detected our object, but the rotation in itself was &#8220;laggy&#8221;, giving us a feeling that the signal to the motors was not ideal. We confirmed this by analyzing the signal output from the raspberry Pi.<\/p>\n\n\n\n<p>We think the bad signals is due to the Raspberry Pi OS not prioritizing the motor calls as needed when running those is a separate thread.<\/p>\n\n\n\n<p><strong>For Tuesday<\/strong> we wanted to address this lag by using the hardware Pulse Width Modulation (PWM) pins on our Raspberry Pi. <\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"635\" height=\"407\" src=\"https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/11\/Screenshot-2023-11-05-133926.png\" alt=\"\" class=\"wp-image-8339\" srcset=\"https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/11\/Screenshot-2023-11-05-133926.png 635w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/11\/Screenshot-2023-11-05-133926-300x192.png 300w\" sizes=\"auto, (max-width: 635px) 100vw, 635px\" \/><figcaption class=\"wp-element-caption\">https:\/\/www.electronicwings.com\/raspberry-pi\/raspberry-pi-pwm-generation-using-python-and-c<\/figcaption><\/figure>\n\n\n\n<p>Using GPIO18 as shown in the picture, together with Mats, we created a function outputting a PWM signal instead. We calculated that by sending a signal of 1600Hz for a duration of 8 seconds should rotate the Turret 90 degrees.  (Based on a step size of 1.8 degrees with a 1:8 relationship with the sun-gear where the gun is mounted).<\/p>\n\n\n\n<p>The PWM-function resulted in fixing the &#8220;lag&#8221; issue, but it still only rotated the Turret around 85 degrees instead of 90. Ole will elaborate more on this in his post. <\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><strong>For next week<\/strong>: Continuation of troubleshooting and implementing the software to follow our desired requirements. We need to test and calculate for the pitch elevation as well as the trigger motor. <\/p>\n\n\n\n<h2 class=\"has-text-align-center wp-block-heading\">Ole Eirik S.Seljordslia<\/h2>\n\n\n\n<p>After using the monday and tuesday on testing our turret system, we had problems with running the motors precisely and smoothly. We found out that the raspberry pi did not produce great output for our motors. We first tried a blocking implementation that would use `time.sleep`. This worked when the system was not under load by other processes. But when we deployed our whole system, the thread performing the blocking bitbanging would miss on the timing due to the process not being prioritized at the right time.&nbsp;&nbsp;<\/p>\n\n\n\n<p>Our next implementation used the raspberry pi\u2019s PWM functionality, this would be non blocking since the timing is implemented in hardware. This solution worked well with the frequency we tried to obtain, but it would randomly skip steps. This meant that this solution would be sporadic inconsistent when we move our motors.&nbsp;<\/p>\n\n\n\n<p>Since timing the PWM signal proved to be a challenge on the raspberry pi when it was under load, we decided to offload this task to a microcontroller. I used the remainder of the week on implementing and testing this solution.&nbsp;<\/p>\n\n\n\n<p class=\"has-text-align-center\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/lh7-us.googleusercontent.com\/JNeN6x8TZjg87hjuGwlvjQmuhKjK7zfPE02Td5Eq7g8UgAVScpPuKKAQdiEmc5JbP7aE0VU4qkvTjYHGbofxAhef7Nbzg6sJoUsg3ndyai8j8cap5Dh9uVbdF1VHBrS7pmaaEGiX5hGXnwrFKFq0uac\" width=\"295\" height=\"253\"><\/p>\n\n\n\n<p>Our idea was to send commands to an Arduino Nano over UART, then the microcontroller could time the signal. Arduino Nano has 6 pins that support hardware PWM, these pins support either 490Hz or 980Hz(<a href=\"https:\/\/www.arduino.cc\/reference\/en\/language\/functions\/analog-io\/analogwrite\/\">Arduino analogWrite<\/a>). We wanted to run our motors at 1300Hz, this proved to be a good frequency combining speed and smoothness with our setup. We could have one of Arduino\u2019s frequencies but this would limit our possibility to optimize our system later on.&nbsp;<\/p>\n\n\n\n<p>One possible solution to adjust the frequency is to adjust a prescaler factor (1,8,54,256) for one of the Nano\u2019s timer clocks. This would help to adjust the frequency of the PWM pins, but we still need to know how many pulses have we sent.(<a href=\"https:\/\/docs.arduino.cc\/tutorials\/generic\/secrets-of-arduino-pwm\">Adjusting prescalers<\/a>).<\/p>\n\n\n\n<p>I chose to bitbang the pulse signal with a timer interrupt, this way I could count the number of pulses and control the frequency with high precision.<\/p>\n\n\n\n<!-- HTML generated using hilite.me --><div style=\"background: #202020;overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em\"><table><tr><td><pre style=\"margin: 0;line-height: 125%\">  1\n  2\n  3\n  4\n  5\n  6\n  7\n  8\n  9\n 10\n 11\n 12\n 13\n 14\n 15\n 16\n 17\n 18\n 19\n 20\n 21\n 22\n 23\n 24\n 25\n 26\n 27\n 28\n 29\n 30\n 31\n 32\n 33\n 34\n 35\n 36\n 37\n 38\n 39\n 40\n 41\n 42\n 43\n 44\n 45\n 46\n 47\n 48\n 49\n 50\n 51\n 52\n 53\n 54\n 55\n 56\n 57\n 58\n 59\n 60\n 61\n 62\n 63\n 64\n 65\n 66\n 67\n 68\n 69\n 70\n 71\n 72\n 73\n 74\n 75\n 76\n 77\n 78\n 79\n 80\n 81\n 82\n 83\n 84\n 85\n 86\n 87\n 88\n 89\n 90\n 91\n 92\n 93\n 94\n 95\n 96\n 97\n 98\n 99\n100\n101\n102\n103\n104\n105\n106\n107\n108\n109<\/pre><\/td><td><pre style=\"margin: 0;line-height: 125%\"><span style=\"color: #cd2828;font-weight: bold\">#include &lt;Arduino.h&gt;<\/span>\n<span style=\"color: #cd2828;font-weight: bold\">#include &lt;definitions.hpp&gt;<\/span>\n<span style=\"color: #cd2828;font-weight: bold\">#include &lt;ArduinoJson.h&gt;<\/span>\n<span style=\"color: #999999;font-style: italic\">\/**<\/span>\n<span style=\"color: #999999;font-style: italic\"> * @brief <\/span>\n<span style=\"color: #999999;font-style: italic\"> * Struct to represent motors<\/span>\n<span style=\"color: #999999;font-style: italic\"> *\/<\/span>\n<span style=\"color: #6ab825;font-weight: bold\">struct<\/span> <span style=\"color: #d0d0d0\">motor<\/span>\n<span style=\"color: #d0d0d0\">{<\/span>\n    <span style=\"color: #6ab825;font-weight: bold\">uint8_t<\/span> <span style=\"color: #d0d0d0\">pulse;<\/span>\n    <span style=\"color: #6ab825;font-weight: bold\">uint8_t<\/span> <span style=\"color: #d0d0d0\">direction;<\/span>\n    <span style=\"color: #6ab825;font-weight: bold\">unsigned<\/span> <span style=\"color: #6ab825;font-weight: bold\">int<\/span> <span style=\"color: #d0d0d0\">steps;<\/span>\n<span style=\"color: #d0d0d0\">};<\/span>\n<span style=\"color: #6ab825;font-weight: bold\">volatile<\/span> <span style=\"color: #d0d0d0\">motor<\/span> <span style=\"color: #d0d0d0\">azimuth<\/span> <span style=\"color: #d0d0d0\">=<\/span> <span style=\"color: #d0d0d0\">{.pulse=TurretSyndrome::Azimuth::pulse,<\/span>\n                 <span style=\"color: #d0d0d0\">.direction<\/span> <span style=\"color: #d0d0d0\">=<\/span> <span style=\"color: #d0d0d0\">TurretSyndrome::Azimuth::direction,<\/span>\n                 <span style=\"color: #d0d0d0\">.steps<\/span> <span style=\"color: #d0d0d0\">=<\/span> <span style=\"color: #3677a9\">0<\/span><span style=\"color: #d0d0d0\">};<\/span>\n<span style=\"color: #6ab825;font-weight: bold\">volatile<\/span> <span style=\"color: #d0d0d0\">motor<\/span> <span style=\"color: #d0d0d0\">pitch<\/span> <span style=\"color: #d0d0d0\">=<\/span> <span style=\"color: #d0d0d0\">{.pulse=TurretSyndrome::Pitch::pulse,<\/span>\n                 <span style=\"color: #d0d0d0\">.direction<\/span> <span style=\"color: #d0d0d0\">=<\/span> <span style=\"color: #d0d0d0\">TurretSyndrome::Pitch::direction,<\/span>\n                 <span style=\"color: #d0d0d0\">.steps<\/span> <span style=\"color: #d0d0d0\">=<\/span> <span style=\"color: #3677a9\">0<\/span><span style=\"color: #d0d0d0\">};<\/span>\n<span style=\"color: #6ab825;font-weight: bold\">volatile<\/span> <span style=\"color: #d0d0d0\">motor*<\/span> <span style=\"color: #d0d0d0\">motors[]<\/span> <span style=\"color: #d0d0d0\">=<\/span> <span style=\"color: #d0d0d0\">{&amp;azimuth,<\/span> <span style=\"color: #d0d0d0\">&amp;pitch};<\/span>\n<span style=\"color: #6ab825;font-weight: bold\">volatile<\/span> <span style=\"color: #6ab825;font-weight: bold\">bool<\/span> <span style=\"color: #d0d0d0\">done<\/span> <span style=\"color: #d0d0d0\">=<\/span> <span style=\"color: #24909d\">false<\/span><span style=\"color: #d0d0d0\">;<\/span>\n<span style=\"color: #999999;font-style: italic\">\/**<\/span>\n<span style=\"color: #999999;font-style: italic\"> * @brief <\/span>\n<span style=\"color: #999999;font-style: italic\"> *  Start timer1, set compare with value in microseconds<\/span>\n<span style=\"color: #999999;font-style: italic\"> * @param value <\/span>\n<span style=\"color: #999999;font-style: italic\"> *\/<\/span>\n<span style=\"color: #6ab825;font-weight: bold\">void<\/span> <span style=\"color: #447fcf\">startTimerOne<\/span><span style=\"color: #d0d0d0\">(<\/span><span style=\"color: #6ab825;font-weight: bold\">unsigned<\/span> <span style=\"color: #6ab825;font-weight: bold\">int<\/span> <span style=\"color: #d0d0d0\">compare)<\/span>\n<span style=\"color: #d0d0d0\">{<\/span>\n    <span style=\"color: #999999;font-style: italic\">\/\/Approx. 4us runtime<\/span>\n    <span style=\"color: #d0d0d0\">TCCR1A<\/span> <span style=\"color: #d0d0d0\">=<\/span> <span style=\"color: #3677a9\">0<\/span><span style=\"color: #d0d0d0\">b00000000;<\/span>\n    <span style=\"color: #d0d0d0\">TCCR1B<\/span> <span style=\"color: #d0d0d0\">=<\/span> <span style=\"color: #3677a9\">0<\/span><span style=\"color: #d0d0d0\">b00000010;<\/span>\n    <span style=\"color: #d0d0d0\">OCR1A<\/span> <span style=\"color: #d0d0d0\">=<\/span> <span style=\"color: #d0d0d0\">compare;<\/span>\n    <span style=\"color: #d0d0d0\">TCNT1H<\/span> <span style=\"color: #d0d0d0\">=<\/span> <span style=\"color: #3677a9\">0<\/span><span style=\"color: #d0d0d0\">;<\/span>\n    <span style=\"color: #d0d0d0\">TCNT1L<\/span> <span style=\"color: #d0d0d0\">=<\/span> <span style=\"color: #3677a9\">0<\/span><span style=\"color: #d0d0d0\">;<\/span>\n    <span style=\"color: #d0d0d0\">TIMSK1<\/span> <span style=\"color: #d0d0d0\">=<\/span> <span style=\"color: #d0d0d0\">_BV(OCIE1A);<\/span>\n<span style=\"color: #d0d0d0\">}<\/span>\n<span style=\"color: #999999;font-style: italic\">\/**<\/span>\n<span style=\"color: #999999;font-style: italic\"> * @brief Interrupt service routine <\/span>\n<span style=\"color: #999999;font-style: italic\"> * Flips pulse pin of motor if number of steps is not reached.<\/span>\n<span style=\"color: #999999;font-style: italic\"> * <\/span>\n<span style=\"color: #999999;font-style: italic\"> *\/<\/span>\n<span style=\"color: #d0d0d0\">ISR(TIMER1_COMPA_vect)<\/span>\n<span style=\"color: #d0d0d0\">{<\/span>\n    <span style=\"color: #d0d0d0\">startTimerOne(TurretSyndrome::ticks);<\/span>\n    <span style=\"color: #999999;font-style: italic\">\/\/ For loop takes approx. 32us<\/span>\n    <span style=\"color: #6ab825;font-weight: bold\">for<\/span><span style=\"color: #d0d0d0\">(<\/span><span style=\"color: #6ab825;font-weight: bold\">auto<\/span><span style=\"color: #d0d0d0\">&amp;<\/span> <span style=\"color: #d0d0d0\">m:<\/span> <span style=\"color: #d0d0d0\">motors)<\/span>\n    <span style=\"color: #d0d0d0\">{<\/span>\n        <span style=\"color: #6ab825;font-weight: bold\">if<\/span><span style=\"color: #d0d0d0\">(m-&gt;steps<\/span> <span style=\"color: #d0d0d0\">!=<\/span> <span style=\"color: #3677a9\">0<\/span><span style=\"color: #d0d0d0\">)<\/span>\n        <span style=\"color: #d0d0d0\">{<\/span>\n            <span style=\"color: #d0d0d0\">digitalWrite(m-&gt;pulse,<\/span> <span style=\"color: #d0d0d0\">!digitalRead(m-&gt;pulse));<\/span>\n            <span style=\"color: #6ab825;font-weight: bold\">if<\/span><span style=\"color: #d0d0d0\">(!digitalRead(m-&gt;pulse))--m-&gt;steps;<\/span>\n        <span style=\"color: #d0d0d0\">}<\/span>\n    <span style=\"color: #d0d0d0\">}<\/span>\n<span style=\"color: #d0d0d0\">}<\/span>\n<span style=\"color: #999999;font-style: italic\">\/**<\/span>\n<span style=\"color: #999999;font-style: italic\"> * @brief Message from raspberry pi<\/span>\n<span style=\"color: #999999;font-style: italic\"> * Assign steps and direction to correct motor.<\/span>\n<span style=\"color: #999999;font-style: italic\"> *\/<\/span>\n<span style=\"color: #6ab825;font-weight: bold\">void<\/span> <span style=\"color: #d0d0d0\">handleIncomingMessage()<\/span>\n<span style=\"color: #d0d0d0\">{<\/span>\n    <span style=\"color: #d0d0d0\">StaticJsonDocument&lt;<\/span><span style=\"color: #3677a9\">100<\/span><span style=\"color: #d0d0d0\">&gt;<\/span> <span style=\"color: #d0d0d0\">document;<\/span>\n    <span style=\"color: #6ab825;font-weight: bold\">if<\/span><span style=\"color: #d0d0d0\">(deserializeJson(document,<\/span> <span style=\"color: #d0d0d0\">Serial)<\/span> <span style=\"color: #d0d0d0\">!=<\/span> <span style=\"color: #d0d0d0\">DeserializationError::Ok)<\/span> <span style=\"color: #6ab825;font-weight: bold\">return<\/span><span style=\"color: #d0d0d0\">;<\/span>\n    <span style=\"color: #6ab825;font-weight: bold\">if<\/span><span style=\"color: #d0d0d0\">(document[<\/span><span style=\"color: #ed9d13\">&quot;A&quot;<\/span><span style=\"color: #d0d0d0\">])<\/span>\n    <span style=\"color: #d0d0d0\">{<\/span>\n        <span style=\"color: #d0d0d0\">azimuth.steps<\/span> <span style=\"color: #d0d0d0\">=<\/span> <span style=\"color: #d0d0d0\">document[<\/span><span style=\"color: #ed9d13\">&quot;A&quot;<\/span><span style=\"color: #d0d0d0\">][<\/span><span style=\"color: #ed9d13\">&quot;S&quot;<\/span><span style=\"color: #d0d0d0\">];<\/span>\n        <span style=\"color: #d0d0d0\">azimuth.direction<\/span> <span style=\"color: #d0d0d0\">=<\/span> <span style=\"color: #d0d0d0\">document[<\/span><span style=\"color: #ed9d13\">&quot;A&quot;<\/span><span style=\"color: #d0d0d0\">][<\/span><span style=\"color: #ed9d13\">&quot;D&quot;<\/span><span style=\"color: #d0d0d0\">];<\/span>\n    <span style=\"color: #d0d0d0\">}<\/span>\n    <span style=\"color: #6ab825;font-weight: bold\">if<\/span><span style=\"color: #d0d0d0\">(document[<\/span><span style=\"color: #ed9d13\">&quot;P&quot;<\/span><span style=\"color: #d0d0d0\">])<\/span>\n    <span style=\"color: #d0d0d0\">{<\/span>\n        <span style=\"color: #d0d0d0\">pitch.steps<\/span> <span style=\"color: #d0d0d0\">=<\/span> <span style=\"color: #d0d0d0\">document[<\/span><span style=\"color: #ed9d13\">&quot;P&quot;<\/span><span style=\"color: #d0d0d0\">][<\/span><span style=\"color: #ed9d13\">&quot;S&quot;<\/span><span style=\"color: #d0d0d0\">];<\/span>\n        <span style=\"color: #d0d0d0\">pitch.direction<\/span> <span style=\"color: #d0d0d0\">=<\/span> <span style=\"color: #d0d0d0\">document[<\/span><span style=\"color: #ed9d13\">&quot;P&quot;<\/span><span style=\"color: #d0d0d0\">][<\/span><span style=\"color: #ed9d13\">&quot;D&quot;<\/span><span style=\"color: #d0d0d0\">];<\/span>\n    <span style=\"color: #d0d0d0\">}<\/span>\n    <span style=\"color: #d0d0d0\">done<\/span> <span style=\"color: #d0d0d0\">=<\/span> <span style=\"color: #24909d\">false<\/span><span style=\"color: #d0d0d0\">;<\/span>\n<span style=\"color: #d0d0d0\">}<\/span>\n<span style=\"color: #999999;font-style: italic\">\/**<\/span>\n<span style=\"color: #999999;font-style: italic\"> * @brief Confirm that motors have performed steps.<\/span>\n<span style=\"color: #999999;font-style: italic\"> * <\/span>\n<span style=\"color: #999999;font-style: italic\"> *\/<\/span>\n<span style=\"color: #6ab825;font-weight: bold\">void<\/span> <span style=\"color: #d0d0d0\">sendResponse()<\/span>\n<span style=\"color: #d0d0d0\">{<\/span>\n    <span style=\"color: #d0d0d0\">Serial.println(<\/span><span style=\"color: #ed9d13\">&quot;Done&quot;<\/span><span style=\"color: #d0d0d0\">);<\/span>\n    <span style=\"color: #d0d0d0\">done<\/span> <span style=\"color: #d0d0d0\">=<\/span> <span style=\"color: #24909d\">true<\/span><span style=\"color: #d0d0d0\">;<\/span>\n<span style=\"color: #d0d0d0\">}<\/span>\n<span style=\"color: #6ab825;font-weight: bold\">void<\/span> <span style=\"color: #d0d0d0\">setup()<\/span>\n<span style=\"color: #d0d0d0\">{<\/span>\n    <span style=\"color: #d0d0d0\">Serial.begin(<\/span><span style=\"color: #3677a9\">115200<\/span><span style=\"color: #d0d0d0\">);<\/span>\n    <span style=\"color: #6ab825;font-weight: bold\">for<\/span> <span style=\"color: #d0d0d0\">(<\/span><span style=\"color: #6ab825;font-weight: bold\">auto<\/span><span style=\"color: #d0d0d0\">&amp;<\/span> <span style=\"color: #d0d0d0\">m:<\/span> <span style=\"color: #d0d0d0\">motors)<\/span>\n    <span style=\"color: #d0d0d0\">{<\/span>\n        <span style=\"color: #d0d0d0\">pinMode(m-&gt;direction,<\/span> <span style=\"color: #d0d0d0\">OUTPUT);<\/span>\n        <span style=\"color: #d0d0d0\">pinMode(m-&gt;pulse,<\/span> <span style=\"color: #d0d0d0\">OUTPUT);<\/span>\n        <span style=\"color: #d0d0d0\">m-&gt;steps<\/span> <span style=\"color: #d0d0d0\">=<\/span> <span style=\"color: #3677a9\">100<\/span><span style=\"color: #d0d0d0\">;<\/span>\n    <span style=\"color: #d0d0d0\">}<\/span>\n    <span style=\"color: #999999;font-style: italic\">\/\/ unsigned long m = micros();<\/span>\n    <span style=\"color: #999999;font-style: italic\">\/\/ startTimerOne(TurretSyndrome::ticks);<\/span>\n    <span style=\"color: #999999;font-style: italic\">\/\/ Serial.println(micros() - m);<\/span>\n<span style=\"color: #d0d0d0\">}<\/span>\n<span style=\"color: #6ab825;font-weight: bold\">void<\/span> <span style=\"color: #d0d0d0\">loop()<\/span>\n<span style=\"color: #d0d0d0\">{<\/span>\n    <span style=\"color: #6ab825;font-weight: bold\">if<\/span><span style=\"color: #d0d0d0\">(!azimuth.steps<\/span> <span style=\"color: #d0d0d0\">&amp;&amp;<\/span> <span style=\"color: #d0d0d0\">!pitch.steps)<\/span>\n    <span style=\"color: #d0d0d0\">{<\/span>\n        <span style=\"color: #6ab825;font-weight: bold\">if<\/span><span style=\"color: #d0d0d0\">(Serial.available())<\/span> <span style=\"color: #d0d0d0\">handleIncomingMessage();<\/span>\n        <span style=\"color: #6ab825;font-weight: bold\">else<\/span> <span style=\"color: #447fcf\">if<\/span><span style=\"color: #d0d0d0\">(!done)sendResponse();<\/span>\n    <span style=\"color: #d0d0d0\">}<\/span>\n<span style=\"color: #d0d0d0\">}<\/span>\n<\/pre><\/td><\/tr><\/table><\/div>\n\n\n\n<p>The interrupt service routine will toggle each motor&#8217;s pin and reduce the number of steps by one if it&#8217;s a falling edge. The ISR uses `digitalWrite` and `digitalRead` which are quite \u201cslow\u201d functions if we compare them to writing directly to registers. But this is a nice abstraction with a cost that we can accept.&nbsp;<\/p>\n\n\n\n<p>The critical function of this code is `startTimerOne`, this function sets up timer one on the Atmega328P to trigger after a number of systemticks. The function starts by configuring `TCCR1A` to 0 which means normal port operation and compare output to disconnected. It then sets `TCCR1B` to 2 which results in setting a prescaler of 8.This means that Timer1 only increments after 8 system ticks. Setting TCNT1H and TCT1L to zero will make the timer start at zero. `TIMESK1 = _BV(OCIE1A)` will configure an interrupt mask for the timer, and set up comparison of `OCIE1A` with Timer1.&nbsp;Reference: <a href=\"https:\/\/ww1.microchip.com\/downloads\/en\/DeviceDoc\/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf\" target=\"_blank\" rel=\"noreferrer noopener\">Atmega328P datasheet<\/a>, see page 108<\/p>\n\n\n\n<p>This means that we can calculate the number of ticks we need with the following formula:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"924\" height=\"120\" src=\"https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/11\/image-4.png\" alt=\"\" class=\"wp-image-8349\" srcset=\"https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/11\/image-4.png 924w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/11\/image-4-300x39.png 300w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/11\/image-4-768x100.png 768w\" sizes=\"auto, (max-width: 924px) 100vw, 924px\" \/><\/figure>\n\n\n\n<p>Where `ToggleFrequency` is 2 times the desired frequency(Each time we toggle the pin). `TimerPropagation` is the time it takes the Arduino Nano to run `startTimerOne`, which is approximately 4 microseconds(This was measured with a test code). And TimerFrequency being the system clock divided by the prescaler, in this case (16\/8 = 2)MHz. We don&#8217;t need take into account the time it takes to run through each motor and check if it needs a pulse, because this will be shifted by the same time each toggle. Some variance can occur but this is jitter we cannot estimate.<\/p>\n\n\n\n<p>This yields:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"874\" height=\"114\" src=\"https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/11\/image-3.png\" alt=\"\" class=\"wp-image-8344\" srcset=\"https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/11\/image-3.png 874w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/11\/image-3-300x39.png 300w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/11\/image-3-768x100.png 768w\" sizes=\"auto, (max-width: 874px) 100vw, 874px\" \/><\/figure>\n\n\n\n<p>This could be verified by measuring each motor pulse pin. This first image is a test of 100 steps with a frequency of 1300Hz. Azimuth pulse is on channel A while Pitch pulse is on channel B.<\/p>\n\n\n\n<p class=\"has-text-align-center\"><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"375\" src=\"https:\/\/lh7-us.googleusercontent.com\/CW2XhYe7cxZAF0lYO608d4isY63sgTHHlgyeO72MHDCqIkX_tD5pMUMgEjIakyq6bJLsOupK8HhSv6Mc60eI3b-SsxhzTfiP3MBptGcDo3eOPnPgmQH_lThdH77In7GauTsQxQshfB5UMxszduRobjA\"><\/p>\n\n\n\n<p>This next measurement is to look at the time between azimuth and pitch. Here we can see that there is about 14 microseconds between the azimuth motor and pitch motor; this could be optimized with using registers directly, but it does not matter for us that pitch and azimuth move unsynchronized since they move independently.<\/p>\n\n\n\n<p class=\"has-text-align-center\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/lh7-us.googleusercontent.com\/MYCvU7Xwp4-tYD9zDeYd7Oh-P5iBe98hyE8eTujN6X_rFkIL-tXdsWJVLGgXhs-eK5xwdGjxYYC48xrGmDcfkVe-AjtabvjsmttA-2Gdg1C1oE_TmAEFkQwNdXLUSf-uThYA0eiNzaU3aC0pQDVsVXY\" width=\"624\" height=\"351\"><\/p>\n\n\n\n<h2 class=\"has-text-align-center wp-block-heading\">Harald Berzinis<\/h2>\n\n\n\n<p>This week I have been busy with 3D-printing the camera mount, and initial testing of it. I have later made a design for the CO2 tank holder.<\/p>\n\n\n\n<h4 class=\"has-text-align-center wp-block-heading\">Camera Mount<\/h4>\n\n\n\n<p>The camera mount was printed with 20% infill at 0.15mm layer height. The main rail and the camera mount fit quite well together, but I needed to sand down a little for a smooth glide. Below are some pictures showcasing the camera mount&#8217;s modularity. Cable management extrusions are also working well.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh7-us.googleusercontent.com\/kFk55hUVCIMb8R536h1QXWWpc2cEPN_w8Xy3G2WENHckr1mWJGp9DbGluVTejZO9O0vVSQs_Ah1KaCrv3TK8SGtu9FLeU5I5R1lpy8dXZmjKG39TZ6MdIQ2Nng_eWkClQB1Fg-I-6PSZ7hCh0XhjfYM\" alt=\"\" \/><figcaption class=\"wp-element-caption\">Full extension<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh7-us.googleusercontent.com\/iE6_oOz4O2vQvCjLPJirtUjSU2WgxjdDTCKxvphAlcuD3l7aqBP_Js1EUrfRk7jaGE9TueK8Wk-yR346DsEcTzlpipbLox7by4hjQoxiIUIQSBjQW09LRmLRlKR3BjQg_LQ_erOpviIRRcJ3GgMMGd8\" alt=\"\" \/><figcaption class=\"wp-element-caption\">Smaller extension<\/figcaption><\/figure>\n\n\n\n<h4 class=\"has-text-align-center wp-block-heading\">CAD-Design for the CO2 Tank Holder<\/h4>\n\n\n\n<p>After I was done testing the rail, I started designing the CO2 tank holder.&nbsp;<\/p>\n\n\n\n<p>The holder will be mounted with four screws to secure it to the wood plate. In addition it will consist of two parts, one being the main body, and second being the extension rail. This is because the size of the model will exceed my maximum build plate height. The extension rail will be used to route the tube of the CO2 tank and securely mounted with zip ties. Below are some screenshots showing how the tank holder will look when it is completed.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh7-us.googleusercontent.com\/AjAaqjojQXexowNmLEBmuK-J0r4UgHeOtUCP8jkbguKbRUolR40ZQ50Frtlk01n0ffjKlc8sxaoetmqQejaNllb2iLvC6Y7lYG_234HLpiyNiFngEm-0-qMnPC50pB9i8EijkaIwOv61TkQVx7jol3Y\" alt=\"\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh7-us.googleusercontent.com\/Zx-dX5UVk4B09_ozNBopkgUx1bL2yuallYnTr5hkdkvWCtDefzlW7gGmg8HdAIGF3786qWlV2MVq49sIqZ496uKqk8C4GVP59D1v2w-5E80_3orMUdl_kYb5E9jHJq92tyMpzvU4iaDyQMYIaxM-F1g\" alt=\"\" \/><figcaption class=\"wp-element-caption\">Different angles of the tank holder<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh7-us.googleusercontent.com\/tFRhu4AmhqaLC-acZtfR7MhyJIuOziPYAaJlNz8EHGvgzGZJ1i4F_hTfMJtQ4WcCr2T5AXGKztOUAXMO3rOCTgC7aZRFSp3Tc47bAP_ZjTqyE002rhEKWSYmnqz3LKB8unAb3mnvlOrQCvm4exRbqic\" alt=\"\" \/><figcaption class=\"wp-element-caption\">Extension rail showcased in different angles.<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh7-us.googleusercontent.com\/mFtT7tMt8HzPph4kaP_I31ACtxSaz5z9fM6Gx8sAR3D862y3wE3awfgXwZRwF8OUB5AgUQ5l_9d7TuXFOuWFvE-lVhBzoVnHm6uxT4YUi2dRR2DDQAj85RdkllLSBrOyToW9rwACHS2rrw1GaChLZ58\" alt=\"\" \/><\/figure>\n\n\n\n<p>Above are three pictures that show how the tank and the extended rail are mounted together. The forth one shows how the zip ties will be holding the CO2-tube in place.&nbsp;<\/p>\n\n\n\n<h4 class=\"has-text-align-center wp-block-heading\">Next week:<\/h4>\n\n\n\n<p>Next week I will be printing the entire holder, and testing it further.&nbsp;<\/p>\n\n\n\n<h2 class=\"has-text-align-center wp-block-heading\">Mats Bergum<\/h2>\n\n\n\n<p>Still have not received all the necessary parts for the 5-volt regulator, still waiting on the 50 \u03bcH inductor. So no progress there. However, Steven got confirmation that the part was on its way. <\/p>\n\n\n\n<p>On the other hand, testing on the pulse signal for the motor controllers was conducted. This was done with Christopher and Ole. We strongly suspected that the &#8220;laggy&#8221; movement was connected to the pulse signal. As you can see in the picture below we were correct.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"542\" src=\"https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/11\/image-42-1024x542.png\" alt=\"\" class=\"wp-image-8413\" srcset=\"https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/11\/image-42-1024x542.png 1024w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/11\/image-42-300x159.png 300w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/11\/image-42-768x407.png 768w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/11\/image-42-1536x814.png 1536w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/11\/image-42.png 1920w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\">Measurement of the pulse signal <\/figcaption><\/figure>\n\n\n\n<p>This indicated that the Raspberry Pi could not properly manage the timing with all the other processes. So, we tried to use an integrated PWM port on the Raspberry Pi. This gave us a better signal but was not nearly good enough to use for controlling.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"401\" src=\"https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/11\/image-43-1024x401.png\" alt=\"\" class=\"wp-image-8414\" srcset=\"https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/11\/image-43-1024x401.png 1024w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/11\/image-43-300x117.png 300w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/11\/image-43-768x300.png 768w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/11\/image-43-1536x601.png 1536w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/11\/image-43.png 1920w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\"><br>Measurement of pulse signal using PWM pin.<\/figcaption><\/figure>\n\n\n\n<p>From the results, we came to the conclusion that it was necessary to allocate this task to an Arduino nano, to properly send the correct signal.<\/p>\n\n\n\n<h2 class=\"has-text-align-center wp-block-heading\">Hannes Weigel<\/h2>\n\n\n\n<h4 class=\"has-text-align-center wp-block-heading\">Projectile 2.0<\/h4>\n\n\n\n<p>Some real-life testing of the previously designed projectile revealed some issues.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"966\" height=\"1024\" src=\"https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/11\/image-44-966x1024.png\" alt=\"\" class=\"wp-image-8421\" srcset=\"https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/11\/image-44-966x1024.png 966w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/11\/image-44-283x300.png 283w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/11\/image-44-768x814.png 768w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/11\/image-44.png 1336w\" sizes=\"auto, (max-width: 966px) 100vw, 966px\" \/><\/figure>\n\n\n\n<p>The first design would slide on the outside of an extended barrel. This proved to be a subpar design, as the acceleration of the projectile was far too short, resulting in a meek 5 meter lob shot.<\/p>\n\n\n\n<p>Without increasing the length of the projectile by a substantial amount, this approach would not suffice.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"281\" src=\"https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/11\/image-45-1024x281.png\" alt=\"\" class=\"wp-image-8422\" srcset=\"https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/11\/image-45-1024x281.png 1024w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/11\/image-45-300x82.png 300w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/11\/image-45-768x211.png 768w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/11\/image-45-1536x421.png 1536w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/11\/image-45-2048x561.png 2048w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>I redesigned the projectile to instead be shot from inside the barrel. This projectile features a mortar-like shape, with 6 aft fins. The projectile consists of 4 separate pieces; The nosecone, the body tube, the aft transition, and the fin tube.<\/p>\n\n\n\n<p>These 4 parts were 3D printed with varying infill and # of perimeters, with a weight bias towards the front. The simulated stability of the projectile is 1.26 which is remarkably stable. <\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"402\" src=\"https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/11\/image-46-1024x402.png\" alt=\"\" class=\"wp-image-8423\" srcset=\"https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/11\/image-46-1024x402.png 1024w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/11\/image-46-300x118.png 300w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/11\/image-46-768x301.png 768w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/11\/image-46-1536x603.png 1536w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/11\/image-46.png 1722w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"457\" src=\"https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/11\/image-47-1024x457.png\" alt=\"\" class=\"wp-image-8424\" srcset=\"https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/11\/image-47-1024x457.png 1024w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/11\/image-47-300x134.png 300w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/11\/image-47-768x343.png 768w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/11\/image-47.png 1282w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>The aft transition and fin tube feature a 2.8 mm hole. As the parts were glued together, there was a chance that the seam between the aft transition and fin tube would be too fragile. Therefore said 2.8mm hole could accomodate a small M3 bolt with the head cut off.<\/p>\n\n\n\n<p>As the seam indeed proved to be weak, the aft transition and fin tube were held together by a small cut M3 bolt.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"288\" src=\"https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/11\/image-48-1024x288.png\" alt=\"\" class=\"wp-image-8425\" srcset=\"https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/11\/image-48-1024x288.png 1024w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/11\/image-48-300x84.png 300w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/11\/image-48-768x216.png 768w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/11\/image-48-1536x432.png 1536w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/11\/image-48-2048x576.png 2048w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>With the bolt added, the center of gravity (CG in checkered blue and white) shifted backwards and worsened the stability by 24%<\/p>\n\n\n\n<p>Despite a stability margin of less than 1, the projectile flew incredibly straight and stable in +20 meter tests.<\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Christopher Daffinrud On Monday when testing our system as a whole together with our software we encountered some issues when calling the motors for rotating the Turret. The turret rotated both clockwise and counterclockwise based on where the Detection Model detected our object, but the rotation in itself was &#8220;laggy&#8221;, giving us a feeling that [&hellip;]<\/p>\n","protected":false},"author":100,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-8338","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/dronesonen.usn.no\/index.php?rest_route=\/wp\/v2\/posts\/8338","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dronesonen.usn.no\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dronesonen.usn.no\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dronesonen.usn.no\/index.php?rest_route=\/wp\/v2\/users\/100"}],"replies":[{"embeddable":true,"href":"https:\/\/dronesonen.usn.no\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=8338"}],"version-history":[{"count":12,"href":"https:\/\/dronesonen.usn.no\/index.php?rest_route=\/wp\/v2\/posts\/8338\/revisions"}],"predecessor-version":[{"id":8426,"href":"https:\/\/dronesonen.usn.no\/index.php?rest_route=\/wp\/v2\/posts\/8338\/revisions\/8426"}],"wp:attachment":[{"href":"https:\/\/dronesonen.usn.no\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=8338"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dronesonen.usn.no\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=8338"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dronesonen.usn.no\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=8338"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}