Making an oscilloscope kit suck less.

A couple of jobs ago I worked in an electronics lab that had all the toys - from tool cabinets as tall as I am to anti-static gear all over the place (and ruthlessly enforced rules for making use of it) to signal analyzers and oscilloscopes. Unfortunately, my job (and the project) were such that I couldn't just go messing around in there to teach myself to use the diagnostic instruments. If the 'scopes weren't in use at the time then they'd been set up specifically for the hardware we were working on. This means that messing around with the settings to see what everything did was not allowed because the other engineers would have had to spend hours re-setting them up, which would also probably have resulted in my getting smacked with my own LART.

Some years later (read: 2020.ev) I realized that there was nothing preventing me from getting my own oscilloscope and learning how to use it. I don't ordinarily have a couple of hundred dollars to drop on a piece of diagnostic equipment just to teach myself how to use it so I did the next best thing: I found a relatively simple oscilloscope kit and added it to my wishlist. I also found a nice signal generator kit that outputs well known and defined signals that I could use as inputs to an o-scope. While I could use one of the many hackable convention badges in my collection there is a minor problem: If I don't know what I'm doing yet, I'm going to have a hell of a time learning how to know what I'm doing. In other words, I'd much rather teach myself with something that I know works, rather than play around with something I don't fully understand and wonder for days on end if I'm probing the right thing on the board, if the settings on the scope are right, did I plug it in right, et multiple cetera.

I'm not an electrical engineer. I just tinker with stuff. If it's not absolutely necessary to do things the hard way, I'm not going to.

Anyway, Yule came and went and I received as gifts one of each gadget. My pile of presents was graced with a DSO-138 open source oscilloscope kit from Aukuyee, and a KKmoon signal generator kit. The former is only technically a kit because the surface mount components were already soldered in place while the latter is comprised of discrete components that were not much of a challenge to place (though I did manage to cause a capacitor to explode by soldering it backwards). That's neither here nor there, though.

While fairly easy to assemble because the circuit boards were already populated, the oscilloscope's case was impressively bad. Out of the box it was just a couple of sheets of fragile, laser cut acrylic that had to be stacked in just the right orientation and order. Of course, the instructions were next to non-existent so a certain amount of trial and error was required, which eventually resulted in one of the structural components breaking. While ordinarily an annoyance the switches used as controls relied upon that one broken sheet of plastic because removable bits of colored acrylic were supposed to sit on top of them, poking out through the layers of plastic to peek out at the user. I tried to fashion a replacement out of a sheet of ABS plastic but it wound up causing more problems than it solved. So I set about figuring out how I could make a somewhat crappy kit much nicer over a couple of weeks.

Note: The DSO-138 kit did not come with a bill of materials and rather a lot of trial and error, web searching, and peering through a microscope was involved to figure out what some of the parts were. I could not have done this without Bolt Depot as my source of screws, nuts, bolts and suchlike. I'm not getting any kickbacks or sponsorship from them, I'm just genuinely impressed with Bolt Depot, and these days they're my go-to for fasteners.

Another note: This post is not, strictly speaking, in chronological order. I turned a few weeks of tinkering into a roughly coherent blog post, so if it doesn't seem like some steps are in the right order, they're not.

First thing to work on was the case. I bought a small Pelican box, tore the silicon rubber lining out, removed the carabiner and took a Dremel to it. I drilled a couple of holes in the bottom of the case to run some machine screws through as board mounts. The screws in question are M3 machine screws, pan heads, 3mm in diameter, 0.5mm thread pitch, 15mm long. After inserting the screw I threaded a nut (also M3) down the shaft to hold the screw in place as well as jack the o-scope's mainboard up a little bit. Another M3 nut was run down the screw to hold the mainboard in place, and just because I had a few sitting around I screwed an acorn nut onto the exposed end of each screw to make it look neater.

In general with this kit, if you get M3 machine screws you're good. The exception is that the screws that are supposed to hold the display board in place are M2 machine screws.

The label on the lid of the case was peeled away and I soaked the remaining adhesive with Goo Gone for an hour, after which it rubbed right off with a tissue. I had to wash the case twice with hot water and hand soap to get rid of the smell, though.

There is a large BNC connector sticking out of the far edge of the o-scope which the test probes attach to. I had to carve a half-inch hole out of the back of the Pelican box so it could stick out, plus I had to make it big enough so that the probes could be attached.

The oscilloscope has four press buttons down the right-hand side for user controls, and a single button on the bottom edge for a system reset button. So that I could use the 'scope without having to open the box I picked up a package of SPST momentary buttons, drilled some quarter inch holes in the lid of the case, and soldered thin leads from each leg of the switch to the connected legs of the pressbuttons on the mainboard. I did it this way after using my multitester in continuity mode (no beep if the button is not pressed, beep if the button is pressed) to suss out which legs had to be patched onto. I made sure to make the wires long enough so that the lid of the case could be opened up the whole way. I also wired up the reset button to make rebooting the oscilloscope a bit easier. Of course, I also hit it by accident once in a while...

It seemed logical to make the o-scope's power supply fully internal, so I unsoldered the little white battery connector on the top-right corner of the mainboard and patched a 9v battery clip in its place. The battery is stuck inside a little clip affixed to the bottom of the Pelican box with foam tape. In the middle of one of the wires on the battery connector I've spliced a SPST rocker switch as a power switch, stuck into a half-inch hole bored into the side of the Pelican box.

There are three multiple-position switches (double pole, triple throw, ON-ON-ON) down the left-hand side of the mainboard. The top one controls the coupling setting - ground, AC, or DC. The middle switch controls the sensitivity of the scope - whether it'll detect signals in excess of 1 volt, 0.1 volts, or 0.001 volts. The bottom switch determines how much to amplify the signal to make it more visible on the display - five times, two times, or one time (i.e., not). The thing is, those do not seem to be common switches at all. They have three positions (left, middle, and right) but four pairs of contacts on the bottom. A little tinkering helped me figure out what to do with them but finding other ones of the same kind that I can bolt to the lid? I had to special order them from Hong Kong, which means that they should get here by the end of April, 2021.ev, so I'm not going to be writing about that part of this project right now. I probably won't at all, because wiring up jumpers isn't inherently interesting (though it does help to have a strong magnifier and a good pair of tweezers for handling thin wires).

This brings me right along to the most important part of the project: The firmware. To be frank, the firmware in this kit sucks. The user controls were laggy and somehow the image of the screen was pushed upward and out of view by about a quarter of the screen's visible area. So of course I went hunting for third-party firmware for this device, because I can't be the only person who's gotten frustrated with the stock software. Lo and behold I discovered the DLO-138 project on Github, complete with pre-built binaries. However, a few minor hardware modifications had to be made so I could flash the new firmware.

If you flip the oscilloscope over and look carefully at the underside of the mainboard, you'll see a couple of pairs of jumper pads, little solderable bits on the board that act like switches if you put a blob of solder across them. They exist because adding switches to the circuit to control a function that 90% of people will never use makes things a little more complicated than they really need to be. What you have to do is put a little solder across the pads of JP1 and JP2 to close them; the next time you power up the DSO-138 oscilloscope it'll be in bootloader mode to accept new firmware, and you'll see an all white screen.

Once you can get the oscilloscope into bootloader mode, unplug the power and hook up a USB to TTL serial cable because the USB jack isn't supported by the stock firmware. Yes, you'll have to get some more equipment to make this happen if you don't already have one laying around, but they're not expensive. I bought this one from Adafruit and it works nicely.

If you look at the bottom edge of the oscilloscope's mainboard, immediately to the left of the mini USB jack you'll see three header pins sticking up. This is basically a serial port, only without the usual connector. From left to right, the three pins are

  • ground
  • receive (RX)
  • transmit (TX)

You only need three wires to make a serial connection. Ground is the reference voltage against which the other signals are compared to determine if there is a 1 or a 0 on the line. Receive and transmit are, as my many calculus professors have said, intuitively obvious. What isn't obvious (to me, anyway (just like all of calculus...)) is that you connect one side's receive pin to the other side's transmit pin. You then connect the one side's transmit pin to the other side's receive pin. It's hard to get right in text.

Hanging out of the non-USB end of your cable are four little wires with connectors on them:

  • red - power
  • black - ground
  • white - receive (RX)
  • green - transmit (TX)

Make sure the USB end of the cable is not plugged in. Plug the black wire into the first pin (ground), the green wire into the second pin (receive), and the white wire into the third pin (transmit). You don't need to plug the fourth wire (power) into anything, just let it hang out because you're going to be powering the oscilloscope with a battery when you reflash it. It should look like this. Plug the USB side of the cable into your computer.

Now you need firmware. Clone the DLO-138 repository on Github to your local machine. If you look in the binaries/ subdirectory you should see two .bin files, DLO-138_encoder_1.0.bin and DLO-138_switches_1.0.bin. From what I can tell, the former is for if you've refit your oscilloscope with rotary encoders instead of pressbuttons. I haven't done this and I couldn't find any suitable rotary encoders when I went looking for them anyway, so I can't speak to it. I flashed the latter (DLO-138_switches_1.0.bin) onto my o-scope and it seems to work just fine. You'll need to install the stm32flash utility to install the new firmware. If you are a Windows user JYE Tech has a helpful document (local mirror) online that tells you how to set your machine up to flash the firmware. I referred to it quite a bit when I was originally doing this song and dance.

Actually installing the DLO-138 firmware requires three steps (technically it's two steps, one is a safety step, just in case). Power your o-scope up while you have it plugged into your laptop. Unlock the flash storage of the oscilloscope:

# Disable read prevention.
{21:34:57 @ Sun Mar 07}
[drwho @ windbringer binaries] () $ sudo stm32flash /dev/ttyUSB0 -k -b 115200

...

# Disable write prevention.
{21:35:00 @ Sun Mar 07}
[drwho @ windbringer binaries] () $ sudo stm32flash /dev/ttyUSB0 -u -b 115200

Now, just to be safe, we're going to back up the existing firmware by copying it out of the oscilloscope's internal storage.

{21:35:30 @ Sun Mar 07}
[drwho @ windbringer binaries] () $ sudo stm32flash /dev/ttyUSB0 -r
    default_DSO-130_firmware.bin -b 115200

And now to flash the new firmware image.

{21:36:01 @ Sun Mar 07}
[drwho @ windbringer binaries] () $ sudo stm32flash /dev/ttyUSB0 -w
    DLO-138_switches_1.0.bin -b 115200

It takes a little while for the firmware upload process to complete so be patient. The stm32flash utility will let you know when it's done. When it's finished unplug the power on your DSO-138, unplug the USB end of the serial cable, and unplug the three wires on the other end from the oscilloscope. Now flip the o-scope's mainboard over and unsolder those two jumper pads that you closed before. The next time you power up your oscilloscope you'll be running the new firmware.

After booting up the new firmware and playing around for a while, I found that it's significantly more responsive. The UX is nice and pretty snappy. While I haven't done any kind of scientific analysis (no reversing of the original firmware or anything like that), I do find it interesting that the open soure firmware image is smaller than the one I backed up from the oscilloscope:

{18:17:03 @ Sun Mar 14}
[drwho @ windbringer binaries] () $ ls -alF
drwxr-xr-x drwho drwho 4.0 KB Sat Feb  6 17:19:03 2021  ./
drwxr-xr-x drwho drwho 4.0 KB Fri Jan  8 23:28:18 2021  ../
.rw-r--r-- drwho drwho 128 KB Sat Feb  6 17:19:18 2021  default_DSO-130-firmware.bin
.rw-r--r-- drwho drwho  34 KB Fri Jan  8 23:28:18 2021  DLO-138_encoder_1.0.bin
.rw-r--r-- drwho drwho  34 KB Fri Jan  8 23:28:18 2021  DLO-138_switches_1.0.bin

128 kilobytes of default firmware. 34 kilobytes of compiled open source firmware. I'm not sure what that says, but I think the speedup makes sense if nothing else.

Now, however, for the hard part. How do you actually use it?

To be honest I'm still trying to figure that out. Using an oscilloscope is not an intuitive thing. When I have time I mess around with it and take notes, which I'm going to be adding to as I have time. Expect updates as I learn new things. This will, of course, correct mistakes I've made.

Anyway, after messing with the new firmware I figured out a few things about the new firmware. The SEL button moves the cursor around the screen counter-clockwise. For every option that has multiple possible settings, the UP button goes upward in the list, and the DOWN button.. goes down through the list. The OK button selects or changes an option. The RESET button reboots the scope. Now let's take a look at the display. Open the linked image in another tab or window...

Bottom center, right above the text '2.4" TFT LCD' silkscreened on the display board: That's where you set how often the o-scope samples from its input. The possible settings are 50mS (milliseconds), 20mS, 10mS, 5mS (which is what I tend to default to), 2mS, 1mS, 0.5mS, 0.2mS, 0.1mS, 50uS (microseconds), 30uS, and 20uS. To the right is the operational mode, which can be 'auto', 'norm' (which normalizes the samples?), and 'sing' (which seems to take snapshots of the input when you tell it to). If you hit the OK button on this option it'll freeze the display. Hit OK again and it'll un-freeze the display, though it takes a couple of seconds for the o-scope to start sampling again.

Next to that is a little icon which seems to indicate when the o-scope will trigger, either when a signal is on its way up or down. I don't entirely understand the implications of this.

On the right-hand side of the display is a little yellow triangle pointing to the left. This appears to set the trigger level, and can be moved up and down with the arrow buttons.

The the top-right corner of the display is where the four potential sampling channels can be turned on and off. A1 is analog channel 1, which can never be turned off (else you don't have much of an oscilloscope). A2 is the analog 2 channel. D1 and D2 are digital channels 1 and 2. If you look at the schematics in the DLO-138 firmware repository you'll find some modifications that you can make to the DSO-138 o-scope to add the other three sampling channels. I haven't done this so I can't speak to it. When this option is active, the DOWN button deactivates a channel each time you press it (A2, then D1, then D1); as you turn them off their trigger lines (the little colored triangles at the edges of the display) disappear. The UP button turns them back on.

At the very top of the display is a horizontal scrollbar-like thing. It lets you scroll back and forth through the oscilloscope's buffer of signal data. As before, the OK button freezes the display (the red "HOLD" box will appear in the top-left forner of the screen). The UP button scrolls to the right, the DOWN button scrolls to the left. Hitting the OK button again unfreezes the display (though, as before, it'll take a few seconds for the oscilloscope to start sampling again).

Finally, down the left-hand side of the display are four colored triangles facing to the right. The yellow triangle corresponds to the A1 channel, the purple triangle to the A2 channel. The red channel represents the D1 channel and the blue triangle maps to the D2 channel. As mentioned earlier, these triangles will disappear if you turn their respective channels off, and if you haven't made the requisite hardware modifications they don't do anything.

The new firmware also makes the mini USB jack usable. I haven't done this yet but the documentation says that if you plug it into a computer's USB port and use a terminal emulator program you can get signal data out of the o-scope. This implies that it's possible to write software that interacts with the o-scope over the USB connection, at the very least in a data acquisition context.

That's all I've got right now. When I have more time to play around with my 'scope I'll add to this post.

Be careful out there, folks. Stay safe.