{"id":13698,"date":"2026-10-06T09:22:42","date_gmt":"2026-10-06T13:22:42","guid":{"rendered":"https:\/\/jeremyclark.ca\/wp\/?p=13698"},"modified":"2026-10-06T14:25:26","modified_gmt":"2026-10-06T18:25:26","slug":"icm20948-9dof-imu-on-raspberry-pi-pico-2","status":"publish","type":"post","link":"https:\/\/jeremyclark.ca\/wp\/nav\/icm20948-9dof-imu-on-raspberry-pi-pico-2\/","title":{"rendered":"ICM20948 9DOF IMU on Raspberry Pi Pico 2"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Introduction<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">In previous posts I looked at using the ICM20948 9DOF IMU with Raspberry Pi4B and Arduino Uno (Ref.1\/2). The ICM20948 is a replacement for the MPU9250 (now end of life) on the popular GY-91 board often used with OpenPlotter. The Raspberry Pi Pico 2 is a very small microcontroller that lends itself to remote sensor applications. With this in mind, I wanted to see how easy it was to interface the ICM20948 with the Pico 2 using either MicroPython or CircuitPython and using the Sparkfun breakout board (<a href=\"https:\/\/www.sparkfun.com\/sparkfun-9dof-imu-breakout-icm-20948-qwiic.html\">Ref.3<\/a>).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Raspberry Pi Pico 2 to ICM20948 Connection<\/h2>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"598\" src=\"https:\/\/jeremyclark.ca\/wp\/wp-content\/uploads\/2026\/10\/pico2_pinout1-1024x598.jpg\" alt=\"\" class=\"wp-image-13732\" srcset=\"https:\/\/jeremyclark.ca\/wp\/wp-content\/uploads\/2026\/10\/pico2_pinout1-1024x598.jpg 1024w, https:\/\/jeremyclark.ca\/wp\/wp-content\/uploads\/2026\/10\/pico2_pinout1-300x175.jpg 300w, https:\/\/jeremyclark.ca\/wp\/wp-content\/uploads\/2026\/10\/pico2_pinout1-768x449.jpg 768w, https:\/\/jeremyclark.ca\/wp\/wp-content\/uploads\/2026\/10\/pico2_pinout1.jpg 1107w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\">Fig.1 Pico 2 Pinout<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"971\" height=\"594\" src=\"https:\/\/jeremyclark.ca\/wp\/wp-content\/uploads\/2026\/10\/pico2_icm20948c.jpg\" alt=\"\" class=\"wp-image-13751\" srcset=\"https:\/\/jeremyclark.ca\/wp\/wp-content\/uploads\/2026\/10\/pico2_icm20948c.jpg 971w, https:\/\/jeremyclark.ca\/wp\/wp-content\/uploads\/2026\/10\/pico2_icm20948c-300x184.jpg 300w, https:\/\/jeremyclark.ca\/wp\/wp-content\/uploads\/2026\/10\/pico2_icm20948c-768x470.jpg 768w\" sizes=\"auto, (max-width: 971px) 100vw, 971px\" \/><figcaption class=\"wp-element-caption\">Fig.2 Pico 2 to ICM20948 Connection on Parallax BOE Dev Board<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Figure 1 shows the pinouts for the Pico 2 as well as the pin assignments. Figure 2 shows the connections to the ICM20948 mounted on the protoboard of a Parallax BOE dev board. Power is supplied from the USB input connection on Pin40. Ground is on Pin38. SDA is connected to Pin6\/I2C0_SDA and SCL is connected to Pin7\/I2C0_SCL. Note that the Pico 2 has two separate I2C controllers.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">MicroPython &amp; Thonny Python IDE<\/h2>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1919\" height=\"1018\" src=\"https:\/\/jeremyclark.ca\/wp\/wp-content\/uploads\/2026\/10\/thonny_pkg_install.jpg\" alt=\"\" class=\"wp-image-13736\" srcset=\"https:\/\/jeremyclark.ca\/wp\/wp-content\/uploads\/2026\/10\/thonny_pkg_install.jpg 1919w, https:\/\/jeremyclark.ca\/wp\/wp-content\/uploads\/2026\/10\/thonny_pkg_install-300x159.jpg 300w, https:\/\/jeremyclark.ca\/wp\/wp-content\/uploads\/2026\/10\/thonny_pkg_install-1024x543.jpg 1024w, https:\/\/jeremyclark.ca\/wp\/wp-content\/uploads\/2026\/10\/thonny_pkg_install-768x407.jpg 768w, https:\/\/jeremyclark.ca\/wp\/wp-content\/uploads\/2026\/10\/thonny_pkg_install-1536x815.jpg 1536w, https:\/\/jeremyclark.ca\/wp\/wp-content\/uploads\/2026\/10\/thonny_pkg_install-1568x832.jpg 1568w\" sizes=\"auto, (max-width: 1919px) 100vw, 1919px\" \/><figcaption class=\"wp-element-caption\">Fig.3 Thonny IDE Loading Python Code via zip File<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1919\" height=\"969\" src=\"https:\/\/jeremyclark.ca\/wp\/wp-content\/uploads\/2026\/10\/thonny_micropython_opt.jpg\" alt=\"\" class=\"wp-image-13737\" srcset=\"https:\/\/jeremyclark.ca\/wp\/wp-content\/uploads\/2026\/10\/thonny_micropython_opt.jpg 1919w, https:\/\/jeremyclark.ca\/wp\/wp-content\/uploads\/2026\/10\/thonny_micropython_opt-300x151.jpg 300w, https:\/\/jeremyclark.ca\/wp\/wp-content\/uploads\/2026\/10\/thonny_micropython_opt-1024x517.jpg 1024w, https:\/\/jeremyclark.ca\/wp\/wp-content\/uploads\/2026\/10\/thonny_micropython_opt-768x388.jpg 768w, https:\/\/jeremyclark.ca\/wp\/wp-content\/uploads\/2026\/10\/thonny_micropython_opt-1536x776.jpg 1536w, https:\/\/jeremyclark.ca\/wp\/wp-content\/uploads\/2026\/10\/thonny_micropython_opt-1568x792.jpg 1568w\" sizes=\"auto, (max-width: 1919px) 100vw, 1919px\" \/><figcaption class=\"wp-element-caption\">Fig.4. Thonny IDE Running MicroPython Code &amp; Sensor Opt in Shell<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"518\" src=\"https:\/\/jeremyclark.ca\/wp\/wp-content\/uploads\/2026\/10\/icm20948_lsb_perG-1024x518.jpg\" alt=\"\" class=\"wp-image-13769\" srcset=\"https:\/\/jeremyclark.ca\/wp\/wp-content\/uploads\/2026\/10\/icm20948_lsb_perG-1024x518.jpg 1024w, https:\/\/jeremyclark.ca\/wp\/wp-content\/uploads\/2026\/10\/icm20948_lsb_perG-300x152.jpg 300w, https:\/\/jeremyclark.ca\/wp\/wp-content\/uploads\/2026\/10\/icm20948_lsb_perG-768x389.jpg 768w, https:\/\/jeremyclark.ca\/wp\/wp-content\/uploads\/2026\/10\/icm20948_lsb_perG.jpg 1364w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\">Fig.5 ICM20948 Sensitivity 16,384 LSB\/g<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">First download MicroPython for the Pico 2 from <a href=\"https:\/\/micropython.org\/download\/\">Ref.4.<\/a> Hold down the BOOTSEL button on the Pico 2 and plug it into the laptop USB port. The Pico 2 uses a micro USB B connector. After 3 seconds let it go. The Pico 2 should now show as a drive with 2 files INDEX.HTM &amp; INFO_UF2.TXT. Drag the downloaded MicroPython uf2 file onto this drive. The Pico 2 will now reboot. Figure 3 shows the Thonny IDE (portable version 5.0.0). used to run the MicroPython code for interfacing. On the bottom RHS of the Thonny display click to find &#8220;MicroPython (Raspberry Pi Pico).comxy&#8221;. The interface code is downloaded as a zip file from the SparkFun github repository (<a href=\"https:\/\/github.com\/sparkfun\/Qwiic_9DoF_IMU_ICM20948_Py\">Ref.5<\/a>). This is then loaded using Thonny Tools\/Manage Packages\/Install from local file. Select the downloaded zip file and Thonny will then install all the code\/dependencies etc from the zip.<br><br>Figure 4 shows ex1_qwiic_ICM20948.py example running with the output displayed below in the shell area. In the example, the sensor is horizontal, so ax = ay = &lt;1000 &amp; az = 16400 approx. Figure 5 shows the sensitivity for the ICM20948 (<a href=\"https:\/\/product.tdk.com\/en\/search\/sensor\/mortion-inertial\/imu\/info?part_no=ICM-20948\">Ref.6<\/a>). Thus az = 16400\/16384 * 9.81m\/sec^2 = 9.82m\/sec^2.<\/p>\n\n\n\n<figure class=\"wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"ICM20948 9DOF IMU on Raspberry Pi Pico 2\" width=\"750\" height=\"422\" src=\"https:\/\/www.youtube.com\/embed\/arhcDV9HVi0?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe>\n<\/div><figcaption class=\"wp-element-caption\">Fig.6 YouTube Video ICM20948 9DOF IMU on Raspberry Pi Pico 2<\/figcaption><\/figure>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><a href=\"https:\/\/jeremyclark.ca\/wp\/blog-topics\/\"><img loading=\"lazy\" decoding=\"async\" width=\"924\" height=\"347\" src=\"https:\/\/jeremyclark.ca\/wp\/wp-content\/uploads\/2025\/04\/electronics.jpg\" alt=\"\" class=\"wp-image-12395\" style=\"aspect-ratio:2.6627865269274613;width:422px;height:auto\" srcset=\"https:\/\/jeremyclark.ca\/wp\/wp-content\/uploads\/2025\/04\/electronics.jpg 924w, https:\/\/jeremyclark.ca\/wp\/wp-content\/uploads\/2025\/04\/electronics-300x113.jpg 300w, https:\/\/jeremyclark.ca\/wp\/wp-content\/uploads\/2025\/04\/electronics-768x288.jpg 768w\" sizes=\"auto, (max-width: 924px) 100vw, 924px\" \/><\/a><figcaption class=\"wp-element-caption\">Electronics Blog Topics<\/figcaption><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\">Please send your comments, questions and suggestions to:<br><a href=\"https:\/\/jeremyclark.ca\/wp\/contact\">contact:<\/a><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/www.youtube.com\/user\/clarktelecom\"><img loading=\"lazy\" decoding=\"async\" width=\"93\" height=\"98\" src=\"https:\/\/jeremyclark.ca\/wp\/wp-content\/uploads\/2020\/01\/youtube.jpg\" alt=\"YouTube Channel\" class=\"wp-image-687\"\/><\/a><figcaption class=\"wp-element-caption\">YouTube Channel<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">References<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">#1. &#8211; &#8220;ICM20948 9DOF IMU on RaspberryPi4B&#8221;<br><a href=\"https:\/\/jeremyclark.ca\/wp\/nav\/icm20948-9dof-imu-on-raspberrypi4b\/\">https:\/\/jeremyclark.ca\/wp\/nav\/icm20948-9dof-imu-on-raspberrypi4b\/<\/a><br><br>#2. &#8211; &#8220;ICM20948 9DOF IMU on Arduino Uno&#8221;<br><a href=\"https:\/\/jeremyclark.ca\/wp\/nav\/icm20948-9dof-imu-on-arduino-uno\/\">https:\/\/jeremyclark.ca\/wp\/nav\/icm20948-9dof-imu-on-arduino-uno\/<\/a><br><br>#3. &#8211; &#8220;SparkFun 9DoF IMU Breakout &#8211; ICM-20948 (Qwiic)&#8221;<br><a href=\"https:\/\/www.sparkfun.com\/sparkfun-9dof-imu-breakout-icm-20948-qwiic.html\">https:\/\/www.sparkfun.com\/sparkfun-9dof-imu-breakout-icm-20948-qwiic.htm<\/a><br><br>#4. &#8211; &#8220;MicroPython&#8221;<br><a href=\"https:\/\/micropython.org\/download\/\">https:\/\/micropython.org\/download\/<\/a><br><br>#5. &#8211; &#8220;SparkFun Qwiic 9DOF &#8211; Python Package&#8221;<br><a href=\"https:\/\/github.com\/sparkfun\/Qwiic_9DoF_IMU_ICM20948_Py\">https:\/\/github.com\/sparkfun\/Qwiic_9DoF_IMU_ICM20948_Py<\/a><br><br>#6. &#8211; &#8220;TDK Data Sheet ICM20948&#8221;<br><a href=\"https:\/\/product.tdk.com\/en\/search\/sensor\/mortion-inertial\/imu\/info?part_no=ICM-20948\">https:\/\/product.tdk.com\/en\/search\/sensor\/mortion-inertial\/imu\/info?part_no=ICM-20948<\/a><br><br><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction In previous posts I looked at using the ICM20948 9DOF IMU with Raspberry Pi4B and Arduino Uno (Ref.1\/2). The ICM20948 is a replacement for the MPU9250 (now end of life) on the popular GY-91 board often used with OpenPlotter. The Raspberry Pi Pico 2 is a very small microcontroller that lends itself to remote&hellip; <a class=\"more-link\" href=\"https:\/\/jeremyclark.ca\/wp\/nav\/icm20948-9dof-imu-on-raspberry-pi-pico-2\/\">Continue reading <span class=\"screen-reader-text\">ICM20948 9DOF IMU on Raspberry Pi Pico 2<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":13762,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6,5],"tags":[],"class_list":["post-13698","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-elec","category-nav","entry"],"_links":{"self":[{"href":"https:\/\/jeremyclark.ca\/wp\/wp-json\/wp\/v2\/posts\/13698","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/jeremyclark.ca\/wp\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/jeremyclark.ca\/wp\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/jeremyclark.ca\/wp\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/jeremyclark.ca\/wp\/wp-json\/wp\/v2\/comments?post=13698"}],"version-history":[{"count":38,"href":"https:\/\/jeremyclark.ca\/wp\/wp-json\/wp\/v2\/posts\/13698\/revisions"}],"predecessor-version":[{"id":13774,"href":"https:\/\/jeremyclark.ca\/wp\/wp-json\/wp\/v2\/posts\/13698\/revisions\/13774"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/jeremyclark.ca\/wp\/wp-json\/wp\/v2\/media\/13762"}],"wp:attachment":[{"href":"https:\/\/jeremyclark.ca\/wp\/wp-json\/wp\/v2\/media?parent=13698"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/jeremyclark.ca\/wp\/wp-json\/wp\/v2\/categories?post=13698"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/jeremyclark.ca\/wp\/wp-json\/wp\/v2\/tags?post=13698"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}