I recently found some HP 5082-7433 LED bubble display modules on eBay. These are three digit, 7 segment displays with decimal points. The “bubble” is a magnifying lens molded into the epoxy package.

7 segment LED bubble display
I ended up finding a datasheet (warning, pdf link), but not one that specifically covers this module. The pinout doesn’t match anything in that datasheet unfortunately, so it took a few minutes of trial and error to come up with one myself. Pin 1 (labeled cathode 1 in the diagram) is indicated by a tiny notch cut out of the pin. It’s hard to see, so fortunately the HP logo on the bottom of the module is on the same end as pin 1.

The module pinout rendered via an extremely precise manual CAD method
Each digit is wired to share the segment anodes with the other digits but has a separate common cathode. This arrangement saves pins, but requires the digits to be multiplexed.
Somewhere below is an arduino sketch I put together to display a simple three digit hexadecimal counter using one module. I used one pin per segment and one for each cathode because a) I’m fresh out of common cathode BCD to 7 segment display drivers, and b) I want a hex display. The first few hexadecimal display chips I turned up were in the $10 range. Crazy. Here’s the circuit wired up on a breadboard:

The Arduino with hexadecmal counter display
Each segment needs a separate current limiting resistor. I chose 2.2k here. This is a 5v Arduino, and the module datasheet indicates a typical forward voltage drop of 1.6v. That leaves 3.4v across the resistor resulting in about 1.5mA per segment. Now, there can be a maximum of 8 segments (including the decimal point) lit at one time, so that means a total of 12mA will be sunk by the cathode pins. The I/O pins on this Arduino can sink 40mA, so the smoke should remain inside.
Here is the sketch I came up with. This code is also available here.
// This is a test which will display a 3-digit hexadecimal counter
// on an HP 5082-7433 LED display
// define pin numbers for convenience
// annodes for seven segments plus decimal point
const int a = 13;
const int b = 12;
const int c = 11;
const int d = 10;
const int e = 9;
const int f = 8;
const int g = 7;
const int dp = 3; //decimal point
// each digit has a common cathode for its segments which must be pulled
// to ground to enable that digit
const int cathode[] = {4,5,6};
// this controls how long each digit is displayed. Adjust for flicker.
const int delaytime = 5;
// this is a table of what segments (left to right, a-g) should be lit for each digit to display
const byte matrix[] = {
B1111110,
B0110000,
B1101101,
B1111001,
B0110011,
B1011011,
B1011111,
B1110000,
B1111111,
B1111011,
B1110111,
B0011111,
B1001110,
B0111101,
B1001111,
B1000111};
unsigned long time;
unsigned int counter = 0x0;
void setup(){
// set all required pins to outputs
pinMode(a, OUTPUT);
pinMode(b, OUTPUT);
pinMode(c, OUTPUT);
pinMode(d, OUTPUT);
pinMode(e, OUTPUT);
pinMode(f, OUTPUT);
pinMode(g, OUTPUT);
pinMode(dp, OUTPUT);
pinMode(cathode[0], OUTPUT);
pinMode(cathode[1], OUTPUT);
pinMode(cathode[2], OUTPUT);
// start off with nothing displayed
digitalWrite(a, LOW);
digitalWrite(b, LOW);
digitalWrite(c, LOW);
digitalWrite(d, LOW);
digitalWrite(e, LOW);
digitalWrite(f, LOW);
digitalWrite(g, LOW);
digitalWrite(dp, LOW);
blankAllDigits();
time = millis();
}
void loop(){
// display each digit in turn, pausing by delaytime in between
// get the digit to display
byte digit = getNybble(counter, 2);
// get the segment pattern from matrix[] accoring to the digit and display that
displayNybble(matrix[digit], 2);
// wait for it
delay(delaytime);
// then do the same for the other two digits
digit = getNybble(counter, 1);
displayNybble(matrix[digit], 1);
delay(delaytime);
digit = getNybble(counter, 0);
displayNybble(matrix[digit], 0);
delay(delaytime);
// increment the counter if it's been at least 100ms
if ((millis() - time) > 100){
counter++;
time = millis();
}
}
byte getNybble(unsigned int source, char index){
// What we're doing here is extracting the nybble (4 bits) that corresponds
// to the hex digit we want from the counter.
// First, shift the counter to the right by the appropriate number of bits
// so the bits we want are all the way to the right.
// Then, cast the 16 bit integer counter to an 8 bit byte which drops the leftmost 8 bits.
// Then do a bitwise AND operation with 00001111. This forces the leftmost 4 bits to zero,
// leaving just the nybble we are interested in.
return (byte)(counter >> (index * 4)) & B00001111;
}
void displayNybble(byte x, int pos){
// x is the bit pattern from matrix[] for the digit we want to display
// This gets the individual bits from x and sets each output pin accordingly.
blankAllDigits();
digitalWrite(a, bitRead(x,6));
digitalWrite(b, bitRead(x,5));
digitalWrite(c, bitRead(x,4));
digitalWrite(d, bitRead(x,3));
digitalWrite(e, bitRead(x,2));
digitalWrite(f, bitRead(x,1));
digitalWrite(g, bitRead(x,0));
enableDigit(pos);
}
void enableDigit(int pos){
// to enable a digit, pull its cathode down to ground
digitalWrite(cathode[pos], LOW);
}
void blankAllDigits(){
// to blank or disable a digit, pull its cathode high
digitalWrite(cathode[0], HIGH);
digitalWrite(cathode[1], HIGH);
digitalWrite(cathode[2], HIGH);
}