I recently found an old BK Precision 1787 Power Supply in my Dad’s garage and, being the slight hoarder that I am, I couldn’t pass up an opportunity to take it home and play with it. Like an abandoned toy, for over a year this power supply sat in my cabinet, collecting dust, just waiting to be played with. I recently pulled it out only to discover that it had an RS-232 port on the back panel:
I wondered to myself, “could I actually control this using an RS-232 cable?” Upon an initial investigation on BK Precision’s website, the original documentation (from over 20 years ago) stated that I needed a special kit in order to make us of the PC interface:
I was pretty disappointed when I came across that notice and thought about trashing the whole unit but I decided to engage in a little experiment. In this article we’re going to look at how I took apart the power supply and transformed it into an IoT controlled device where voltage and current could be set or read through your phone or any internet connected device. We’ll look at the UART commands, sniffing the bus to validate serial communication, and building a REST API server on a Raspberry Pi Pico W to provide the IoT capability of this piece of equipment.
Rather than e-waste the power supply I decided that I wanted to tinker with it a little. Most power supplies today can be controlled over Serial (e.g. UART), USB (usually as a COM or USBTMC device), and/or Ethernet (generally controlled via VISA). I haven’t, however, seen many pieces of equipment that support Wi-Fi capabilities. I imagine this is because it’s a bit of a nuisance to set up and most designers or test engineers aren’t really bothered by a hard wired connection. My power supply came with an RS-232 port but nothing else. I thought it would be kind of neat to give it Wi-Fi capability with a REST API front end so I could control it from anywhere using an internet connected device.
The one major issue I had was my inability to talk to the power supply. As you saw above, the manual stated that you needed a proprietary kit and software in order to utilize the PC interface. My first attempt to “hack” the power supply resulted in an utter failure. I hooked up an RS-232 UART cable to the back panel port and started typing in random characters. I removed the lid and traced signals via the RS-232 port to a MAX202C transceiver chip and scoped out the TX and RX signals on both sides of the chip. All I got was a bunch of garbage:
Luckily, the folks at BK Precision were super helpful and got me the command set that was needed to control the supply. They were even able to provide me screenshots with the software they were using and all the UART settings so I could confirm I had everything set up correctly. With their help I was able to test out my commands and watch them be processed correctly on my oscilloscope as well:
While this seems like a superfluous step, this helped me with establishing a baseline to compare with when I would hook up my Raspberry Pi Pico W directly to the UART lines. At this point I was able to establish proper communication and I was ready to start retrofitting my power supply to become an IoT enabled device.
Now that I had a working setup using a USB RS-232 UART cable, I wanted to replicate the same setup using a Raspberry Pi Pico W. Most of my projects for the Raspberry Pi Pico are written in MicroPython (a smaller, more compact version of Python targeted for microcontrollers) so I decided to utilize the machine.uart library. This required me to hook up my UART/RS-232 lines to the UART specific hardware pins. In this case I used GPIO 16 and 17. After sending serial commands via UART within my MicroPython code I discovered that all the data being sent and coming back was garbage. The code kept reporting that the bytecodes coming back weren’t even ASCII characters. Clearly something was off. For this specific reason it was critical that I got a scope capture of a working setup. Immediately I was able to determine that the signals had become inverted by the time they got to the Raspberry Pi Pico device. After setting the TX and RX to invert (when instantiating the UART library object) the serial data that came back was pristine.
It’s important to note that the Raspberry Pi Pico device sits at 3.3V voltage levels and the BK Precision 1787 (specifically the MAX202C chip that it uses) sits at 5V. Sending 5V signals to the GPIO pins of the Raspberry Pi Pico device for prolonged periods can damage the input buffers of the chip. For long term use it is highly advisable to use a level shifter to properly convert the voltage levels from 3.3V to 5V between the devices.
At this point I had established communication and written a driver library that provided full control of my power supply via serial communication. The next step was to configure a basic web server and validate that I would be able to control my device over the web. Thanks to microdot I was able to shortcut my REST API and create a very fast “Hello World” prototype to validate that the Raspberry Pi Pico H device could host a web server for me. Aside from a simple “Hello World” return statement I also confirmed that I could toggle LEDs by using POST functions. At this point I was ready to integrate everything.
To make the final code more readable and scalable I made use of classes in my code. Object oriented code is not something new to the software world but it is often overlooked in embedded systems. When writing web services, especially ones that are controlling different pieces of hardware, it’s important to abstract your code nicely so the detailed hardware code sits outside of the main application. In my case you’ll notice in main.py that there is very little code referencing the power supply except for calling specific functions such as setting or reading current/voltage (versus handling the actual UART command within main.py). This allows a cleaner view of what’s happening at the web application level and abstracts away the details of what’s going on at the device communication level.
In main.py I create two different types of endpoints to control my power supply. One type is used a POST method that is typically used within the REST API for updating fields on a backend to the server (e.g. insert a row of a database). I could have easily used a PUT method since it’s just a single value that I was editing but, for no real good reason, I stuck with POST. It’s up to you, truthfully, which type of method you’d like to implement in this specific scenario.
I also created a route called “controller” which spits out a very simple submit form where a user can set the voltage/current and hit “submit” which would, in turn, perform a POST action and trigger the webservice to update the voltage/current settings on the power supply. This is where the IoT, smartphone enabled, aspect comes in. Performing a POST method isn’t very simple to do from your smartphone or run-of-the-mill browser. You could issue a GET method but you would end up with a long URL string as well. A very simple way of achieving the “smartphoness” aspect of your project is to drop a basic webform that anyone can hit from any device. Once you support a basic web form within your web application (and properly routed incoming traffic through your router’s firewall), you’ve, pretty much, demonstrated that your code is “IoT enabled.”
Some other health monitoring/debug features that I threw into this project include:
Having these little extras really help turn a hobby project into something a bit more mature that can be diagnosed when issues arise.
At this point I had successfully put all the pieces together and I now possessed an old school power supply with cutting edge tech. “For what purpose would this super retro power supply serve?” I asked myself. Well, that piece I’m still trying to figure out.
To view the full code repository visit https://gitlab.com/embedded-designs/rest-api-controlled-power-supply-using-micropython.