{"id":12166,"date":"2025-10-27T13:23:55","date_gmt":"2025-10-27T12:23:55","guid":{"rendered":"https:\/\/dronesonen.usn.no\/?p=12166"},"modified":"2025-10-27T13:36:19","modified_gmt":"2025-10-27T12:36:19","slug":"autobalance-week-9","status":"publish","type":"post","link":"https:\/\/dronesonen.usn.no\/?p=12166","title":{"rendered":"AutoBalance: Week 9"},"content":{"rendered":"\n<p><strong>Meron:<\/strong><\/p>\n\n\n\n<p>This week, I worked on designing the new <strong>Phase 2 version of our auto-balance motorcycle<\/strong>. While the data team focused on programming the steering system, I continued improving the mechanical design. The new version is <strong>smaller and lighter<\/strong> than the one from Phase 1, and I also made the <strong>wheels thinner<\/strong> and added <strong>support wheels<\/strong> to help with balance.<\/p>\n\n\n\n<p>The idea behind this design is to make it more realistic and ready for steering control in the next steps. The support wheels will help the motorcycle stay stable while testing. The goal is to make the design ready for both <strong>mechanical assembly and software testing<\/strong> so we can see movement and steering working together soon.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"641\" height=\"238\" src=\"https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2025\/10\/image-3.gif\" alt=\"\" class=\"wp-image-12167\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p><strong>Salim:<\/strong><br>As I mentioned last week, I will be focusing mainly on my engineering internship since it\u2019s an important week there. However, I\u2019ve now succeeded in getting the controller to work. There was a challenge with the R button (P16), as it is quite loose. Another issue I ran into was that without using pins.sets_pull, the left and backwards buttons would freeze on the buttons. It took some time to fix that. The main structure of the code is divided into three modes:<ul><li>Mode 0: Buttons \u2013 Left (P13), Backwards (P14), Forward (A), and Right (B).,<\/li><li>Mode 1: Joystick \u2013 Activated by pressing L (P15), showing \u201cJ\u201d for joystick. The X and Y axes of P1 and P2 control the directions.,<\/li><li>Mode 2: Tilt \u2013 Activated by pressing R (P16), showing arrows that function the same way as the other modes.,<\/li><li>Pressing R and L simultaneously returns the controller to Mode 0.,<\/li><li>The buttons, joystick and tilt need to hold for it to move. because the standard is that the motorcycle dose not move. it will be shown whit stop &#8220;S&#8221; and &#8220;-&#8220;,<\/li><\/ul>We\u2019ve also started considering using Git, since the code is getting longer. Below are the code and video<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>radio.on()\nradio.set_group(67)\n\nmode = 0 \nlastState = \"STOP\"\n\nbasic.show_string(\"S\")\n\n\npins.set_pull(DigitalPin.P13, PinPullMode.PULL_UP) \npins.set_pull(DigitalPin.P14, PinPullMode.PULL_UP)\npins.set_pull(DigitalPin.P15, PinPullMode.PULL_UP)\npins.set_pull(DigitalPin.P16, PinPullMode.PULL_UP)\n\ndef vis_mode(symbol: str):\n    basic.show_string(symbol)\n    basic.pause(200)\n    basic.clear_screen()\n\ndef buttons():\n    global lastState\n    pressed = False\n\n    if input.button_is_pressed(Button.A):\n        radio.send_string(\"F\")\n        basic.show_string(\"F\")\n        pressed = True\n        lastState = \"FORWARD\"\n\n    elif input.button_is_pressed(Button.B):\n        radio.send_string(\"R\")\n        basic.show_string(\"R\")\n        pressed = True\n        lastState = \"RIGHT\"\n\n    elif pins.digital_read_pin(DigitalPin.P13) == 0:\n        radio.send_string(\"L\")\n        basic.show_string(\"L\")\n        pressed = True\n        lastState = \"LEFT\"\n\n    elif pins.digital_read_pin(DigitalPin.P14) == 0: \n        radio.send_string(\"B\")\n        basic.show_string(\"B\")\n        pressed = True\n        lastState = \"BACKWARDS\"\n\n    if not pressed and lastState != \"STOP\":\n        radio.send_string(\"S\")\n        basic.show_string(\"S\")\n        lastState = \"STOP\"\n        basic.pause(200)\n\ndef joystick():\n    global lastState\n    X = pins.analog_read_pin(AnalogPin.P1)\n    Y = pins.analog_read_pin(AnalogPin.P2)\n\n    pressed = False\n\n    if Y &lt; 300: \n        radio.send_string(\"B\")\n        basic.show_string(\"B\")\n        pressed = True\n        lastState = \"BACKWARDS\"\n\n    elif Y &gt; 700: \n        radio.send_string(\"F\")\n        basic.show_string(\"F\")\n        pressed = True\n        lastState = \"FORWARD\"\n\n    elif X &lt; 300: \n        radio.send_string(\"L\")\n        basic.show_string(\"L\")\n        pressed = True\n        lastState = \"LEFT\"\nelif X &gt; 700:\n        radio.send_string(\"R\")\n        basic.show_string(\"R\")\n        pressed = True\n        lastState = \"RIGHT\"\n\n    if not pressed and lastState != \"STOP\":\n        radio.send_string(\"S\")\n        basic.show_string(\"S\")\n        lastState = \"STOP\"\n\ndef tilt():\n    xx = input.acceleration(Dimension.X)\n    yy = input.acceleration(Dimension.Y)\n\n    if yy &lt; -300: \n        radio.send_string(\"F\")\n        basic.show_leds(\"\"\"\n            . . # . .\n            . # # # .\n            # # # # #\n            . . # . .\n            . . # . .\n        \"\"\")\n    elif yy &gt; 300: \n        radio.send_string(\"B\")\n        basic.show_leds(\"\"\"\n            . . # . .\n            . . # . .\n            # # # # #\n            . # # # .\n            . . # . .\n        \"\"\")\n    elif xx &lt; -300: \n        radio.send_string(\"L\")\n        basic.show_leds(\"\"\"\n            . . # . .\n            . # # . .\n            # # # # #\n            . # # . .\n            . . # . .\n        \"\"\")\n    elif xx &gt; 300: \n        radio.send_string(\"R\")\n        basic.show_leds(\"\"\"\n            . . # . .\n            . . # # .\n            # # # # #\n            . . # # .\n            . . # . .\n        \"\"\")\n    else: \n        radio.send_string(\"S\")\n        basic.show_leds(\"\"\"\n            . . . . .\n            . . . . .\n            # # # # #\n            . . . . .\n            . . . . .\n        \"\"\")\n    basic.pause(100)\n\ndef on_forever():\n    global mode\n    L1 = pins.digital_read_pin(DigitalPin.P15) == 0 \n    R1 = pins.digital_read_pin(DigitalPin.P16) == 0 \n    if L1 and R1:\n        mode = 0\n        vis_mode(\"S\")\n        basic.pause(200)\n\n    elif L1 and not R1 and mode != 1:\n        mode = 1\n        vis_mode(\"J\")\n        basic.pause(200)\n\n    elif R1 and not L1 and mode != 2:\n        mode = 2\n        vis_mode(\"T\")\n        basic.show_string(\"-\")\n        basic.pause(200)\n\n    if mode == 0:\n        buttons()\n    elif mode == 1:\n        joystick()\n    elif mode == 2:\n        tilt()\n    basic.pause(100)\nbasic.forever(on_forever)<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex\"><\/figure>\n\n\n\n<figure class=\"wp-block-video\"><video controls src=\"https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2025\/10\/IMG_5851.mp4\"><\/video><\/figure>\n\n\n\n<p><br><br><strong>Muhammed \u00d8:<\/strong><br>This week, I worked on implementing the servo control for the steering system for the motorcycle. The goal was to allow the front wheel to turn right and left based on the commands received from the remote controller.<br><br>The servo is connected to pin P0, and to the micro bit. The micro bit is receiving digital signals from the remote controller, therefore we dont have a way to continously adjust the servo position, I used a short delay in the code after one second the servo automatically returns to its neutral position (90 degrees). This temporary solution allows the wheel to return to center after each turn. When the system receives an \u201cL\u201d command, the servo turns to 150 degrees (left turn) and when it receives an \u201cR\u201d command, it turns to 30 degrees (right turn).<br><br>In the future, we plan to move away from digital control signals and instead use analog signals (PWM). This will allow us to control the servo angle more precisely and create smoother, more realistic steering behavior.<br>this is the updated code:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>def servo_left():\n    servos.P0.set_angle(150)\n    basic.pause(1000)\n    servos.P0.set_angle(90)\n\ndef motor_forward():\n    pins.digital_write_pin(DigitalPin.P8, 1)\n    # ENA HIGH\n    pins.digital_write_pin(DigitalPin.P3, 1)\n    pins.digital_write_pin(DigitalPin.P1, 0)\n\ndef motor_backward():\n    pins.digital_write_pin(DigitalPin.P8, 1)\n    # ENA HIGH\n    pins.digital_write_pin(DigitalPin.P3, 0)\n    pins.digital_write_pin(DigitalPin.P1, 1)\n\ndef motor_stop():\n    pins.digital_write_pin(DigitalPin.P8, 0)\n    # ENA LOW\n    pins.digital_write_pin(DigitalPin.P3, 0)\n    pins.digital_write_pin(DigitalPin.P1, 0)\n\ndef servo_right():\n    servos.P0.set_angle(30)\n    basic.pause(1000)\n    servos.P0.set_angle(90)\n\nmessage = \"\"\n# Sett opp radio\nradio.set_group(67)\nservos.P0.set_angle(90)\n\ndef on_forever():\n    global message\n    message = radio.receive_string()\n    if message == \"F\":\n        basic.show_string(\"F\")\n        motor_forward()\n    elif message == \"B\":\n        basic.show_string(\"B\")\n        motor_backward()\n    elif message == \"L\":\n        basic.show_string(\"L\")\n        servo_left()\n    elif message == \"R\":\n        basic.show_string(\"R\")\n        servo_right()\n    else:\n        motor_stop()\n        basic.show_string(\"S\")\nbasic.forever(on_forever)\n<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Meron: This week, I worked on designing the new Phase 2 version of our auto-balance motorcycle. While the data team focused on programming the steering system, I continued improving the mechanical design. The new version is smaller and lighter than the one from Phase 1, and I also made the wheels thinner and added support [&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-12166","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/dronesonen.usn.no\/index.php?rest_route=\/wp\/v2\/posts\/12166","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=12166"}],"version-history":[{"count":2,"href":"https:\/\/dronesonen.usn.no\/index.php?rest_route=\/wp\/v2\/posts\/12166\/revisions"}],"predecessor-version":[{"id":12171,"href":"https:\/\/dronesonen.usn.no\/index.php?rest_route=\/wp\/v2\/posts\/12166\/revisions\/12171"}],"wp:attachment":[{"href":"https:\/\/dronesonen.usn.no\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=12166"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dronesonen.usn.no\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=12166"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dronesonen.usn.no\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=12166"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}