The story of this project goes back to 5 years ago when I purchased a broken Fluke 87V with the intention of repairing it and reselling. While I may have originally believed I had the skills to diagnose and fix the root cause of the tool, I quickly realized that the problem was far beyond my knowledge and I wouldn't be able to complete the repair. Unfortunately for the meter, this revelation came after I removed and attempted to replace multiple components on the board through my (patented) shotgun diagnosis technique. After acknowledging my complete and utter failure, I did as most people would do and simply boxed up the remains of my mistake for later excavation and analysis.
The BeginningFlash forward 5 years and I have now graduated college, started full-time work, and (slightly) improved my technical aptitude with regard to consumer electronics repair. While searching for parts for another project, I stumbled upon a series of zip lock bags that contained the forgotten Fluke 87V parts and decided it was finally time to do something about them. Though, I no longer saw the value in further attempting to repair the meter and instead saw a new opportunity to design it into something more Advanced... Better, Faster, Stronger... A Simple Arduino based Alarm Clock!!!
Yeah, I know... Not very exciting... Though, after inspecting what was left of the board, it appeared I was missing several components (including the main MCU...) and I still had no idea what was the root cause of the original problem... or even what the original problem was at this point. So, I decided to just take what parts I had left and come up with a new project. Seeing as the main components of a Fluke 87V, outside of all the fancy voltage/current measurement goodness, include a segment LCD and a passive buzzer, I thought what could be better than to design a new PCB to turn one of the most popular multimeters of all time into a simple device that can be found at a dollar store!
Get on with it...Now that I've setup what kicked this project off, lets get into the actual system design. My original thought was I would design a simple replacement PCB for the original Fluke 87V board that would include all the necessary components for a simple digital alarm clock (MCU, LED display, RTC, buzzer, power supply) but I quickly decided to expand the scope and set a new project goal: carry over as many components from the original Fluke as possible and modify them as little as possible. This would make things a bit more challenging as I didn't have much design information for the Fluke 87V (outside of this epic service manual) and would need to measure and reverse engineer some of the details myself. I set an initial target to try and reuse the following core Fluke 87V components in my new design:
- Yellow Holster (MUST)
- Grey Plastic Outer Shell (MUST)
- Segment LCD (MUST)
- Passive Buzzer (MUST)
- LED Backlight (WANT)
- Carbon Pill Button Matrix (WANT)
- Rotary Knob (WANT)
To start off, I first analyzed the original Fluke 87V PCB to understand the it's overall functionality. The board is broken into sections with a lot of the fusing and input protection located near the bottom next to the input jacks and the Fluke multimeter chipset and main MCU located at the top of the board near the LCD. Also near the top of the board is the continuity buzzer circuit which includes a CD4069 based oscillator circuit that drives the passive buzzer molded into the inside of the back case shell via 3 spring contacts. Right next to the buzzer circuit is a 3020 white LED which is paired with a light pipe placed underneath the LCD to form the display backlight. Lastly, we have the classic Fluke rotary dial which is comprised of a series of circular pads on the board that essentially act as switch contacts when shorted by the spring contacts on the selector dial. Similarly, the rubber button matrix above the dial uses a series of rectangular pads that are shorted by carbon impregnated "pills" that are molded onto the backside of the buttons. Now that we have gone through a high level overview of the Fluke 87V PCB, let's dive into the most complicated component we will be working with: the segment LCD.
Segment LCDsAdmittedly, when I started this project, I didn't know a lot about Segment LCDs. To be honest, I assumed that they would be similar to Segment LED displays in which you simply apply a DC voltage to one of the anode pins (through an appropriate current limiting resistor), ground the corresponding cathode pin, and your selected segment is indicated. This, unfortunately, is nowhere near the case. Segment LCDs need to be driven using AC input signals which (generally) isn't possible on most common microcontrollers. Notice how I used *generally* as there are still some microcontrollers available today with integrated segment LCD controllers like the TI MSP430F448 used on the original board. I won't dive any deeper into the operation of segment LCDs and how to drive them seeing as there is already tons of documentation on their inner workings (even application notes demonstrating how to drive segment LCDs on MCUs without integrated segment LCD controllers!) and a great video series by Dave Jones of the EEVBlog on segment LCD technology and how to even design your own! Seeing as I was already set on using an ATMEGA328P, I decided to cheat and take the easy route of selecting a dedicated IC to perform the task of driving the LCD. But, before we select an appropriate device for this task, we need to understand the display we plan to interface with.
Fluke 87V Segment LCDLike most multiplexed segment LCDs, the Fluke 87V display has multiple segment pins and 4 common/backplane pins that are used to select/indicate desired icons/digits on the display.
The Fluke display uses elastomeric connectors (aka zebra connectors) to interface the display pads with exposed pads on the PCB. In order to design a footprint in KiCad for our display, we first need to do some measuring and take a look at the Fluke 87V schematic.
After comparing the pin labels on the schematic to the PCB, I was able to determine the pinout for the LCD and create a footprint in KiCad. The Fluke 87V LCD has a total of 34 segment pins and 4 common/backplane pins. The full display pinout is shown below.
With my trusty digital calipers in hand, I then began measuring the footprint on the Fluke 87V PCB and did my best to replicate it inside KiCad. This is a somewhat tedious although necessary process as (to my knowledge) there are no existing mechanical drawings of the Fluke 87V available to the public. Once my measurements were complete, I then created a quick symbol for the LCD and added it to a new schematic project in KiCad.
Display ControllerNow that I knew what I was working with, I decided to look for an acceptable display controller for the Fluke 87V LCD. After a quick search, I stumbled upon the BU9796 80 segment LCD controller from Rohm. It seemed like it would be easy enough to control over I2C with my ATMEGA328P and required barely any external components to operate. However, you should be aware that 80 segments means 80 display segments, not 80 segment pins! Seeing as the Fluke 87V display has 34 segment pins with 4 common/backplane pins, I would need a controller that supports 136 segments in order to driver every possible segment on the display! This seemed a bit excessive and it appears to be less common for external segment LCD controllers to support that large amount of segments. So, rather than continue looking for higher segment display controllers, I decided to review the segment map included in the Fluke 87V schematic to see if I really needed to drive every single segment in my application.
For my alarm clock, I really only needed to control the 4.5 digit 7-segment display portion of the LCD. Inside the map, these segments appear to be labeled as 1B, C -> 5G where the first number is the digit number (1, 2, 3, 4, 5) and the character is the corresponding segment (A, B, C, D, E, F, G).
Digit #1 can only be used to indicate the value 1 so segments B and C are simply connected together. With an idea of what segments I actually wanted to drive and knowing the segment number constraint of the BU9796, I then trimmed down the number of segments and defined the pin assignments in my schematic.
One of the main features of the original Fluke 87V is the rotary knob which allows the user to select the measurement mode of the device. As mentioned previously, this is basically just a series of switches that are opened and closed as the dial is rotated. I thought it might be a cool feature if we are able to use this functionality in a simplified form for the clock power switch! For example, the user can power the device ON by rotating the dial clockwise from the OFF position. Then, if the alarm is activated while the device is ON, the user can disable the alarm by simply rotating the dial to the OFF position to power off the device.
To implement this function, I simply added an AO3401 P-channel mosfet in series with the 9V supply input and connected its gate to our custom rotary dial switch which will short the pin to ground, enabling the pfet, when rotated clockwise past the OFF position. This circuit also functions as the reverse polarity protection for the 9V input. I took some more measurements of the Fluke 87V PCB and then created a custom footprint for the rotary dial using custom shape primitives in KiCad. I decided to just use one of circular contacts for our power switch as I currently didn't have any other use cases for the dial (possible future enhancement?).
Lots of Boring Schematic Design Work Later...I'm going to skip over a bunch of less interesting design work in KiCad but I basically completed component selection and finalized the remaining footprint/symbol/schematic design over the course of a few days. I decided to use the Maxim/Analog Devices DS3231 for my Real Time Clock (RTC) as it seems to have better accuracy compared to the DS1307 and has an integrated temperature compensated oscillator. For the RTC battery backup, I added a CR1220 coin cell holder (CR2032 was a little too big unfortunatly). I went back and forth on what I should use for the main input supply but I ended up settling on the original 9V input to ensure the backlight and buzzer (both driven by 9V) matched the original device. Speaking of the buzzer, I basically just copied the circuit from the original Fluke 87V schematic and added an AO3400A N-channel mosfet to enable/disable the circuit from the ATMEGA328P. The backlight circuit also includes an AO3400A with a Dialight 597 series 3020 white LED I selected to match the original Nichia LED (unavailable). For the main supply rail I selected to use 3.3V provided by a NCP1117 LDO regulator. Lastly, I decided I would use the Arduino Pro Mini (3.3V/8MHz) bootloader for the ATMEGA328P so I included a UART programming header and 8MHz ceramic resonator. Now that we have a finalized schematic and library of symbols/footprints we can finally get down to designing our custom PCB!
PCB DesignThe PCB design process took quite a bit of time but I ended up being pretty happy with the overall outcome. The majority of my time was spent measuring and remeasuring the original Fluke 87V PCB to make sure I placed all of the footprints and mounting holes in exactly the right spot so everything would fit together just like the original device. Since I planned to use the original enclosure without modification, I also needed to make sure the programming header and 9V input connector were accessible with the board inside the case. For quick sanity checks during the design process, I used KiCad's STEP export to 3D print a model of the PCB for test fitting. This helped catch a few mistakes early on before I sent the board off to fab.
Assembly and Board Bring-upOnce the boards arrived from OSH Park, I quickly assembled them, checked fitment in the case, and started the board bring-up process in the Arduino IDE with a simple "blinky" example followed by a more in-depth check of each function.
Thankfully my extended design process paid off and I found no major issues! Now that we completed our initial bring-up process, we can move into preparing our Arduino sketch and testing the segment LCD.
Rohm BU9796 DDRAM MappingThe Rohm BU9796 is a pretty straightforward display controller that can be interfaced with basically any common MCU with an I2C peripheral. The controller has several different commands to configure settings like the input clock source, LCD drive mode, and even an integrated blink function with configurable timing! All the available commands are explained really well in the device datasheet and an example initialization sequence is even provided to get things up and running very quickly. Though, one area I found a little confusing was the BU9796 DDRAM mapping.
A table is provided in the datasheet to explain how the end user needs to arrange their display buffer but I decided to just create my own one which I think is a little easier to understand (at least for my brain). The high level summary is that the BU9796 display RAM is organized in 10 bytes, with each segment (0:19) having a 4 bit register. Those individual 4 bits (COM0:COM3) configure which common backplane pin to enable for the selected segment. As an example, a value of 0b0100 in the register for SEG1 would enable the display segment corresponding to SEG1, COM1. Now that we understand how the DDRAM is laid out and how we connected the BU9796 to our Fluke 87V display, we can create another table with the application unique mapping for our board.
One additional item that tripped me up a little was regarding bit D7 of every display command. It's explained in the datasheet but I somehow still managed to mix it up so I figured I would explain it here. D7 is used to indicate to the BU9796 if the byte following the command is DDRAM data. For most general commands this bit can stay as 1 but during the DDRAM write process you will need to set it to 0 to let the display controller know your updated DDRAM buffer will be getting sent over starting with the next incoming byte.
Now that we have a hold on how the BU9796 operates and how we can write to it's DDRAM, we can move on to preparing a basic Arduino Library/Sketch!
BU9796 Arduino LibraryTo make the software side of this project a little easier to manage, I decided to just create a simple Arduino Library for the BU9796 related functions and prepared a few basic examples for others who would like to create their own project using this awesome display controller. Note that based on how your specific display is connected to the BU9796 you will have to modify the map tables inside of the "bu9796.cpp" file. I added comments that explain how I decided to adapt the DDRAM map table I created in the previous section. Example usage of the library for the gif above is shown below!
#include "bu9796.h"
BU9796 display;
int counter = 0;
void setup()
{
//init BU9796
display.begin();
}
void loop()
{
//write new counter value to buffer
display.writeValue(counter);
//write buffer to BU9796 RAM
display.update();
//increment counter variable
counter++;
//reset counter
if(counter>9999)
{
counter = 0;
}
delay(1000);
}
Fluke 87V Alarm Clock Arduino SketchWe've done it! It's finally time to write the final sketch to glue everything together and turn our Fluke 87V into an alarm clock. Again, I'm not going to spend a ton of time delving into the details the full sketch. Most of the sketch is comprised of trivial Arduino code and taking advantage of Adafruit's solid RTClib library for interfacing with the DS3231 and configuring it's (2) user adjustable alarms for updating the clock and triggering a wake up alarm. Speaking of the wake up alarm, I prepared a basic buzzerBeep function to assert the digital pin connected to the CD4069 enable mosfet with a user selectable beep duration. Similarly, I defined a basic function to toggle the backlight pin on the falling edge of the backlight button pin to match the original Fluke 87V backlight button. For detecting button presses, I configured timer 1 to trigger a simple button polling function every 100ms.
The outcome is a super simple digital alarm clock with programmable wake up alarm (currently only adjustable via reprogramming the ATMEGA).
The full Arduino sketch is available inside the GitHub repo for those interested!
ConclusionThis project was a really fun experience for me and I'm glad I was able to convert some parts that were likely heading to the junk pile into a usable product. I hope you all also found some enjoyment in reading through my adventure! This is my first time creating a writeup for one of my projects so please let me know if you have any suggestions on improvement or if you would like to see more of these in the future!
Eventually I plan to put some more work into this project and maybe add some new features like giving the user the ability to adjust the alarm time without reprogramming the entire device.
Comments