0

There is a common anode and common cathode of 7 segments display. But I got an unusual one.

There are 7 pins controlling 4 digits 7 segments. enter image description here

I find the pinout by a multimeter. Basically, each pin can be anode or cathode. enter image description here

My questions:

  1. What is the exact name of this 7 segments display?
  2. How to drive this display by Arduino, any website/sample code?
  3. If I am using the 5V tolerant board, which resistor I need to use? And how is the schematic?
2
  • It appears to be some sort of proprietary 7-segment display, possibly from a clock or clock radio. I doubt you are going to find any Arduino library that supports this directly and you may be better off just getting a standard display that can work with existing libraries. Otherwise you will certainly learn a lot by figuring out how to make this one work and writing your own library. As far as resistors, it's difficult to say since we don't know what's inside the thing. Start with something conservative, say 1K, and work down from there. – jwh20 Dec 7 '20 at 14:56
  • Looks like a Charlieplexed matrix. You may try a Web search for “Arduino Charlieplexing”. – Edgar Bonet Dec 7 '20 at 15:37
5

This display seems to have 32 addressable LEDs controlled by only 7 pins. Judging from this fact, and from the provided pinout table, it looks like a Charlieplexed matrix.

A typical way to drive this kind of matrix is by looping over the cathodes. You pull one cathode pin LOW, and then pull HIGH all the anodes of the LEDs you want to shine which are connected to this particular cathode. Wait a few milliseconds, then move to the next cathode. It is important that all pins that are not involved in lighting an LED remain in INPUT mode.

For example, let's say you want to light all the segments of the first digit (display an “8”) while keeping everything else off. You first pull pin 1 LOW (first cathode) and pull HIGH pins 2–5 (segments F, G, C and D). Let that shine for a few milliseconds, then put everything to high impedance (pins to INPUT) and move to the next cathode: pin 2 goes LOW and pin 1 (segment A) goes HIGH. And so on until you have done all the cathodes.

For the coding part, I would suggest using a 7×7 matrix of booleans telling whether a particular segment is meant to be lit. The indices of the array would be row = cathode number and column = anode number. The array would have the same structure as the pinout table you posted, except for the fact that the lines and columns would have indices ranging 0–6 instead of 1–7. This should make it easy to handle refreshing the display.

Drawing the digits is a bit trickier than with traditional 7-segment displays, as for each segment you will have to find its coordinates in the matrix (cathode number and anode number). For this, I would use a “mapping matrix” that stores the mapping (digit number, segment number) → (cathode number, anode number).

Below is a tentative, and untested, implementation of these strategies. Note that I did not write a function to output a digit, but that should be easy to implement on top of the set_segment() function defined here. Besides, the question of how to draw a digit once you know how to control individual segments is the standard 7-segment problem, for which you should be able to find many tutorials.

Note that this code assumes you drive the display directly, using no iterface other than current-limiting resistors. This carries the risk of either overloading the cathode outputs or having the display be too dim, depending on the current-limiting resistors. You may want to use transistors for the cathodes, in which case you would have a set of cathode pins different from the set of anode pins.

// Arduino pins connected to the display.
const uint8_t display_pins[7] = {2, 3, 4, 5, 6, 7, 8};

// Which segments are lit. Each segment is located in this matrix at
// the coordinates [cathode][anode].
bool segment_lit[7][7];

// Coordinates in the matrix above where a segment can be found.
struct SegmentCoordinates {
    uint8_t cathode;
    uint8_t anode;
};

// segments[digit][segment] gives the coordinates of
// any segment (0 = A) of any digit (0 = 1st digit).
const SegmentCoordinates segments[4][7] = {
// seg: A      B        C       D      E        F       G
    {{1, 0}, {2, 0}, {0, 3}, {0, 4}, {3, 0}, {0, 1}, {0, 2}},
    {{2, 1}, {3, 1}, {1, 4}, {5, 1}, {4, 1}, {1, 2}, {1, 3}},
    {{3, 4}, {4, 2}, {4, 3}, {0, 5}, {2, 5}, {2, 3}, {2, 4}},
    {{5, 6}, {6, 5}, {5, 4}, {3, 5}, {5, 3}, {4, 5}, {6, 4}}
};

// Turn a segment OFF (lit = false) or ON (lit = true).
void set_segment(uint8_t digit, uint8_t segment, bool lit) {
    SegmentCoordinates coordinates = segments[digit][segment];
    segment_lit[coordinates.cathode][coordinates.anode] = lit;
}

void setup(){}

void loop() {
    static uint8_t cathode;  // currently used cathode

    // Set the current cathode to OUTPUT LOW.
    digitalWrite(display_pins[cathode], LOW);
    pinMode(display_pins[cathode], OUTPUT);

    // Set the relevant anodes to OUTPUT HIGH.
    for (int anode = 0; anode < 7; anode++) {
        if (segment_lit[cathode][anode]) {
            digitalWrite(display_pins[anode], HIGH);
            pinMode(display_pins[anode], OUTPUT);
        }
    }

    // Let that shine for a while.
    delay(10);

    // Turn off everything.
    for (int pin = 0; pin < 7; pin++) {
        pinMode(display_pins[pin], INPUT);
    }

    // Move to the next cathode.
    if (++cathode >= 7) cathode = 0;
}

I used delay() here for simplicity. In production code you would handdle the timings with millis() in a non-blocking fashion, in the spirit of the “Blink without delay” tutorial.

1
  • Thanks, it works. I just modify the delay(10) to delay(1), and add the set_segment() into setup() – Allen Chak Dec 11 '20 at 17:02
2
  1. I don't know. If I had to talk about it, I would say a LED segment display with a matrix layout with a complementary drive.

  2. If a pin is used as a cathode, a LOW signal must be applied. If it is used as an anode, a HIGH signal must be applied.

You could define constants for each segments anode and cathode that define a pin number. e.g :

#define CAT_1A = 2    
#define AN_1A  = 1

and so on. Then if you whant to show segment 1A set CAT_1A to LOW and AN_1A to HIGH.

Of course the whole process is more complicated. You have to define which segments must be light up to show a specific digit. You must show all four digits one by one in a fast loop and so on. But that's the same as you would do for an ordinary LED segment bar. The difference is that you have to configure pin pairs and not single pins.

  1. Use your Multimeter to measure the Forward voltage of the segments. If they are red, it should be around 1.8 to 2.4 Volts. Substract this Voltage from 5 Volts. Then devide by 0.02 (20 mA) and you get the Resistor in Ohms. A standard LED is bright enough with about 20 mA.

Example:

(5V - 1.8V) / 0.02A) = 160 Ohm

Use a resistor of say 100 Ohms at each pin. It is common available and as the current flows always through 2 pins, you have 200 Ohms together.

It is also possible that the LED bar has internal resistors. Try to meassure the resistance beetween to pins.

Edit When I said, "each digit must be shown in a fast loop", I forgot to clearify that, for each digit, the segments must be switched sequentially.

You can do it even more complicated and show all Segments with a common cathode or a common annode at once. Then you need fewer cycles, but as you use resistors for all pins (see point 3.) this could dim the LEDs remarkably. Also, becaus technically, the forward voltage of different LED may differ, so the some could be brighter the others.

There is also another thing, I did not think of, when I wrote the answer. If you power a segment, say from pin A (+5V) to pin B (GND), you have a resistor (100 Ohms), an LED (minus 1.8 Volts) and a second resitor (100 Ohms) in series. So in an ideal situation the voltage on pin B (also on the second resitor) would by around 1.6 Volts. Pin B is the cathode of the LED segment, but can also be the anode of another segment (S2). If the cathode of S2 is connected to GND there is a very small chance, that the segment lights up. If you don't see (ghost) lights, all is fine. But if some segments light up (but much darker than the right ones) you have to find a better solution.

7
  • Re “You must schow all four digits one by one in a fast loop”: That won't work. At any given time, you can only light segments that all share either the same anode or the same cathode. So, instead of looping over the digits, you will have to loop over the anodes (or over the cathodes). – Edgar Bonet Dec 7 '20 at 15:44
  • @EdgarBonet Showing Digit one by one is meant in addition to show each segment one by one. It seams that I did not express myself clearly. I'll edit the answer. – Peter Paul Kiefer Dec 7 '20 at 16:45
  • Re “show all Segments with a common cathode [...] could dim the LEDs remarkably”: no more than showing the segments one by one. If you want a brighter display, you have to drive the cathodes with transistors. Re “If the cathode of S2 is connected to GND there is a very small chance, that the segment lights up”: that's why that cathode should not be pulled LOW (connected to GND): it should be left floating (INPUT mode, a.k.a. “high impedance”). – Edgar Bonet Dec 7 '20 at 17:23
  • @EdgarBonnet As multiple LEDs with a common cathode or a common anode have a single source or drain with a resistor. The current through all LEDs together is the same as the current through that single resistor. So each LED sees only a part of the current. Say you have 5 LEDs with a common cathode then the current through the common resistor is 5V / (100Ohm+20Ohm) ~~ 41mA. The current through each LED is 1/5 of this ~ 8,3 mA. I think you would see the difference. Using high impedance state for unused pins is one of the better solutions I mentioned. – Peter Paul Kiefer Dec 7 '20 at 18:07
  • You are right, of course, the display will be dim. But that's not my point. My point is that it will also be dim if you handle the segments one by one. Think duty cycle, and average the brightness over a full scan cycle. – Edgar Bonet Dec 7 '20 at 19:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.