Posts

Showing posts from 2022

Can you spare a 200 bytes? When enabling Serial is enough to crash an Arduino app

I have an old piece of Arduino code that doesn't work if I enable Serial Output.  The code consists of 3 main pieces:  Ethernet/Web server Neopixel driver 5110 LCD display The code runs fine if I disable Serial output or if I remove the 5100 LCD display code and libraries. Note that the Arduino doesn't actually boot correctly and initialize the displays so this is even before any web server requests.  I couldn't figure out what was happening until I looked at the compiler output. It turns out that Serial() reserves about 200 bytes for input/output buffers. This makes sense but pushed me over the edge. I don't have a good way to figure out the minimum I need but obviously, 234 bytes isn't enough.   Code Used https://github.com/freemansoft/build-monitor-devices/tree/main/arduino_ethernet_NeoPixel Compiler Messages This is the Arduino compiler output with just the following line in the code or commented out.  These numbers were captured after moving all constant string

Working with state in MicroPython Timer callbacks

Image
MicroPython supports hardware and software timers with callbacks. Timers can be configured as single-shot or periodic events meaning they trigger only once or on a periodic basis. You can bind a Python function to the timer running in either mode.  Your function will receive a  callback  whenever the timer rolls over or expires.  Hardware timers are bound to the actual CPU timers and typically correlate 1:1 to hardware devices.  This means the hardware timer configuration is hardware specific to the size and capabilities of the hardware timers.  In general, you can only tie one callback to each timer because the callback is bound to the hardware timer interrupt handler.   MicroPython also supports software timers. Software timers are the only option on CPUs like the ESP8266 where hardware timers are scarce or are dedicated to other functions. They have the same callback/handler restrictions as hardware timers. Video Content YouTube:  Working with Python state in Timer and IRQ Callbacks

Running timed background tasks on IoT devices the easy way with MicroPython

Image
MicroPython is single-threaded but it turns out it is easy to have it do periodic tasks while doing other work like waiting on network requests when running a web server. Here we demonstrate a simple wrapper class that makes it trivial to trigger actions with a timer while at the same time accepting web requests. Everything discussed here runs on a simple ESP8266 IOT board. The code is on Github https://github.com/freemansoft/ESP8266-MicroPython Web Server gives direct control and enables Timed Events The IoT device runs a small web server written in MicroPython.   It coughs up a web page with a series of device controls.  This image contains a direct servo pin control and a timed operations control.  The latter basically causes some action to be taken on a regular basis, in this case flashing an LED.  This happens continually while the system waits for and receives HTTP requests on this UI. We can move the servo around while the light flashes without any complicated wait loops. The

Dependency Injection - locally testing a Python IoT component

Image
Dependency Injection is a method of reducing coupling by removing the knowledge of where how that component's dependencies are created.  The dependencies required in a component are provided to it rather than created by it.  Removing this coupling lets us change the nature of the things a component relies on.  In the case of this example: a hardware-specific dependency can be swapped with a virtual hardware version for testing or for alternative uses. References Sample Code:  https://github.com/freemansoft/ESP8266-MicroPython Video Discussion:  https://youtu.be/cHM4FydObmw Summary View Our code contains two different entry points.   On the IoT device, main.py is the actual IoT based entry point.   main.py  can configure I/O pins based on some configuration information. It can then do the same for Servo pins.  Finally, the main.py initializes a web server passing in the configured I/O and Servo pins. On our development machine or any computer,  webserver_test.py  is the entry point.

Embedding videos in blogger with an IFrame

There are a bunch of ways you can embed your video in a blog or other article. You can create a hyperlink URL on top of a thumbnail of your video.  I usually embed the video in an iframe in a way that should rotate with the device.   IFrame Magic for YouTube Videos Replace the string in the url  replacethis with the video identifier for your video <iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; fullscreen" allowfullscreen="" frameborder="0" height="360" src="https://www.youtube.com/embed/replacethis" width="640"></iframe> Revision History Created 2022 12

Browsers open extra connections in anticipation of additional requests

Image
Browsers can open extra connections or pre-stage open connections to improve the user experience.  You can see this if you build your own web server for IoT devices or monitor the connections and not just the requests.  These pre-staged connections do not show up in the browser developer tools. I was troubleshooting a connection timeout issue in a Python-based web server where there were sometimes suspicious connections that timed out.  All my testing was done via a browser rather than Postman so I decided to investigate if it was a browser issue or a problem with my service.  The developer tools console in Chrome did not  show the extra connection in the network traces. The Python web server generating the logs has a 10-second connection timeout. A single browser action appears to generate two inbound connection requests but only one HTTP request. The 2nd inbound connection appears to be timing out if the user doesn't click on or initiate any additional browser action. Got a conne

Visual Aids when Prioritizing Work and Calculating WSJF

Image
WSJF is an analytical work prioritization method that attempts to ensure the delivery of the most value in the least amount of time.  It takes into account a Business Feature's value as weighted by the cost of delay and cost of delivery. WSJF scores are re-evaluated to continually reprioritize the backlog to ensure the highest value items are at the top of the work queues. Programs are always working on today's most valuable work and not some work that was important at some time in the past. In my opinion, one of the most interesting things about it is that the process completely ignores sunk costs continually making financial decisions, a fundamental principle in Lean. Troy did a great job making this approachable. Codifying Prioritization based on Value and Effort The WSJF is based on a simple formula that takes into account two values generated by product ownership and engineering. Teams meet in prioritization sessions and calculate both values and then sort all your deliver

UiFlow Python turns an M5Stack into an Azure App Insights Dashboard

Image
I wanted to build an IoT dashboard that auto-populates from query Azure Application Insights and displays the query results. UIFlow, Circuit Python, and Micro Python all let you create low-code programs on IoT devices. I used M5Stack's UiFlow as a low-code Python generator.  The program runs an Azure query via REST API and displays the results on the built-in M5 Core display. The query can be manually triggered or run automatically on a timer without me writing any code. https://flow.m5stack.com/ This flow is available on This .m5f example on GitHub. Video Walkthrough Device Topology Our IoT device, the M5Stack Core 2, runs an API query against Application Insights.  The search results are returned as JSON.  The Device Display UiFlow lets us lay different fields and labels onto the LCD panel via drag and drop.  We can set the name of the component for later access. UiFlow/Python has pre-built blocks that let me