{"id":12790,"date":"2025-11-11T16:03:31","date_gmt":"2025-11-11T15:03:31","guid":{"rendered":"https:\/\/dronesonen.usn.no\/?p=12790"},"modified":"2025-11-12T11:44:29","modified_gmt":"2025-11-12T10:44:29","slug":"autobalance-week-12","status":"publish","type":"post","link":"https:\/\/dronesonen.usn.no\/?p=12790","title":{"rendered":"AutoBalance: Week 12"},"content":{"rendered":"\n<p><strong>Mohammed A:<\/strong><br>I focused primerly on fixing and addapting the middel section of the motorbike with the new components that will be implemented to the motorbike. I have figured out that the bike will be stretched in the longer side, and that the momntum wheel should have enough space to rotete and enough space for the bolts and nuts to be connected to the wheel with extra weight and make sure that it won&#8217;t colide with the bike. Doing further more reaserch and doing some analysis on the motor and I found out the the stable platfrom that the motor will stand on and with extra weight can break the extended platform that the motor is standing on. My primerly work is consentrated for now on the middel part of the motorbike, but still consider the thought of how to implent hob wheels (tron wheels) and servo motor to the bike without making it look clunky.<br><br><strong>Salim:<\/strong><\/p>\n\n\n\n<p>I\u2019ve been sick this week. Therefore, I was not able to attend in person.<br>I\u2019ve mainly been working on the IMU sensor \u2014 step 2 and 3 from the last blog.<\/p>\n\n\n\n<p>step 2:<\/p>\n\n\n\n<p>The IMU sensor sends data that tells us the motorcycle\u2019s angle.<br>It consists of a gyroscope and an accelerometer.<br>Before the IMU can be used, I need to calibrate it and determine its zero point \u2014 that is, the position when the motorcycle is standing upright.<\/p>\n\n\n\n<p>I start by reading the IMU sensor values while the motorcycle is stationary.<br>Then, I find the difference between the motorcycle\u2019s zero point and the IMU\u2019s zero point. This difference is the offset.<br>When reading from the sensor, this offset is subtracted manually.<\/p>\n\n\n\n<p>This gives the IMU a zero point that matches the motorcycle\u2019s upright position, which is critical for the next steps.<\/p>\n\n\n\n<p>step 3:<\/p>\n\n\n\n<p>Once the correct zero point is found, I use data from the accelerometer and gyroscope to determine how much the motorcycle tilts to the sides.<br>These two sensors are used together in modern systems to determine orientation.<\/p>\n\n\n\n<p>The accelerometer tells how far the motorcycle is from the ground. It\u2019s stable but becomes noisy when the motorcycle vibrates, causing inaccurate readings.<\/p>\n\n\n\n<p>The gyroscope tells how fast the motorcycle is tilting \u2014 the rate of angular change. Over time, it drifts and becomes inaccurate.<\/p>\n\n\n\n<p>By combining both with a complementary filter, they correct each other\u2019s weaknesses.<\/p>\n\n\n\n<p>The angle is calculated:<br>Angle = \u03b1 (previous angle + gyro rate * delta t) + (1- \u03b1) * accelerometer angle<\/p>\n\n\n\n<p>Where the terms are:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>previous_angle \u2013 the angle measured in the previous step<\/li>\n\n\n\n<li>gyro_change \u2013 the change in angle measured by the gyroscope<\/li>\n\n\n\n<li>accel_angle \u2013 the angle measured by the accelerometer<\/li>\n\n\n\n<li>\u03b1 (alpha) \u2013 how much of the gyroscope data to trust (0\u20131, where 1 = 100% gyroscope)<\/li>\n\n\n\n<li>This angle value will be used by the PID controller to control the balancing wheel.<\/li>\n<\/ul>\n\n\n\n<p>The first part of the code:<br>\/\/ sette opp elektroniske koblinger<br>\/\/ st\u00f8tte for imus sensor(bibliotek)<\/p>\n\n\n\n<p>float angleNOW, gyroChange, angle;<br>float offset = 0; \/\/JUSTER<br>float a = 0.9; \/\/ JUSTER<br>unsigned long time;<\/p>\n\n\n\n<p>void setup() {<br>imu.initialize();<br>Serial.println(&#8220;Hold motorsykkelen, for \u00e5 kalibrere&#8221;);<br>delay(2000);<\/p>\n\n\n\n<p>\/\/ finne nulpunkt<br>int sum = 0;<br>for (int i = 0; i &lt; 100; i++) {<br>sum += imu.getRotationX\/Y\/Z(); \/\/ test<br>delay(50);<br>}<\/p>\n\n\n\n<p>offset = sum \/ 100;<br>Serial.print(&#8220;Offset: &#8220;);<br>Serial.println(offset);<\/p>\n\n\n\n<p>time = millis();<br>}<\/p>\n\n\n\n<p>void loop() {<br>\/\/ IMU reads raw data<br>int16_t accX, accY, accZ, gyroX, gyroY, gyroZ;<br>imu.getMotion6(&amp;accX, &amp;accY, &amp;accZ, &amp;gyroX, &amp;gyroY, &amp;gyroZ);<\/p>\n\n\n\n<p>\/\/ last check<br>float lastCh = (millis() &#8211; time) \/ 1000.0;<br>time = millis();<\/p>\n\n\n\n<p>\/\/ akselerometer: sjekk for acc x,y og z. test<br>angleNow = atan2(accX, accZ) * 180 \/ PI; \/\/JUSTER<\/p>\n\n\n\n<p>\/\/ gyroskop: teste f\u00f8lsom heten til motorsykkelen, med 65,5 og 32.8<br>gyroChange = (gyroY &#8211; offset) \/ 131.0;<\/p>\n\n\n\n<p>\/\/ gyro + akselerometer<br>angle = a * (angle + gyroChange * lastCh) + (1 &#8211; a) * angleNow;<\/p>\n\n\n\n<p>\/\/ Angle<br>Serial.print(&#8220;Angle: &#8220;);<br>Serial.println(angle);<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<p>Things I still need to test:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Verify that the angle direction is correct<\/li>\n\n\n\n<li>Adjust which axis from the accelerometer is used<\/li>\n\n\n\n<li>Fine-tune the offset calibration<\/li>\n\n\n\n<li>Adjust how much of the gyroscope data (\u03b1) is used in the filter<\/li>\n<\/ul>\n\n\n\n<p>Next week, I will test this together with the rest of Muhammed \u00d8\u2019s code, and perform physical testing on the motorcycle.<\/p>\n\n\n\n<p><strong>Muhammed \u00d8:<\/strong><br>I was going to add this part to last&nbsp;weeks&nbsp;blog post but&nbsp;I&nbsp;didn\u2019t&nbsp;have time to add it in therefore&nbsp;I&nbsp;am adding it to&nbsp;this&nbsp;weeks&nbsp;blog post.&nbsp;<br><br>We had broken one of the buttons on the BitPlayer for the micro:bit microcontroller, as shown in the pictures below.<br><img loading=\"lazy\" decoding=\"async\" width=\"274\" height=\"365\" src=\"https:\/\/dronesonen.usn.no\/e183f389-53cf-4944-a003-911a28ca0496\" alt=\"Close-up of a black device\n\nAI-generated content may be incorrect.\"><img loading=\"lazy\" decoding=\"async\" width=\"284\" height=\"364\" src=\"https:\/\/dronesonen.usn.no\/d23bcab9-9557-4082-bc25-effe57012cb2\"><br>when we would hold the button in place and try to use it we noticed that it would work sometimes, which means that the pins from the button is sticking enough out to have a connection with the board, which made me attempt to repair it.<br><br>I first heated the solder which is already on the board while pressing the button in place, this allowed the solder to flow and get attached back to the button. After which I added more solder to the pins that were sticking out of the back. The button was attached nicely and was working as intended. Unfortunately, my friend who was helping me accidentally dropped the controller, which made the button brake off again, and the second time I tried to re attach the button it wasn\u2019t as good as the first, but it was still working.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"342\" height=\"450\" src=\"https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2025\/11\/image-14.jpeg\" alt=\"\" class=\"wp-image-12798\" srcset=\"https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2025\/11\/image-14.jpeg 342w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2025\/11\/image-14-228x300.jpeg 228w\" sizes=\"auto, (max-width: 342px) 100vw, 342px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"395\" height=\"296\" src=\"https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2025\/11\/image-15.jpeg\" alt=\"\" class=\"wp-image-12797\" srcset=\"https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2025\/11\/image-15.jpeg 395w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2025\/11\/image-15-300x225.jpeg 300w\" sizes=\"auto, (max-width: 395px) 100vw, 395px\" \/><\/figure>\n\n\n\n<p>This week I focused on the step four and step five for implementing the self-balancing element of the motorcycle.<br><br><\/p>\n\n\n\n<p>We have chosen moderate values for the X values of the PID algorithm, this is something that will potentially be changed when we test the code next week depending on how the system acts. The X values are as follows: X1: 25, X2: 0.9 and X3: 1.4. in the code I wrote one function responsible for setting the motor speed based on the output from the PID, and this is the code:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ sette opp elektroniske koblinger\n\/\/ st\u00f8tte for imus sensor(bibliotek)\nfloat X1 = 25.0;\nfloat X2 = 0.9;\nfloat X3 = 1.4;\nint speed1 = 0;\n\nint MotorENA = 9;\nint MotorIN1 = 8;\nint MotorIN2 = 7;\n\n\n\nvoid setup() {\n  pinMode(MotorENA, OUTPUT);\n  pinMode(MotorIN1, OUTPUT);\n  pinMode(MotorIN2, OUTPUT);\n  Serial.begin(9600);\n}\n\nvoid setMotorSpeed(int speed) {\n  if (speed &gt;= 0) {\n    \/\/ Fremover\n    digitalWrite(MotorIN1, HIGH);\n    digitalWrite(MotorIN2, LOW);\n  } else {\n    \/\/ Bakover\n    digitalWrite(MotorIN1, LOW);\n    digitalWrite(MotorIN2, HIGH);\n    speed = -speed; \/\/ Gj\u00f8r positiv for PWM\n  }\n  \n  \/\/ Begrens hastighet til 0-255\n  speed = constrain(speed, 0, 255);\n  analogWrite(MotorENA, speed);\n}\n\nvoid loop() {\n  \/\/ PID-lignende kontroller\n  int pwm_s = -constrain(X1 * angle + X2 * gyroChange + X3 * -setMotorSpeed(speed1), -255, 255);\n  speed1 = pmw_s;\n\n  \/\/ Styr motoren\n  setMotorSpeed(pwm_s);\n\n  Serial.print(\" | PWM: \");\n  Serial.println(pwm_s);\n}\n\n\n\n\n<\/code><\/pre>\n\n\n\n<p><strong>Meron:<\/strong><\/p>\n\n\n\n<p>This week I was focused on the balancing system for our auto balancing motorcycle. I worked on creating different versions of balancing wheels with various diameters and sizes to test which one works best. After getting feedback from Rechard, I used the laser cutter instead of the 3Dprinter for some of the parts which gave more accurate and cleaner results.<\/p>\n\n\n\n<p>I then assembled the balancing wheels and added screws on the top to give extra weight to help the wheel create better balance when it spins. The balancing system is now mounted in the middle section of the motorcycle allowing the motor to handle turning and movement smoothly. Like u see down in pictures Now the system is ready for testing to check how well it is balancing the motorcycle. There will be more testing, redesigning and printing in the coming weeks to improve the setup. The balancing wheel with rubber will be used in our final version of the motorcycle<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"453\" height=\"648\" src=\"https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2025\/11\/image-87.png\" alt=\"\" class=\"wp-image-12812\" style=\"width:292px;height:auto\" srcset=\"https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2025\/11\/image-87.png 453w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2025\/11\/image-87-210x300.png 210w\" sizes=\"auto, (max-width: 453px) 100vw, 453px\" \/><\/figure>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Mohammed A:I focused primerly on fixing and addapting the middel section of the motorbike with the new components that will be implemented to the motorbike. I have figured out that the bike will be stretched in the longer side, and that the momntum wheel should have enough space to rotete and enough space for the [&hellip;]<\/p>\n","protected":false},"author":112,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-12790","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/dronesonen.usn.no\/index.php?rest_route=\/wp\/v2\/posts\/12790","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\/112"}],"replies":[{"embeddable":true,"href":"https:\/\/dronesonen.usn.no\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=12790"}],"version-history":[{"count":5,"href":"https:\/\/dronesonen.usn.no\/index.php?rest_route=\/wp\/v2\/posts\/12790\/revisions"}],"predecessor-version":[{"id":12813,"href":"https:\/\/dronesonen.usn.no\/index.php?rest_route=\/wp\/v2\/posts\/12790\/revisions\/12813"}],"wp:attachment":[{"href":"https:\/\/dronesonen.usn.no\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=12790"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dronesonen.usn.no\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=12790"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dronesonen.usn.no\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=12790"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}