StackBlitz: a Web App for Building Web Apps

It’s always nice when the team behind a particular piece of software put in an effort to make newcomer introduction easy. Part of Angular’s low-friction introduction shopping app tutorial is letting us learn Angular basics without installing anything on our development machines, by using the web-based development environment StackBlitz. After I used it for the Angular tutorial, I took a quick detour to learn a bit more about StackBlitz to see what else it might be useful for.

According to the StackBlitz announcement post in 2017, its foundation is built from components of Visual Studio Code but transformed to be accessible via a browser. Behind the VSCode-based UI is a big pool of virtual machines spun up on-demand to support front-end web development. StackBlitz started with support for Angular and React, and more have been added since. Plus a beta program for full stack development so their ambition is still expanding. These virtual machines perform code compilation and also a web server to host the results. These servers are public by default, so developers can check how their results look on a cell phone, on a tablet, etc.

But while StackBlitz gives us online compute resources, their generosity does not extend to online storage. Their “tight GitHub integration” is another way of saying all our project code must be stored in our GitHub repositories. If a user is not willing to enter their GitHub credentials, their work only lasts until they disconnect and the virtual machines are shut down. Since I’m squeamish about spreading my GitHub credentials any more than I absolutely have to, this meant abandoning my Angular introductory app once it was complete.

That was the biggest damper on my enthusiasm for StackBlitz. If it weren’t for that bit of security paranoia, I would consider it a good replacement (at least, for the supported types of projects) for Cloud9 which used to be another free online development environment. Unfortunately, after Cloud9 was acquired by Amazon, using Cloud9 is no longer free. Even though Cloud9 is still very affordable in absolute terms (doing my LRWave project on Cloud9 only cost me $0.43 USD) there’s a huge psychological gap between $0.43 and free. Will StackBlitz lose its free usage in the future? Probably. Money to pay the bills for those virtual machines have to come from somewhere.

If this freebie goes away, so be it. It wouldn’t be the end of the world for the average Angular developer because the primary usage scenario is still centered around installing the tools on a development machine.

Notes on Angular Getting Started Shopping App

Wading into a new domain always means learning a new vocabulary as well. The first thing I read was Introduction to Angular Concepts, knowing full well not all of it would make sense until later. The most valuable thing it taught me is that certain generic-sounding words actually have specific meanings within an Angular context, which is an important lesson to learn while reading documentation. In this case, I have to be careful when coming across words like “modules”, “components”, and “services”.

Angular’s “Getting Started” section starts out with a “Try It” walk through building a sample Angular application. It is a mock shopping app with a product list, a shopping cart, and checkout UI. They do the usual web app things like creating forms (got to have those forms) and communicate over HTTP. Following along with this sample, I got to see the concepts of “components” and “services” put into practice. I’m still a little fuzzy on “modules”, though. I believe it is because modules don’t really come into their own until we have a much larger project. At which point it makes sense to group lots of components into modules, something that would not be necessary in a small sample tutorial.

I also got to see the good and bad sides of using TypeScript. The good news is that some mistakes will trigger compile-time errors for me to fix before proceeding. I find this a vast and compelling improvement over JavaScript standard operating procedure of watching things going awry at runtime and trying to debug what went wrong. The bad news is that it’ll take some experience before I can understand what those error messages are trying to tell me. Here’s one example of an error message that I found bewildering. It wasn’t immediately obvious to me that I used too many curly braces, three instead of two.

Template parse errors:
Parser Error: Missing expected : at column 9 in [ {{{}}} ] in ng:///AppModule/ProductListComponent.html@3:6 ("

<div *ngFor="let product of products">
<h3>[ERROR ->]
"): ng:///AppModule/ProductListComponent.html@3:6
Parser Error: Unexpected end of expression: {{{}}} at the end of the expression [ {{{}}} ]

Going through the exercise I learned that an Angular component typically associates the three parts of web development (HTML, CSS, JavaScript) into a functional unit. The JavaScript file defines the component class. The HTML is modified with Angular-specific annotations and called the component template. And the component style sheet was a pleasant surprise, since I had struggled with how to best organize my style sheet files in earlier projects. Hopefully Angular components will make it easier.

I felt it was an effective introduction, giving a quick tour of major components of Angular and giving me enough of a vague idea of what’s going on, enough to proceed further and learn more. But before I go deeper into Angular, a little detour to look at the infrastructure behind this “Try It” walkthrough.

Siren Call of Angular Material

I started thinking about doing another web technology project because I thought it might be good to have the option of building my own custom Node-RED Dashboard widgets. But during my research of study prerequisites I started reading about Angular. The more I read, the more I think it’s worth a closer look. I was enticed by the following:

  • It is a web technology of the SPA (single page application) era, moving more processing to the web browser and reducing load on the web server. Google has obvious incentive to reduce their server load, but it also means SPAs can be compiled down to static content and hosted on any web server. For hobbyist projects, this drops the minimum hardware requirement from a Raspberry Pi (to run something like Ruby on Rails) down to an ESP32 (static web server).
  • Angular is built on TypeScript, which adds compile-time type checking capabilities to JavaScript. Potentially eliminating a lot of JavaScript runtime failures that have frustrated me in the past.
  • And last but definitely not least: Angular Material components

Angular Materials is now my primary motivation, displacing Node-RED Dashboard. I’ve been fascinated by Google’s Material Design ever since the concept was launched. This is not a surprise to anyone who’ve seen my web technology projects. The SGVHAK rover UI was built on an early version of Materialize CSS. It gave me a Material Design look but with usage semantics somewhat resembling Bootstrap. My LRWave project was written using completely different set of tools, but it also picked up a Material Design style by the use of Material Design Components (MDC) for Web.

So the siren song call of Material Design has pulled me in yet again, this time to Angular and the promise of being able to build UI for projects that can be hosted anywhere… from static servers like an ESP32 or GitHub Pages, to full fledged web server running on a Raspberry Pi, to desktop applications via ElectronJS.

It all sounds very attractive for a tool to add to my toolbox, so I’ll start investing some time into learning Angular.

Diving Into Web Technologies Again

Digging into an obscure button was fun, but (sadly?) not the main focus of this blog, which is for me to write down notes about my projects and technology explorations. If anyone finds the information useful, that’s just icing on the cake.

This time around, getting back to “work” puts focus on software development. My learning experience with the Node-RED Dashboard taught me it was very easy to get a functional browser-based UI up and running giving users like myself a fantastic way to build out ideas. But with ease of use comes the usual trade-off of limited control. The people behind Node-RED Dashboard is aware of this, providing anyone who is unsatisfied with the default tools an entry point to add custom dashboard widgets. Unfortunately, the learning curve climbs sharply upwards for me since I have little experience with many of the underlying technologies. If I want to explore that world, I have to weigh the following points:

  1. No experience with AngularJS (a.k.a Angular v1) which is the foundation of Node-RED Dashboard.
  2. No experience with Angular (a.k.a. Angular v2+) which is an incompatible but currently-maintained replacement.
  3. No experience with creating reusable JavaScript modules or the convention around creating packages.
  4. Only basic skills with HTML, CSS, and JavaScript.

This list is sorted roughly in the order of most- to least-specific to my original motivation of creating custom Node-RED widgets. With such a list it usually makes the most sense to start at the top (focus on the motivating goal) or start at the bottom (build a solid foundation.)

For the purposes of foundation building, I’ve tackled a few HTML/CSS/JavaScript projects but nothing that really stuck with me for long term development. An early example was the web based UI for SGVHAK rover, which eventually became my default control scheme for Sawppy rover as well. Updating that UI has been on my to-do list ever since, and I have yet to get back to it. I later explored a different set of web development tools with my LRWave project, but again that had been set aside after v1.0 was complete. Given this track record, I’m not sure retreading the same grounds will give better results.

So what about the other side? Start with AngularJS? I was ready to do so because of Node-RED Dashboard, but most of my motivation evaporated when I learned AngularJS has been abandoned. If I want to learn something that’ll be useful beyond Node-RED dashboards, I should learn its successor Angular instead.

But there was also a more vain attraction to Angular that called to me…

A Delight for the Button Connoisseur

Yesterday I documented my quest to track down a button I saw on a prop used in the movie Sneakers which premiered 28 years ago. Eventually learning that they were Omron B3J-2100s, and they are still available for purchase from Digi-Key. Given the age of the movie, plus the fact this little detail was not important to the plot, plus the fact the rows of buttons were on screen for only roughly five seconds, I expected my blog post to quickly disappear into footnotes of the internet. Like everything else on this blog it was just a note from my personal explorations. Maybe it’ll receive an occasional a visitor, here to learn how to get these buttons for themselves.

Judging by web traffic, I was quite mistaken. I knew that the movie made impressions on others like myself, but I underestimated how many of us were out there. And even more surprisingly, these buttons made an impression on people as well. I had no idea there were so many button connoisseurs out there whose appreciation for a switch goes beyond whether it can reliable close and open a circuit. My blog post and associated Tweet were picked up by Adafruit blog and someone even submitted it to Hacker News where it was as high as #13 for a brief time. Amazing.

Its popularity also received feedback from many others. I found the prop in the movie was a Sequential Circuits Prophet 2002, but several people brought up the Roland TR-808 and there was also a mention of the Oberheim OB-X. They all used similar looking buttons for similar purposes: select options and an associated LED to indicates the active item. However, despite the similarity (and the TR-808 uses color to great effect) they are not the same Omron B3J buttons of a Prophet 2002.

I started posting a few corrections, but then I stopped. I realized that people were just sharing their own fond memories and there is no particular reason I have to point out they weren’t Omron B3Js. If someone is fond of a stylish button, what’s the point of taking away their joy? For the sake of pedantic correctness? Nah, we’re all connoisseurs of our own favorites. They have theirs, and I have Omron B3J.

Thanks to [garrettlarson] on Hacker News, we have a link to a YouTube clip where we can see the Prophet 2002 and its row of Omron B3J-2100s. (Go to ~1:20 if embedded time offset isn’t working.)

Quest for the Whistler Button

I’m a fan of physical, tactile buttons that provide visual feedback. I realize the current trend favors capacitive touch, but I love individual buttons I can find by feel. And one of the best looking buttons I’ve seen was from the 1992 movie Sneakers. When the blind character Whistler used a Braille-labeled device to add a sound effect representing the “thump” sound of a car going over seams of a concrete bridge.

They were only on screen for a few seconds, but I was enamored with the black buttons, each with a corresponding red LED. The aesthetics reminded me of 2001, like the eye of HAL in a mini monolith. Or maybe Darth Vader, if the Sith lord were a button. When I first watched the movie many years ago, I thought they were neat and left it at that. But in recent years I’ve started building electronics projects. So when I rewatched the movie recently and saw them again, I decided to research these buttons.

The first step is to determine if they were even a thing. All we saw was the front control panel of an unknown device. It was possible the buttons and LEDs were unrelated components sitting adjacent to each other on the circuit board, and only visually tied together by pieces of plastic custom-made for the device. So the first step was to find that device. There was a label at the bottom of the panel below Whistler’s hand, but due to the shallow depth of field I could only make out the end as “… 2002 digital sampler”. Time to hit the internet and see if anyone recognized the machine.

The first step is the Trivia section of the movie’s page on Internet Movie Database where people contribute random and minute pieces of information. Firearms enthusiasts can usually be counted on to name specific guns used in a film, and automotive enthusiasts frequently contribute make and model of cars as well.

Sadly, the electronics audio enthusiasts have not felt fit to contribute to this page, so I went elsewhere on the internet trying various keyword combinations of “Sneakers”, “Whistler”, “sampler”, etc. The answer was found in a comment to a Hackaday post about the movie. I’ve complained a lot about the general quality of internet comments, but this time one person’s nitpicking correction is my rare nugget of gold.

Whistler’s device is a Sequential Circuits Prophet 2002 Digital Sampler rack. As befitting the movie character, the sampler’s control panel had Braille labels covering the default text. But otherwise it appears relatively unmodified for the movie. I wish the pictures were higher resolution, but their arrangement strongly implies the button and LED are part of a single subcomponent. The strongest evidence came from the presence of four vertical axis buttons, rotated 90 degrees from the rest.

Aside: On the far right of the control panel, we can see a sign of the era, a 3.5″ floppy drive for data storage.

Encouraged by this find, I started searching for Prophet 2002 buttons. I quickly found an eBay community offering replacement parts for Sequential Circuits products including these buttons. What’s intriguing to me is that these are sold in “New” condition, not surplus or salvaged from old units. I’m optimistically interpreting this as a hint these buttons might still be in production, decades after the Prophet 2002 was released in 1985.

Thanks to those eBay listings, I have seen a picture of the component by itself and it is exactly what I hoped it would be: the button’s exterior surface, the electric switch itself, and the LED are integrated into a single through-hole component. Given the tantalizing possibility it is still in active production and something I can buy for my own projects, I went next to electronics supplier Digi-Key.

Digi-Key carries 305,212 components under its “Switches” section, not practical for individual manual review. Fortunately there are subsections and I first tried “Tactile Switches” (5721 items) because those buttons look like they’d give a good tactile response. In the movie we also heard a satisfying click when the button was pressed, but I don’t know if that was added later by the film’s sound mixer.

Within the “Tactile Switches” section, I aggressively filtered by the most optimistic wish they are active and in stock:

  • Part Status: Active
  • Stocking Options: In Stock
  • Illumination: Illuminated
  • Illuminator: LED, Red

That dropped it to 76 candidates. Almost all of them carried their illumination under the button instead of adjacent to it. The closest candidate is a JF Series switch by NKK Switches, the JF15RP3HC which has a Digi-Key part number 360-3284-ND.

It is a more modern and refined variant of the same concept. The button is sculpted, and the illuminated portion sits flush with the surroundings. This would be a great choice if I was updating the design, but I am chasing a specific aesthetic and this switch does not look like a monolith or Vader.

So that wasn’t too bad, but I’m not ready to stop. Peer to “Tactile Switches” are several other subsections worth investigating. I next went to “Pushbutton Switches” (175,722 items) and applied the following filters. Again starting with the optimistic wish they are active and in stock:

  • Part Status: Active
  • Stocking Options: In Stock
  • Type: Keyswitch, Illuminated
  • Illumination Type, Color: LED, Red

That filter cut the number of possibilities from 175,722 down to 21 which felt like an overly aggressive shot in the dark, and I expected I would have to adjust the search. But it wouldn’t hurt to take a quick look over those 21 and my eyes widened when I saw that list. Most of the 21 results had a very similar aesthetic and would make an acceptable substitute, but that would not be necessary because I saw the Omron B3J-2100.

Yes, I’ve hit the jackpot! Even if that isn’t precisely the correct replacement for a Prophet 2002 sampler, it has the right aesthetics: a dark angular block with the round LED poking out. But now that I’ve found the component, I can perform web searches with its name to confirm that others have also decided Omron B3J is the correct replacement.

Omron’s B3J datasheet showed a list of models, where we can see variations on this design. The button is available in multiple colors, including this black unit and the blue also used by the Prophet 2002. The number and color of LEDs add to the possible combinations, from no LEDs (a few blue examples on a Prophet 2002 have no lights) to two lights in combinations of red, green, or yellow.

Sure, these switches are more expensive than the lowest bidder options on Amazon. But the price premium is a small price to pay when I’m specifically seeking this specific aesthetic. When I want the look that started me on this little research project, only the Omron B3J-2100 will do. And yeah, I’m going to call them “Whistler buttons”.

[Follow-up: This post became more popular than I had expected, and I’m glad I made a lot of fellow button enthusiasts happy.]

Monoprice PowerCache 220 Teardown

After a service life of over two and a half years, this Monoprice PowerCache 220 was retired due to its degraded battery and malfunctioning thermal protection system. I bought a Paxcess Rockman 200 to replace this old workhorse, which is now long out of warranty and has also been discontinued. Can I fix it? Should I fix it? I won’t know until I take it apart and see what I can find out.

The first step is removing side panels. They are held by hex-drive socket head fasteners that appear to be large durable machine bolts.

Once freed by a hex wrench, however, we see it was an illusion. Underneath the big beefy top is a short self-tapping screw fastened to the plastic. I don’t recall ever seeing a self-tapping fastener with a hex-drive socket head before today.

Once the tough-looking (but actually not) fasteners have been removed, the side panels could slide downwards roughly 1cm, then they can be freed.

With the sides removed, we’ll need to remove the rear fasteners. This is fairly straightforward, none are hiding behind labels. They are all self-tapping Philips screws in clearly visible recessed round holes.

Once those screws are removed, rear half of the enclosure can be lifted to expose the remaining attachment point: a wire harness for the cooling fan mounted in the rear enclosure.

It was easy to unplug the fan (looked like a JST-XH polarized connector) to get a clear look at the interior. Most of the available volume is allocated to a large sealed lead-acid battery. The battery is surrounded by a few pieces of foam padding, probably so it wouldn’t rattle around as the unit is carried around..

This PCB is dominated by large components we would expect to see in a power control application.

Attached to the aluminum heat sinks are power control MOSFETs.

The Golden Rule of Teardowns: Whenever an identifier is visible, put it into a web search to see what comes up. Unfortunately we’ve got nothing for SGD005-INV. In time, the search engines will find this page and send people here. I apologize in advance to those who come to this page seeking information I don’t have.

I was pleasantly surprised to see an easily replaceable fuse. It looks like a standard blade-style fuse popular in automotive applications. I feel it is on the lenient side as 35A * 12V = 420 Watts. I agree if this fuse blows, something has gone very very wrong, but I’m not convinced it’ll blow early enough to protect the rest of the device.

I had expected unpopulated debug points like the RX TX and GND visible towards the right, but the connection to the left actually had populated headers and that was a surprise.

I was encouraged by what I’ve seen so far. It all looks nice and tidy. If I can figure out the thermal problem, I should be able to restore this to full function with a new sealed lead-acid battery. Either way, the degraded battery needed to be removed. This was when I learned the foam padding was glued to the battery. I had hoped they could be easily transferred to a replacement battery, but sadly not.

Once the battery was removed it became much easier to move things around to get a better look. The temperature sensors are likely thermistors, and they have been held into a channel on the heat sink with some kind of glue that dried into a white blob. I had hoped maybe a sensor is misplaced, or dislodged, or unplugged, but it was none of those obvious problems. With those easy fixes ruled out, my prospect for repair dropped.

And once I flipped up the power PCB, my willingness to figure out the temperature problem also dropped. While one side was nice and tidy, the back side is a mess. I see lots of extra solder tinned to various areas on the circuit board, presumably to increase electric current capacity by some amount. And there’s some kind of white residue left all over the board presumably from soldering flux.

A quick web search found that this “heaps of solder” approach is not unusual for lowest-bidder circuit boards. Supposedly it is not terribly effective, but it does provide some benefit for nearly zero additional cost and thus sometimes chosen over any other “right way” approaches to solve the problem.

Not knowing the design constraints placed upon the engineers behind this product, I shouldn’t criticize. After all, it has worked well for over two and a half years. However, it doesn’t make me terribly fond of the device and given that the trivial fixes have been ruled out, repairing it has dropped very low on my priority list. Heck, let’s just say it has been removed from the priority list entirely.

Focus thus shifted from “evaluation for repair” to “satisfy curiosity and evaluate parts salvage.” Looking around the messy circuit board some more, I see the brains of the operation: the STM32F030K6 is a 32-bit ARM Cortex-M0 microcontroller, a cousin of the chip used in the “blue pill” development boards. Unsurprisingly, it is right next to the populated debug header pins I noticed earlier, though the traces don’t seem to go directly into the chip.

Looking past the power control PCB, I see another circuit board. Ah, yes, we would certainly need another board for the front panel status display, and on/off buttons.

Unplugging a few wiring harnesses gave us a better look.

The brains of this operation is a less powerful 8-bit chip, the STM8L052C6.

To give myself a little more room to work, all connectors to the power control PCB has been removed.

But it’s still too cramped, so I also removed the handle. This is a very sturdy handle that is also comfortable to hold. Attached with not just six screws but also molded-in channels to take up weight from the front and rear enclosure halves. Usually when I tear down retired products for salvage, the non recyclable plastic is sent to the landfill. But this time I’m looking at a sturdy enclosure with a handle and think there may be a second life for them.

Finally the control PCB is freed.

Not too many immediate candidates for salvage on the back side.

But the front is a different story. Multiple buttons and LEDs, plus four jacks. Two of them are common 5.5mm OD / 2.1mm ID barrel jacks, the other two are less common but matches the size used by Lenovo for some devices. Piezo buzzer, USB ports, all kinds of good stuff. I doubt I’ll find another use for the LCD panel, though.

I’m still very wary of 110V AC, but these sockets are so easy to salvage I might as well do so. I’m amused at the fact the grounding prong is left unconnected. A portable power source is not connected to ground, so of course there’s nothing to connect them to, but it’s still funny to see.

The 12V “cigarette lighter” socket is very likely to find another use. I wanted to salvage this connector but it was not obvious how. It took me a while to figure out what I was looking at, the answer is that the entire outer base is the “nut” holding the socket in place. In order to remove it from the panel, I had to turn the whole exterior counter-clockwise. And before I could do that, I had to break away most of the solidified orange adhesive.

Nonstandard size meant I had to dig through the tool box for pliers and vise grips of the right sizes to grip without crushing the thin metal exterior can. But eventually it was freed, and the socket could be removed from the panel.

Using earlier pictures as reference, I plugged all the electrical connectors back where they were. Then the mechanical components were laid out for this final roll call without the battery.

Out of all the electronics, I believe the cooling fan will be the first to find a use somewhere, followed by the 12V socket. But I’m actually more intrigued by the enclosure. It is sturdy, already designed to carry something heavy, has provision for cooling, has a big confidence-inspiring handle, and soft rubber feet cushions impact when I set down the box. I think I will cut away the front panel and replace it with something 3D-printed or laser-cut, and the rest of the… whatever it will be… can be installed inside the box. There are lots of potential here.

First Impressions: Paxcess Rockman 200

I had been using a Monoprice PowerCache 220 to store and use power generated by my small Harbor Freight solar array. Due to its degrading battery and erroneous thermal protection circuit, I bought a Paxcess Rockman 200(*) to replace it. Thanks to its lithium chemistry battery, the Paxcess is far smaller and lighter than the Monoprice unit it replaced. Which made a good first impression as something I noticed before I even opened the box.

Two means of charging were included with the Rockman 200, giving users two choices of power source. Either use an automotive “cigarette lighter” power socket adapter, or use a household AC voltage power adapter. But I intended to charge from solar power, so I had to fashion my own charging adapter. Fortunately the Rockman 200 used commodity barrel jacks (5.5mm outer diameter, 2.1mm inner diameter) so it was easy to build one from my most recent purchase(*) of such connectors. This was much easier than the hack I had to do for my Monoprice.

Once up and running I was indeed able to charge from my Harbor Freight solar array. The maximum no-load open circuit voltage of these panels were around 21V, lower than the 24V maximum input voltage limit of the Rockman 200. The Rockman 200 had a far more informative display than the very limited one on board Monoprice PowerCache 220. I like to see how many watts the solar array is delivering, and seeing the number of watts being drawn by anything I had plugged in. Unfortunately, there were two disadvantages relative to the PowerCache 220.

  1. It is not possible to use the AC power output while charging. Like the Monoprice, 12V DC and USB DC power output can be used while charging. But while the Monoprice was willing to deliver AC power while charging, the Paxcess is not.
  2. When drawing DC power while charging, the cooling fan always comes on. I suppose this is some sort of DC voltage conversion process. In contrast the Monoprice stays silent if it can stay cool enough. Or at least it used to, before the thermal sensing system broke down.

Neither the Monoprice or the Paxcess attempts to perform maximum power point tracking (MPPT). I realize this means the panel is not operating at maximum efficiency, but a MPPT controller (*) cost significantly more money than their non-MTTP counterpart (*). Given that a standalone controller costs almost as much as the array, or the Paxcess itself, I don’t fault the Paxcess for not doing MPPT.

However, the Paxcess is even more non-MPPT than the Monoprice. The Monoprice pulls the voltage level down to whatever level its internal lead-acid battery is at, which is usually in the range of 11-13 volts. In contrast, the Paxcess drags the voltage all the way down to 9.5 volts, which is even further away from the maximum power point, as seen by varying power input wattage on the information display.

The display also shows a charge percentage for its internal battery. This allows me the option to stay within the 30% – 80% range if I want to minimize stress on the battery. Lithium chemistry batteries have a different care and feeding procedure than lead acid batteries. Speaking of which, with the new battery storage unit in hand, I opened up the old one to try to fix it.

(*) Disclosure: As an Amazon Associate I earn from qualifying purchases.

Out with the Lead-Acid, In with the Lithium-Ion.

A little over two and a half years ago, I bought a Monoprice PowerCache 220 (Item #15278) to help store power generated by my cheap Harbor Freight solar array and also to utilize that power by the way of AC inverter and USB power converters. When new, the PowerCache was quite capable of gathering up the day’s solar generation and using that energy to charge various battery-powered devices around the house. Up to and including charging an Apple MacBook Air (2014).

I expected this battery to wear down, I just didn’t know how quickly. Battery University has a capacity loss chart, but that is for lead acid batteries held on standby for long periods of time (like in an UPS) showing the capacity would fade to about 85% after two and a half years. However, this battery was cycled on a daily basis for most of the past 2+ years. And while the charge controller does perform an occasional top-off charge, it’s probably not as much as the battery desires.

As a result of this stressful usage pattern, the battery inside my PowerCache 200 has degraded to a point where it could barely hold enough energy to charge a cell phone. That by itself was not a disaster, as I had anticipated battery degradation and was prepared to revive the machine with a new lead-acid battery. Unfortunately the machine has developed another problem: the thermal protection system has gone amok. Within five minutes of the PowerCache starting up (when everything is still room temperature) the “overheating” warning triangle starts blinking and soon the thermal protection routine kicks in and shuts everything down.

So instead of shopping for a replacement lead-acid battery for the PowerCache 220, I started looking at replacing it entirely. I was pleasantly surprised to see that the cost of lithium based batteries have dropped significantly within the past two and a half years. As of right now, lead-acid based systems are still cheaper, but the price premium for going lithium-ion is now small enough to convince me to make the switch. I’ll pay a little extra, but I’ll get something that’s far smaller and lighter. Thus I bought a Paxcess Rockman 200 Portable Power Station (*) to see how it handles my usage scenarios.

[UPDATE: I opened up the PowerCache 220 with the intent to fix it, but things took an ugly turn and ended up as a full teardown.]

(*) Disclosure: As an Amazon Associate I earn from qualifying purchases.

Raspberry Pi GPIO on Node-RED Needs Raspberry Pi OS

I didn’t manage to get Bluetooth Low Energy (BLE) running in Node-RED on a Windows PC, so experimentation moved on to other hardware platforms. Specifically the hardware hacking darling Raspberry Pi. I knew it was possible because of the number of projects that already existed, plus Node-RED has an instruction page dedicated to Raspberry Pi installation. This would be straightforward… except I intentionally made things difficult for myself.

The twist is that my Raspberry Pi 3 readily available for experimentation was most recently set up to check out ROS on arm64. Which meant it was running Ubuntu 20 for 64-bit Raspberry Pi instead of the default Raspberry Pi OS. (Formerly known as Raspbian.) I was confident all the fundamental parts of Node-RED such as flows and network I/O would continue functioning, which makes it a low-power alternative to running Node-RED on a PC. But the other reason to run Node-RED is to interface with devices via Raspberry Pi’s GPIO pins. I wanted to know how well that would work under arm64 Ubuntu.

And I got my answer: it does not work. It appears whatever means Node-RED employed to access Raspberry Pi GPIO is not available on Ubuntu arm64 builds. I assume it is possible to install and/or port over the components required for such support, but today’s experiment is just to see if it works out of the box and now I know it does not.

31 Aug 20:36:53 - [info] Node-RED version: v1.1.3
31 Aug 20:36:53 - [info] Node.js version: v12.18.3
31 Aug 20:36:53 - [info] Linux 5.4.0-1016-raspi arm64 LE
31 Aug 20:36:54 - [info] Loading palette nodes
/bin/sh: 1: /home/ubuntu/.node-red/node_modules/node-red-node-pi-gpio/ not found
31 Aug 20:36:56 - [warn] rpi-gpio : Raspberry Pi specific node set inactive

Adding Noble Specified Hardware Failed To Enable BLE Discovery

I’ve known Bluetooth Low Energy (BLE) to be a new technology that can still be challenging to interface with. I’ve had success so far with Node-RED making hard things easy, most recently in reading battery power state in an old Windows 10 laptop. So I wanted to see if BLE can be just as easy. The answer: it was not. Getting node-red-contrib-noble-bluetooth set up and launching a flow was easy, but attempting to discover nearby BLE devices caused Node-RED itself to crash.

No compatible USB Bluetooth 4.0 device found!

Looking at the crash stack, the culprit appears to be Noble, the Node.js BLE module upon which the Node-RED extension was built. There are some native code components that were built for Noble support, and if things go sour in native code, it fails like native code, hence the jarring failure. Quite unlike the typical recoverable JavaScript exception I’ve become spoiled by.

Searching on that error message, I found more information in this GitHub issue filed against Noble, which pointed to a Noble document explaining that support is limited to a fixed list of hardware. Not surprisingly, the chip on board my experimental laptop was not on the list. I searched for the hardware on that list, and thought the Asus USB-BT400 (*) was cheap enough to order and give it a try.

For the BT400 to function under Noble, I also needed to circumvent the normal driver installation process and instead install WinUSB so Noble can directly access the hardware to bypass Windows’ Bluetooth stack. The WinUSB installation link in Noble Wiki is dead, but a web search pointed to this link as the modern replacement.

Once WinUSB driver was installed for the Asus USB-BT400 Bluetooth adapter, Noble was able to find it and didn’t crash when I attempted to discover nearby BLE devices. Unfortunately, neither did it find any of the BLE hardware I had on hand for this test. I had hoped that, even if I couldn’t use that hardware, I could at least discover their presence.

This test was not a success, ah well. Life moves on to other experiments.

(*) Disclosure: As an Amazon Associate I earn from qualifying purchases.

Node-RED Challenge Round 2: Bluetooth Low Energy

My first challenge to Node-RED was a success: I was able to read battery voltage and charge percentage from a slow Samsung 500T tablet stuck on an old 32-bit build of Windows 10, and the hardest part of that process was retrying installation after it timed out because the computer was so slow.

This next challenge is significantly more difficult: connect to peripherals via Bluetooth Low Energy. Despite Bluetooth in the name, BLE is actually a completely different protocol from the earlier grand wireless protocol to rule them all. (Sometimes called “Bluetooth Classic” now.) But it is now administered by the same consortium,. so there we go.

As its name implies, a primary goal for BLE is reducing power requirements to make it feasible for battery powered devices. And in this context “battery” is not a gigantic brick of rechargeable lithium-ion cells, BLE wants to be practical for devices to run for months on little coin cell batteries. It’s new, with its own set of rules, and tricky to get right. Thus the perfect advanced level challenge.

This time the hardware is the HP Split X2 from NUCC, an old Windows laptop with built-in Bluetooth. It has a decent processor and RAM but hobbled by an old hard drive that’s difficult to upgrade. As a result installing Node-RED took almost as long as it did on the Samsung 500T’s slow eMMC storage, but at least the CPU was fast enough to avoid a timeout.

The Node-RED extension of interest here is node-red-contrib-noble-bluetooth. Out of all the nodes claiming Bluetooth capability, this one seems to be the one that has general BLE capability (not tied to specific devices) and updated most recently. I installed that extension, started a query for nearby BLE devices, and Node-RED crashed. Not throwing an error that a flow might try to handle, not an error message, Node-RED itself crashed with an error thrown by Noble.

No compatible USB Bluetooth 4.0 device found!

Ah well, I didn’t expect it to be as easy as reading battery level and fully anticipated some bumps on the road to this advanced challenge. Time to do a little investigation.

Initial Solar Power Strategy for Samsung 500T

I foresee a lot of refinement ahead for optimizing how to run my Samsung 500T (displaying ESA ISS tracker) on solar power as much as possible using its internal battery. But I have to start somewhere, thus this first plan as starting point.

To improve battery cycle life, I want to keep its state of charge (SoC) between 20% and 80% which should be fairly straightforward to put into a program. That’s just the easy part, the harder part is optimizing for solar power by trying to keep the charging periods as much as possible during times when panels are delivering energy. And it wouldn’t be possible do use internal battery capacity around the clock because that “middle 60%” of the battery is not enough to take the tablet all the way through the night. So it will need to draw upon the lead-acid array sometime overnight but that should be kept as low as possible.

Accomplishing this goal will require optimizing for both ends of the period when solar power is available. In the late afternoon, power should be connected to get up to 80% SoC just as the sun goes down, which requires knowing when sunset will be. During the late-night feeding, the tablet should be given just enough power to leave it at 20% SoC when the sun is back up, which requires knowing when sunrise will be. Add to this seasonal variability other random factors like rainy days, and we have a pretty complex power management challenge on our hands.

Right now 60% of power can keep the tablet running for approximately 9 hours, a number that I expect to shrink as the battery degrades in the future. That inevitable degradation is, in fact, part of the experiment! But right now that means we need a little less than three discharge-charge cycles per day. According to cycle life chart at Battery University, 80% SoC is near the optimal trade off point between cycle life and capacity. But if don’t need three full cycles, we can prolong battery cycle life even further by charging to some level less than 80%, just enough to make it to the next event.

With those considerations, here’s the initial daily charging plan:

  1. The most important cycle is the one just before sunset bringing the battery up to 80%. This maximizes the solar energy captured for running when there’s no direct solar energy.
  2. The following charging cycle will occur sometime overnight. It does not need to get all the way up to 80%, the goal is to give the tablet just enough to leave it with 20% by the time solar panels are delivering power again. When should this charging cycle start and where it should end is yet to be determined.
  3. After the sun starts shining, we’ll need another charging cycle to bring the battery back up via solar power. Ideally we charge up to 80% SoC and stay there until sunset, but we don’t have the means to control that. So we’ll charge just enough to leave us with 20% by the time of the sunset charge (#1 above).

Depending on the amount of sun available, charge cycles #2 and #3 should halt before reaching 80%, which should help prolong battery life. This plan was my starting point to run a multi-week experiment using different strategies, as well as finding unexpected perturbations I’ll have to account for.

Approaches to Optimizing Samsung 500T For Solar Power

My Samsung 500T solar power project is an exercise to maximize a battery’s ability to help store and use solar power by creating a usage regimen maximizing its cycle life. I’m doing this on the 500T because it was available and I wouldn’t cry too much if I make a mistake ruining it. Hopefully ruination is unlikely, as I plan to leave the built-in battery management circuit intact to save me from drastic mistakes.

According to Battery University, best longevity of lithium batteries comes when they avoid the stress of either end of their capacity. This means avoiding charging to full, and avoiding discharging to empty. A common approach is to charge until 80% and no further, leaving 80% – 100% unused. And when discharging, go no lower than 20%, leaving 20% – 0% unused. Using just the “middle” 60% means the battery would have to go through almost twice as many charge/discharge cycles to deliver the same overall energy, but doing so is rewarded with a battery that can survive much more than twice the number of cycles so we come out ahead.

Maintaining such a protective regimen is a hassle that isn’t usually worth the trouble for consumer electronics, because they’re usually replaced within a few years for reasons other than battery degradation. But such maintenance is done for batteries intended for longer lifespan, like those on satellites and electric cars. My 2012 Chevy Volt does this in a way transparent to the driver: When my car told me the battery is empty, it’s actually somewhere around 20% and when it told me the battery is full, it’s actually roughly 80%. The Samsung 500T does not do this, which we could verify by watching both the proclaimed charge percentage and its actual voltage.

Handling the low end should be easy – watch for the charge percentage to drop to 20% and connect power to lead acid array for charging. The high end is a little trickier. Ideally I could attach power to the 500T and charge it slowly up to 80% during daylight hours, but I don’t have that kind of control. When I connect power, it will charge to 100% as fast as it could. I could only cut power at 80% charge to avoid going into the upper 20%. This means we’ll end up with an extra discharge cycle during the day, but if the overall power regimen actually improves cycle life by more than triple, it will still be a worthwhile trade off.

Constraints on Optimizing Samsung 500T For Solar Power

I monitored a battery discharge and recharge cycle on a Samsung 500T to get a feel on how it can be a better partner in my mini solar system. Right now it is constantly plugged in to the lead-acid battery array, leaving its own internal battery constantly full. I want to make use of that battery capacity to help store solar power for the 500T’s current task of displaying ESA’s space station tracker.

For this first draft I want to avoid cracking the computer open, which means I don’t have any control over the charging algorithm. It will charge at full speed whenever I connect power, and it will try to charge to 100%. Charging to full is stressful for lithium ion batteries and decreases their lifespan. Some computers offer the ability to halt charging at 80% reducing use of capacity in exchange for extending the usable life of the battery. Unfortunately I saw no such option with the 500T.

The discharge rate is also pretty much fixed, as I’ve turned off all I can of Windows and Samsung crapware. Leaving just the ISS tracker and Node-RED running. About the only parameter I can adjust is the rate at which Node-RED queried data, and I think I can back off from once per minute to maybe once per three or five minutes. This will help a tiny bit.

The good news is that, watching through the data retrieved by Node-RED through a discharge and charge cycle, I see nothing worrisome about that data and willing to trust it. With data in hand, there are two more things to bring in to the picture: (1) a switch for the tablet’s power cord to my lead acid batteries, and (2) a program to connect/disconnect that power at the best times to optimize the system. I want to think over the latter before I spend money on the former.

Monitoring Samsung 500T Discharge-Charge Cycle

Getting through Node-RED installation on my Samsung 500T tablet was the hard part. Once done, it was trivial to set up a flow to extract the tablet’s battery voltage and charge percentage. I didn’t want to add any more overhead than I already have, so the flow sends that data off to a MQTT broker. Allowing me to analyze that data on a different computer without impacting the battery consumption on the 500T.

It was instructive to watch those two graphs after I unplugged the 500T, charting its battery discharge down to under 10% followed by a charge back up to 100%. During this time, the 500T kept its screen on displaying ESA’s ISS Tracker, plus the normal Windows background tasks. And now it also has Node.JS running Node-RED to query the battery voltage and charge percentage.

The first observation is that the battery discharge percentage graph is impressively linear. As a user I never felt this way intuitively, as my most memorable episodes are battery meters whose value seem to drop faster and faster as I raced to finish a task before my battery gave out. A linear graph is impressive because a lithium ion battery’s discharge voltage is not linear, something we can see on the voltage graph. It drops sharply off 8.4V before stabilizing on a gentle slope that’s more like a curve as it gradually slowed approaching 7.4V. (That is the commonly listed nominal voltage level for two lithium ion battery cells in series.) Once it dips below 7.4V, voltage curve starts dropping rapidly and trending towards a steep dive when I plugged the 500T back in to a power source. We can also see that the voltage level is a bit noisy, fluctuating as it discharges. In contrast, except for a little dip off 100%, the percentage graph is steadily and reliably decreasing under a constant workload. Just as we’d expect, with no surprises. I have a lot of complaints about this machine, but its power management is rock solid.

For the charge cycle, again the percentage value is not based solely on battery voltage as we see those two are wildly divergent during charging. When I plugged in to recharge, there was a big jump upwards as the machine switched to charging cycle. Towards the end of that cycle as charge state approached 100%, there was some kind of a top-off procedure. I was surprised to see that charge controller allowing the battery voltage to exceed 8.4V, something I’ve been taught to never do when charging bare 2S LiPo battery packs. But according to this voltage graph, exceeding that voltage was part of the process of filling the battery before letting it settle down to around 8.35V. All through this top-off procedure, the battery percentage reported 100%.

I enjoyed this opportunity to geek out over battery management minutiae, but it isn’t just for curiosity’s sake. There was a project idea behind all this.

Installing Node-RED on Samsung 500T

When I saw that Node-RED community contributions included a general battery state-of-charge reporting node, I thought that would be a practical and useful first step into playing with contribution nodes. I wanted to give that specific ndoe a try because given my past miserable user experience on my Samsung 500T tablet, I was not terribly motivated to put in the effort required to write my own code to extract battery information. But I’m willing to see if that Node-RED node can work its magic here, and the first step of is, obviously, see if we can even install Node-RED on the unloved machine.

There were many reasons to be pessimistic. Windows was and is still seen as a second-class citizen in many web-centric products. And not only is the tablet running Windows, it is stuck on an old version of Windows because of the whole Intel Clover Trail mess preventing modern Windows 10 support. Furthermore, Clover Trail is a 32-bit only chip without support for x86-64 a.k.a. amd64 instructions that are starting to become a requirement on modern software frameworks. And it only has 1GB of RAM. And we’re still dealing with that molasses-slow eMMC storage. The list goes on.

Fortunately Node.JS still has a 32-bit Windows installer, though installation failed after nearly an hour of grinding away. I was first disappointed but then relieved to see it was “merely” a timeout installing one of the auxiliary components. This was not a huge surprise given how slow this machine is, so I waited for the system to settle down (lots of backlog waiting on that eMMC) before retrying. Node.JS installation succeeded the second time and after that I installed Node-RED without drama.

Launching Node-RED faced another unnecessary hurdle in the form of Windows Firewall. Annoyingly, this was one of the differences between Windows 1607 and modern builds, so I had none of the menu options I’ve become familiar with. But eventually I was able to let Node.JS open up a port to serve the Node-RED user interface, where I could install node-red-contrib-battery.

I dropped three nodes into the blank flow: an inject node, a debug node, and the newly installed battery node between them. I hit “Deploy” and clicked to see if that battery node can extract any information and… it can! Not a lot, as most of the fields are blank or null, but it did return the current battery voltage and the charge percentage. This is all I need to observe this tablet’s charge and discharge behavior.

Node-RED Challenge Round 1: Battery Level Reporting

When I discovered Node-RED and its vast library of community contributions, I checked for several pieces of functionality that might enable several different projects ideas on my to-do list. One of them was the ability to query battery discharge level on a computer.

This was a follow-up to my earlier project assigning a Samsung 500T tablet to display an ISS track around the clock. When I last left that project, I modified the tablet so it runs on my small solar power array. But the arrangement was not optimal: the tablet is constantly pulling power from the array storage battery, instead of contributing its own battery to help store solar energy.

I had the thought to integrate that battery in an automated fashion. There are several ways it could go, but an important data point is battery discharge level. It is the key piece of information in any algorithm’s decision to charge the tablet during the day and let it run on battery at night.

This is something I knew I can accomplish by writing a bit of code. I need to find the APIs to query battery level, then I need to write code to extract that information and do something with it. None of that were technically challenging tasks, but I never allocated the time to do it.

Now I have Node-RED and its library of tools, which included node-red-contrib-battery purported to report battery information in a common way across Linux, MacOS, and Windows. If it works as advertised, all that battery query coding I kept putting off could be as simple as hooking up some nodes. It’s definitely worth trying.

Node-RED Community Contributions

Evaluated in isolation as a novel way to program computers, Node-RED scores high. I got up and running with my serial communication projects much more quickly than writing code in a UWP application, it was easy to plot a graph of data fed by my Mitutoyo SPC connector project. While I did have to climb the learning curve of a new way of thinking and a new set of vocabulary, but once I climbed it (pretty shallow, all things considered) I understood another huge attraction of Node-RED: the collection of community contributions.

I got a brief glimpse of this when I installed the Node-RED Dashboard extension, where I went in to the extension menus to search for Dashboard. The fact there was a search function implies a sizable number of extensions, so I made a note to check it out later. This was affirmed when I went to search for the serial port node, but again I put it off to later.

Returning to browse the “Flows” directory of Node-RED, I’m very excited by the extensive toolbox people have shared and made easily usable by others. This is a clear sign of a virtuous cycle at work: an attractive and useful tool attracts a seed group of users on its own merits. These users share their improvements, making the tool more useful and attractive to other users, and the cycle repeats until we have a big toolbox with contribution by people everywhere.

I queried for functionalities that I knew I would need for many projects on the hypothetical to-do list. Majority of queries came back with something that looked promising. After a few successful hits in a row, I was half expecting to find a Node-RED extension to control a webcam attached to a 3D printer carriage. Alas, no such extension existed to trivialize my current project. Fortunately, there’s a community contributed battery information node that could pick up where a past project left off, so I’ll try that first.

Arduino Interface for Mitutoyo SPC Data Port

I started looking for an inexpensive electronic indicator with digital output port, and ended up splurging for a genuine Mitutoyo. Sure it is over five times the cost of the Harbor Freight alternative, but I thought it would be worth the price for two reasons. One: Mitutoyo is known for high quality precision instruments, and two: they are popular enough that the data output port should be documented somewhere online.

The second point turned out to be moot because the data output port was actually documented by pamphlet in the box, no need to go hunting online. But I went online anyway to get a second opinion, and found this project on Instructables. Most of the information matched up, but the wiring pinout specifically did not. Their cable schematic had a few apparent inconsistencies. (Example: one end of the cable had two ground pins and the other end did not.) They also had a “Menu” button that I lacked. These may just be the result of different products, but in any case it is information on the internet to be taken with a grain of salt. I took a meter to my own cable to ensure I have the pinout described by the pamphlet in my own instrument.

Their Arduino code matched the pamphlet description, so I took that code as a starting point. I then released my derivative publicly on GitHub with the following changes:

  • Calculate distance within numeric domain instead of converting to string and back.
  • Decimal point placement with a single math expression instead of a list of six if statements.
  • Their code didn’t output if value is inch or millimeter, I added units.

A limitation of their code (that I did not fix) is a recovery path, should the Arduino falls out of sync. The Mitutoyo protocol was designed with a recovery provision: If the communication gets out of sync, we can sync back up using the opening 0xFFFF. But since there’s no code watching for that situation, if it falls out of sync our code would just be permanently confused until reset by the user.

For debugging I added the capability to output in raw hex. I was going to remove it once I had the distance calculation and decimal point code figured out, but I left it in place as a compile-time parameter just in case that would become handy in the future. Sending just hexadecimal data and skipping conversion to human-readable text would allow faster loops.

Note that this Mitutoyo Statistical Process Control (SPC) protocol has no interactive control — it just reports whatever is on the display. Switching units, switching direction, zeroing, all such functions are done through device buttons.

Once it all appears to work on the prototyping breadboard, I again soldered up a compact version and put it inside a custom 3D printed enclosure.

This image has an empty alt attribute; its file name is mitutoyo-spc-arduino-compact.jpg