{"id":7939,"date":"2023-10-08T18:57:22","date_gmt":"2023-10-08T17:57:22","guid":{"rendered":"https:\/\/dronesonen.usn.no\/?p=7939"},"modified":"2023-10-08T19:08:00","modified_gmt":"2023-10-08T18:08:00","slug":"keeping-up-with-the-microbros-week-7","status":"publish","type":"post","link":"https:\/\/dronesonen.usn.no\/?p=7939","title":{"rendered":"Keeping Up With the MicroBros &#8211; Week 7"},"content":{"rendered":"\n<p>What\u2019s up readers, mid-term presentations are over, so let\u2019s get <em>right <\/em>into the news this week.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Jonathan \u200b<img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/pf-emoji-service--cdn.us-east-1.prod.public.atl-paas.net\/standard\/caa27a19-fc09-4452-b2b4-a301552fd69c\/32x32\/1f9d9-200d-2642-fe0f.png\" alt=\":man_mage:\" width=\"20\" height=\"20\"><\/h2>\n\n\n\n<p>PRESENTATION IS DONE, WE MAY NOW FOCUS ON DOING THE \u200b<img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/pf-emoji-service--cdn.us-east-1.prod.public.atl-paas.net\/standard\/caa27a19-fc09-4452-b2b4-a301552fd69c\/32x32\/1f44a.png\" alt=\":punch:\" width=\"20\" height=\"20\"> WORK \u200b<img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/pf-emoji-service--cdn.us-east-1.prod.public.atl-paas.net\/standard\/caa27a19-fc09-4452-b2b4-a301552fd69c\/32x32\/1f44a.png\" alt=\":punch:\" width=\"20\" height=\"20\"><\/p>\n\n\n\n<p>I\u2019m still working on a localization feature of the micromouse, and there are quite a few problems to overcome:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Acquire a gyroscope to sense rotation rates for sensor fusion:<br>Considering something like this <a href=\"https:\/\/www.amazon.com\/HiLetgo-Gyroscope-Acceleration-Accelerator-Magnetometer\/dp\/B01I1J0Z7Y#:~:text=Have%20one%20to%20sell%3F%20Sell,See%20more\">sensor<\/a> should interface with our micro:bit v2 through I2C. That sensor does include an accelerometer and magnetometer as well which we already have built-in on the micro:bit, but I can\u2019t seem to find a standalone gyro so it will have to do. Maybe Steven has one I can use? Otherwise will just order one. There is also some soldering involved in using this will have to ask help from somebody who knows how to do that.<\/li>\n\n\n\n<li>Proper mathematical formulas for accelerometer, gyroscope and magnetometer sensor fusion.<br>The formulas I\u2019ve used until now only work for ideal settings where bias and noise factors are not present. Need formulas that factor this in so I can filter accordingly.<\/li>\n\n\n\n<li>Need to consider other \u201ccreative\u201d ways to filter noise\/drift like:<br>Only accepting new accelerometer input when I\u2019ve also signalled the wheels to move. This could remove drift when the car is not in motion.<br>Setting accelerometer values to zero when detecting no changes in ultrasonic distance sensors.<br>Maybe use distance sensors as a budget gyro? Having two distance sensors facing the same direction (in the front) could maybe give me rotation rates while the car is somewhat perpendicular to the wall?<br>BTW: Need to figure out how to make the ultrasonic sensors facing the same direction not to cause interference with each other. Should be solveable with some delays.<\/li>\n\n\n\n<li>Visualizing sensor data stream for debugging:<br>Can use a serial oscilloscope for this. Considering to use one like this: <a href=\"https:\/\/x-io.co.uk\/serial-oscilloscope\/\">serial oscilloscope<\/a>\u200b. Using this will help me detect the bias and noise of the sensors so I can filter them out.<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/10\/Untitled.png\" alt=\"\" class=\"wp-image-7940\" width=\"556\" height=\"414\" srcset=\"https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/10\/Untitled.png 725w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/10\/Untitled-300x223.png 300w\" sizes=\"auto, (max-width: 556px) 100vw, 556px\" \/><figcaption class=\"wp-element-caption\">Accelerometer data visualized with serial oscilloscope<\/figcaption><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Mats \u200b<img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/pf-emoji-service--cdn.us-east-1.prod.public.atl-paas.net\/standard\/caa27a19-fc09-4452-b2b4-a301552fd69c\/32x32\/1f9d1-200d-1f4bb.png\" alt=\":technologist:\" width=\"20\" height=\"20\"><\/h2>\n\n\n\n<h4 class=\"wp-block-heading\">Adding shared logging utilities for micro:bit and simulator \u200b<img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/pf-emoji-service--cdn.us-east-1.prod.public.atl-paas.net\/standard\/caa27a19-fc09-4452-b2b4-a301552fd69c\/32x32\/1f4dc.png\" alt=\":scroll:\" width=\"20\" height=\"20\"><\/h4>\n\n\n\n<p>Until now I have just been using the <a href=\"https:\/\/github.com\/fmtlib\/fmt\">fmt<\/a> text formatting library with the print and println functions within the simulator.<\/p>\n\n\n\n<p>However Jonathan has started working on positioning with the micro:bit, turns out it makes more sense to log instead of breaking in a debugger for this. The built in <a href=\"https:\/\/github.com\/lancaster-university\/codal-core\/blob\/5236dd2e29172854b45c6611d09001603be182a2\/source\/driver-models\/Serial.cpp#L394-L472\">printf function<\/a> in CODAL does not support types like floats.<\/p>\n\n\n\n<p>I had tried to add fmt to our Firmware target in CMake before but it made the program flash usage reach 110% which was big a stopper, but I decided to look into fmt again and see if there is anything I can do to trim some fat out of the code size.<\/p>\n\n\n\n<p>Looking through the headers I found the <code>FMT_STATIC_THOUSANDS_SEPARATOR <\/code>define which disabled the usage of including &lt;locale&gt; and suddenly the code size went down to a fraction of what it was!<\/p>\n\n\n\n<p>I\u2019ve implemented some basic functions to print and added macros that can be used from any namespace to call the main Logger implementation which will use stdout in the simulator and serial in the firmware:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"795\" height=\"202\" src=\"https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/10\/Untitled-1.png\" alt=\"\" class=\"wp-image-7941\" srcset=\"https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/10\/Untitled-1.png 795w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/10\/Untitled-1-300x76.png 300w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/10\/Untitled-1-768x195.png 768w\" sizes=\"auto, (max-width: 795px) 100vw, 795px\" \/><\/figure>\n\n\n\n<h4 class=\"wp-block-heading\">Implementing BLE communication \u200b<img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/pf-emoji-service--cdn.us-east-1.prod.public.atl-paas.net\/standard\/caa27a19-fc09-4452-b2b4-a301552fd69c\/32x32\/1f4e1.png\" alt=\":satellite:\" width=\"20\" height=\"20\"><\/h4>\n\n\n\n<p>Last week I wrote \u201cMore Debugging? \u200b<img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/pf-emoji-service--cdn.us-east-1.prod.public.atl-paas.net\/standard\/caa27a19-fc09-4452-b2b4-a301552fd69c\/32x32\/1f62d.png\" alt=\":sob:\" width=\"20\" height=\"20\">\u201c within the Next week section, but I had no idea it would turn into as much debugging I underwent with getting BLE working.<\/p>\n\n\n\n<p>CODAL has it\u2019s own class you can extend that will register BLE services. In short BLE services can contain \u201ccharacteristics\u201d which can be read or written to (with multiple methods) that you define.<\/p>\n\n\n\n<p>All of that is easy, CODAL already has most of the UUID defined, only a small 16-bit part is set. And defining the service is not much harder than this:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"758\" height=\"546\" src=\"https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/10\/Untitled-2.png\" alt=\"\" class=\"wp-image-7942\" srcset=\"https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/10\/Untitled-2.png 758w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/10\/Untitled-2-300x216.png 300w\" sizes=\"auto, (max-width: 758px) 100vw, 758px\" \/><\/figure>\n\n\n\n<p>The problems came in when pairing stopped getting persisted over resets and other weird behavior, it actually worked once!. After a significant amount of time debugging I lost track of I finally found the issue. After having tried different combinations of the CODAL BLE compile-time definitions and simplifying things and eventually found out that I had to allocate it on the heap instead of just let the compiler put it on the stack.<\/p>\n\n\n\n<p>My guess is something got moved when the separate fiber for BLE got fired off and weird undefined behavior ensued. \u200b<img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/pf-emoji-service--cdn.us-east-1.prod.public.atl-paas.net\/standard\/caa27a19-fc09-4452-b2b4-a301552fd69c\/32x32\/1f47b.png\" alt=\":ghost:\" width=\"20\" height=\"20\"><\/p>\n\n\n\n<p>The important part is that communication works, would have been nice if it was documented in the BLEService class though. \u200b<img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/pf-emoji-service--cdn.us-east-1.prod.public.atl-paas.net\/standard\/caa27a19-fc09-4452-b2b4-a301552fd69c\/32x32\/1f62a.png\" alt=\":sleepy:\" width=\"20\" height=\"20\"><\/p>\n\n\n\n<p>Since all my structures have a static size, and both modern sane microprocessors and the nRF52833 (Cortex M4) in the micro:bit v2 are little-endian. I can get away with just doing a simple size check and casting \u200b<img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/pf-emoji-service--cdn.us-east-1.prod.public.atl-paas.net\/standard\/caa27a19-fc09-4452-b2b4-a301552fd69c\/32x32\/1f642.png\" alt=\":slight_smile:\" width=\"20\" height=\"20\">. Or as I call it: zero-cost serialization (Zero-cost because there is actually no serialization \u200b<img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/pf-emoji-service--cdn.us-east-1.prod.public.atl-paas.net\/standard\/caa27a19-fc09-4452-b2b4-a301552fd69c\/32x32\/1f60f.png\" alt=\":smirk:\" width=\"20\" height=\"20\">).<\/p>\n\n\n\n<p>After having thrown together a Bluetooth connection manager in the Simulator using <a href=\"https:\/\/github.com\/OpenBluetoothToolbox\/SimpleBLE\">SimpleBLE<\/a>, I was ready to write to the motor.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"408\" height=\"180\" src=\"https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/10\/Untitled-3.png\" alt=\"\" class=\"wp-image-7943\" srcset=\"https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/10\/Untitled-3.png 408w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/10\/Untitled-3-300x132.png 300w\" sizes=\"auto, (max-width: 408px) 100vw, 408px\" \/><\/figure>\n\n\n\n<p>For now you can manually enable a remote motor control which has support for both keyboard and gamepad input through SDL which the simulator uses for window &amp; input management and rendering.<\/p>\n\n\n\n<p>And now, featuring no wired communication! \u200b<img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/pf-emoji-service--cdn.us-east-1.prod.public.atl-paas.net\/standard\/caa27a19-fc09-4452-b2b4-a301552fd69c\/32x32\/1f389.png\" alt=\":tada:\" width=\"20\" height=\"20\"><\/p>\n\n\n\n<figure class=\"wp-block-video aligncenter\"><video controls src=\"https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/10\/VID202310061725461.mp4\"><\/video><\/figure>\n\n\n\n<p>Sadly, the speed which a motor has to run at to even be able to turn the gear is so high that I was unable to make it drive slowly, ruining the fun of analog input. \u200b<img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/pf-emoji-service--cdn.us-east-1.prod.public.atl-paas.net\/standard\/caa27a19-fc09-4452-b2b4-a301552fd69c\/32x32\/1f636-200d-1f32b-fe0f.png\" alt=\":face_in_clouds:\" width=\"20\" height=\"20\"><\/p>\n\n\n\n<p>From here utilizing the BLE communication for telemetry and stopping and running algorithms definitely makes sense to implement soon-ish.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Iver \u200b<img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/pf-emoji-service--cdn.us-east-1.prod.public.atl-paas.net\/standard\/caa27a19-fc09-4452-b2b4-a301552fd69c\/32x32\/1f474.png\" alt=\":older_man:\" width=\"20\" height=\"20\"><\/h2>\n\n\n\n<h4 class=\"wp-block-heading\">Implementing IR sensors<\/h4>\n\n\n\n<p>This week has been a frustrating one. I have tried to set up the IR sensor on the breadboard multiple times, but I constantly get the value of 1, which does not help me much. My theory is that I set up the transistor wrong. The troubleshooting will go on. And if I cant do it before the group meet again. The boys might know whats wrong.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/10\/Untitled-768x1024.jpg\" alt=\"\" class=\"wp-image-7945\" width=\"257\" height=\"342\" srcset=\"https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/10\/Untitled-768x1024.jpg 768w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/10\/Untitled-225x300.jpg 225w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/10\/Untitled-1152x1536.jpg 1152w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/10\/Untitled-1536x2048.jpg 1536w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/10\/Untitled.jpg 1600w\" sizes=\"auto, (max-width: 257px) 100vw, 257px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Next week on Keeping Up With the MicroBros \u200b<img loading=\"lazy\" decoding=\"async\" width=\"20\" height=\"20\" src=\"https:\/\/pf-emoji-service--cdn.us-east-1.prod.public.atl-paas.net\/standard\/caa27a19-fc09-4452-b2b4-a301552fd69c\/32x32\/1fac2.png\" alt=\":people_hugging:\"><\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>More moving, tracking and facepalms \u200b<img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/pf-emoji-service--cdn.us-east-1.prod.public.atl-paas.net\/standard\/caa27a19-fc09-4452-b2b4-a301552fd69c\/32x32\/1f926-200d-2642-fe0f.png\" alt=\":man_facepalming:\" width=\"20\" height=\"20\"><\/li>\n\n\n\n<li>Maybe the MicroMouse will become artificially intelligent and demand rights \u200b<img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/pf-emoji-service--cdn.us-east-1.prod.public.atl-paas.net\/standard\/caa27a19-fc09-4452-b2b4-a301552fd69c\/32x32\/1f916.png\" alt=\":robot:\" width=\"20\" height=\"20\"><\/li>\n\n\n\n<li>Deadly amounts of debugging (worst-case) \u200b<img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/pf-emoji-service--cdn.us-east-1.prod.public.atl-paas.net\/standard\/caa27a19-fc09-4452-b2b4-a301552fd69c\/32x32\/2620.png\" alt=\":skull_crossbones:\" width=\"20\" height=\"20\"><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>What\u2019s up readers, mid-term presentations are over, so let\u2019s get right into the news this week. Jonathan \u200b PRESENTATION IS DONE, WE MAY NOW FOCUS ON DOING THE \u200b WORK \u200b I\u2019m still working on a localization feature of the micromouse, and there are quite a few problems to overcome: Mats \u200b Adding shared logging [&hellip;]<\/p>\n","protected":false},"author":95,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-7939","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/dronesonen.usn.no\/index.php?rest_route=\/wp\/v2\/posts\/7939","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\/95"}],"replies":[{"embeddable":true,"href":"https:\/\/dronesonen.usn.no\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=7939"}],"version-history":[{"count":3,"href":"https:\/\/dronesonen.usn.no\/index.php?rest_route=\/wp\/v2\/posts\/7939\/revisions"}],"predecessor-version":[{"id":7949,"href":"https:\/\/dronesonen.usn.no\/index.php?rest_route=\/wp\/v2\/posts\/7939\/revisions\/7949"}],"wp:attachment":[{"href":"https:\/\/dronesonen.usn.no\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=7939"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dronesonen.usn.no\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=7939"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dronesonen.usn.no\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=7939"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}