<?xml version='1.0' encoding='UTF-8'?><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" xmlns:blogger="http://schemas.google.com/blogger/2008" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" version="2.0"><channel><atom:id>tag:blogger.com,1999:blog-7859657580199211900</atom:id><lastBuildDate>Mon, 06 Apr 2026 10:00:00 +0000</lastBuildDate><category>Python</category><category>WiFi</category><category>Video</category><category>Boards</category><category>News</category><category>Projects</category><category>Bluetooth</category><title>Raspberry Pico Adventures</title><description></description><link>https://raspico.blogspot.com/</link><managingEditor>noreply@blogger.com (Daniel Quadros)</managingEditor><generator>Blogger</generator><openSearch:totalResults>46</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7859657580199211900.post-6658494037855606579</guid><pubDate>Mon, 06 Apr 2026 10:00:00 +0000</pubDate><atom:updated>2026-04-06T03:00:00.118-07:00</atom:updated><title>Mini-Review: WaveShare&#39;s RP2350B-Plus-W</title><description>&lt;p&gt;An unexpected new from Raspberry Pi was the commercialization, in module form, of the Raspberry Pi Pico W radio circuit. This facilitates the creation of boards compatible with the Pico W.&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBRTBSjCzUhUhPaTKVUJGeq9B3GxavZVmr7gR2LEXuqLl9m84_IJk1lQ12lSUGiPqbNNca0eJtQ1iIbbbLbR34ExI-_cAR5XkQQWiArMswYEi-PuZSpfXaReyaSClP5cdi-6LqhUnTAl5UXPwk02h7XzNk0kmPDSEilYJh1JxAaIS5gCmdD2kuvz_p3Ag/s1600/RP2350B-Plus-W.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;692&quot; data-original-width=&quot;1600&quot; height=&quot;173&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBRTBSjCzUhUhPaTKVUJGeq9B3GxavZVmr7gR2LEXuqLl9m84_IJk1lQ12lSUGiPqbNNca0eJtQ1iIbbbLbR34ExI-_cAR5XkQQWiArMswYEi-PuZSpfXaReyaSClP5cdi-6LqhUnTAl5UXPwk02h7XzNk0kmPDSEilYJh1JxAaIS5gCmdD2kuvz_p3Ag/w400-h173/RP2350B-Plus-W.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;/span&gt;The board we&#39;re looking at here is listed for US$11. Considering that the Pico 2 W is listed at US$7, does the RP2350B-Plus-W have advantages that make it competitive?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Let&#39;s start with what the RP2350B-Plus-W has in common with the Pico 2: the pinout on the edges. The physical format is slightly different: on one end, we have a USB-C instead of micro USB; on the other, the antenna extends beyond the end of the board. One absence is where to solder a debug connector.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In addition to the BOOT button, there is a Reset button (an annoying absence in the Pico).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;One difference that surprised me is the use of the RP2350B instead of the RP2350A used in the Pico 2. The B model has more I/O pins. One of these pins is connected to an LED (the other LED is connected to the radio module, as on Pico boards). The remaining pins are located on the underside of the board.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;The Flash memory is 16 MB, a significant improvement over the 4 MB on the Pico 2. The problem is that the Flash memory is located on the underside of the board, which complicates the use of &quot;castellated&quot; pins (when the board is soldered directly onto another).&amp;nbsp; Also on the underside, there is a location for soldering a PSRAM.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBLLVnJAFV0ZO77Ak1gpQYEE7zKpwUbB1gSxiXxiq3LR2RFYQNggZMUgpWYu3eP7j0E_QAiTpUf-wqLooCDurIi8HcyhDXLtJy6tEYobOOvs2THt7HrTRlBr9j-IQ6BFyCGMAjZHg5vniDM7RBIxgKZ1OpzQ0fw7PlsovTDyKm5hspr5aONBaz5F46GkM/s1400/RP2350B-Plus-W_Parts2.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;824&quot; data-original-width=&quot;1400&quot; height=&quot;376&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBLLVnJAFV0ZO77Ak1gpQYEE7zKpwUbB1gSxiXxiq3LR2RFYQNggZMUgpWYu3eP7j0E_QAiTpUf-wqLooCDurIi8HcyhDXLtJy6tEYobOOvs2THt7HrTRlBr9j-IQ6BFyCGMAjZHg5vniDM7RBIxgKZ1OpzQ0fw7PlsovTDyKm5hspr5aONBaz5F46GkM/w640-h376/RP2350B-Plus-W_Parts2.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;A difference you won&#39;t see in these photos is the radio module&#39;s connections to the RP2350. Waveshare chose to use different pins, making the board incompatible with Pico2 W firmwares. The unofficial Arduino package fully supports this board (see &lt;a href=&quot;https://github.com/earlephilhower/arduino-pico/blob/master/variants/waveshare_rp2350b_plus_w/init.cpp&quot;&gt;here&lt;/a&gt;), but there is no support in MicroPython or CircuitPython yet.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;div&gt;My humble opinion is that it was a mistake to make this board in the Pico format, but with differences that make it difficult to use as a direct replacement. A different format (as we&#39;ve seen in other boards) would facilitate the use of additional pins, the installation of a PSRAM, and the use of castellated pins.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;</description><link>https://raspico.blogspot.com/2026/04/mini-review-waveshares-rp2350b-plus-w.html</link><author>noreply@blogger.com (Daniel Quadros)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBRTBSjCzUhUhPaTKVUJGeq9B3GxavZVmr7gR2LEXuqLl9m84_IJk1lQ12lSUGiPqbNNca0eJtQ1iIbbbLbR34ExI-_cAR5XkQQWiArMswYEi-PuZSpfXaReyaSClP5cdi-6LqhUnTAl5UXPwk02h7XzNk0kmPDSEilYJh1JxAaIS5gCmdD2kuvz_p3Ag/s72-w400-h173-c/RP2350B-Plus-W.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7859657580199211900.post-4128990272079633119</guid><pubDate>Sat, 27 Sep 2025 20:30:00 +0000</pubDate><atom:updated>2025-09-27T13:30:16.425-07:00</atom:updated><title>The Final Countdown - An RP3250 based Event Timer </title><description>&lt;p&gt;Sometimes, we are counting down the days to an important event, such as a trip or an anniversary. A few years ago, I built a timer for this, using an ESP-8266 board and two LED bar displays:&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj65hcsQogLs3_0S2hA_AFCkuobXTQd69qnyb_9QwpG6hvYppylc7woe8m8oeSaG3MRzSZwibqHf3n6Bgodm4dCW0eDtp0HJ4x5lQ0ZW-0S-R-mUY_13FkUt0orHL3ZPeSSqlLTdAZLaIpxwFbEh8zbKVZTPk0VGR31aj4D-HMcgJigzM3mj8sXXaMpejs/s827/ContagemRegressiva_I.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;827&quot; data-original-width=&quot;800&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj65hcsQogLs3_0S2hA_AFCkuobXTQd69qnyb_9QwpG6hvYppylc7woe8m8oeSaG3MRzSZwibqHf3n6Bgodm4dCW0eDtp0HJ4x5lQ0ZW-0S-R-mUY_13FkUt0orHL3ZPeSSqlLTdAZLaIpxwFbEh8zbKVZTPk0VGR31aj4D-HMcgJigzM3mj8sXXaMpejs/s320/ContagemRegressiva_I.png&quot; width=&quot;310&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;It worked fine, but powering it through the USB connector was a bit of a pain. So, I started thinking about a battery-powered device. Looking at my parts stash, I found a few components that could be used in this project:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;An e-paper display: it shows the last image even if powered down.&lt;/li&gt;&lt;li&gt;A tinyRTC module, with a DS1307 with battery backup and an AT24C32 EEProm: it can save the event date and keep track of the current date and time.&lt;/li&gt;&lt;li&gt;A XIAO RP2350 board: it has support for a rechargeable battery.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;I had enough experience with the first two modules, the XIAO RP2350 brought the adventure of learning about power saving with the RP2350.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhj5NlL6BzN-IIY4hoW7q9KqXbsqiMWa9nxoEQm3lpIlCs2rrleP8FqcS_ggOU5oB0j5kBWVrMzKoVKIVwq_JRJrDmxPaQhvZL7ftOOn4bLR7bFjgLCMWBoHtI0akp0vx6uZAFyf63YCFPWQNyy6uAfs1PnhO3-_Q0XHsdYE0bJei68H8QzPGYr7cCWxgI/s2959/ContagemRegressiva_II.jpg&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;2959&quot; data-original-width=&quot;2008&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhj5NlL6BzN-IIY4hoW7q9KqXbsqiMWa9nxoEQm3lpIlCs2rrleP8FqcS_ggOU5oB0j5kBWVrMzKoVKIVwq_JRJrDmxPaQhvZL7ftOOn4bLR7bFjgLCMWBoHtI0akp0vx6uZAFyf63YCFPWQNyy6uAfs1PnhO3-_Q0XHsdYE0bJei68H8QzPGYr7cCWxgI/s320/ContagemRegressiva_II.jpg&quot; width=&quot;217&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;span&gt;&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;/span&gt;&lt;div&gt;Before&amp;nbsp;&lt;span&gt;delving into the project details, a word of caution regarding the tinyRTC module: it was designed for use with a rechargeable LR2032 battery, but it typically&amp;nbsp;comes with&amp;nbsp;&lt;span&gt;a CR2032 non-rechargeable battery. The charging circuit also does not follow the LR2032 specifications. So, I am using a CR2032 and removing the D1 diode to disable the recharge circuit.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiG7wdGof8hX08ANEUfdtF80ovb9A9LFv0FPtVx98FG35Ci2qDtj7Vuay3vq_T9HSeCxN2Zvm-IKDWp5WrnlMryY8-7m5nrbhwHuPaNDlIdcPtyfqcTKOQsdwjlaSpRZSScyMa5KxilN0VCEa39bhAiLV9Ai4VixMQB2xi4SFAPtC0kGP_m_QZzjgMC6C4/s898/TinyRTC_Carga.jpg&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;614&quot; data-original-width=&quot;898&quot; height=&quot;219&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiG7wdGof8hX08ANEUfdtF80ovb9A9LFv0FPtVx98FG35Ci2qDtj7Vuay3vq_T9HSeCxN2Zvm-IKDWp5WrnlMryY8-7m5nrbhwHuPaNDlIdcPtyfqcTKOQsdwjlaSpRZSScyMa5KxilN0VCEa39bhAiLV9Ai4VixMQB2xi4SFAPtC0kGP_m_QZzjgMC6C4/s320/TinyRTC_Carga.jpg&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;The interconnections are straightforward:&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;The display utilizes a three-wire SPI interface (MOSI, SCK, and CS), three digital signals (BUSY, RES, and D/C), plus power (3.3V) and ground.&lt;/li&gt;&lt;li&gt;The tinyRTC utilizes an I2C interface (SDA and SCL), plus power (3.3V) and ground.&lt;/li&gt;&lt;li&gt;A button is connected between a digital input and ground.&lt;/li&gt;&lt;li&gt;The XIAO has pins connected to the spi0 and i2c1 interfaces in the RP2350. The digital signals were assigned to the other pins more or less randomly..&lt;/li&gt;&lt;/ul&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi77pSWRUTmENavJOyJmp9JjGNsoC6IGNvrzddWBeSoXD4Je0KJeO4xtN-po1SKGVWF9gcKTelfM3cpdwNanOWoPkUjgb2D724YCdJfCRW8tVZiiTEUNgcnaI2VZMEl3icHsEmjc7oyljLHG8ridl6k7YAfII3A_pc72mmd3YNfk75PfQNwjlKsI2UqVyU/s1400/Connections.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1000&quot; data-original-width=&quot;1400&quot; height=&quot;286&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi77pSWRUTmENavJOyJmp9JjGNsoC6IGNvrzddWBeSoXD4Je0KJeO4xtN-po1SKGVWF9gcKTelfM3cpdwNanOWoPkUjgb2D724YCdJfCRW8tVZiiTEUNgcnaI2VZMEl3icHsEmjc7oyljLHG8ridl6k7YAfII3A_pc72mmd3YNfk75PfQNwjlKsI2UqVyU/w400-h286/Connections.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;The assembly was done using a protoboard PCB, female pin connectors, and wire-wrapping wires.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhO31QuHun4ohDSlaZEEYsaAAVFPBZzOcznXZHPQTEwhfxYkUykQHHROJdC0fjUuFrWru3333x40kD3gVOPhIUbPZYfYL4tc5Dthp0dq5OCIa-RMVlPIP2CUwZyK7bBLJN3VFqcwn3nC0rCC6kznwohpCLjI3Tfeteq7Jp4owG8L3VQ5Rh931_8RfiqG3w/s800/ContagemRegressiva_verso.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;559&quot; data-original-width=&quot;800&quot; height=&quot;224&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhO31QuHun4ohDSlaZEEYsaAAVFPBZzOcznXZHPQTEwhfxYkUykQHHROJdC0fjUuFrWru3333x40kD3gVOPhIUbPZYfYL4tc5Dthp0dq5OCIa-RMVlPIP2CUwZyK7bBLJN3VFqcwn3nC0rCC6kznwohpCLjI3Tfeteq7Jp4owG8L3VQ5Rh931_8RfiqG3w/s320/ContagemRegressiva_verso.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;The code for interfacing the tinyRTC module is also straightforward. I store my &quot;configuration&quot; (the event date and time) in the EEProm with a simple XOR checksum.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The display itself is a little more complicated; the code for initializing and updating the display is adapted from a &lt;a href=&quot;https://github.com/WeActStudio/WeActStudio.EpaperModule&quot;&gt;manufacturer&#39;s example&lt;/a&gt;. With enough RAM in the RP2350, I could keep an image of the display in memory.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;For text, I chose a 12x16 font. This requires some bit-shifting, as the characters are not byte-aligned. To draw a simple clock dial, I added routines to draw lines and circles. The algorithm for these routines is based on my 1990 book, &quot;&lt;a href=&quot;https://datassette.org/livros/br-brasil-ibm-pc-livros/pc-assembler-usando-graficos-e-sons&quot;&gt;PC Assembler: Usando Gráficos e Sons&lt;/a&gt;&quot;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The program will wake the RP2350 every 15 minutes to update the display. That leaves us with the task of putting the RP2350 to sleep. The RP2350 documentation is not particularly informative on this matter, nor is the SDK documentation. The SDK has a module named &lt;a href=&quot;https://www.raspberrypi.com/documentation/pico-sdk/hardware.html#group_hardware_powman&quot;&gt;hardware_powman&lt;/a&gt; with a few routines, and there are a couple of examples at a &lt;a href=&quot;https://github.com/peterharperuk/pico-examples/tree/powman/powman&quot;&gt;fork of the pico-examples&lt;/a&gt;. Not much, but enough for this project:&lt;/div&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;We will switch between two power states: P0_0 (where everything is turned on) and P1_7 (where most of the hardware is turned off).&lt;/li&gt;&lt;li&gt;The change from P0_0 to P1_7 is commanded by the software.&lt;/li&gt;&lt;li&gt;The change from P1_7 back to P0_0 can be commanded by a timer alarm or a GPIO change.&lt;/li&gt;&lt;li&gt;The change from P1_7 back to P0_0 will result in a reset, with the previous RAM content lost.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;For now, I am using the timer alarm to wake up the RP2350. The downside is that this timer is not very precise, but I can not use the tinyRTC to drive a GPIO (more about this at the end).&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I am not using the USB in normal operation; it is used for configuring the timer and debugging purposes. To reduce power consumption, the USB hardware must be disabled before the device goes to sleep. This is done by a kind of &quot;magic incantation&quot; copied from the powman_timer example.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The full code is available on my github:&amp;nbsp;https://github.com/dquadros/FinalCountdown.git&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;As a future enhancement, I plan to replace the tinyRTC module with one that utilizes the DS3231 chip. This RTC has better precision and an alarm feature, allowing me to wake the RP2350 through a GPIO pin. Best yet, I found a DS3231 module with a pinout that allows for the replacement without altering the wiring of the RTC connector.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;</description><link>https://raspico.blogspot.com/2025/09/the-final-countdown-rp3250-based-event.html</link><author>noreply@blogger.com (Daniel Quadros)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj65hcsQogLs3_0S2hA_AFCkuobXTQd69qnyb_9QwpG6hvYppylc7woe8m8oeSaG3MRzSZwibqHf3n6Bgodm4dCW0eDtp0HJ4x5lQ0ZW-0S-R-mUY_13FkUt0orHL3ZPeSSqlLTdAZLaIpxwFbEh8zbKVZTPk0VGR31aj4D-HMcgJigzM3mj8sXXaMpejs/s72-c/ContagemRegressiva_I.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7859657580199211900.post-320855280048071936</guid><pubDate>Mon, 14 Jul 2025 10:00:00 +0000</pubDate><atom:updated>2025-07-14T03:00:00.115-07:00</atom:updated><title>RP2350 Boards</title><description>&lt;p&gt;Over the past few months, I have collected a few boards that utilize the RP2350 microcontroller. In this post, I will provide a brief description of each one.&lt;/p&gt;&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLn1ns2GUoBjmkFXYxYd4izL5_2D885RaOOYyt68nWPBIH3HKwj5vhB6A89WYnw6Sohw-U3BlaKREzVeB_PW6mHVVCKggUk3CISEP5U4w4e8gcrjgYb_mxKah1sDX7SYNzVGtFkYns8YUOEFS9qQLZPrpLAxVXPsaXK5gQv-KTH09vYt46HgymSS2L6Ec/s824/Placas_RP2350.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;548&quot; data-original-width=&quot;824&quot; height=&quot;266&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLn1ns2GUoBjmkFXYxYd4izL5_2D885RaOOYyt68nWPBIH3HKwj5vhB6A89WYnw6Sohw-U3BlaKREzVeB_PW6mHVVCKggUk3CISEP5U4w4e8gcrjgYb_mxKah1sDX7SYNzVGtFkYns8YUOEFS9qQLZPrpLAxVXPsaXK5gQv-KTH09vYt46HgymSS2L6Ec/w400-h266/Placas_RP2350.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;1:RP2350USB, 2:RP2350 Stamp XL, 3:RP2350-GEEK, 4:RP2350 Stamp,&lt;br /&gt;5:RP2350 Zero, 6:XIAO RP2350, 7:Feather RP2350, 8:Raspberry Pi Pico 2,&lt;br /&gt;9:RP2350B Core Board, 10:Raspberry Pi Pico 2 W&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;span&gt;&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;/span&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;Raspberry Pi Pico 2 and Pico 2 W&lt;/h3&gt;&lt;p&gt;I already talked about these boards. They follow the shape and pin-out of the original Pico boards, including the use of a USB micro connector and the absence of a reset button. Both have 4 megabytes&amp;nbsp; of Flash (an upgrade from the 2 megabytes in the original Pico) and a single user-controlled LED (connected to the RF module in the W boards).&lt;/p&gt;&lt;p&gt;All the other boards mentioned here use a USB-C connector and, except for the RP2350-GEEK, include a reset button.&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;SeeedStudio XIAO RP2350&lt;/h3&gt;&lt;p&gt;SeeedStudio&#39;s XIAO line has many models, each using a different microcontroller, sharing the same shape and pin-out (as far as possible). The RP2350 model includes battery support and access to a few other pins through solder points at the bottom side of the board. It has two user-controlled LEDs, one single-color and the other RGB (WS2812).&amp;nbsp;&lt;/p&gt;&lt;p&gt;It is the smallest board in this group, but it has only 2 megabytes&amp;nbsp;of RAM.&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;Solder Party RP2350 Stamp and RP2350 Stamp XL&lt;/h3&gt;&lt;div&gt;You can read my mini-review of these boards &lt;a href=&quot;https://raspico.blogspot.com/2025/03/mini-review-solder-partys-rp2350-boards.html&quot;&gt;here&lt;/a&gt;. These boards have a 2 mm pin spacing and can be used with &quot;Carrier Boards&quot;. Both have 16 megabytes of Flash. The XL modules use the RP2350B chip that has additional GPIO and ADC pins.&lt;/div&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;Waveshare RP2350 Zero&lt;/h3&gt;&lt;div&gt;This board has the same dimensions and pinout as the RP2040 Zero (a favorite of mine for small projects). A compact board with access to many pins. It features 16 megabytes&amp;nbsp;of Flash and an RGB (WS2812) LED.&lt;/div&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;WeActStudio RP2350B Core Board&lt;/h3&gt;&lt;div&gt;Another board using the RP2350B model, it uses dual-row connectors that are not protoboard-friendly. It has 16 megabytes&amp;nbsp;of Flash, one user-controlled single-color LED, and one user-readable button.&lt;/div&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;Adafruit Feather RP2350 with with HSTX Port and PSRAM&lt;/h3&gt;&lt;div&gt;The Feather is another line of boards with different microcontrollers but the same board dimensions and pinout. The particular model I bought has 8 megabytes&amp;nbsp;of Flash and 8 megabytes&amp;nbsp;of PSRAM and a special connector for using the HSTX peripheral. An additional board is available to connect the HSTX port to a DVI connector for video output.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The board has battery support, one single-color LED, and one RGB (WS2812) LED.&lt;/div&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;RP2350USB&lt;/h3&gt;&lt;div&gt;This is a no-brand board found in many stores on AliExpress. The board can be plugged directly into a USB port, and it is available with 4 or 16 megabytes&amp;nbsp;of Flash. Like the XIAO and RP2350 Zero, a few additional pins are available through solder points.&lt;/div&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;Waveshare RP2350-GEEK&lt;/h3&gt;&lt;div&gt;This board comes in a white enclosure with a USB-A connector. It has 16 megabytes&amp;nbsp;of Flash, a small (1.14&quot;) color display with 240x135 resolution, and a RGB (WS2812) LED. There are connectors for USART, DEBUG, I2C, and micro SD. It has a BOOT button, but no Reset button.&lt;/div&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;Concluding Notes&lt;/h3&gt;&lt;div&gt;For general use, particularly in a protoboard, I recommend the Pico boards. For compact projects, the RP2350 Zero and XIAO are good options. The other boards are more appropriate for specific projects.&lt;/div&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;References&lt;/h3&gt;&lt;div&gt;&lt;div&gt;&lt;a href=&quot;https://www.seeedstudio.com/Seeed-XIAO-RP2350-p-5944.html&quot;&gt;https://www.seeedstudio.com/Seeed-XIAO-RP2350-p-5944.html&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;a href=&quot;https://www.waveshare.com/wiki/RP2350-Zero&quot;&gt;https://www.waveshare.com/wiki/RP2350-Zero&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;a href=&quot;https://github.com/WeActStudio/WeActStudio.RP2350BCoreBoard&quot;&gt;https://github.com/WeActStudio/WeActStudio.RP2350BCoreBoard&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;a href=&quot;https://www.adafruit.com/product/6000&quot;&gt;https://www.adafruit.com/product/6000&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;a href=&quot;https://www.aliexpress.com/item/1005008622261552.html&quot;&gt;https://www.aliexpress.com/item/1005008622261552.html&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;a href=&quot;https://www.waveshare.com/rp2350-geek.htm&quot;&gt;https://www.waveshare.com/rp2350-geek.htm&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;a href=&quot;https://www.waveshare.com/wiki/RP2350-GEEK&quot;&gt;https://www.waveshare.com/wiki/RP2350-GEEK&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;</description><link>https://raspico.blogspot.com/2025/07/rp2350-boards.html</link><author>noreply@blogger.com (Daniel Quadros)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLn1ns2GUoBjmkFXYxYd4izL5_2D885RaOOYyt68nWPBIH3HKwj5vhB6A89WYnw6Sohw-U3BlaKREzVeB_PW6mHVVCKggUk3CISEP5U4w4e8gcrjgYb_mxKah1sDX7SYNzVGtFkYns8YUOEFS9qQLZPrpLAxVXPsaXK5gQv-KTH09vYt46HgymSS2L6Ec/s72-w400-h266-c/Placas_RP2350.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7859657580199211900.post-1986612771667981247</guid><pubDate>Sat, 21 Jun 2025 14:05:00 +0000</pubDate><atom:updated>2025-06-21T07:05:38.055-07:00</atom:updated><title>Building a One-time Password Token</title><description>&lt;p&gt;&lt;b&gt;One-time passwords&lt;/b&gt; are an alternative to the more common &quot;permanent&quot; passwords. The problem with a &quot;normal&quot; password is that it can be captured during communication, by fake login screens or by key-loggers.&amp;nbsp; Once a normal password is captured, it can be used until it is changed.&lt;/p&gt;&lt;p&gt;To avoid this &quot;repetition attack&quot;, one-time passwords work just once. For each login, a new password is used. This creates a new problem: how to set up these passwords? One solution is to have a &quot;password book&quot;, but that is very clumsy.&lt;/p&gt;&lt;p&gt;In this post, we will see how to build a device that generates one-time passwords, one at a time. The other side can use the same algorithm to check the passwords. We will use a &lt;b&gt;Raspberry Pi Pico W&lt;/b&gt; board with a &lt;b&gt;MicroPython&lt;/b&gt; application.&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjm1Fsio-EO_HbaOuCVbCqJVhcACjW5d80jciaIcQtRswbCQu3aPluKEuWP3SoQIxuwfSYBccd2xhQqeq79WmG7Sf_xGV4tqB4uLoUJdMJAezH9ooMs0cY6vm-8wdiPZUfcIXdiKSej-fDCjM6y_w6PHIxJmvARKcuKTu8RpxyyCeXFZem__uKiLjjjD1g/s860/token.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;860&quot; data-original-width=&quot;800&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjm1Fsio-EO_HbaOuCVbCqJVhcACjW5d80jciaIcQtRswbCQu3aPluKEuWP3SoQIxuwfSYBccd2xhQqeq79WmG7Sf_xGV4tqB4uLoUJdMJAezH9ooMs0cY6vm-8wdiPZUfcIXdiKSej-fDCjM6y_w6PHIxJmvARKcuKTu8RpxyyCeXFZem__uKiLjjjD1g/s320/token.png&quot; width=&quot;298&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;&lt;span style=&quot;color: red;&quot;&gt;&lt;b&gt;WARNING: This is a demo only. The encrypting key will be in plain text in the code, open to any curious eyes. Do not use this with any real key!&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;span&gt;&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;/span&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;A Little Theory&lt;/h3&gt;&lt;p&gt;What we will use is an HMAC-based one-time&lt;b&gt;&amp;nbsp;password&lt;/b&gt; (&lt;b&gt;HOTP&lt;/b&gt;). Both sides keep a &lt;b&gt;counter&lt;/b&gt; and know a &lt;b&gt;secret key&lt;/b&gt;. The counter is processed by a cryptographic hash (HMAC); the password is extracted from the resulting hash. The algorithm used is described in &lt;a href=&quot;https://datatracker.ietf.org/doc/html/rfc4226&quot;&gt;RFC 4226&lt;/a&gt;, and is the same employed by many sites (like Github) and applications (like Google Authenticator).&lt;/p&gt;&lt;p&gt;The &lt;b&gt;counter&lt;/b&gt; is created from the current UTC time. To account for clock variations and user response times, the counter is incremented every 30 seconds. Furthermore, the side checking the password can accept the previous and next passwords. To account for long-time drift (in cases where the device clock is set only at manufacturing), the checking side can record the differences and take them into account in the next checks. The code uses the Unix Epoch (number of seconds from 1/1/1970 00:00:00 UTC).&lt;/p&gt;&lt;p&gt;&lt;b&gt;HMAC&lt;/b&gt;s are normally used to check a text integrity. They generate a value (the hash) from a text and a key. RFC 4226 mandates the use of HMAC-SHA1, resulting in a 160-bit (20 bytes) hash. The input text is the counter, encoded as 8 bytes with the more significant byte first (big-endian).&lt;/p&gt;&lt;p&gt;To extract the password from the 20-byte hash, we will:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Get an offset (0 to 15) from the 4 least significant bits in the last byte&lt;/li&gt;&lt;li&gt;Obtain a 32-bit number from the 4 bytes starting at the offset (more significant byte first, ignoring the signal bit)&lt;/li&gt;&lt;li&gt;Extract the 6 least significant digits from the decimal representation of this 32-bit number&lt;/li&gt;&lt;/ul&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjt3rdyPF8TcilReZJ4U8m2mSXkG4jsYqECU_dZuHBllwx70jf_qE8jyH2SGRDEXNUrjECTA76iGg-U9pPQF3qiwjsYXdd_VcabqILh0UHwSZGzo2pTSrOwIW-8kbLAb6y5m1EZpCFrV4cfexLdyfOMk-2cz3LTQ1-8sg2949Ffz7X0z3qQlM32mRU_MQg/s1442/OTP_FromHash.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;552&quot; data-original-width=&quot;1442&quot; height=&quot;245&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjt3rdyPF8TcilReZJ4U8m2mSXkG4jsYqECU_dZuHBllwx70jf_qE8jyH2SGRDEXNUrjECTA76iGg-U9pPQF3qiwjsYXdd_VcabqILh0UHwSZGzo2pTSrOwIW-8kbLAb6y5m1EZpCFrV4cfexLdyfOMk-2cz3LTQ1-8sg2949Ffz7X0z3qQlM32mRU_MQg/w640-h245/OTP_FromHash.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;Implementation&lt;/h3&gt;&lt;div&gt;We will use a &lt;b&gt;Raspberry Pi Pico W&lt;/b&gt; board connected to a small &lt;b&gt;128x32 OLED display&lt;/b&gt;:&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0BEwFjyiHgpPUbzg0U6QLaMGS7xzFNdxmgFAiA6xIEn6MDi3Yex9bPgT3IWybckA4p1vIMd0T-AFT5K62i3dzJMsKpp7-QZZGDN_TagdJHr7hbCbyqjaYFKa-ZsVJ_FliIfpHTCrfSRy7bSOF7BeQBmPr9iKzPnZ5SpjcfZehmb67ou_UBXtGaIIwY48/s876/otp_token_bb.png&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;753&quot; data-original-width=&quot;876&quot; height=&quot;275&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0BEwFjyiHgpPUbzg0U6QLaMGS7xzFNdxmgFAiA6xIEn6MDi3Yex9bPgT3IWybckA4p1vIMd0T-AFT5K62i3dzJMsKpp7-QZZGDN_TagdJHr7hbCbyqjaYFKa-ZsVJ_FliIfpHTCrfSRy7bSOF7BeQBmPr9iKzPnZ5SpjcfZehmb67ou_UBXtGaIIwY48/s320/otp_token_bb.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;Check the pinout for your display, mine was different!&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;p&gt;To obtain the counter, we will:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Connect to a WiFi network&lt;/li&gt;&lt;li&gt;Get the current time using the NTP protocol&lt;/li&gt;&lt;li&gt;Divide the current time by 30&lt;/li&gt;&lt;li&gt;Convert the result into a bytearray&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Note: &lt;i&gt;On RP2040-based boards, MicroPython uses the Unix Epoch. On some other boards (like ESP32-based boards) the epoch is 1/1/2000&lt;/i&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The SHA1 algorithm is available MicroPython in the hashlib library. HMAC needs to be downloaded from&amp;nbsp;&lt;a href=&quot;https://github.com/micropython/micropython-lib/tree/master/python-stdlib/hmac&quot;&gt;https://github.com/micropython/micropython-lib/tree/master/python-stdlib/hmac&lt;/a&gt; and installed in the Lib directory on the board.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The driver for the OLED display is available at&amp;nbsp;&lt;a href=&quot;https://raw.githubusercontent.com/micropython/micropython-lib/master/micropython/drivers/display/ssd1306/ssd1306.py&quot;&gt;https://raw.githubusercontent.com/micropython/micropython-lib/master/micropython/drivers/display/ssd1306/ssd1306.py&lt;/a&gt;&amp;nbsp;and needs to be installed in the Lib directory on the board.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The project is available at &lt;a href=&quot;https://github.com/dquadros/otp_token&quot;&gt;https://github.com/dquadros/otp_token&lt;/a&gt;. To use the software you will need to put your WiFi credentials in the &lt;span style=&quot;font-family: courier;&quot;&gt;secrets.py&lt;/span&gt; file. If you want, you can also change the HMAC key.&lt;/div&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;Testing&lt;/h3&gt;&lt;div&gt;An easy way to test our project is to use the Google Authenticator app on an Android phone. You can register the secret key using a QRcode containing&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;otpauth://totp/{name}?secret= {secret}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;where {name} is the name shown in the app and {secret} is the secret key coded in Base32.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In my repository, I included a Python script that can be run on a PC to generate the qrcode. This program requires the &lt;span style=&quot;font-family: courier;&quot;&gt;segno&lt;/span&gt; module.&lt;/div&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;Further Ideas&lt;/h3&gt;&lt;div&gt;You can use this software with other boards supported by Micro Python, the main difference will be the display connections. Supporting other types of display should not be too hard.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;You can also adapt the project for offline operation, setting manually the date and tine. An external battery-backed RTC (such as the DS1307) can be used to achieve greater precision and maintain the time when the Pico is powered off.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The biggest problem with this example is that the secret key is exposed. It would be very hard to avoid this using MicroPython. A professional solution should be written in C for the Pico 2 (or other board using the RP2350), storing the secret key in the OTP, encrypting the firmware, and disabling debugging.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;</description><link>https://raspico.blogspot.com/2025/06/building-one-time-password-token.html</link><author>noreply@blogger.com (Daniel Quadros)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjm1Fsio-EO_HbaOuCVbCqJVhcACjW5d80jciaIcQtRswbCQu3aPluKEuWP3SoQIxuwfSYBccd2xhQqeq79WmG7Sf_xGV4tqB4uLoUJdMJAezH9ooMs0cY6vm-8wdiPZUfcIXdiKSej-fDCjM6y_w6PHIxJmvARKcuKTu8RpxyyCeXFZem__uKiLjjjD1g/s72-c/token.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7859657580199211900.post-5739650991128143313</guid><pubDate>Wed, 26 Mar 2025 10:00:00 +0000</pubDate><atom:updated>2025-03-26T03:00:00.133-07:00</atom:updated><title>Mini-Review: Solder Party&#39;s RP2350 boards</title><description>&lt;p&gt;&lt;a href=&quot;https://www.solder.party/&quot;&gt;Solder Party&lt;/a&gt; is a Swedish company that has some peculiar boards. For the RP2350 (and RP2040), they have &lt;b&gt;stamp&lt;/b&gt; boards, which contain the microcontroller, and &lt;b&gt;carrier&lt;/b&gt; boards, where the stamps are connected and provide power and input/output connectors.&lt;/p&gt;&lt;p&gt;One detail that will bother many people is that the pin spacing on the stamp boards is 2 mm instead of the more traditional 0.1&quot; (2.54 mm). SolderParty sells connectors with this spacing.&lt;/p&gt;&lt;p&gt;Although some carriers have RP2040 in their names, all models work with RP2040 and RP2350 stamps.&lt;/p&gt;&lt;p&gt;I purchased both stamp models with RP2350 and the three carrier models. Here are some comments on them.&lt;/p&gt;&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiWKgdIuhyS_FG0z-AgfpD4yE_3zVgYIaFcbeoFRkRTKQlMnrgi0mo4Z6OTy15MB5BdZQoH7bXkPvUrgAQCgvizB4brkr0bYbucBojBTxuZvNHTkLA1MM12Uwk2p_y5vMmQJZHDZnMDGcAnlyJM_Z9aXf2sUVGLpJk7Gg70uCl7pQ0b1qyPEd1XwbJXSwE/s800/SP_CarrierXL.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;421&quot; data-original-width=&quot;800&quot; height=&quot;336&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiWKgdIuhyS_FG0z-AgfpD4yE_3zVgYIaFcbeoFRkRTKQlMnrgi0mo4Z6OTy15MB5BdZQoH7bXkPvUrgAQCgvizB4brkr0bYbucBojBTxuZvNHTkLA1MM12Uwk2p_y5vMmQJZHDZnMDGcAnlyJM_Z9aXf2sUVGLpJk7Gg70uCl7pQ0b1qyPEd1XwbJXSwE/w640-h336/SP_CarrierXL.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;The RP2350 Stamp XL installed into the RP2xxx Stamp Carrier XL&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;p&gt;&lt;b&gt;&lt;span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;&lt;b&gt;RP2350 Stamp&lt;/b&gt;&lt;/h3&gt;&lt;p&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOq2BuUQChT3U8m70T6c3rO_0kNZWKWwgnkGWO9cQbH7MJbV8LdpI8SreP8_AfjhdjC2Kswy2Q4L1C-Dg2Vu08zdsCASaE6rZ42We5pEX6hAfzNkMcHbci8yugSD8ZLJDtsjm7R4FzxLtzApYf3A80xq-l4WYFJm2zfXqk1xousnQVrryAJi2yZ1MNap0/s600/SP_RP2350Stamp.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;567&quot; data-original-width=&quot;600&quot; height=&quot;302&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOq2BuUQChT3U8m70T6c3rO_0kNZWKWwgnkGWO9cQbH7MJbV8LdpI8SreP8_AfjhdjC2Kswy2Q4L1C-Dg2Vu08zdsCASaE6rZ42We5pEX6hAfzNkMcHbci8yugSD8ZLJDtsjm7R4FzxLtzApYf3A80xq-l4WYFJm2zfXqk1xousnQVrryAJi2yZ1MNap0/s320/SP_RP2350Stamp.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;This is a small board, measuring 1&quot; by 1&quot;. Along a RP2350A, it contains quite a lot of stuff:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;16M of Flash&lt;/li&gt;&lt;li&gt;LDO voltage regulator, supplying 3.3V @ 500mA&lt;/li&gt;&lt;li&gt;LIPO battery support, including charging&lt;/li&gt;&lt;li&gt;Boot and Reset buttons&lt;/li&gt;&lt;li&gt;12MHz crystal&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The pins on the edge include the 30 GPIO pins, USB, power, and SWD. The pinout is the same as the RP2040 model.&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;&lt;b&gt;RP2350 Stamp XL&lt;/b&gt;&lt;/h3&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgyM1_My1fVyGNTGMR2vxrGA73csNNx9_eS_Wzvv3xK4OdwVtNftpaCfZnNMW3-egHhlUAWkj8V2SrD35sCFBeVb-5yQa9CO53SNGjas-4ZsjIDum40ta3nHMl21ATrq7InGsdmCE7cUWq1f_K3mtyoOVE0IELIenW_CsDzU0t67bhScqGjbAd8dKPh7F0/s800/SP_RP2350StampXL.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;442&quot; data-original-width=&quot;800&quot; height=&quot;221&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgyM1_My1fVyGNTGMR2vxrGA73csNNx9_eS_Wzvv3xK4OdwVtNftpaCfZnNMW3-egHhlUAWkj8V2SrD35sCFBeVb-5yQa9CO53SNGjas-4ZsjIDum40ta3nHMl21ATrq7InGsdmCE7cUWq1f_K3mtyoOVE0IELIenW_CsDzU0t67bhScqGjbAd8dKPh7F0/w400-h221/SP_RP2350StampXL.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This model is slightly larger, measuring 1&quot; by 1.75&quot;. The main difference is that it uses the RP2350B, which adds 18 more GPIO pins. In addition, it:&lt;/div&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Has pads for the standard Raspberry Pi connectors for SWD (debug) and UART&lt;/li&gt;&lt;li&gt;Space to solder a second Flash or PSRAM&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;&lt;b&gt;RP2040 Stamp Carrier&lt;/b&gt;&lt;/h3&gt;&lt;p&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4jz3Egtk8q7TxIufANPYsAdaC_GiWGiTUAf4GizA58AONVBdgoAcd2H3ksRLnVegjbEDtt2w1wijRN5SVkyT_LeCyOt0oux7PO64ftkuQ0iPZwaimkHvcqDx-tac4tK_leDut1NMVYhjJycWAbkfKGxkUbP_aqtWTwmj-dKBpEuaXNTnWWj2y8VHTjG0/s600/SP_RP2040Carrier.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;458&quot; data-original-width=&quot;600&quot; height=&quot;305&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4jz3Egtk8q7TxIufANPYsAdaC_GiWGiTUAf4GizA58AONVBdgoAcd2H3ksRLnVegjbEDtt2w1wijRN5SVkyT_LeCyOt0oux7PO64ftkuQ0iPZwaimkHvcqDx-tac4tK_leDut1NMVYhjJycWAbkfKGxkUbP_aqtWTwmj-dKBpEuaXNTnWWj2y8VHTjG0/w400-h305/SP_RP2040Carrier.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;The stamp (RP2040 or RP2350) can be connected by direct soldering or using connectors with 2 mm spacing.&lt;/p&gt;&lt;p&gt;The board follows the format and pinout of the Uno R3, but with pins working at 3.3 V. It has:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Boot and Reset buttons at the edges&lt;/li&gt;&lt;li&gt;USB-C connector&lt;/li&gt;&lt;li&gt;Power barrel connector (7 to 12 VDC)&lt;/li&gt;&lt;li&gt;Connector (non-standard) for SWD&lt;/li&gt;&lt;li&gt;Connector for LIPO battery&lt;/li&gt;&lt;li&gt;LED&lt;/li&gt;&lt;li&gt;Standard Qwiic I2C connector&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;The through-hole connectors are supplied with the board, but not soldered.&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;&lt;b&gt;RP2040 Stamp Round Carrier&lt;/b&gt;&lt;/h3&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi43BRIwGJW2-QJeCqvY9EmUz6B-PQ-OvrhXkiZpbqrFLLvn-twckbwufurhnwAM6Vc0XrthUEjGQY9ITwpIMeCF3Q-g-arDHcgdOwaoXodGV9PA6s90J9rAUP6qocwsRouHYJeHHBzP58YLi6dPortXE73nwBjbrQvgifZj8aGfKTkR8fHQHUPhpzvCr4/s600/SP_RoundCarrier.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;590&quot; data-original-width=&quot;600&quot; height=&quot;315&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi43BRIwGJW2-QJeCqvY9EmUz6B-PQ-OvrhXkiZpbqrFLLvn-twckbwufurhnwAM6Vc0XrthUEjGQY9ITwpIMeCF3Q-g-arDHcgdOwaoXodGV9PA6s90J9rAUP6qocwsRouHYJeHHBzP58YLi6dPortXE73nwBjbrQvgifZj8aGfKTkR8fHQHUPhpzvCr4/s320/SP_RoundCarrier.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;The Round Carrier is, as the name suggests, a circular board containing 16 WS2812B RGB LEDs. The stamp (RP2040 or RP2350) can be connected by direct soldering, using connectors with 2 mm spacing, or using &lt;b&gt;FlexyPins&lt;/b&gt; (which I will describe later).&lt;/p&gt;&lt;p&gt;The board has holes on the edge for connection using alligator clips and:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;A USB-C connector&lt;/li&gt;&lt;li&gt;One normal LED&lt;/li&gt;&lt;li&gt;A on/off switch&lt;/li&gt;&lt;li&gt;A LIPO battery connector&lt;/li&gt;&lt;li&gt;Two user buttons&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;&lt;b&gt;RP2xxx Stamp Carrier XL&lt;/b&gt;&lt;/h3&gt;&lt;p&gt;This model is the only one that supports the RP2350 Stamp XL. It can also be used with the RP2040 and RP2350 Stamps, but then several pins will be disconnected. The stamp connection can be made by direct soldering, using connectors with 2 mm spacing, or using FlexyPins.&lt;/p&gt;&lt;p&gt;The board has the dimensions of the Arduino Mega/Due, but with pins working at 3.3V and without the double row of pins on the opposite end to the USB connector. It has:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Boot and Reset buttons&lt;/li&gt;&lt;li&gt;USB-C and USB-A connectors&lt;/li&gt;&lt;li&gt;A power barrel connector (7 to 12 VDC)&lt;/li&gt;&lt;li&gt;A micro SD card socket&lt;/li&gt;&lt;li&gt;Standard Raspberry Pi connectors for SWD (debug) and UART&lt;/li&gt;&lt;li&gt;A LIPO battery connector&lt;/li&gt;&lt;li&gt;One normal LED&lt;/li&gt;&lt;li&gt;Two user buttons&lt;/li&gt;&lt;li&gt;A standard Qwiic I2C connector&lt;/li&gt;&lt;li&gt;A micro HDMI connector for use with the RP2350 HSTX peripheral&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;The through-hole connectors are supplied with the board, but not soldered.&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;&lt;b&gt;FlexyPin&lt;/b&gt;&lt;/h3&gt;&lt;div&gt;The purpose of FlexyPins is to provide a solderless connection of the stamp board to the carrier. This allows for quick and easy stamp replacement.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhs0zYV4GEbFlllhJBbyv_kQm-WcdU5juFczzOi84OUENr7TJ776wvGgjAsOGjuYRNbSPJeGk58YMdsuk6WkC-c9To0NbSzBDTRL5pvJCPwEMRspX_79MY99gN0oFpyWADnUv8_iEVgJ_a__MjWGftSh4DTWy-pggoxAm1Xa1vsJFARPE-Gc6iay3SOrMI/s4624/20250315_100134.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;4624&quot; data-original-width=&quot;3468&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhs0zYV4GEbFlllhJBbyv_kQm-WcdU5juFczzOi84OUENr7TJ776wvGgjAsOGjuYRNbSPJeGk58YMdsuk6WkC-c9To0NbSzBDTRL5pvJCPwEMRspX_79MY99gN0oFpyWADnUv8_iEVgJ_a__MjWGftSh4DTWy-pggoxAm1Xa1vsJFARPE-Gc6iay3SOrMI/s320/20250315_100134.jpg&quot; width=&quot;240&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;When I first bought the boards from Solder Party, FlexyPins were out of stock. I ended up soldering an RP2350 stamp to the Round Carrier. When I managed to buy the FlexyPins, there was only one option left: the Carrier XL. Here&#39;s the first catch: when soldering the FlexiPins, you decide what type of stamp you&#39;re going to use (normal or XL).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Soldering the pins is quite laborious and slow. The biggest problem is fitting the pin to the board. Over time, I got the hang of it. But even so, the pins would sometimes rebel. Soldering is easier if you fit and solder the pins one by one. If you fit several before soldering, the access by the soldering iron becomes more restricted.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The first impression was that the spring force was insufficient, but the board worked properly.&lt;/div&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;&lt;b&gt;Verdict&lt;/b&gt;&lt;/h3&gt;&lt;div&gt;As I said at the beginning, these are somewhat peculiar boards. The 2mm spacing on the stamp boards is annoying, and I&#39;m not entirely convinced of the benefits of FlexyPins. On the other hand, stamps and carriers have several useful features, such as LIPO battery support.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The RP2350 Stamp XL and RP2xxx Stamp Carrier XL combination is a great option for studying video generation using the RP2350&#39;s HSTX and the additional GPIO pins of the RP2350B.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;</description><link>https://raspico.blogspot.com/2025/03/mini-review-solder-partys-rp2350-boards.html</link><author>noreply@blogger.com (Daniel Quadros)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiWKgdIuhyS_FG0z-AgfpD4yE_3zVgYIaFcbeoFRkRTKQlMnrgi0mo4Z6OTy15MB5BdZQoH7bXkPvUrgAQCgvizB4brkr0bYbucBojBTxuZvNHTkLA1MM12Uwk2p_y5vMmQJZHDZnMDGcAnlyJM_Z9aXf2sUVGLpJk7Gg70uCl7pQ0b1qyPEd1XwbJXSwE/s72-w640-h336-c/SP_CarrierXL.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7859657580199211900.post-8341740718224282303</guid><pubDate>Mon, 23 Dec 2024 10:00:00 +0000</pubDate><atom:updated>2024-12-23T02:00:00.120-08:00</atom:updated><title>Using an RP2040  to Load Programs from a SD Card into a ZX81 Microcomputer</title><description>This was a fun project, putting together my old and new hobbies. Back in the 80s, cheap personal computers used K7 tape to store programs. I still got a few of these old computers, but tape is pretty rare these days and my K7 players are breaking apart. You can find a lot of ZX81 software in the internet, as files for emulators. How about using an RP2040 to generate the necessary audio signals from these files?&lt;div&gt;&lt;br /&gt;&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXDtIUrZB3QirgDLmcSDPe0Hp60WfifhmIj6QGBNK1tztz-NsV1PMyRZE_q2Kx-lqniIFwf6mmpeK3xLKNlfS7a6XP7wvLtZBu-8jIx2MkI9IbHogo6IaY9uchI6I4jBaeXSYsG-HlyZZfnotGrQPPYfP5AxtaXrRHMptbNXKlqWNPXueieNBMnxeIPGo/s2000/PicoK7.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1116&quot; data-original-width=&quot;2000&quot; height=&quot;179&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXDtIUrZB3QirgDLmcSDPe0Hp60WfifhmIj6QGBNK1tztz-NsV1PMyRZE_q2Kx-lqniIFwf6mmpeK3xLKNlfS7a6XP7wvLtZBu-8jIx2MkI9IbHogo6IaY9uchI6I4jBaeXSYsG-HlyZZfnotGrQPPYfP5AxtaXrRHMptbNXKlqWNPXueieNBMnxeIPGo/s320/PicoK7.jpg&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;The final assembly&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;span&gt;&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;/span&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;How the ZX81 Loads and Stores Programs&lt;/h3&gt;&lt;/div&gt;&lt;div&gt;The ZX81 microcomputer was as frugal as it comes. Using only 4 chips (a Z80 microcontroller, an 8K ROM, a 1K RAM and a custom chip known as &quot;ULA&quot;), it can be connected to a TV and includes a very quirky BASIC interpreter.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;With cycles and ROM bytes at a premium, saving and loading was done by small loops in the BASIC interpreter (written in assembly). At the lower level, 0 and 1 bits are coded as sequences of pulses (4 pulses for a 0, 9 pulses for a 1), followed by a short period of silence. There is no special mark between bytes or signaling the start of a byte. What is saved? First there is the program name, with the last character with the high bit at 1. Then a dump of most of the memory, including some system variables, the screen, the BASIC program, and the BASIC variables (so a loaded program could just resume operation from where it was when a SAVE command was executed).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgn6NY98PJM0GINYEe__se_lIgE8P500hLci_t0a4WxR5_D81szRs12tJv5MJmQ_twdZuvYtAxCHZzKz0IDxLrg76v03FanMu0rwtisdx4ijxB-Bnz_M5usKvfmLR2P5Ojbcef8Z8S_nYDkFXCe5Fksp2HM48DBIw7FlUVTFAAqFtW91ej4R-diSdWY5nw/s2000/PicoK7_v1.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;657&quot; data-original-width=&quot;2000&quot; height=&quot;131&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgn6NY98PJM0GINYEe__se_lIgE8P500hLci_t0a4WxR5_D81szRs12tJv5MJmQ_twdZuvYtAxCHZzKz0IDxLrg76v03FanMu0rwtisdx4ijxB-Bnz_M5usKvfmLR2P5Ojbcef8Z8S_nYDkFXCe5Fksp2HM48DBIw7FlUVTFAAqFtW91ej4R-diSdWY5nw/w400-h131/PicoK7_v1.jpg&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;Testing using a Brazilian ZX81 clone&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The usual format for the program files on the internet (.P files) is just the memory dump (sometimes with garbage at the end).&lt;/div&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;The Hardware&lt;/h3&gt;&lt;div&gt;In the final assembly I used an RP2040 Zero from Waveshare, during developing I used a Raspberry Pi Pico (for easy access to the debugging pins). An LCD display and a rotary encoder is used for user interaction and an SD module is used for reading the SD card.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;A single NPN transistor is used to interface the RP2040&#39;s signal to the tape input in the ZX81.&lt;/div&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;The Software&lt;/h3&gt;&lt;div&gt;Here is where the fun comes! I used an existing library (&lt;span style=&quot;background-color: white; color: #222222; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13.2px;&quot;&gt;&amp;nbsp;&quot;&lt;/span&gt;&lt;a href=&quot;https://github.com/carlk3/no-OS-FatFS-SD-SDIO-SPI-RPi-Pico&quot; style=&quot;background-color: white; color: #2288bb; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13.2px; text-decoration-line: none;&quot;&gt;no-OS-FatFS-SD-SDIO-SPI-RPi-Pico&lt;/a&gt;&lt;span style=&quot;background-color: white; color: #222222; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13.2px;&quot;&gt;&quot;&lt;/span&gt;) is used to read the files from the SD card. I already had code for the display and rotary encoder.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;That leaves the pulse generation. For a first test, I just used delay calls to timing, but I could not resist using the PIO for this task. Using the PIO I just load bytes into the PIO FIFO and it takes care of shifting the bits and generating the pulses. This eases the time constrains on my code and allows to show the progress on the LCD.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In the end, I used three PIO programs: one for the pulse generation, one for reading the rotary encoder, and one for controlling the RGB LED on the RP2040 Zero.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The full project is available at&amp;nbsp;&lt;a href=&quot;https://github.com/dquadros/PicoK7&quot; style=&quot;background-color: white; color: #2288bb; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13.2px; text-decoration-line: none;&quot;&gt;https://github.com/dquadros/PicoK7&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;</description><link>https://raspico.blogspot.com/2024/12/using-rp2040-to-load-programs-from-sd.html</link><author>noreply@blogger.com (Daniel Quadros)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXDtIUrZB3QirgDLmcSDPe0Hp60WfifhmIj6QGBNK1tztz-NsV1PMyRZE_q2Kx-lqniIFwf6mmpeK3xLKNlfS7a6XP7wvLtZBu-8jIx2MkI9IbHogo6IaY9uchI6I4jBaeXSYsG-HlyZZfnotGrQPPYfP5AxtaXrRHMptbNXKlqWNPXueieNBMnxeIPGo/s72-c/PicoK7.jpg" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7859657580199211900.post-2922399475974089721</guid><pubDate>Mon, 11 Nov 2024 13:30:00 +0000</pubDate><atom:updated>2024-11-11T05:30:00.116-08:00</atom:updated><title>I2C Pico USB Adapter: Part 4 - Usage</title><description>&lt;p&gt;In this last part, I will show a few ways to use the adapter under Linux and Windows.&lt;/p&gt;&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzqqXk9vzWbJa_P8-SwtuR5iZidkfnVslDLABQ19TZU37h5R_h9PB8vcAPr4N_EPTRKqBfsT_KzP55pkEtjMa0V18iBYB4rRGYdG4fufGVi3uQctKWUA7IW9oJERNS1nhSBmA3RO88ehqdgMArrzile3qS03OfAEfTA2w7dUod1i7iMcGzJEvGy2b-ZYY/s952/i2cpico_Windows2.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;916&quot; data-original-width=&quot;952&quot; height=&quot;308&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzqqXk9vzWbJa_P8-SwtuR5iZidkfnVslDLABQ19TZU37h5R_h9PB8vcAPr4N_EPTRKqBfsT_KzP55pkEtjMa0V18iBYB4rRGYdG4fufGVi3uQctKWUA7IW9oJERNS1nhSBmA3RO88ehqdgMArrzile3qS03OfAEfTA2w7dUod1i7iMcGzJEvGy2b-ZYY/s320/i2cpico_Windows2.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;Accessing an I2C device with Python, under Windows&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;span&gt;&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;/span&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;Linux&lt;/h3&gt;&lt;p&gt;The i2c-tiny-usb started under Linux, and a driver is standard on Linux.&lt;/p&gt;&lt;p&gt;A few utilities are available in the i2c-tools package (you probably will need to install it with your distro&#39;s package manager). To check if the adapter is working and recognized use&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;sudo i2cdetect -l&lt;/span&gt;&lt;/p&gt;&lt;p&gt;The output should include a line like &quot;i2c-n i2c-tiny-usb at ...&quot;, where &#39;n&#39;&amp;nbsp;
is a number that identifies the I2CBUS. You will use this number in other i2c-tools commands. To check the address of connected devices, use&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;sudo i2c-detect n&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
You will first get a warning that probing for i2c devices can have bad effects on some devices, you can use the &lt;span style=&quot;font-family: courier;&quot;&gt;-y&lt;/span&gt; option to suppress this warning.&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6qOtp8Hqh__82GiNbZThYjvxTI61RWnUkVWLz_m3L7FR1P9X2D73OOMrITe_v0BLNUISnNL5VkC63_Gigxo5X9cLsX5HHMtZVI61CXQpkK1lmxsFlHk_7eLuLICt1v07r5svnu6DyQ-i77ya7i5DMkRmCSKrR_0B-m5b9iOqwQhejfhx2MNvruf7q9S8/s901/i2cpico_Linux_2.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;562&quot; data-original-width=&quot;901&quot; height=&quot;200&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6qOtp8Hqh__82GiNbZThYjvxTI61RWnUkVWLz_m3L7FR1P9X2D73OOMrITe_v0BLNUISnNL5VkC63_Gigxo5X9cLsX5HHMtZVI61CXQpkK1lmxsFlHk_7eLuLICt1v07r5svnu6DyQ-i77ya7i5DMkRmCSKrR_0B-m5b9iOqwQhejfhx2MNvruf7q9S8/s320/i2cpico_Linux_2.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;The &#39;i2c-get&#39;&amp;nbsp;and &#39;i2c-put&#39;&amp;nbsp;commands can be used to read and write to and from I2C devices that use the concept of registers, where a read is preceded by a write of the register&#39;s address (form 0x00 to 0xFF).&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEisx4zjNcD58E9DlxPS-lcsrKrAmXP6kmeHgyEmgKd3XqDie73KaqbWaFS7F6gTb5XY1mAn-QFctpE0fw7yV8jpz7K-ENiwBiwiHfGdHBGlc-gLW_Zy81Tkyc1l_8MmHNPdGMTEJZJ-V39euvbCm8MLUvxy-4O_q89diEjPBe1reYWetbxKsorkw1L_i_M/s901/i2cpico_Linux_3.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;562&quot; data-original-width=&quot;901&quot; height=&quot;200&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEisx4zjNcD58E9DlxPS-lcsrKrAmXP6kmeHgyEmgKd3XqDie73KaqbWaFS7F6gTb5XY1mAn-QFctpE0fw7yV8jpz7K-ENiwBiwiHfGdHBGlc-gLW_Zy81Tkyc1l_8MmHNPdGMTEJZJ-V39euvbCm8MLUvxy-4O_q89diEjPBe1reYWetbxKsorkw1L_i_M/s320/i2cpico_Linux_3.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;Details for the i2c-tools commands can be found on the man pages.&lt;/p&gt;&lt;p&gt;Like most devices, the i2cbus can be accessed like a file. The name is &#39;&lt;span style=&quot;font-family: courier;&quot;&gt;/dev/i2c-n&lt;/span&gt;&#39;, and there are a few ioctl functions available. Documentation can be found at&amp;nbsp;&lt;a href=&quot;https://www.kernel.org/doc/Documentation/i2c/dev-interface&quot;&gt;https://www.kernel.org/doc/Documentation/i2c/dev-interface&lt;/a&gt;. It is not hard to write small C programs to interact with I2C devices.&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;Windows&lt;/h3&gt;&lt;p&gt;Windows does not have built-in support for the adapter, but we can still use it.&amp;nbsp;
You will need to install a driver (libusb) for the adapter. The easiest way is to use Zadig (&lt;a href=&quot;https://zadig.akeo.ie/&quot;&gt;https://zadig.akeo.ie/&lt;/a&gt;). Plug the adapter, run Zadig, and select &quot;libusb-win32&quot;.&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVsRPhNq5dGJj-6oBqXk7HsYGfAGjkn69BjelUeWK1oYavtbFtDBdd46nCCu3hsbW2bGrVUR2Vseql6_FG7KYDbPJ6QX1HWfN2UIVOZrPmIV8QiX2Tn4xfDttT3rg9P72Y0TfOsCR5MFNtPOqdkDX7mm3FZzaQMKkXooSylgRlplcEI5b3frI8CINbrcI/s782/i2cpico_Windows1.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;550&quot; data-original-width=&quot;782&quot; height=&quot;225&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVsRPhNq5dGJj-6oBqXk7HsYGfAGjkn69BjelUeWK1oYavtbFtDBdd46nCCu3hsbW2bGrVUR2Vseql6_FG7KYDbPJ6QX1HWfN2UIVOZrPmIV8QiX2Tn4xfDttT3rg9P72Y0TfOsCR5MFNtPOqdkDX7mm3FZzaQMKkXooSylgRlplcEI5b3frI8CINbrcI/s320/i2cpico_Windows1.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;There are many ways to use libusb under Windows. In my testing, I used PyUSB (&lt;a href=&quot;https://github.com/pyusb/pyusb&quot;&gt;https://github.com/pyusb/pyusb&lt;/a&gt;) with Python 3. Notice that this is a low-level API that just gives access to the adapter&#39;s endpoints.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description><link>https://raspico.blogspot.com/2024/11/i2c-pico-usb-adapter-part-4-usage.html</link><author>noreply@blogger.com (Daniel Quadros)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzqqXk9vzWbJa_P8-SwtuR5iZidkfnVslDLABQ19TZU37h5R_h9PB8vcAPr4N_EPTRKqBfsT_KzP55pkEtjMa0V18iBYB4rRGYdG4fufGVi3uQctKWUA7IW9oJERNS1nhSBmA3RO88ehqdgMArrzile3qS03OfAEfTA2w7dUod1i7iMcGzJEvGy2b-ZYY/s72-c/i2cpico_Windows2.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7859657580199211900.post-4827108723450651250</guid><pubDate>Thu, 31 Oct 2024 10:00:00 +0000</pubDate><atom:updated>2024-10-31T03:00:00.117-07:00</atom:updated><title>I2C Pico USB Adapter: Part 3 - I2C</title><description>I expected implementing the I2C communication would be very easy. After all, the RP microcontrollers have hardware for this and the SDK has support for it. Alas, I did not take into account some limitations of the hardware and the way i2c-tiny-usb implements its commands.&lt;div&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjT4xyVE4ZCYBGn4UFYvVZbOZhcke_uJ6x40bXpC-FZ23loWj3tPOYhFlYyj0Q1_aDyWqqsxWRbBEyH-kNF6jz3di3XEJmr31imnO8xd5sYkPkBLl35G_YaDmGyD6qdYa79HlzKleBpbiVYNWxEt8TjuSAI97aVt2efAQKK06e3LPx5p02-FwM3FTCp3dw/s646/i2c_topology.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;486&quot; data-original-width=&quot;646&quot; height=&quot;241&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjT4xyVE4ZCYBGn4UFYvVZbOZhcke_uJ6x40bXpC-FZ23loWj3tPOYhFlYyj0Q1_aDyWqqsxWRbBEyH-kNF6jz3di3XEJmr31imnO8xd5sYkPkBLl35G_YaDmGyD6qdYa79HlzKleBpbiVYNWxEt8TjuSAI97aVt2efAQKK06e3LPx5p02-FwM3FTCp3dw/s320/i2c_topology.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;span&gt;&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;/span&gt;&lt;div&gt;As a quick refresh, I2C is a serial protocol over two wires, one for clock (SCL) e the other for data (SDA). SCL is always controlled by the master (the microcontroller), SDA can be controlled by the master or the slave. Both signals are normally high, thanks to pullup resistors. During normal communication, SDA only changes when SCL is low. The exceptions mark the beginning (START) and ending (STOP) of an I2C transaction.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The first byte sent by the master after a START condition is a 7 bit address plus a 1 bit read/write indicator. The device with the corresponding address (if there is one)&amp;nbsp; acknowledges this byte. Data bytes are sent after the address, each one acknowledged by the receiver.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimuJIp9YzbYMki6nTby_msf4zBa1SNHy8fAA7JJwFiMVXp58J9T4CpQWKwhB6og9g1cXJ5m-PnvQGnQ2HNUBMAXIiLMfd193B3jXT_zGxxfB3FXMACG38pG5HrCiye_7gMIattyhZchcCPw-QI35L_PRz8tjj6PcxE4YqQhdvYYVEbc_cNjCpaknjuVsg/s714/cap10_i2c_write.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;234&quot; data-original-width=&quot;714&quot; height=&quot;131&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimuJIp9YzbYMki6nTby_msf4zBa1SNHy8fAA7JJwFiMVXp58J9T4CpQWKwhB6og9g1cXJ5m-PnvQGnQ2HNUBMAXIiLMfd193B3jXT_zGxxfB3FXMACG38pG5HrCiye_7gMIattyhZchcCPw-QI35L_PRz8tjj6PcxE4YqQhdvYYVEbc_cNjCpaknjuVsg/w400-h131/cap10_i2c_write.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;As we saw in the previous post, the address byte is sent when we get the I2C_IO command in the SETUP stage, if it is a read, we then get the data from the I2C device; if it is a write, we wait until the DATA stage to send the data.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;A special case is when there is no data to send or receive. This is used (as a hack) to check if there is a device with some address in the I2C bus. I say hack, because it is not part of the specification, and some devices will take some action when they are addressed, even before any data is transferred. For this reason, it is more common to use a zero-byte write operation instead of a zero-byte read operation.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The problem with the RP&#39;s I2C peripheral is that it automatically emits the START and the address&amp;nbsp;when data is written. You do not have much control over the START and STOP conditions and cannot do zero-byte writes.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The solution is to do as i2c-tiny-usb does: implement I2C manually, using GPIO functions. Something I had done a long time ago, when I used PIC microcontrollers.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;</description><link>https://raspico.blogspot.com/2024/10/i2c-pico-usb-adapter-part-3-i2c.html</link><author>noreply@blogger.com (Daniel Quadros)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjT4xyVE4ZCYBGn4UFYvVZbOZhcke_uJ6x40bXpC-FZ23loWj3tPOYhFlYyj0Q1_aDyWqqsxWRbBEyH-kNF6jz3di3XEJmr31imnO8xd5sYkPkBLl35G_YaDmGyD6qdYa79HlzKleBpbiVYNWxEt8TjuSAI97aVt2efAQKK06e3LPx5p02-FwM3FTCp3dw/s72-c/i2c_topology.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7859657580199211900.post-2869586993416742020</guid><pubDate>Mon, 28 Oct 2024 10:00:00 +0000</pubDate><atom:updated>2024-10-28T03:00:00.241-07:00</atom:updated><title>I2C Pico USB Adapter: Part 2 - USB Communication</title><description>The USB standard is complex. Even having studied it hard for my book on the RP2040, I admit I was sometimes confused. This particular application involves some functions of the tinyusb library that are not much discussed in the documentation.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgRk9IgtdcjYz4CiRCTzQX3v85T36C9pytx2pA85pjlpPfT74k2jziVhU31qajuB2FwwHZWUDm7QxHsqMFvDnIqbRHqG-HFEHVbtGlE1nbrCaMTrAMtiuTgGeIplb3nykLJnWwSZrUjCnO4hLNY9b1zGdq70MtIzVaQOe0UXA0nWNNaIhLFxAYneYk46Lo/s764/USB_Control_Transfers.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;310&quot; data-original-width=&quot;764&quot; height=&quot;163&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgRk9IgtdcjYz4CiRCTzQX3v85T36C9pytx2pA85pjlpPfT74k2jziVhU31qajuB2FwwHZWUDm7QxHsqMFvDnIqbRHqG-HFEHVbtGlE1nbrCaMTrAMtiuTgGeIplb3nykLJnWwSZrUjCnO4hLNY9b1zGdq70MtIzVaQOe0UXA0nWNNaIhLFxAYneYk46Lo/w400-h163/USB_Control_Transfers.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;USB Control Transfers,&amp;nbsp;Taken from Figure 8-37 of the USB 2.0 specifications&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;span&gt;&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;/span&gt;&lt;div&gt;Let&#39;s start from the beginning. USB devices are grouped into&amp;nbsp;&lt;i&gt;classes&lt;/i&gt;. The I2C adapter is in the &lt;i&gt;vendor&lt;/i&gt; class, meaning it does not follow a standard set of messages (like HID or serial devices). There are a few ways USB devices can transfer data, the I2C adapter uses &lt;i&gt;control transfers&lt;/i&gt;. These transfers have a very limited payload, but are easier to implement (that makes a lot of sense when you are bit-banging the protocol in a 12 MHz 8-bit microcontroller).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The first thing needed to implement a USB device is to create a handful of &lt;i&gt;descriptors&lt;/i&gt;. These are structures that inform the PC what the device is, what it does, and how to communicate with it. Two important pieces of information are the vendor and product IDs; I used the same ones as the original i2c-tiny-usb, so I can use the same drivers (note that you should not do this if you intend to manufacture and distribute the adapter). As said, the class of the device is &lt;i&gt;vendor&lt;/i&gt;, it has only one interface with the two standard endpoints (one for input and the other for output).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Messages sent through control transfers have a fixed format but the interpretation of the fields is up to the device. In this case, one of the fields contains a command:&lt;/div&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;&lt;b&gt;Echo&lt;/b&gt; sends back information in the received message&lt;/li&gt;&lt;li&gt;&lt;b&gt;Get_Func&lt;/b&gt; asks for what capabilities our implementation support&lt;/li&gt;&lt;li&gt;&lt;b&gt;Set_Delay&lt;/b&gt; defines the clock frequency for the I2C bus (I am ignoring this for now)&lt;/li&gt;&lt;li&gt;&lt;b&gt;I2C_IO&lt;/b&gt; transfers data to or from an I2C device. Flags in this command control the generation of START and END conditions (more on this in the next part)&lt;/li&gt;&lt;li&gt;Status sends back the result of the previous command&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;In the USB protocol, control transfers have three stages: SETUP, DATA (optional), and STATUS. One confusing thing in tinyusb is when your code is called and what you should do at each stage.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The routine you need to code is&amp;nbsp;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;b&gt;tud_vendor_control_xfer_cb()&lt;/b&gt;&lt;/span&gt;; one of its parameters in the stage:&lt;/div&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;&lt;b&gt;SETUP&lt;/b&gt; means that the command has been received and you should set up the answer you will send. If the command is&amp;nbsp; I2C_IO, send the I2C address to the I2C device and check for the device acknowledgment. If the command is an I2C read, perform the reading and pass the result back to tinyusb for transmission.&lt;/li&gt;&lt;li&gt;&lt;b&gt;DATA&lt;/b&gt; means that the data transfer is done. If the command was an I2C write, now you can get the data to write from tinyusb (it took me some time to realize this).&lt;/li&gt;&lt;li&gt;&lt;b&gt;STATUS &lt;/b&gt;means the transfer is completed, nothing needs to be done.&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;You can see the full code at github:&amp;nbsp;&lt;a href=&quot;https://github.com/dquadros/I2C-Pico-USB&quot;&gt;https://github.com/dquadros/I2C-Pico-USB&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;</description><link>https://raspico.blogspot.com/2024/10/i2c-pico-usb-adapter-part-2-usb.html</link><author>noreply@blogger.com (Daniel Quadros)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgRk9IgtdcjYz4CiRCTzQX3v85T36C9pytx2pA85pjlpPfT74k2jziVhU31qajuB2FwwHZWUDm7QxHsqMFvDnIqbRHqG-HFEHVbtGlE1nbrCaMTrAMtiuTgGeIplb3nykLJnWwSZrUjCnO4hLNY9b1zGdq70MtIzVaQOe0UXA0nWNNaIhLFxAYneYk46Lo/s72-w400-h163-c/USB_Control_Transfers.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7859657580199211900.post-7806575758243490861</guid><pubDate>Fri, 25 Oct 2024 21:40:00 +0000</pubDate><atom:updated>2024-10-25T14:40:08.582-07:00</atom:updated><title>Halloween with MicroPython</title><description>&lt;p&gt;This is a quick Halloween project (if you have the parts, they are easy to find).&amp;nbsp; With a little imagination, you can adapt it to different components or behaviors. The software is written in MicroPython for a RP2040 (or RP2350), you can port it to other boards by replacing the PIO code for the HC-SR04 sensor with normal GPIO operations.&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUGw3mQrbs987zc3jH9mNEhrUQmC82woMxBsvX7WcwNEu17coUn3_J5j91dfLSJseI_3RcovCa6jC5rLFk3QSvwnHxqKTxBHIUptTQZEOGUFOZWdlxavF2ZX_tTLyUjcV5-5JyIn6V_NBs4DdQERf16Z8D-Bw7ukY0fBJqxhSP2JzbODGb_jS9G4uZN1c/s1301/Skull_1.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1301&quot; data-original-width=&quot;1200&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUGw3mQrbs987zc3jH9mNEhrUQmC82woMxBsvX7WcwNEu17coUn3_J5j91dfLSJseI_3RcovCa6jC5rLFk3QSvwnHxqKTxBHIUptTQZEOGUFOZWdlxavF2ZX_tTLyUjcV5-5JyIn6V_NBs4DdQERf16Z8D-Bw7ukY0fBJqxhSP2JzbODGb_jS9G4uZN1c/s320/Skull_1.png&quot; width=&quot;295&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;A resin skull (bought in a trinket store) is transformed into a spooked object that lights up and makes strange noises, especially when someone nears it.&lt;/p&gt;&lt;span&gt;&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;/span&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;What you need&lt;/h3&gt;&lt;p&gt;Here is a list of the parts needed for this project&lt;br /&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;An RP2040 (or RP2350) board. We will use one UART and four GPIOs pins. The Pico or Pico2 works fine. A &lt;a href=&quot;https://raspico.blogspot.com/2022/05/mini-reviews-waveshare-rp2040-zero-and.html&quot;&gt;XIAO RP2040 or RP2040 Zero&lt;/a&gt;&amp;nbsp;is a very compact option. In the pictures, I am using a Feather RP2040 that has battery support&lt;/li&gt;&lt;li&gt;Three WS2812B RGB LEDs (or more)&lt;/li&gt;&lt;li&gt;An HC-SR04 ultrasound distance sensor&lt;/li&gt;&lt;li&gt;A DFPlayer Mini MP3 Player, a micro SD card, and a small speaker&lt;/li&gt;&lt;/ul&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;Schematic&lt;/h3&gt;&lt;div&gt;The picture below shows the interconnection of the parts:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi29LgnRYJ8zTeq2A1xsFw80BWGKcixnnWAnqEuA8vF3nQlgzbSzIJYEbKk5GxL0K-A_PrV7ZVE_RPsQy4PYGrolpiC1y_OkfsWHP9giTJGTSUZTyWwz2wSq37UuGXRs3piJ25IPdmJYPPzIL3ylNxxM5tyOGo1i8edx7QtsbhxgTKfHa_KlwIk_Liq12I/s1968/assembly_bb.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1242&quot; data-original-width=&quot;1968&quot; height=&quot;253&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi29LgnRYJ8zTeq2A1xsFw80BWGKcixnnWAnqEuA8vF3nQlgzbSzIJYEbKk5GxL0K-A_PrV7ZVE_RPsQy4PYGrolpiC1y_OkfsWHP9giTJGTSUZTyWwz2wSq37UuGXRs3piJ25IPdmJYPPzIL3ylNxxM5tyOGo1i8edx7QtsbhxgTKfHa_KlwIk_Liq12I/w400-h253/assembly_bb.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;Nothing special here, just notice that the HC-SR04 is powered by 5V (I could not get it to work reliably at 3.3V), so a voltage divisor is used in the Echo signal.&lt;/div&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;Mechanical Assembly&lt;/h3&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;The details for the mechanical assembly will depend on the particular skull you got and your skills (or lack of them, as is my case).&lt;/p&gt;&lt;p&gt;For easy access to the skull&#39;s interior, I use a hole saw to make a big opening at the bottom. Small holes were made at the eyes, and two RGB LEDs were fixed with hot glue, the third LED was fixed at the back with tape.&lt;/p&gt;&lt;p&gt;The main circuit was housed in a cardboard box used as a base for the skull. Holes were made for the sensor, speaker, and USB cable. If you power the board with a battery or USB power bank, you may do without the hole for the USB cable.&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjr-vGMtw6gB_2w2ZxtUKOrFNtXHs00dATGq6Rmu9XHCow9lI85a_V1-178-3JfqkAqyin1gLI9L9JUxDZw13F2MGwg4pi9NPZLagdQEDca0tzbKQ17mmndu4Z0Za7szYmBZJFd35-C_TcPjhJ0gmAEU6dO3D8uBZyhgJq86eqf9QbNONKqvzG2XCubuTE/s1200/Skull_2.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;840&quot; data-original-width=&quot;1200&quot; height=&quot;224&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjr-vGMtw6gB_2w2ZxtUKOrFNtXHs00dATGq6Rmu9XHCow9lI85a_V1-178-3JfqkAqyin1gLI9L9JUxDZw13F2MGwg4pi9NPZLagdQEDca0tzbKQ17mmndu4Z0Za7szYmBZJFd35-C_TcPjhJ0gmAEU6dO3D8uBZyhgJq86eqf9QbNONKqvzG2XCubuTE/s320/Skull_2.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;I used a small breadboard, but you can solder wires for a more definitive and rugged assembly.&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;Software&lt;/h3&gt;&lt;p&gt;You can get the code (and the MP3 files I used) from github:&amp;nbsp;&lt;a href=&quot;https://github.com/dquadros/HalloweenSkull&quot;&gt;https://github.com/dquadros/HalloweenSkull&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Here is a concise explanation of its working:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;The MP3 class controls the MP3 player. The command used plays files named nnnn.mp3 in a mp3 directory on the SD card.&amp;nbsp; The end of the sound is detected by the Busy signal from the player.&lt;/li&gt;&lt;li&gt;The HCSR04 class uses the HCSR04 sensor to measure the distance of an object in front of the sensor. It uses a PIO program to trigger the sensor and measure the time to receive an echo.&lt;/li&gt;&lt;li&gt;The standard neopixel module is used to control the RGB LEDs. It is assumed that the first LED is at the back of the skull and the next two are at the eyes.&lt;/li&gt;&lt;li&gt;The main loop action depends on the distance to the object in front of the sensor:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;If there is something near the sensor (less than 40 cm),&amp;nbsp;the eyes will light up and a sinister laugh will be played&lt;/li&gt;&lt;li&gt;If there is nothing near the sensor, the eyes will randomly blink and a strange voice will sound.&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;Changing the Project&lt;/h3&gt;&lt;p&gt;It should not be hard to make changes to the project. Some ideas:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Change the code to increase or decrease the occurrence of the actions&amp;nbsp;&lt;/li&gt;&lt;li&gt;Change the sounds, by replacing the MP3 files&lt;/li&gt;&lt;li&gt;Increase the number of random sounds, by loading more MP3 files and changing the software&lt;/li&gt;&lt;li&gt;Use another kind of sensor to trigger the lighting of the eyes&lt;/li&gt;&lt;li&gt;Add a servo motor to make something move when someone comes near the skull&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description><link>https://raspico.blogspot.com/2024/10/halloween-with-micropython.html</link><author>noreply@blogger.com (Daniel Quadros)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUGw3mQrbs987zc3jH9mNEhrUQmC82woMxBsvX7WcwNEu17coUn3_J5j91dfLSJseI_3RcovCa6jC5rLFk3QSvwnHxqKTxBHIUptTQZEOGUFOZWdlxavF2ZX_tTLyUjcV5-5JyIn6V_NBs4DdQERf16Z8D-Bw7ukY0fBJqxhSP2JzbODGb_jS9G4uZN1c/s72-c/Skull_1.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7859657580199211900.post-145164440938458956</guid><pubDate>Thu, 24 Oct 2024 10:00:00 +0000</pubDate><atom:updated>2024-10-24T03:00:00.156-07:00</atom:updated><title>I2C Pico USB Adapter: Part 1 - Introduction</title><description>&lt;p&gt;In this series of posts I will describe my latest project: an I2C to USB adapter that can be constructed with an RP2040 or RP2350 board.&lt;/p&gt;&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiMUzIv3OzCInmrp9LYjq8PIo18wGO0MFoyPrhExThP9-69GiiK2Wja7O0WJHvHpJZa75J1LZeerIX-ApXiZzqfZfycSkrbtKIoFgazKYUa_KPD3xHuQ6aryvNzShTdyrT8wTZE4EAza_RcDdmEU8g5BwT5JyhKXs-a2UnA4ZXheShUMYk_q1jJD4DKOew/s1576/i2cpicousb_xiao.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1536&quot; data-original-width=&quot;1576&quot; height=&quot;312&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiMUzIv3OzCInmrp9LYjq8PIo18wGO0MFoyPrhExThP9-69GiiK2Wja7O0WJHvHpJZa75J1LZeerIX-ApXiZzqfZfycSkrbtKIoFgazKYUa_KPD3xHuQ6aryvNzShTdyrT8wTZE4EAza_RcDdmEU8g5BwT5JyhKXs-a2UnA4ZXheShUMYk_q1jJD4DKOew/s320/i2cpicousb_xiao.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;The adapter using a XIAO RP2040 connected to a PCF8583 RTC+RAM&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;span&gt;&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;/span&gt;&lt;p&gt;This project is an adaptation of &lt;a href=&quot;https://github.com/harbaum/I2C-Tiny-USB&quot;&gt;i2c-tiny-usb&lt;/a&gt;, a project with the same goals but built with an ATtiny microcontroller.&lt;/p&gt;&lt;p&gt;The main idea is an adapter that plugs in a PC&#39;s USB port and allows the connection of one or more I2C devices. Programs running on the PC can interact with the I2C devices through USB messages,&lt;/p&gt;&lt;p&gt;When I found the i2c-tiny-usb project, it looked like the RP2040 (or RP2350) would be a good fit, as it is easily available, cheap, and has full USB hardware (USB is implemented in software on the ATtiny by some clever bit-banging). As we will see in the next parts, things were more challenging than I thought.&lt;/p&gt;&lt;p&gt;Only the USB port and a pair of GPIOs are needed for a minimal adapter, so you can use one of the small RP boards if you want a compact device.&lt;/p&gt;&lt;p&gt;For the firmware development, I used the Pico C SDK. As the USB is used for communication with the PC a pico debug probe was very helpful.&lt;/p&gt;&lt;p&gt;Another thing that attracted me to this project is the availability of driver and library support for the adapter under Linux, Windows, and Mac. In the last part of this series we will take a quick look at this (for Linux and Windows, I do not have a Mac).&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description><link>https://raspico.blogspot.com/2024/10/i2c-pico-usb-adapter-part-1-introduction.html</link><author>noreply@blogger.com (Daniel Quadros)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiMUzIv3OzCInmrp9LYjq8PIo18wGO0MFoyPrhExThP9-69GiiK2Wja7O0WJHvHpJZa75J1LZeerIX-ApXiZzqfZfycSkrbtKIoFgazKYUa_KPD3xHuQ6aryvNzShTdyrT8wTZE4EAza_RcDdmEU8g5BwT5JyhKXs-a2UnA4ZXheShUMYk_q1jJD4DKOew/s72-c/i2cpicousb_xiao.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7859657580199211900.post-8711619112600135135</guid><pubDate>Wed, 04 Sep 2024 14:06:00 +0000</pubDate><atom:updated>2024-09-04T07:06:07.950-07:00</atom:updated><title>I found a crazy bug in the unofficial Arduino support for the RP2040 v 4.01!</title><description>&lt;p&gt;This is a strange tale... I&#39;ve been using&amp;nbsp; the excellent&amp;nbsp;&lt;a href=&quot;https://github.com/earlephilhower/arduino-pico&quot;&gt;Raspberry Pi Pico Arduino Core&lt;/a&gt;, managed by Earle F.&amp;nbsp; Philhower III, from its beginnings. It has been recently updated to support the new Pico2 and RP2350.&lt;/p&gt;&lt;p&gt;As part of my preparations for testing the new Pico2 (received it yesterday), I was playing with some old microcontroller benchmarks. When I tried a Whetstone benchmark in the old Pico the program just stopped somewhere in the middle of the calculations, and here starts the tale.&lt;/p&gt;&lt;pre&gt;double X; // declared here so the multiplication is not removed by optimization

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);

  double T = millis();
  X = -1.3 * T;

  digitalWrite(LED_BUILTIN, HIGH);
}

void loop() {
  delay(100);
}
&lt;/pre&gt;&lt;p&gt;&lt;i&gt;
  This code forces the bug!&lt;/i&gt;&lt;/p&gt;&lt;span&gt;&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;/span&gt;&lt;p&gt;The first messages from the full code appeared in the Serial Monitor, and then no activity. Trying to load new software using the Arduino bootloader would not work, I had to manually enter boot mode to try a new version.&lt;/p&gt;&lt;p&gt;I should have been more methodical. It all started with what I thought would be a quick test, re-running software that had worked fine in the past. I grabbed one of my Pico boards and a USB cable and started testing. After having to unplug and reconnect the USB cable to enter boot mode a few times, I should have moved to a protoboard with a reset button attached to the Pico board, but I never came around to it.&lt;/p&gt;&lt;p&gt;The first thing I did was place a few Serial.print()s. The program crashed somewhere in the middle of the first floating point calculations. I tried a few changes with no results.&lt;/p&gt;&lt;p&gt;I then reverted to version 3.9 and everything worked fine!&lt;/p&gt;&lt;p&gt;A stated trying to isolate a minimum program that showed the problem. The problem disappeared with some changes, but I could make no sense why. After a few hours, I put it aside and went to sleep.&lt;/p&gt;&lt;p&gt;The next day I took a look at the generated code, and found out that the error occurred on the first floating point operation. It disappeared when the compiler optimization took out the operation! I ended up with the code shown at the start, where I even removed the serial outputs and used the LED to show that the code stopped at the floating point multiply.&lt;/p&gt;&lt;p&gt;Out of ideas, I opened an &lt;a href=&quot;https://github.com/earlephilhower/arduino-pico/issues/2410&quot;&gt;issue at the project&lt;/a&gt;. To my surprise, one hour later Earle confirmed that it was bug, by looking at the logs (why didn&#39;t I do that?). Turns out that a single typo had resulted in the &lt;a href=&quot;https://github.com/earlephilhower/arduino-pico/pull/2411&quot;&gt;RP2040&amp;nbsp;ROM FPU calls not being added in the Pico library&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;What &quot;ROM FPU calls&quot; you ask? You see, the RP2040 does not have a Floating Point Unit (FPU), so floating point calculations must be done by software routines. Raspberry Pi have written some very optimized routines (better than the ones in the gcc compiler) and placed them in ROM. Thanks to the typo, the compiler was not using the ROM routines nor the non-optimized routines - it just panicked.&lt;/p&gt;&lt;p&gt;The new version should be generally available soon.&lt;/p&gt;&lt;p&gt;Many thanks to Earl for taking the time to test my crazy error report and quickly finding the case and fixing it.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description><link>https://raspico.blogspot.com/2024/09/i-found-crazy-bug-in-unofficial-arduino.html</link><author>noreply@blogger.com (Daniel Quadros)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7859657580199211900.post-7875209703453387583</guid><pubDate>Wed, 14 Aug 2024 10:00:00 +0000</pubDate><atom:updated>2024-08-14T03:00:00.118-07:00</atom:updated><title>Some Fun with CircuitPython</title><description>&lt;p&gt;CircuitPython Day 2024 will be next Friday (Agoust 16), so here is a simple project! I am using a few modules I got in my drawers:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;An RP2040 Feather board. This is a nice RP2040 board with 8 MB of Flash and a battery charger (not used in this project).&lt;/li&gt;&lt;li&gt;A BMP390 sensor. I chose this particular board because it has a&amp;nbsp;&amp;nbsp;STEMMA QT connector, just like the Feather board.&lt;/li&gt;&lt;li&gt;A 128x64 pixels OLED display, with I2C interface.&lt;/li&gt;&lt;li&gt;A 4 by 4 WS2812 RGB LED matrix.&lt;/li&gt;&lt;/ul&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNDsyZ5aOxB-G68nonUClGCK_auuVkEUHOa0dmiQbZ684F-ua2TE2KeEGVkuMrnl20PoJpjupbZr2LL_92Wk3VMle-sCjFvSXMug1jkVq2ax2SNJoe46cubhIehIkFyuIz3uiZKS53jkGiIoKy7IE9hAAaxNEGyeU9ED8A2TJ7t37lX79ssGFusMA7KPc/s3212/20240813_201133.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1967&quot; data-original-width=&quot;3212&quot; height=&quot;245&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNDsyZ5aOxB-G68nonUClGCK_auuVkEUHOa0dmiQbZ684F-ua2TE2KeEGVkuMrnl20PoJpjupbZr2LL_92Wk3VMle-sCjFvSXMug1jkVq2ax2SNJoe46cubhIehIkFyuIz3uiZKS53jkGiIoKy7IE9hAAaxNEGyeU9ED8A2TJ7t37lX79ssGFusMA7KPc/w400-h245/20240813_201133.jpg&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This project aims to use the sensor to measure temperature, air pressure, and altitude, show this information in the OLED display and set the RGB LEDs to a color based on the temperature.&lt;/div&gt;&lt;span&gt;&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;/span&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;Hardware&lt;/h3&gt;&lt;div&gt;The connections between the modules are:&lt;/div&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Pins +3.3V, GND and A0 are connected to the RGB LED matrix (Vcc, GND an IN, respectively).&lt;/li&gt;&lt;li&gt;A STEMMA cable connects the Feather to the sensor.&lt;/li&gt;&lt;li&gt;The OLED display is connected to the sensor board (to make wiring simpler). The pins used are Vin, GND, SCL and SDA.&lt;/li&gt;&lt;/ul&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;Software Setup&lt;/h3&gt;&lt;/div&gt;&lt;div&gt;The first step is to install the latest CircuitPython firmware on the Feather. Just download the uf2 file from&amp;nbsp;&lt;a href=&quot;https://circuitpython.org/board/adafruit_feather_rp2040/&quot;&gt;https://circuitpython.org/board/adafruit_feather_rp2040/&lt;/a&gt;, connect the Feather to a PC, press boot and reset to put it in the bootloader and copy the uf2 file to the RPI-RP2 drive that will show up.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The board will reboot at the end of the copy&amp;nbsp;and a CIRCUITPY drive will appear.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now go to&amp;nbsp;https://github.com/adafruit/Adafruit_CircuitPython_Bundle/releases/latest and download the Adafruit CircuitPython Bundle for the CircuitPython version you installed (in my case, 9.x). Expand the zip in your PC and copy the following files/directories to CIRCUITPY/lib:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;adafruit_bus_device directory&lt;/li&gt;&lt;li&gt;adafruit_register directory&lt;/li&gt;&lt;li&gt;adafruit_bmp3xx.mpy file&lt;/li&gt;&lt;li&gt;adafruit_ssd1306.mpy file&lt;/li&gt;&lt;li&gt;neopixel.mpy file&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Last, download&amp;nbsp;&lt;a href=&quot;https://github.com/adafruit/Adafruit_CircuitPython_framebuf/blob/main/examples/font5x8.bin&quot;&gt;https://github.com/adafruit/Adafruit_CircuitPython_framebuf/blob/main/examples/font5x8.bin&lt;/a&gt; and place it at the root of the CIRCUITPY drive.&lt;/div&gt;&lt;/div&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;Software&lt;/h3&gt;&lt;div&gt;Here is the full application:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;pre&gt;# BMP390 Sensor Example
import board
from busio import I2C
from time import sleep
import neopixel
from adafruit_bmp3xx import BMP3XX_I2C
import adafruit_ssd1306

np_onboard = neopixel.NeoPixel(board.NEOPIXEL, 1)
np_onboard.fill((0, 0, 0))

np = neopixel.NeoPixel(board.A0, 16)
np.fill((0, 0, 0))

temp_colors = (
    (12, 28, 32),  # &amp;lt; 0       light blue
    (0,  18, 32),  #  0 to 10  blue
    (32, 29, 8),  # 10 to 20 yellow
    (32, 13, 0),   # 20 to 30 orange
    (32, 7,  2),   # 30 to 40 light red
    (32, 0,  0)    # &amp;gt; 50 dark red
    )

i2c = board.STEMMA_I2C()
bmp = BMP3XX_I2C(i2c)

oled = adafruit_ssd1306.SSD1306_I2C(128, 32, i2c, addr=0x3c)
oled.fill(0)
oled.show()

def color_temp(temp):
    temp = -9 if temp &amp;lt; -9 else 49 if temp &amp;gt; 49 else temp
    return temp_colors[int(temp+10) // 10]

while True:
    # Read Sensor
    press = bmp.pressure
    temp = bmp.temperature
    alt = bmp.altitude
    print (&#39;Temperature: {:.1f}C  Pressure: {:.0f}Pa  Altitude: {:.1f}m&#39;.format(
        temp, press*100, alt))

    # Show Temperature and Pressure on display
    oled.fill(0)
    oled.text(&#39;Temperature: {:.1f}C&#39;.format(temp), 0, 0, 1)
    oled.text(&#39;Pressure: {:.0f}Pa&#39;.format(press*100), 0, 10, 1)
    oled.text(&#39;Altitude: {:.1f}m&#39;.format(alt), 0, 20, 1)
    oled.show()
    

    # Choose color based on temperature
    np.fill(color_temp(temp))

    # Wait before updating
    sleep(2)
&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;</description><link>https://raspico.blogspot.com/2024/08/some-fun-with-circuitpython.html</link><author>noreply@blogger.com (Daniel Quadros)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNDsyZ5aOxB-G68nonUClGCK_auuVkEUHOa0dmiQbZ684F-ua2TE2KeEGVkuMrnl20PoJpjupbZr2LL_92Wk3VMle-sCjFvSXMug1jkVq2ax2SNJoe46cubhIehIkFyuIz3uiZKS53jkGiIoKy7IE9hAAaxNEGyeU9ED8A2TJ7t37lX79ssGFusMA7KPc/s72-w400-h245-c/20240813_201133.jpg" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7859657580199211900.post-4121523871636314644</guid><pubDate>Tue, 13 Aug 2024 10:00:00 +0000</pubDate><atom:updated>2024-08-13T03:00:00.117-07:00</atom:updated><title>The New Raspberry Pi Pico 2, RP2350 and RP2354: a Short Recap</title><description>&lt;p&gt;On August 8th, Raspberry announced a new version of the Pi Pico board, the Pi Pico 2, along with a new microcontroller, the RP2350 / RP2354. In this post I will tell the highlights of these new products, along with my comments.&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHah2VYgDHqGHOcyMzg7mkzjPnVPcM_XmQwA0YTBYC334nsG4IHN-aC1qbtNSreKLY4ywnXekWtOS-Cmrl5SHG5caVA7Q8_O5o2IH7GpEljT_7-DB6GAU7LWCdN41lIo8nMHf6EG4OE8YghlqnuqkxUa5Pqxt1Alt_LLTg91a14E_ebFv9SrZ8W9rYWbg/s498/Pico1_Pico2.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;498&quot; data-original-width=&quot;459&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHah2VYgDHqGHOcyMzg7mkzjPnVPcM_XmQwA0YTBYC334nsG4IHN-aC1qbtNSreKLY4ywnXekWtOS-Cmrl5SHG5caVA7Q8_O5o2IH7GpEljT_7-DB6GAU7LWCdN41lIo8nMHf6EG4OE8YghlqnuqkxUa5Pqxt1Alt_LLTg91a14E_ebFv9SrZ8W9rYWbg/s320/Pico1_Pico2.png&quot; width=&quot;295&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;span&gt;&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;/span&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;The Raspberry Pi Pico 2&lt;/h3&gt;&lt;p&gt;There is not much to say about the board itself. The RP2040 is replaced by the new RP2350 and the 2 MB flash is replaced by 4 MB. Everything else is about the same, including the micro USB connector and the lack of a Reset button. It is clear that a main objective was to make a drop-in replacement for the older version. Price increase from US$4 to US$5.&lt;/p&gt;&lt;p&gt;A Pico W 2 board is expected before the end of the year, using the same RF chip as the current Pico W.&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;The RP2350A, RP2350B, RP2354A, and RP2354B&lt;/h3&gt;&lt;p&gt;This is the important stuff, with great improvements over the RP2040.&lt;/p&gt;&lt;p&gt;The RP2040 has two ARM Cortex M0+ cores. The M0+ is establishing itself as the most popular core for entry-level microcontrollers, replacing the old 8-bit cores.&lt;/p&gt;&lt;p&gt;The new RP254x chips replace the M0+ by the M33, and they are very different animals. They are more recent, have a more advanced ARM architecture (&amp;nbsp;ARMv8-M vs ARMv6-M) with more instructions and features. This includes single-precision floating-point, DSP and TrustZone instructions. The RP254x also includes a double-precision co-processor to accelerate double-precision calculations. These are great news for applications like digital signal processing and machine learning.&lt;/p&gt;&lt;p&gt;The clock was also improved, from 133MHz to 150MHz. The overall expected improvement in performance (compared to the RP2040) is somewhere between 1.5 and 2.&lt;/p&gt;&lt;p&gt;RAM was also increased, from 264kB to 520kB. If you need more, the RP254x now supports external PSRAM.&lt;/p&gt;&lt;p&gt;If you are a PIO (Programmable I/O) fan, you will be happy to hear that now there are 3 PIOs, increasing the total number of state machines from 8 to 12. This is important as the state machines in a PIO share some common configurations and the same 32 position instruction memory. There are also some small improvements in the instructions available.&lt;/p&gt;&lt;p&gt;A new HSTX peripheral can do multi-bit serial transmission at higher rates than the PIOs. Adafruit has already used it to generate DVI video.&lt;/p&gt;&lt;p&gt;The RP254x has a lot of security features. It is now possible to secure the Flash against unauthorized software installation and encrypt the application. A new OTP memory can be used to store cryptographic keys. There are also mechanisms against fault injection (trying to get the processor in an invalid state where it relaxes the protection).&lt;/p&gt;&lt;p&gt;Power consumption has been improved, especially in the sleep state.&lt;/p&gt;&lt;p&gt;And now the big surprise: the RP235x has also two RISC-V cores! There are a few gotchas:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;You can have only two cores (from the four available) running at the same time&lt;/li&gt;&lt;li&gt;Core switching involves a reset, so you should select the cores at boot time and not change it&lt;/li&gt;&lt;li&gt;While it is possible to have an ARM core along a RISC-V core, things are a lot easier if you use only ARM or RISC-V cores.&lt;/li&gt;&lt;li&gt;The RISC-V cores have no float-point instructions and no access to the double-precision co-processor or some security features&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;The new microcontroller is available in four versions. The RP2354 versions include a 2 MB Flash in the same package. The A versions use a&amp;nbsp;QFN-60 package (similar to the QFN-56 used by the RP2040), providing 30 GPIOs. The B versions use a bigger&amp;nbsp;QFN-80 package and have 48 GPIOs.&lt;/div&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;My Verdict (so far)&lt;/h3&gt;&lt;div&gt;The RP235x chips are a great upgrade to the original RP2040. Prices are slightly higher but cost/performance is better. The M33 cores will allow applications that demand more performance, particularly for computations.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The models with internal Flash may be used on smaller and cheaper boards, while the 48 GPIOs versions will eliminate the need for I/O expanders in some applications.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The Pico 2 is a good starting point to play with the new microcontroller, but other companies are already offering boards with some added features.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;</description><link>https://raspico.blogspot.com/2024/08/the-new-raspberry-pi-pico-2-rp2350-and.html</link><author>noreply@blogger.com (Daniel Quadros)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHah2VYgDHqGHOcyMzg7mkzjPnVPcM_XmQwA0YTBYC334nsG4IHN-aC1qbtNSreKLY4ywnXekWtOS-Cmrl5SHG5caVA7Q8_O5o2IH7GpEljT_7-DB6GAU7LWCdN41lIo8nMHf6EG4OE8YghlqnuqkxUa5Pqxt1Alt_LLTg91a14E_ebFv9SrZ8W9rYWbg/s72-c/Pico1_Pico2.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7859657580199211900.post-6053805257705960207</guid><pubDate>Wed, 10 Jul 2024 10:00:00 +0000</pubDate><atom:updated>2024-07-30T11:28:07.212-07:00</atom:updated><title>Mini Review: RP2040 Pi Zero</title><description>&lt;p&gt;It is common to see confusion between the Raspberry Pi Pico and other Raspberry Pi boards. The RP2040 Pi Zero, from Waveshare, makes it even more confusing, putting an RP2040 microcontroller in a Pi Zero form factor (including a mini HDMI connector).&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjH_Ntso7IXutUzMIQx6KwyoOV0NmcYMm8hq-ilCN_JbktrPbCWSQR8GS2Q7QW9wWCJZdvFZe2IGQ52QWz90geVwdx2d9ORCN7UmBR5vfVme3ek-bA7RuGtcdv7wNmXweAn4nZgjJ_BaEPeBWbj6cc0W0X-1KneoAiRZ6kKg4L4AEMyzU6u3_htb2oWapw/s1024/RP2040Pi_Zero.jpg&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;577&quot; data-original-width=&quot;1024&quot; height=&quot;225&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjH_Ntso7IXutUzMIQx6KwyoOV0NmcYMm8hq-ilCN_JbktrPbCWSQR8GS2Q7QW9wWCJZdvFZe2IGQ52QWz90geVwdx2d9ORCN7UmBR5vfVme3ek-bA7RuGtcdv7wNmXweAn4nZgjJ_BaEPeBWbj6cc0W0X-1KneoAiRZ6kKg4L4AEMyzU6u3_htb2oWapw/w400-h225/RP2040Pi_Zero.jpg&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;span&gt;&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;/span&gt;&lt;p&gt;At the heart of this board, we have the same RP2040 with a 12MHz crystal as the Raspberry Pi Pico. 16 Mbytes of flash memory and buttons for Reset and Boot are provided. There is a power LED but no LED connected to a GPIO. You can solder a three-pin header for debugging. A USB-C connector is connected to the USB pins in the RP2040 and can be used to power the board.&lt;/p&gt;&lt;p&gt;There is also provision for a lithium battery to power the board. The battery is charged when power is applied through the USB-C or the expansion connector. A micro SD slot is connected to GPIO 18, 19, 20 and 21.&lt;/p&gt;&lt;p&gt;So far, nothing that will rise our eyebrows, just a nice RP2040 board. The expansion connector is 40 pin header similar to the one in the Raspberry Pi Single Board Computers. Some Raspberry Pi hats (expansion boards) should work with the RP2040 Pi Zero, as long as you can figure out the software side.&lt;/p&gt;&lt;p&gt;A second USB-C connector, labeled PIO-USB, is&amp;nbsp;connected to GPIO6 and GPIO7. It is meant to be used with a PIO/software USB implementation, but you could use it as a very confusing GPIO connector.&lt;/p&gt;&lt;p&gt;Last, but not least, there is the mini HDMI connector. This is actually a DVI interface that uses various GPIOs. Its use requires special software that uses DMA, PIO, and overclocking to generate the required signals.&lt;/p&gt;&lt;p&gt;Of course, this board will not run Linux (but there are ports of a couple of Unix-like operating systems for the RP2040, with no DVI support).&lt;/p&gt;&lt;p&gt;DVI software support is very sketchy right now. There are two examples at the Waveshare wiki, based on the ones found at&amp;nbsp;&lt;a href=&quot;https://github.com/Wren6991/PicoDVI&quot;&gt;https://github.com/Wren6991/PicoDVI&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Should you buy this board? The answer depends on your application. The HDMI/DVI interface will be useful only if you have the knowledge and time to develop a special application or if you find someone who has done that (serial terminal and old computer emulation are likely candidates).&lt;/p&gt;&lt;p&gt;If you will not use the HDMI connector, you get a nice 16M RP2040 board with battery support, an SD card slot, and a second USB-C connector. In some cases, the 40-pin connector will allow you to use an existing Rapberry Pi hat. All this could reduce the amount of connections and external hardware when compared to the Pi Pico.&lt;/p&gt;&lt;p&gt;More details can be seem at the &lt;a href=&quot;https://www.waveshare.com/wiki/RP2040-PiZero&quot;&gt;Waveshare wiki&lt;/a&gt;,&lt;/p&gt;</description><link>https://raspico.blogspot.com/2024/07/mini-review-rp2040-pi-zero.html</link><author>noreply@blogger.com (Daniel Quadros)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjH_Ntso7IXutUzMIQx6KwyoOV0NmcYMm8hq-ilCN_JbktrPbCWSQR8GS2Q7QW9wWCJZdvFZe2IGQ52QWz90geVwdx2d9ORCN7UmBR5vfVme3ek-bA7RuGtcdv7wNmXweAn4nZgjJ_BaEPeBWbj6cc0W0X-1KneoAiRZ6kKg4L4AEMyzU6u3_htb2oWapw/s72-w400-h225-c/RP2040Pi_Zero.jpg" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7859657580199211900.post-8705122825448571750</guid><pubDate>Fri, 02 Feb 2024 10:00:00 +0000</pubDate><atom:updated>2024-02-02T02:00:00.132-08:00</atom:updated><title>Using the LCD 12864-06D Display with the Raspberry Pi Pico</title><description>&lt;p&gt;The&amp;nbsp;LCD 12864-06D is a graphic (128 by 64 pixels) monochrome Liquid Crystal Display. You will find it in AliExpress and many other stores, but information on it is scarce. An intriguing point is that ads mention that it is graphic and has a Chinese font.&lt;/p&gt;&lt;p&gt;In this post I will present the information I have gathered and share some sample code (using the unofficial RP2040 support for Arduino by&amp;nbsp;&amp;nbsp;Earle F. Phillhoower III).&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-bmbeKJvji3eHw_RdNwbc4_7cly7b74Sddu6U6YgyjloVXWoj5ieB0njYW0qMM4yqTHUQTPgNfmJBt6GZQAXRWNdbvjyz0ojBK_IuYr23LhctUl1ifF7WCeD9ZPhGaQbJMwvwRBqh6B-9pLmC0iBE3XGQBKBFEbWkHRvDQpFdF8XWnf-cBKXXJTLJyMs/s4624/20240104_092015.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;3468&quot; data-original-width=&quot;4624&quot; height=&quot;240&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-bmbeKJvji3eHw_RdNwbc4_7cly7b74Sddu6U6YgyjloVXWoj5ieB0njYW0qMM4yqTHUQTPgNfmJBt6GZQAXRWNdbvjyz0ojBK_IuYr23LhctUl1ifF7WCeD9ZPhGaQbJMwvwRBqh6B-9pLmC0iBE3XGQBKBFEbWkHRvDQpFdF8XWnf-cBKXXJTLJyMs/s320/20240104_092015.jpg&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;span&gt;&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;/span&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;&lt;span&gt;&lt;b&gt;Technical Specs&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;&lt;p&gt;The display area is 58 by 28 millimeters, a nice size. It is available in three different configurations (blue, gray and black background), the one I bought has white pixels on blue background.&lt;/p&gt;&lt;p&gt;The power voltage is 3.3V, but I&#39;ve seen articles where the display is directly connected to a 5V Arduino (I recommend using level converters or voltage divisors in this case).&amp;nbsp;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdowqL_XYvmcdNOq9Zq-C7XQD8vNRypDYY8bgjMdCyHRwcq_wGH7U3x11u6ELbMZe8KJaanLqC697neDeE0vhZwVDQ4ki0KXRKJgfHFxlPWi3KDeJxJA5ZhfmFBODcA3hxExz-8BWekjBnAcbtLrscZqY2K36DTT3l0Mxzr7W43q9NSErep0JXyd4JHvM/s800/LCD_Specs.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;628&quot; data-original-width=&quot;800&quot; height=&quot;251&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdowqL_XYvmcdNOq9Zq-C7XQD8vNRypDYY8bgjMdCyHRwcq_wGH7U3x11u6ELbMZe8KJaanLqC697neDeE0vhZwVDQ4ki0KXRKJgfHFxlPWi3KDeJxJA5ZhfmFBODcA3hxExz-8BWekjBnAcbtLrscZqY2K36DTT3l0Mxzr7W43q9NSErep0JXyd4JHvM/s320/LCD_Specs.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;The display has a 13 pin connector. The first 5 pins are the traditional signals (CS, RES, RS, SCK, SI) for a unidirectional SPI connection to a display controller (ST7565R). The next two pins are the power supply (VDD and GND). Next we have 2 pins for the backlight LED&amp;nbsp;&amp;nbsp;(LEDA e LEDK). The last four pins are for a second SPI interface&amp;nbsp;(SCK, CS, SDO e SDI) that is connected to a ROM chip (16S1Y / ER3805-1).&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;The&amp;nbsp;ST7565R Display Controller&lt;/h3&gt;&lt;p&gt;This controller is similar to other monochrome graphic LCD controllers. Its internal memory stores the display image (up to 132x64). It supports SPI and parallel interfaces, but in this particular display, it is set up to SPI only. The ST7565R has 23 commands, initialization is done by sending many of these commands with values specific to the display and waiting some time between them.&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHB5YABVheB4p7r7N8X2z8rgbkT1t2YRV6tZIN3gU52FV8_Xgnvx2eC1S0AxcEFet4-F6T0Ylg_ccNQ_7PdaHIufy8geCR9BtbtU2V7kLhAV8lFMsXI_0ZvrUwcBBjsq18PY9xSkN8trvdsBbMjsb59vBYreZxVsZvA0qocvj_sXRATb12oRjX5Hffja8/s829/LCD_Cmds.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;829&quot; data-original-width=&quot;665&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHB5YABVheB4p7r7N8X2z8rgbkT1t2YRV6tZIN3gU52FV8_Xgnvx2eC1S0AxcEFet4-F6T0Ylg_ccNQ_7PdaHIufy8geCR9BtbtU2V7kLhAV8lFMsXI_0ZvrUwcBBjsq18PY9xSkN8trvdsBbMjsb59vBYreZxVsZvA0qocvj_sXRATb12oRjX5Hffja8/s320/LCD_Cmds.png&quot; width=&quot;257&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;The figure below shows the mapping of the internal memory to the pixels, assuming the display is oriented with the connectoron top:&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWDsP56PwlH4jIDfCYkDGN-u1Pk_UVBgO6cKAhHJle_o7Ax-VpUiKbFVvDc5LuScCl2hoCkvms0nfqliGNKtyNqC6LRLB78zB6xC1tQziUHGKYisudJsIbtDsQ3eQWAEsq2Gp0Sv99N4LCzYtV1z2TxKjOvFjC4-3WWHUod-BMXrxLEwl3qOPSldeknZQ/s598/LCD_Mem_Mapping.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;355&quot; data-original-width=&quot;598&quot; height=&quot;190&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWDsP56PwlH4jIDfCYkDGN-u1Pk_UVBgO6cKAhHJle_o7Ax-VpUiKbFVvDc5LuScCl2hoCkvms0nfqliGNKtyNqC6LRLB78zB6xC1tQziUHGKYisudJsIbtDsQ3eQWAEsq2Gp0Sv99N4LCzYtV1z2TxKjOvFjC4-3WWHUod-BMXrxLEwl3qOPSldeknZQ/s320/LCD_Mem_Mapping.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;The Font ROM (16S1Y / ER3805-1)&lt;/h3&gt;&lt;p&gt;This memory has 248K and contains fonts for simplified chinese and ASCII:&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhCILQ-PlgLLVOsN7jDkEPZqCvTO-TofXbeoWfo0F-GTVbMV2mZbdBZcJsqGN4VoxPcadpXa0DifDWem9akE1tInpnpyZYcqKseQJyzERe_JwewVvZIKJOEKA0tGzBeI5sKLZhKB1Z_w4OxGdvviuacwJloQaDQtHWP0vqpDRItvSDxZ93Z6mgBsZfHDos/s719/LCD_Fonts.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;259&quot; data-original-width=&quot;719&quot; height=&quot;144&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhCILQ-PlgLLVOsN7jDkEPZqCvTO-TofXbeoWfo0F-GTVbMV2mZbdBZcJsqGN4VoxPcadpXa0DifDWem9akE1tInpnpyZYcqKseQJyzERe_JwewVvZIKJOEKA0tGzBeI5sKLZhKB1Z_w4OxGdvviuacwJloQaDQtHWP0vqpDRItvSDxZ93Z6mgBsZfHDos/w400-h144/LCD_Fonts.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;The memory accepts two commands through the SPI interface:&amp;nbsp;&amp;nbsp;&quot;Read Data Bytes&quot; (for up to 20MHz operation ) and &quot;Read Data Bytes at Higher Speed&quot; (for up to 30MHz operation). After the command you must send three bytes with the start address (plus one additional dont-care byte if using the &quot;Higher Speed&quot; option). After data you get one memory byte for each byte sent.&lt;/p&gt;&lt;p&gt;This memory is useful for systems with restricted non-volatile memory (not the case for the Pi Pico).&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;Connecting the Display to the Pi Pico&lt;/h3&gt;&lt;p&gt;I used the same SPI channel for the display controller and font ROM. The display and the backlight are powered by the 3.3V output of the Pico. A 220R resistor is used to limit the backlight current.&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihpOPfx88Y1WaVma3ajwRNeE7pxWmUB3uhx5t2iuz91WQWmMRa3ZongY18y_ozws3Mkjya2jSExU2hayqUAl4la_GsVvCbhmmEfq2Z0qVmlvnpRHWRe_jaJzvQg_qWzW8T-ceaSPPfF50-aC-ZvlV0njswJOoDvK5I8Jxla9HenbepaM174-5GiaCrWpI/s1755/PicoConnections_bb.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;984&quot; data-original-width=&quot;1755&quot; height=&quot;224&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihpOPfx88Y1WaVma3ajwRNeE7pxWmUB3uhx5t2iuz91WQWmMRa3ZongY18y_ozws3Mkjya2jSExU2hayqUAl4la_GsVvCbhmmEfq2Z0qVmlvnpRHWRe_jaJzvQg_qWzW8T-ceaSPPfF50-aC-ZvlV0njswJOoDvK5I8Jxla9HenbepaM174-5GiaCrWpI/w400-h224/PicoConnections_bb.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;Some Example Code&lt;/h3&gt;&lt;p&gt;The examples I wrote are available at&amp;nbsp;&lt;a href=&quot;https://github.com/dquadros/LCD12864&quot;&gt;https://github.com/dquadros/LCD12864&lt;/a&gt;. At this moment there are three examples:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;&lt;b&gt;Basic Test&lt;/b&gt; initializes the display controller and writes digits on it, using an 8x8 font stored in the program.&lt;/li&gt;&lt;li&gt;&lt;b&gt;FontDump&lt;/b&gt; exercises communication with the ROM, listing in the Arduino monitor one or more characters in the 7x8 ASCII font. This shows that the font is stored with 8 bytes per character (1 byte for each column, with the last byte always zero). The least significant bit in a byte corresponds to the top pixel.&lt;/li&gt;&lt;li&gt;&lt;b&gt;UseRomFont&lt;/b&gt; writes a text on the screen using the 7x8 ASCII font in the ROM.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description><link>https://raspico.blogspot.com/2024/02/using-lcd-12864-06d-display-with.html</link><author>noreply@blogger.com (Daniel Quadros)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-bmbeKJvji3eHw_RdNwbc4_7cly7b74Sddu6U6YgyjloVXWoj5ieB0njYW0qMM4yqTHUQTPgNfmJBt6GZQAXRWNdbvjyz0ojBK_IuYr23LhctUl1ifF7WCeD9ZPhGaQbJMwvwRBqh6B-9pLmC0iBE3XGQBKBFEbWkHRvDQpFdF8XWnf-cBKXXJTLJyMs/s72-c/20240104_092015.jpg" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7859657580199211900.post-2661198982711093102</guid><pubDate>Wed, 31 May 2023 10:00:00 +0000</pubDate><atom:updated>2023-05-31T03:00:00.142-07:00</atom:updated><title>Using a Pi Pico to Test DS18B20 Temperature Sensors</title><description>&lt;p&gt;&amp;nbsp;The DS18B20 is an easily found temperature sensor, both the sensor itself (it looks like a transistor) and as a waterproof probe with the sensor inside a metallic case. What many don&#39;t know is that a large part of the sensors sold are not original parts and many have serious defects.&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhiux-W7X7KF-nB8WlNj3UaFaNV7ciJKL92cJywmGgyERbE6kcvs3KC9_NvUVLqW36Sk9UYgGVitEIZ0iL4HHX4jkgTT8OW4IpDG6eK7kIsmkPqgDoEhqH9eE3-54LdvUXNKl4GhMy-mdyDKTzgRfuO263kQ35NAu-koNZ89axILxxc1UONvsVEm3dS/s500/DS18B20%20Suspeito.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;500&quot; data-original-width=&quot;411&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhiux-W7X7KF-nB8WlNj3UaFaNV7ciJKL92cJywmGgyERbE6kcvs3KC9_NvUVLqW36Sk9UYgGVitEIZ0iL4HHX4jkgTT8OW4IpDG6eK7kIsmkPqgDoEhqH9eE3-54LdvUXNKl4GhMy-mdyDKTzgRfuO263kQ35NAu-koNZ89axILxxc1UONvsVEm3dS/s320/DS18B20%20Suspeito.jpg&quot; width=&quot;263&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;span&gt;&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;/span&gt;&lt;p&gt;A throughout study on these clone sensors was done by Chris Petrich, the result can be seen at&amp;nbsp;&lt;a href=&quot;https://github.com/cpetrich/counterfeit_DS18B20&quot;&gt;https://github.com/cpetrich/counterfeit_DS18B20&lt;/a&gt;. In the Arduino IDE&#39;s Library Manager, you will find the library CheckDS18B20 by Koen DV which can identify the various versions found by Chris.&lt;/p&gt;&lt;p&gt;I decided to make my own version of the test from Chris&#39;s observations. In my first tests, I used a Pi Pico W with an e-Paper display (just because that was what I had in my hands at that moment). Later I opted for a soldered version, using an RP2040 Zero and an OLED display. The result fits in an Altoids box:&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBss7ylRa13dVXV63B2Vq4bofQhrNeXteHHGGb4_2eJFjyXbho1cXKvmSE6SfJfIuTqMexUrhTeI331vdZzWRPNP_2XWCJYHfFQSgazdrAtAcGibJKjtYwz-JRrmL4QoYIXGZzGQlYFUgWrMEQi2VmbUBihQbd1xcUBGDMFq-ATu4IsLwm3sH_cF-V/s4624/20230529_093959.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;3468&quot; data-original-width=&quot;4624&quot; height=&quot;240&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBss7ylRa13dVXV63B2Vq4bofQhrNeXteHHGGb4_2eJFjyXbho1cXKvmSE6SfJfIuTqMexUrhTeI331vdZzWRPNP_2XWCJYHfFQSgazdrAtAcGibJKjtYwz-JRrmL4QoYIXGZzGQlYFUgWrMEQi2VmbUBihQbd1xcUBGDMFq-ATu4IsLwm3sH_cF-V/s320/20230529_093959.jpg&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;My software is based on both documented and observed characteristics of the legit and fake sensors:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;The pattern of the sensor&#39;s address (in the legit part the address is a 48-bit counter and the two most significant bytes are still zero)&lt;/li&gt;&lt;li&gt;The initial content of the registers (as documented in the datasheet)&lt;/li&gt;&lt;li&gt;The support for various ADC resolutions (some clones only support 12-bit resolution)&lt;/li&gt;&lt;li&gt;The time needed to do a temperature reading (as observed by Chris)&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;The software and hardware details can be seen at&amp;nbsp;&lt;a href=&quot;https://github.com/dquadros/TestadorDS18B20&quot;&gt;https://github.com/dquadros/TestadorDS18B20&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The bad news is that most of the sensors I have are not original parts and some have big defects.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;</description><link>https://raspico.blogspot.com/2023/05/using-pi-pico-to-test-ds18b20.html</link><author>noreply@blogger.com (Daniel Quadros)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhiux-W7X7KF-nB8WlNj3UaFaNV7ciJKL92cJywmGgyERbE6kcvs3KC9_NvUVLqW36Sk9UYgGVitEIZ0iL4HHX4jkgTT8OW4IpDG6eK7kIsmkPqgDoEhqH9eE3-54LdvUXNKl4GhMy-mdyDKTzgRfuO263kQ35NAu-koNZ89axILxxc1UONvsVEm3dS/s72-c/DS18B20%20Suspeito.jpg" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7859657580199211900.post-4667492642844043879</guid><pubDate>Mon, 13 Mar 2023 10:00:00 +0000</pubDate><atom:updated>2023-03-13T03:00:00.147-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">WiFi</category><title>Using WiFi in the Raspberry Pi Pico (Part 5)</title><description>&lt;p&gt;In this post we will see how to access a REST API&amp;nbsp;with the Raspberry Pi Pico W, using the SDK C/C++ and MicroPython.&lt;/p&gt;&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj21BkO_Z-knFD1bF-E-nVV81vA7GtqqvrjwuoZvEvgG8BikecJ2LjtwrYuJZJRnX-A2hmMQUF0lRQEjzJ2suLjnJcwm0fXXjvjdO1HRKS7eI8-1dPJPrIMDPAimKRXNKy7wiUp4OtDcmbQxGrLAWdlC6a9v8wmxH-GQJkr18y0Yr08PXFHkX-m0lxr/s853/API.png&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;589&quot; data-original-width=&quot;853&quot; height=&quot;276&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj21BkO_Z-knFD1bF-E-nVV81vA7GtqqvrjwuoZvEvgG8BikecJ2LjtwrYuJZJRnX-A2hmMQUF0lRQEjzJ2suLjnJcwm0fXXjvjdO1HRKS7eI8-1dPJPrIMDPAimKRXNKy7wiUp4OtDcmbQxGrLAWdlC6a9v8wmxH-GQJkr18y0Yr08PXFHkX-m0lxr/w400-h276/API.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;An example of a call to a RESP API, using &lt;a href=&quot;https://www.postman.com/&quot;&gt;Postman&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;Basically, a REST API is uses an HTTP method (like GET and POST) to access and manipulate &quot;resources&quot;.&lt;/p&gt;&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;div&gt;&lt;b&gt;Using the C/C++ SDK&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;div&gt;For my first example I will use an API that gives information on Brazilian postcodes (&quot;&lt;i&gt;CEP&lt;/i&gt;&quot;):&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;blockquote style=&quot;border: none; margin: 0px 0px 0px 40px; padding: 0px;&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;GET http:viacep.com.br/ws/{cep}/json/&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;where&amp;nbsp; {cep} is the 8 digit postcode we want to consult.&lt;/p&gt;&lt;p&gt;The lwIP library have an &lt;a href=&quot;https://www.nongnu.org/lwip/2_1_x/group__httpc.html&quot;&gt;HTTP_ client&lt;/a&gt; module for HTTP access. This module have two methods:&amp;nbsp;&amp;nbsp;&lt;span style=&quot;font-family: courier;&quot;&gt;httpc_get_file&lt;/span&gt;() and&amp;nbsp;&lt;span style=&quot;font-family: courier;&quot;&gt;httpc_get_file_dns()&lt;/span&gt;.&amp;nbsp; The &quot;get_file&quot; part may be confusing, originally HTTP was only used to access files in the web server.&lt;/p&gt;&lt;p&gt;It may also seem that the second method only resolves the server name through DNS and then does the same thing as the first method, but there is an import difference: the second method puts the server name in the HTTP headers. It is very common for a web server (with a single IP) answer requests that come to different server names and use the name in the header to figure out what it needs to do.&lt;/p&gt;&lt;p&gt;Now all we have to do is the old &lt;i&gt;callback&lt;/i&gt;&amp;nbsp;programming. The signature of&amp;nbsp;&amp;nbsp;&lt;span style=&quot;font-family: courier;&quot;&gt;httpc_get_file_dns()&lt;/span&gt;&amp;nbsp;is:&lt;/p&gt;&lt;pre&gt;err_t 	 httpc_get_file_dns (
   const char *server_name, 
   u16_t port, 
   const char *uri, 
   const httpc_connection_t *settings,
   altcp_recv_fn recv_fn, 
   void *callback_arg, 
   httpc_state_t **connection)
&lt;/pre&gt;&lt;p&gt;Where httpc_connection_t contains:&lt;/p&gt;&lt;pre&gt;typedef struct _httpc_connection {
  ip_addr_t proxy_addr;
  u16_t proxy_port;
  u8_t use_proxy;
  /* this callback is called when the transfer is finished (or aborted) */
  httpc_result_fn result_fn;
  /* this callback is called after receiving the http headers
     It can abort the connection by returning != ERR_OK */
  httpc_headers_done_fn headers_done_fn;
} httpc_connection_t;
&lt;/pre&gt;&lt;p&gt;So there are three callbacks involved:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;recv_fn is where we get the data&lt;/li&gt;&lt;li&gt;result_fn is where we get the final result (but not the data)&lt;/li&gt;&lt;li&gt;headers_done_fn is where we get the headers in the response&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;/div&gt;&lt;div&gt;Let&#39;s write a very simple example that consults the 01001000 CEP and shows the response in the standard output:&lt;/div&gt;
  &lt;div&gt;&lt;pre&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
#include &amp;lt;time.h&amp;gt;

#include &quot;pico/stdlib.h&quot;
#include &quot;pico/cyw43_arch.h&quot;
#include &quot;hardware/i2c.h&quot;

#include &quot;lwip/pbuf.h&quot;
#include &quot;lwip/tcp.h&quot;
#include &quot;lwip/apps/http_client.h&quot;
#include &quot;secret.h&quot;

char myBuff[2000];

// called at the end of the transfer
void got_result(void *arg, httpc_result_t httpc_result,
        u32_t rx_content_len, u32_t srv_res, err_t err)

{
    printf(&quot;\nTransfer fineshed\n&quot;);
    printf(&quot;result=%d\n&quot;, httpc_result);
    printf(&quot;http code=%d\n&quot;, srv_res);
}

// called when we get the headers
err_t got_headers(httpc_state_t *connection, void *arg, 
    struct pbuf *hdr, u16_t hdr_len, u32_t content_len)
{
    printf(&quot;\nHeaders received\n&quot;);
    printf(&quot;Content length=%d\n&quot;, content_len);
    printf(&quot;Header length %d\n&quot;, hdr_len);
    pbuf_copy_partial(hdr, myBuff, hdr_len, 0);
    myBuff[hdr_len] = 0;
    printf(&quot;Headers: \n&quot;);
    printf(&quot;%s&quot;, myBuff);
    printf(&quot;\nContent body:\n&quot;);
    return ERR_OK;
}

// called when we get the data
err_t got_data(void *arg, struct altcp_pcb *conn, 
                            struct pbuf *p, err_t err)
{
    pbuf_copy_partial(p, myBuff, p-&amp;gt;tot_len, 0);
    myBuff[p-&amp;gt;tot_len] = 0;
    printf(&quot;%s&quot;, myBuff);
    return ERR_OK;
}


// Main program
int main() {
    // Start stdio and wait USB connected
    stdio_init_all();
    while (!stdio_usb_connected()) {
        sleep_ms(100);
    }
    printf(&quot;\nREST API Test\n&quot;);

    // Start CYW43 and select country
    if (cyw43_arch_init_with_country(CYW43_COUNTRY_BRAZIL)) {
        printf(&quot;failed to initialise\n&quot;);
        return 1;
    }

    // Start WiFi in Station Mode
    cyw43_arch_enable_sta_mode();

    // Try to connect
    if (cyw43_arch_wifi_connect_timeout_ms(WIFI_SSID, WIFI_PASSWORD, 
        CYW43_AUTH_WPA2_AES_PSK, 10000)) {
        printf(&quot;Error connecting WiFi\n&quot;);
        return 1;
    }
    char sIP[] = &quot;xxx.xxx.xxx.xxx&quot;;
    strcpy (sIP, ip4addr_ntoa(netif_ip4_addr(netif_list)));
    printf (&quot;Connected, IP %s\n&quot;, sIP);

    // Access the API
    httpc_connection_t settings;
    settings.result_fn = got_result;
    settings.headers_done_fn = got_headers;

    cyw43_arch_lwip_begin();
    err_t err = httpc_get_file_dns(
            &quot;viacep.com.br&quot;, 80, &quot;/ws/01001000/json/&quot;,
            &amp;amp;settings, got_data, NULL, NULL
        ); 
    cyw43_arch_lwip_end();

    printf(&quot;Immediate Status: %d \n&quot;, err);
    while (true){
        #if PICO_CYW43_ARCH_POLL
        cyw43_arch_poll();
        sleep_ms(1);
        #else
        sleep_ms(10);
        #endif
    }
    
    cyw43_arch_deinit();
    return 0;    
}&lt;/pre&gt;&lt;/div&gt;
&lt;div&gt;This code is very crude and limited. Most API nowadays use http&lt;b&gt;s&lt;/b&gt;, which requires an encrypted connection. Also, the HTTP module does not support redirects (this broke my first try).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Using MicroPython&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;MicroPython makes things easier and does support https. For this example I will use a free and open API for information on the Star Wars movies. For the full documentation, access &lt;a href=&quot;https://swapi.dev/documentation&quot;&gt;https://swapi.dev/documentation&lt;/a&gt;. A query is done by acessing &lt;span style=&quot;font-family: courier;&quot;&gt;https://swapi.dev/api/films/{film}/&lt;/span&gt; where{film} is the film number (1 to 9 in the release order). The answer comes in json format:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;nbsp; &amp;nbsp; &quot;characters&quot;: [&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &quot;https://swapi.dev/api/people/1/&quot;,&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ...&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;nbsp; &amp;nbsp; ],&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;nbsp; &amp;nbsp; &quot;created&quot;: &quot;2014-12-10T14:23:31.880000Z&quot;,&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;nbsp; &amp;nbsp; &quot;director&quot;: &quot;George Lucas&quot;,&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;nbsp; &amp;nbsp; &quot;edited&quot;: &quot;2014-12-12T11:24:39.858000Z&quot;,&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;nbsp; &amp;nbsp; &quot;episode_id&quot;: 4,&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;nbsp; &amp;nbsp; &quot;opening_crawl&quot;: &quot;It is a period of civil war...&quot;,&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;nbsp; &amp;nbsp; &quot;planets&quot;: [&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &quot;https://swapi.dev/api/planets/1/&quot;,&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ...&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;nbsp; &amp;nbsp; ],&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;nbsp; &amp;nbsp; &quot;producer&quot;: &quot;Gary Kurtz, Rick McCallum&quot;,&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;nbsp; &amp;nbsp; &quot;release_date&quot;: &quot;1977-05-25&quot;,&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;nbsp; &amp;nbsp; &quot;species&quot;: [&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &quot;https://swapi.dev/api/species/1/&quot;,&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ...&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;nbsp; &amp;nbsp; ],&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;nbsp; &amp;nbsp; &quot;starships&quot;: [&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &quot;https://swapi.dev/api/starships/2/&quot;,&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ...&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;nbsp; &amp;nbsp; ],&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;nbsp; &amp;nbsp; &quot;title&quot;: &quot;A New Hope&quot;,&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;nbsp; &amp;nbsp; &quot;url&quot;: &quot;https://swapi.dev/api/films/1/&quot;,&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;nbsp; &amp;nbsp; &quot;vehicles&quot;: [&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &quot;https://swapi.dev/api/vehicles/4/&quot;,&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ...&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;nbsp; &amp;nbsp; ]&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The code bellow consult the data on the first film and prints its title and opening crawl text.&lt;/div&gt;
&lt;div&gt;&lt;pre&gt;import rp2
import network
import time
import urequests
import json
 
film = 1
url = &#39;https://swapi.dev/api/films/{0}/&#39;.format(film)
TIMEOUT = 10
 
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(&#39;essid&#39;, &#39;password&#39;)
 
print (&#39;Connecting...&#39;)
 
timeout = time.ticks_add(time.ticks_ms(), TIMEOUT*1000)
while not wlan.isconnected() and wlan.status() &amp;gt;= 0 and \
      time.ticks_diff(timeout, time.ticks_ms()) &amp;gt; 0:
    time.sleep(0.2)
     
if wlan.isconnected():
    print (&#39;Connected&#39;)
    print (&#39;Querying film {0}&#39;.format(film))
    r = urequests.get(url)
    if r.status_code == 200:
        response = json.loads(r.text)
        print (&#39;Episode {0}: {1}&#39;.format(response[&#39;episode_id&#39;],
               response[&#39;title&#39;]))
        print (response[&#39;opening_crawl&#39;])
    else:
        print (&#39;ERROR: {0}&#39;.format(r.status_code));
    r.close()
else:
    print (&#39;ERROR: Could not connect the WiFi!&#39;)
 
wlan.active(False)&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;</description><link>https://raspico.blogspot.com/2023/03/using-wifi-in-raspberry-pi-pico-part-5.html</link><author>noreply@blogger.com (Daniel Quadros)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj21BkO_Z-knFD1bF-E-nVV81vA7GtqqvrjwuoZvEvgG8BikecJ2LjtwrYuJZJRnX-A2hmMQUF0lRQEjzJ2suLjnJcwm0fXXjvjdO1HRKS7eI8-1dPJPrIMDPAimKRXNKy7wiUp4OtDcmbQxGrLAWdlC6a9v8wmxH-GQJkr18y0Yr08PXFHkX-m0lxr/s72-w400-h276-c/API.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7859657580199211900.post-6679936164594913429</guid><pubDate>Mon, 06 Mar 2023 10:00:00 +0000</pubDate><atom:updated>2023-03-06T02:00:00.151-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Boards</category><title>Mini Review: Banana Pi BPI-PicoW-S3, an ESP32-S3 Board with the Pico Form Factor</title><description>&lt;p&gt;Banana Pi is known for its alternatives to Raspberry Pi SBCs (single board computers). Now they have launched a board with the same pinout and form factor as the Pi Pico, but with an ESP32-S3 microcontroller. Let&#39;s take a look at it.&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjN0QBM-e4IetpK05pu8YUxh25iqsTjKUFd5rekm3T1hvPsolv_H5pC5gboRiFuE4RYgvtKHXg8YGazYyKIXnRw9nsBcKRBpz3WlU3Np62289iMXkUVHH8RofCH-Il7672JWLTnM1Fv_TdevgemfcojSVzsyJ-eZ-k9wxaeTGdysXOco-HTFE9Du4NN/s1280/BPI_PicoW.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;720&quot; data-original-width=&quot;1280&quot; height=&quot;180&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjN0QBM-e4IetpK05pu8YUxh25iqsTjKUFd5rekm3T1hvPsolv_H5pC5gboRiFuE4RYgvtKHXg8YGazYyKIXnRw9nsBcKRBpz3WlU3Np62289iMXkUVHH8RofCH-Il7672JWLTnM1Fv_TdevgemfcojSVzsyJ-eZ-k9wxaeTGdysXOco-HTFE9Du4NN/s320/BPI_PicoW.jpg&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;span&gt;&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;/span&gt;&lt;p&gt;Physically the board has the same size, the same number of pins (castellated and with practically the same signals) and the same USB micro connector as the Pico.&lt;/p&gt;&lt;p&gt;The difference is that it has an ESP32-S3 instead of a RP2040. The S3 line was launched by Espressif in 2020 (four years after the original ESP32) and has some advantages over the &quot;plain&quot; ESP32 (that is still available):&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Two eXtensa LX7 cores instead of two LX6 cores, adding vector instructions. The clock remains at 240MHz&lt;/li&gt;&lt;li&gt;Bluetooth was upgraded to version 5&lt;/li&gt;&lt;li&gt;Native OTG USB (can be used as host or device).&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Internal RAM is nearly the same (512k in the S3 versus 520K in the original ESP32). The chip used includes 2M of PSRAM (inside the chip but external of the microcontroller. Two features of the original ESP32 are not available in the ESP32-S3: the DAC and the ethernet interface.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Of course, the ESP32-S3 includes WiFi and Bluetooth that is not available in the RP2040 and the plain Pico. The Pico W uses an external chip to implement wireless and Bluetooth support is beta at this moment.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The board includes an 8M Flash, a Reset button and a WS2812 RGB LED. Instead of a BOOT button (like most ESP32 boards), there are two pads that can be shorted with tweezers.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;On the software side, there is support for all traditional environments: ESP-IDF, Arduino, MicroPython and CircuitPython.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The BPI-PicW-S3 os a powerful and well made board with good software support and good documentation (at&amp;nbsp;&lt;a href=&quot;https://wiki.banana-pi.org/BPI-PicoW-S3&quot;&gt;https://wiki.banana-pi.org/BPI-PicoW-S3&lt;/a&gt;). Price (in Aliexpress stores) is around US$10.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I am not sure if using the Pico form factor is a great advantage. On one hand, this gives mechanical and electrical compatibility with the few Pico expansion boards available. On the other hand, there is the question of software compatibility. Software written using the Pico SDKs will not be easy to adapt to ESP-IDF. Code written in MicroPython or CircuitPython we need adjustments, there is greater hope with Arduino code. All this if the code does not use the PIO feature of the RP2040, as the ESP32-S3 has nothing equivalent.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;</description><link>https://raspico.blogspot.com/2023/03/mini-review-banana-pi-bpi-picow-s3.html</link><author>noreply@blogger.com (Daniel Quadros)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjN0QBM-e4IetpK05pu8YUxh25iqsTjKUFd5rekm3T1hvPsolv_H5pC5gboRiFuE4RYgvtKHXg8YGazYyKIXnRw9nsBcKRBpz3WlU3Np62289iMXkUVHH8RofCH-Il7672JWLTnM1Fv_TdevgemfcojSVzsyJ-eZ-k9wxaeTGdysXOco-HTFE9Du4NN/s72-c/BPI_PicoW.jpg" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7859657580199211900.post-2445490684229609533</guid><pubDate>Mon, 27 Feb 2023 10:00:00 +0000</pubDate><atom:updated>2023-02-27T02:00:00.151-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">News</category><title>Raspberry Pi Debug Probe and C/C++ SDK &amp; Tools Easy Install on Windows</title><description>&lt;p&gt;&amp;nbsp;In an unexpected move, the Raspberry Foundation&amp;nbsp; &lt;a href=&quot;https://www.raspberrypi.com/news/raspberry-pi-debug-probe-a-plug-and-play-debug-kit-for-12/&quot;&gt;announced&lt;/a&gt; the &lt;i&gt;Raspberry Pi Debug Probe&lt;/i&gt;, an interesting accessory for the Pico boards (and other boards with ARM microcontrollers).&lt;/p&gt;&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhhI1w2ZtRjKPVDZyIe5jiAjNwQef_bIqDqDac660nuRS57oL0G2zrg8AOvDcKAGX8N9i-JFQGjSns9KuqehEiHZN-9o-XoS5uu0at1AfCalF-GJMmUmhcpS1IamX-I72kgwt-MKOlCldrWwKgk9k7L-MzzIsSQV8coUc9FPTmtU2OlOVogMCicfvtq/s800/DEBUG_PROBE_PCB_TOP-800x531.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;531&quot; data-original-width=&quot;800&quot; height=&quot;212&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhhI1w2ZtRjKPVDZyIe5jiAjNwQef_bIqDqDac660nuRS57oL0G2zrg8AOvDcKAGX8N9i-JFQGjSns9KuqehEiHZN-9o-XoS5uu0at1AfCalF-GJMmUmhcpS1IamX-I72kgwt-MKOlCldrWwKgk9k7L-MzzIsSQV8coUc9FPTmtU2OlOVogMCicfvtq/s320/DEBUG_PROBE_PCB_TOP-800x531.jpg&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;The Debug Probe board&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;p&gt;A few days later, they &lt;a href=&quot;https://www.raspberrypi.com/news/raspberry-pi-pico-windows-installer/&quot;&gt;announced&lt;/a&gt; the &lt;i&gt;Raspbery Pi Pico Windows Installer&lt;/i&gt; for easier installation of the SDK and the complete toolchain needed for developing C/C++ for the Picos under Windows.&lt;/p&gt;&lt;span&gt;&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;/span&gt;&lt;p&gt;The &lt;i&gt;Debug Probe&lt;/i&gt; is a commercial version of the &lt;i&gt;picoprobe&lt;/i&gt; (described in the&amp;nbsp;&lt;i&gt;Getting Started with Raspberry Pi Pico&lt;/i&gt; document). Like other ARM based microcontroller, the RP2040 includes debugging facilities accessible through an SWD (Serial Wire Debug) port. This port requires two signals, SWIO (data) and SWCLK (clock), plus ground connections. Its use boils down to controlling this signals according to a protocol.&lt;/p&gt;&lt;p&gt;The picoprobe is an normal Raspberry Pi Pico running an special firmware to make it act as an &quot;SWD bridge&quot;. It is pretty simple to connect the picoprobe to another Pico (the target of the debugging) . With a little more effort you can get the OpenOCD debugger working, even inside Visual Code.&lt;/p&gt;&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhFcTC1vIbV-8ugWyEJJhgfTijzcnKYfoq90Mhz4pfxDJyyadjckT8-9e3mX1CMEw-ZnKzj05WP0dEoJLQx7BdUdHBdzsNLPgbvP4-ETItkAq35sBgbMUxE5Sx7YJU4YWW2tya8tgIDRm8YXRLgsZBB39btLQ4fN3ZedY1oK0VA3L73uALipOU1gBxp/s1365/picoprobe.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1365&quot; data-original-width=&quot;1024&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhFcTC1vIbV-8ugWyEJJhgfTijzcnKYfoq90Mhz4pfxDJyyadjckT8-9e3mX1CMEw-ZnKzj05WP0dEoJLQx7BdUdHBdzsNLPgbvP4-ETItkAq35sBgbMUxE5Sx7YJU4YWW2tya8tgIDRm8YXRLgsZBB39btLQ4fN3ZedY1oK0VA3L73uALipOU1gBxp/s320/picoprobe.jpg&quot; width=&quot;240&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;My take on the picoprobe&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;The picoprobe (and the Debug Probe) can also be used as a serial to USB adapter for any kind of asynchronous (UART) communication at 3.3V.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The Debug Probe is a beautiful product. Instead of the Pico it uses a dedicated board (with an RP2040, of course) that has connectors for the SWD and UART. It comes in a nice transparent box and three cables:&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGNaRCrU1ctsG8ha4nwU4cmc1rB0KwBVuco6ZgSLR37zfg7UF3OmP-Tgg75sHNxo-6qDXl2GsmWTmIn6AAgQfHJP2tmUcoCj8HJXC_QpFxxPlJa4a3GhMGUTJhlcA5leB2UoZcAro-XpJ4Xj6moe2aCX4adUS1HP_SjaRd8tRoEvZxMBGQISxPkrZe/s800/DEBUG_PROBE_WITH_CABLES-800x533.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;533&quot; data-original-width=&quot;800&quot; height=&quot;213&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGNaRCrU1ctsG8ha4nwU4cmc1rB0KwBVuco6ZgSLR37zfg7UF3OmP-Tgg75sHNxo-6qDXl2GsmWTmIn6AAgQfHJP2tmUcoCj8HJXC_QpFxxPlJa4a3GhMGUTJhlcA5leB2UoZcAro-XpJ4Xj6moe2aCX4adUS1HP_SjaRd8tRoEvZxMBGQISxPkrZe/s320/DEBUG_PROBE_WITH_CABLES-800x533.jpg&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Back there I said it takes some work to set up the debugger. The same could be said about the toolchain necessary for developing C/C++ applications for the Pico under Windows. Multiple downloads were necessary from various places. Well, no more! The&amp;nbsp;&amp;nbsp;&lt;i&gt;Raspbery Pi Pico Windows Installer&lt;/i&gt; is a single download that automates all this process. It will install in a Windows machine:&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Arm GNU Toolchain&lt;/li&gt;&lt;li&gt;CMake&lt;/li&gt;&lt;li&gt;Ninja&lt;/li&gt;&lt;li&gt;Python 3.9&lt;/li&gt;&lt;li&gt;Git for Windows&lt;/li&gt;&lt;li&gt;Visual Studio Code&lt;/li&gt;&lt;li&gt;OpenOCD&lt;/li&gt;&lt;li&gt;Pico C/C++ SDK&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;At the end of the install you will be ready to develop (and debug) C/C++ applications for the Pico. A great help indeed.&lt;/div&gt;&lt;div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;/div&gt;</description><link>https://raspico.blogspot.com/2023/02/raspberry-pi-debug-probe-and-cc-sdk.html</link><author>noreply@blogger.com (Daniel Quadros)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhhI1w2ZtRjKPVDZyIe5jiAjNwQef_bIqDqDac660nuRS57oL0G2zrg8AOvDcKAGX8N9i-JFQGjSns9KuqehEiHZN-9o-XoS5uu0at1AfCalF-GJMmUmhcpS1IamX-I72kgwt-MKOlCldrWwKgk9k7L-MzzIsSQV8coUc9FPTmtU2OlOVogMCicfvtq/s72-c/DEBUG_PROBE_PCB_TOP-800x531.jpg" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7859657580199211900.post-5459870907994150427</guid><pubDate>Mon, 13 Feb 2023 10:00:00 +0000</pubDate><atom:updated>2023-02-23T11:34:34.506-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">WiFi</category><title>Using WiFi in the Raspberry Pi Pico (Part 4)</title><description>&lt;p&gt;We will now take a look at TCP communication. There are client and server examples at pico-examples, let&#39;s see if we can understand what is done.&lt;/p&gt;&lt;span&gt;&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;/span&gt;&lt;p&gt;These two examples are written to talk one to the other. The clients connects to the server, that sends a message. The client receives this message and send it back to the server. This is repeated a few times and the test is concluded.&lt;/p&gt;&lt;p&gt;I will not analyze the code for the WiFi connection (we have looked at it before).&lt;/p&gt;&lt;p&gt;&lt;b&gt;TCP Client&lt;/b&gt;&lt;/p&gt;&lt;p&gt;The code can be seem at&amp;nbsp;&lt;a href=&quot;https://github.com/raspberrypi/pico-examples/blob/master/pico_w/tcp_client/picow_tcp_client.c&quot;&gt;https://github.com/raspberrypi/pico-examples/blob/master/pico_w/tcp_client/picow_tcp_client.c&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Like in UDP, the communication state is stores in a &quot;pcb&quot; structure&amp;nbsp; (in this case tcp_pcb). The creation of this structure, the registering of the callbacks and the triggering of the connection are in the&amp;nbsp;&lt;span style=&quot;font-family: courier;&quot;&gt;tcp_client_open &lt;/span&gt;function:
&lt;/p&gt;&lt;pre&gt;// Simplified and commented version
static bool tcp_client_open(void *arg) {
	
    // create the PCB PCB (Protocol Control Block)
    state-&amp;gt;tcp_pcb = tcp_new_ip_type(IP_GET_TYPE(&amp;amp;state-&amp;gt;remote_addr));

    // Define the callbacks argument
    tcp_arg(state-&amp;gt;tcp_pcb, state);
	
    // Register a callback called periodic
    tcp_poll(state-&amp;gt;tcp_pcb, tcp_client_poll, POLL_TIME_S * 2);
    
    // Register a callback that is called when a transmission is acknowledge by the receiver
    tcp_sent(state-&amp;gt;tcp_pcb, tcp_client_sent);
    
    // Register a callback that is called when data is received
    tcp_recv(state-&amp;gt;tcp_pcb, tcp_client_recv);
    
    // // Register a callback that is called when a fatal error occurs
    tcp_err(state-&amp;gt;tcp_pcb, tcp_client_err);

    // Triggers the connection, tcp_client_connected will be called if and when a connection is successful
    cyw43_arch_lwip_begin();
    err_t err = tcp_connect(state-&amp;gt;tcp_pcb, &amp;amp;state-&amp;gt;remote_addr, 
                        TCP_PORT, tcp_client_connected);
    cyw43_arch_lwip_end();

    return err == ERR_OK;
}&lt;/pre&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;OK, we can understand this. TCP communication works through the callbacks, lwIP will call your routines when something happens. Let&#39;s see what each callback does in the example:&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;tcp_client_poll(): just does a print to signal it was called&lt;/li&gt;&lt;li&gt;tcp_client_err(): prints an error message&lt;/li&gt;&lt;li&gt;tcp_client_connected(): updates the application state to wait data from the server&lt;/li&gt;&lt;li&gt;tcp_client_recv(): receives the data from the server and, optionally, prints it. The data is sent back to the server through a tcp_write()&lt;/li&gt;&lt;li&gt;tcp_client_sent(): checks if the test is finished, if not waits for more data&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;At the end of the test all callbacks are cancelled and the connection is closed.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;b&gt;TCP Server&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;The server initiation (at&amp;nbsp;&amp;nbsp;&lt;span style=&quot;font-family: courier;&quot;&gt;tcp_server_open&lt;/span&gt;) is done by calling:&lt;/div&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;tcp_bind()&amp;nbsp; to set the port that will be monitored&lt;/li&gt;&lt;li&gt;tcp_listen_with_backlog(): to get ready for connection requests, return a pcb specific for this. All connection requests will be put in a queue (in this case with just one position)&lt;/li&gt;&lt;li&gt;tcp_accept(): start waiting for a connection and sets the callback that will be called when it is established&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;The next step in the server occurs in the&amp;nbsp;&lt;span style=&quot;font-family: courier;&quot;&gt;tcp_server_accept()&lt;/span&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt; function that is called when a connection is &lt;/span&gt;established&lt;span style=&quot;font-family: inherit;&quot;&gt;. This routine defines the&amp;nbsp;&lt;/span&gt;poll, err, recv and sent callbacks (as in the client) and uses tcp_write() to send data to the client.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The sent callback readies the server to receive the answer from the client. When the answer is received (in the recv callback), it is checked. If everything is OK, and the test is not finished, another data message is sent.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;At the end of the test all callbacks are cancelled and the connection is closed.&lt;/div&gt;&lt;br /&gt;&lt;b&gt;Some Comments&lt;/b&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;Once you get used to the examples code structure it is not hard to understand the programs. The lwIP TCP programming interface is not complex (if you are used to work with callbacks).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This examples are written to do a single test. At the end of a connection the server will not loop to the accept to wait for another client to connect.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Based on this example (and writing a good amount of code) should not be hard to write two applications that talk to each other using simple TCP messages. By today it all about using RESP APIs and that is what I gonna try in the next post.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;</description><link>https://raspico.blogspot.com/2023/02/using-wifi-in-raspberry-pi-pico-part-4.html</link><author>noreply@blogger.com (Daniel Quadros)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7859657580199211900.post-5678101227208432852</guid><pubDate>Sat, 11 Feb 2023 14:03:00 +0000</pubDate><atom:updated>2023-02-23T11:34:54.905-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Bluetooth</category><title>Support for Bluetooth in the Pico W Has Arrived (and more)</title><description>&lt;p&gt;When the Raspberry Pi Pico W was launched (seven months ago), a somewhat surprise was that the hardware supported Bluetooth but the software did not. All that was said then was that it &lt;i&gt;maybe&lt;/i&gt; added in the future. At the beginning of this year, &lt;a href=&quot;https://github.com/raspberrypi/pico-sdk/issues/1164&quot;&gt;BT support was included in the plans for version 1.5 of the C/C++ SDK&lt;/a&gt;, &lt;a href=&quot;https://twitter.com/aallan/status/1610616300597907456&quot;&gt;expected for the end of January&lt;/a&gt;. It took a few days more, but the new SDK version was released and yes, it includes support for Bluetooth in the Pico W, but it is labeled as &lt;i&gt;BETA&lt;/i&gt;. It also includes other important fixes and enhancements.&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjv-xdwoHrEpgFkdtLx0fI6LWy4VqtUud4ztVq-TffzxXrpWAhbDiF7m9S7e1DY5zRB0OEDl1GYJ71sEVd7yawDitaJBepvfFaVrqqNJsY7V6LfejuidJsWoZViJrBjVcLCCUmBAcurJVtDdPunHaWH48n7eeIEAgUK9YsWUW2XX7ug_VQoAbL0kWmy/s1236/PicoSDK150.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;230&quot; data-original-width=&quot;1236&quot; height=&quot;120&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjv-xdwoHrEpgFkdtLx0fI6LWy4VqtUud4ztVq-TffzxXrpWAhbDiF7m9S7e1DY5zRB0OEDl1GYJ71sEVd7yawDitaJBepvfFaVrqqNJsY7V6LfejuidJsWoZViJrBjVcLCCUmBAcurJVtDdPunHaWH48n7eeIEAgUK9YsWUW2XX7ug_VQoAbL0kWmy/w640-h120/PicoSDK150.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;Bluetooth support is through the &lt;a href=&quot;https://github.com/bluekitchen/btstack&quot;&gt;BTstack&lt;/a&gt; open source library. One concern is that this library is free only for non-commercial applications, it is expect that the &lt;a href=&quot;https://github.com/raspberrypi/pico-sdk/issues/1164&quot;&gt;Raspberry Pi Foundation will cut some kind of deal with the developers&lt;/a&gt; to allow unrestricted use with the Pico W. BTstack is a very comprehensive implementation of the Bluetooth protocols with support for BLE and many BT profiles. Specific documentation for the Pico W is not available right now but there are quite a few examples available.&lt;p&gt;&lt;/p&gt;&lt;p&gt;It is expected that MicroPython and CircuitPython will add Bluetooth support soon. Also expected are projects from the community.&lt;/p&gt;&lt;p&gt;But the new version is not only about Bluetooth support. The full list of changes can be seem at &lt;a href=&quot;https://github.com/raspberrypi/pico-sdk/releases/tag/1.5.0&quot;&gt;github&lt;/a&gt;, here are some highlights:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;numerous bugfixes&lt;/li&gt;&lt;li&gt;many small enhancements to the existing libraries with the addition of new functions&lt;/li&gt;&lt;li&gt;upgrade of tinyusb from version&amp;nbsp;0.12.0 to 0.15.0. This can break some existing code, but promises great improvements in host mode&lt;/li&gt;&lt;li&gt;addition of a library (pico_i2c_slave) for implementing I2C slaves&lt;/li&gt;&lt;li&gt;addition of TLS support (pico_mbedtls library)&lt;/li&gt;&lt;li&gt;addition of the&amp;nbsp;pico_rand library for generating &quot;largely unpredictable random numbers&quot; for better crypto applications&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;If you are developing for the RP2040 in C or C++, you should start looking right now into this version. If you are using tinyusb you may have to make some changes in your code.&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;This also means that a will have to revise my book on the RP2040 (now also available on &lt;a href=&quot;https://www.amazon.com/dp/B0BRCBL9N7&quot;&gt;Amazon&lt;/a&gt;).&lt;/p&gt;</description><link>https://raspico.blogspot.com/2023/02/support-for-bluetooth-in-pico-w-has.html</link><author>noreply@blogger.com (Daniel Quadros)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjv-xdwoHrEpgFkdtLx0fI6LWy4VqtUud4ztVq-TffzxXrpWAhbDiF7m9S7e1DY5zRB0OEDl1GYJ71sEVd7yawDitaJBepvfFaVrqqNJsY7V6LfejuidJsWoZViJrBjVcLCCUmBAcurJVtDdPunHaWH48n7eeIEAgUK9YsWUW2XX7ug_VQoAbL0kWmy/s72-w640-h120-c/PicoSDK150.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7859657580199211900.post-5000596764017089180</guid><pubDate>Thu, 24 Nov 2022 10:00:00 +0000</pubDate><atom:updated>2023-02-23T11:34:34.506-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">WiFi</category><title>Using WiFi in the Raspberry Pi Pico (Part 3)</title><description>&lt;p&gt;As the next step in my studies, I implemented a SNTP client. I also connected an alphanumeric display, so there was something to see in the photo.&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvRxDepo4wOBZAeDnxyjF9MTeL3aJXPkyP67Xer4bZQxr0OG8sadBTZTGAN-ojg4i6Bl4c7i7vh1YBwEewr-pCLtBYOL3LmVSxoYzG3CRim1ZETYMYMvxrP7DsBCOVlG683MKhX5_gbmYeF4xUDON0ZGIfYwklkUjCejIPzIng511P6-5ioZUImfDh/s2048/SNTP_PicoW.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1691&quot; data-original-width=&quot;2048&quot; height=&quot;264&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvRxDepo4wOBZAeDnxyjF9MTeL3aJXPkyP67Xer4bZQxr0OG8sadBTZTGAN-ojg4i6Bl4c7i7vh1YBwEewr-pCLtBYOL3LmVSxoYzG3CRim1ZETYMYMvxrP7DsBCOVlG683MKhX5_gbmYeF4xUDON0ZGIfYwklkUjCejIPzIng511P6-5ioZUImfDh/s320/SNTP_PicoW.jpg&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;span&gt;&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;/span&gt;&lt;p&gt;&lt;b&gt;Compiling for the Pico W using Visual Code&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Thought having Visual Code already set for the plain Pico, it took me sometime to set things for compiling a program for the Pico W (the &quot;Getting Started&quot; guide shows only compiling using the command line). I used Windows in this test, but the settings should also work under Linux.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ol style=&quot;text-align: left;&quot;&gt;&lt;li&gt;In the CMakeLists.txt file, put &quot;set(PICO_BOARD pico_w)&quot;&lt;/li&gt;&lt;li&gt;Also in CMakeLists.txt, add the current directory to the list of include directories &quot;target_include_directories(projeto PRIVATE ${CMAKE_CURRENT_LIST_DIR} )&quot;&lt;/li&gt;&lt;li&gt;Still in CMakeLists.txt, put pico_cyw43_arch_lwip_poll in the library list (target_link_libraries)&lt;/li&gt;&lt;li&gt;Copy the lwipopts_examples_common.h file from pico_examples\pico_w to your working directory with the name lwipopts.h&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;I, unintendedly, built the debug version. This cause some interesting messages to be sent to stdio.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Connecting the Display&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Nothing very special here. I disregarded my own advice and connected the 3.3V Pico directly to the I2C interface of the 5V display. Do that at your own risk!&lt;/p&gt;&lt;p&gt;I adapted the code from some old project.&lt;/p&gt;&lt;p&gt;&lt;b&gt;The SNTP Client&lt;/b&gt;&lt;/p&gt;&lt;p&gt;I started from some code I wrote before, but the TCP communication is very different in the Pico W (as compared to the Arduino libraries). I tried to write something a little more readable than the SDK examples. My original code used synchronous functions (that block until they finished), in this version everything is done asynchronous (the SNTPupdate() function must be called periodically&amp;nbsp;).&lt;/p&gt;&lt;p&gt;DNS is consulted before each access to the SNTP server, like in the SDK example. Thanks to the local caching actual communication is not done at every call.&lt;/p&gt;&lt;p&gt;The final result can be seem at&amp;nbsp;&lt;span style=&quot;background-color: white; color: #222222; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13.2px;&quot;&gt;&lt;a href=&quot;https://github.com/dquadros/SNTP_PicoW&quot;&gt;https://github.com/dquadros/SNTP_PicoW&lt;/a&gt;&amp;nbsp;(with Portugues comments).&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description><link>https://raspico.blogspot.com/2022/11/using-wifi-in-raspberry-pi-pico-part-3.html</link><author>noreply@blogger.com (Daniel Quadros)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvRxDepo4wOBZAeDnxyjF9MTeL3aJXPkyP67Xer4bZQxr0OG8sadBTZTGAN-ojg4i6Bl4c7i7vh1YBwEewr-pCLtBYOL3LmVSxoYzG3CRim1ZETYMYMvxrP7DsBCOVlG683MKhX5_gbmYeF4xUDON0ZGIfYwklkUjCejIPzIng511P6-5ioZUImfDh/s72-c/SNTP_PicoW.jpg" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7859657580199211900.post-2084232643185427163</guid><pubDate>Mon, 14 Nov 2022 13:00:00 +0000</pubDate><atom:updated>2023-02-23T11:34:34.506-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">WiFi</category><title>Using WiFi in the Raspberry Pi Pico (Part 2)</title><description>&lt;p&gt;As I mentioned before, I decided to start my study of the Pi Picos&#39;s C/C++ SDK function for WiFi communication implementing an &lt;b&gt;SNTP client&lt;/b&gt;. This just an exercise, as it is also available in both the lwIP library and the SDK examples. So we start by looking how it is done in the SDK example (code &lt;a href=&quot;https://github.com/raspberrypi/pico-examples/blob/master/pico_w/ntp_client/picow_ntp_client.c&quot;&gt;here&lt;/a&gt;).&lt;/p&gt;&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBUFU5uwkOtpkUwZ_C5tF3mGlRA6S_nF_ZFwzQyIjNaR6u5tvaVjfZFu8fn8qXu6pC76b5o1b5cML7IwxoPXEsP31Ih6T7sPTwQqJ7HH8nO-m57NVISrA9uotBLdNX-HDx0fCxKVmOdlqz_Y8MATAoOMknaS96X6P1hoLrAH3GYB6sYsluUi0wgnqk/s661/NtpClient.png&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;150&quot; data-original-width=&quot;661&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBUFU5uwkOtpkUwZ_C5tF3mGlRA6S_nF_ZFwzQyIjNaR6u5tvaVjfZFu8fn8qXu6pC76b5o1b5cML7IwxoPXEsP31Ih6T7sPTwQqJ7HH8nO-m57NVISrA9uotBLdNX-HDx0fCxKVmOdlqz_Y8MATAoOMknaS96X6P1hoLrAH3GYB6sYsluUi0wgnqk/s16000/NtpClient.png&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;The Pico example output&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;span&gt;&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;/span&gt;My first read of the code was not encouraging. To understand it we will examine it a part at a time. I am assuming you know the basics of TCP/IP and recommend you read my comments alongside the source code.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The first block to analyze is the the &lt;span style=&quot;font-family: courier;&quot;&gt;main()&lt;/span&gt; function. It contains calls to the following&amp;nbsp;cyw43_arch functions:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;cyw43_arch_init()&lt;/span&gt;&amp;nbsp;- initializes the WiFi communication librarties&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;cyw43_arch_enable_sta_mode()&lt;/span&gt;&amp;nbsp;- puts the WiFi in &quot;&lt;i&gt;station&lt;/i&gt;&quot; mode, as we are going to connect to an WiFi AP&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;cyw43_arch_wifi_connect_timeout_ms()&lt;/span&gt;&amp;nbsp;- try to connect to the AP&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;cyw43_arch_deinit()&lt;/span&gt;&amp;nbsp;- ends the use of the WiFi communication librarties&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;All these functions are documented in the&amp;nbsp;&lt;a href=&quot;https://datasheets.raspberrypi.com/pico/raspberry-pi-pico-c-sdk.pdf&quot;&gt;SDK manual&lt;/a&gt;.&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;So far, so good. Let&#39;s look now at&amp;nbsp;&lt;span style=&quot;font-family: courier;&quot;&gt;run_ntp_test()&lt;/span&gt;, where we find the main loop. The first step of this routine is to call&amp;nbsp;&lt;span style=&quot;font-family: courier;&quot;&gt;ntp_init()&lt;/span&gt;. The program is built around an structure (NTP_T) that holds all its state.&amp;nbsp;&lt;span style=&quot;font-family: courier;&quot;&gt;ntp_init()&lt;/span&gt;&amp;nbsp; allocates this structure and call two functions from the lwIP library (documented &lt;a href=&quot;https://www.nongnu.org/lwip/&quot;&gt;here&lt;/a&gt;):&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;udp_new_ip_type()&lt;/span&gt;&amp;nbsp;- this routine returns a pointer to a&amp;nbsp;&lt;span style=&quot;font-family: courier;&quot;&gt;udp_pcb&lt;/span&gt;&amp;nbsp;structure. &quot;pcb&quot; stands for&amp;nbsp;&lt;i&gt;Protocol Control Block&lt;/i&gt;, the pcbs in lwIP contain the needed information to control the communication for the various protocols.&amp;nbsp;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;udp_recv()&lt;/span&gt;&amp;nbsp;- Here we define the routine that will be called when a UDP packet is received. As we did not specify a protocol port in the pcb, this routine will be called when data is received at any port. We also define that this routine will receive the state as its parameter.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;These functions are parte of the&amp;nbsp;&lt;i&gt;raw&lt;/i&gt;&amp;nbsp;lwIP API. lwIP has others, higher level, APIs but they can be used only along with an RTOS (&lt;i&gt;Real Time Operating System&lt;/i&gt;). The raw API works&amp;nbsp; mainly through &lt;i&gt;callbacks&lt;/i&gt; (don&#39;t call me, I will call you when there are news).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Going back to the main loop (and ignoring the error treatments), the following functions are called:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;cyw43_arch_lwip_begin()&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;dns_gethostbyname()&lt;/span&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;&amp;nbsp;- finds out the AP address of a hostname&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;cyw43_arch_lwip_end()&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;The begin/end surround the lwIP calls to protect against concurrency problems. There are two ways to use lwIP. In the simple way is works by &lt;i&gt;polling&lt;/i&gt;: the&amp;nbsp;&lt;span style=&quot;font-family: courier;&quot;&gt;cyw43_arch_poll()&lt;/span&gt;&amp;nbsp;routine must be called periodically and the begin/end routines do nothing. In the &lt;i&gt;background&lt;/i&gt; mode, lwIP will transparently work concurrently with your code anda begin/end are essentials.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;There are many possible returns from&amp;nbsp;&lt;span style=&quot;font-family: courier;&quot;&gt;dns_gethostbyname()&lt;/span&gt;. The firs time it will return ERR_INPROGRESS, meaning it is still processing the request; the final result will came through a callback. If everything goes fine, the next calls (for a limited time) will use the previous result and return immediately with ERR_OK. Values different from these two indicate errors. In the example, the &lt;span style=&quot;font-family: courier;&quot;&gt;ntp_dns_found()&lt;/span&gt;&amp;nbsp;callback&amp;nbsp; stores the IP address and calls&amp;nbsp;&lt;span style=&quot;font-family: courier;&quot;&gt;ntp_request()&lt;/span&gt;. This same routine is called if&amp;nbsp;&amp;nbsp;&lt;span style=&quot;font-family: courier;&quot;&gt;dns_gethostbyname()&lt;/span&gt;&amp;nbsp;returns ERR_OK immediatly.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now we get to&amp;nbsp;&lt;span style=&quot;font-family: courier;&quot;&gt;ntp_request()&lt;/span&gt;, where the actual SNTP request is sent. Here is the full routine:&lt;/div&gt;
&lt;div&gt;&lt;pre&gt;// Make an NTP request
static void ntp_request(NTP_T *state) {
    cyw43_arch_lwip_begin();
    struct pbuf *p = pbuf_alloc(PBUF_TRANSPORT, NTP_MSG_LEN, PBUF_RAM);
    uint8_t *req = (uint8_t *) p-&amp;gt;payload;
    memset(req, 0, NTP_MSG_LEN);
    req[0] = 0x1b;
    udp_sendto(state-&amp;gt;ntp_pcb, p, &amp;amp;state-&amp;gt;ntp_server_address, NTP_PORT);
    pbuf_free(p);
    cyw43_arch_lwip_end();
}&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div&gt;A few points to highlight:&lt;/div&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;The transmitted packet&amp;nbsp; is allocated using&amp;nbsp;&amp;nbsp;&lt;span style=&quot;font-family: courier;&quot;&gt;pbuf_alloc()&lt;/span&gt;, an lwIP routine that reserves space for the protocol headers and makes sure the packet is allocated in the appropriate memory area according to the system (in the RP2040 case, this can be anywhere in the SRAM).&lt;/li&gt;&lt;li&gt;The actual transmission is done by&amp;nbsp;&amp;nbsp;&lt;span style=&quot;font-family: courier;&quot;&gt;udp_sendto()&lt;/span&gt;, properly surrounded by cw43_arch_lwip_begin/end&lt;/li&gt;&lt;li&gt;The packet can be discarded as soon as&amp;nbsp;&lt;span style=&quot;font-family: courier;&quot;&gt;udp_sendto()&lt;/span&gt;&amp;nbsp;returns.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;In this example there is no association betwen send and received packets. Received packets are treated in the receive callback.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;From an SNTP standard viewpoint this implementation is not robust. Let&#39;s see if I can do better in the next post.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
</description><link>https://raspico.blogspot.com/2022/11/using-wifi-in-raspberry-pi-pico-part-2.html</link><author>noreply@blogger.com (Daniel Quadros)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBUFU5uwkOtpkUwZ_C5tF3mGlRA6S_nF_ZFwzQyIjNaR6u5tvaVjfZFu8fn8qXu6pC76b5o1b5cML7IwxoPXEsP31Ih6T7sPTwQqJ7HH8nO-m57NVISrA9uotBLdNX-HDx0fCxKVmOdlqz_Y8MATAoOMknaS96X6P1hoLrAH3GYB6sYsluUi0wgnqk/s72-c/NtpClient.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7859657580199211900.post-684157137467998564</guid><pubDate>Mon, 07 Nov 2022 10:00:00 +0000</pubDate><atom:updated>2023-02-23T11:34:34.506-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">WiFi</category><title>Using WiFi in the Raspberry Pi Pico (Part 1)</title><description>&lt;p&gt;&amp;nbsp;The Raspbery Pi Pico &lt;b&gt;W&lt;/b&gt;&amp;nbsp;adds to the Pico the ability to do network communication using WiFi (and, maybe, Bluetooth in the future). For starters, I will focus on C/C++ programming. The first steps in learning about the way WiFi is implemented and how to use it are the &lt;a href=&quot;https://www.raspberrypi.com/documentation/microcontrollers/c_sdk.html&quot;&gt;SDK documentation&lt;/a&gt; and the &lt;a href=&quot;https://github.com/raspberrypi/pico-examples&quot;&gt;official examples&lt;/a&gt;. For those who want an easier and faster path, there is also MicroPython support.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgsKc5ROx-HIlKdZMvElA-d8RTVpwJflAfQ6zIQPQ6gSdzJN5MjX97A7wDk4W6Jg-toeS9EB6gi_hi6J-lhvDWbdmE-_JsJelA1OzR0RN2d_t5pZ188lEchvXomvhX6R5YiGnX74oPyHwDxWIx1Y1cYTjknguEe9GetdZeS6ndar6F39idAoaxcbJM9/s2748/20220828_200836.jpg&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1342&quot; data-original-width=&quot;2748&quot; height=&quot;156&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgsKc5ROx-HIlKdZMvElA-d8RTVpwJflAfQ6zIQPQ6gSdzJN5MjX97A7wDk4W6Jg-toeS9EB6gi_hi6J-lhvDWbdmE-_JsJelA1OzR0RN2d_t5pZ188lEchvXomvhX6R5YiGnX74oPyHwDxWIx1Y1cYTjknguEe9GetdZeS6ndar6F39idAoaxcbJM9/s320/20220828_200836.jpg&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;My first Pico W!&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;The WiFi chip used in the Pico W (CYW43439&amp;nbsp;) is a MAC (&lt;i&gt;Media Access Control&lt;/i&gt;) layer solution. This means that it implements the physical layer with its addressing (the MAC address) and the way devices share a common communication medium.&lt;p&gt;&lt;/p&gt;&lt;p&gt;For most practical uses we need other layers above the MAC. Theses layers are implemented in the RP2040 software. In these days, the most used network protocol is TCP/IP.&lt;/p&gt;&lt;p&gt;The support for WiFi and TCP/IP in the RP2040 C/C++ SDK is done by three parts:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;pico_cyw43_arch: this part connects the other two so they can (potentially) be replaced by compatible alternative implementations. It also manages the LED that is connected to the WiFi chip.&lt;/li&gt;&lt;li&gt;the TCP/IP stack: &lt;a href=&quot;https://savannah.nongnu.org/projects/lwip/&quot;&gt;lwIP &lt;/a&gt;is used by the SDK.&lt;/li&gt;&lt;li&gt;cyw43_driver: this is the driver for the chip used in the Pico.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Both the driver and the TCP/IP stack have routines that must be called periodically. The SDK has two versions of the pico_cyw43_arch that implement different solutions for this:&lt;/div&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;&#39;poll&#39;: here it is the application responsibility to periodically call the cyw43_arch_poll routine. The communication functions are not interrupt or multiple core safe, you need to enclose them with calls to&amp;nbsp; cyw43_arch_lwip_begin() and cyw43_arch_lwip_end() in the non-interrupt code.&lt;/li&gt;&lt;li&gt;&#39;thread_safe_background&#39;: this is a more sophisticated option where things are done automatically in background an the functions are interrupt and multiple core safe. There is an specific version of this for use with FreeRTOS.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;If all you want is to control the LED that is now connected to the CYW43439, and need no WiFi communication, there is a third version of&amp;nbsp;pico_cyw43_arch just for this.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;</description><link>https://raspico.blogspot.com/2022/11/using-wifi-in-raspberry-pi-pico-part-1.html</link><author>noreply@blogger.com (Daniel Quadros)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgsKc5ROx-HIlKdZMvElA-d8RTVpwJflAfQ6zIQPQ6gSdzJN5MjX97A7wDk4W6Jg-toeS9EB6gi_hi6J-lhvDWbdmE-_JsJelA1OzR0RN2d_t5pZ188lEchvXomvhX6R5YiGnX74oPyHwDxWIx1Y1cYTjknguEe9GetdZeS6ndar6F39idAoaxcbJM9/s72-c/20220828_200836.jpg" height="72" width="72"/><thr:total>0</thr:total></item></channel></rss>