Reading a 12 pin 7 segment (3 digits) using Arduino uno. Please Help!

Hi Arduino Experts,

I have an old wall mount thermometer that uses 3 digital segment display to display the temperature. What i want to do is to read the temperature with Arduino UNO or Mega serial.print.

When the display lights up a value, i want the Arduino to be able to read its value and display in serial.print.

My question is:

  1. Is it possible to get the data from the display?
  2. If so, can i connect jumpers to each pin of the display to read its output?
  3. What code should i use?

Any direction should help. I had been trying to solve this problems for weeks.

So I have an old dual 7 segment display that displays outside temperature, what i want to do is read t

Please see the photo of the display.

Any help would be very very appreciated!!

Thanks again for reading.

LED7SEGMENT3_2_1_3_1_1_1.jpg

LED7SEGMENT3_2_1_3_1_1_1.jpg

  1. Is it possible to get the data from the display?

Theoretically yes, but practically it is difficult, quite difficult.

That display is multiplexed that is one digit is being displayed at any one time, and that digit is continuously changing. Each digit has an enable pin to indicate it is the one that is on. So you have to look at that and that will tell you which digit the current state of the seven segments refer to.

No that sounds easy, if it does not then stop here.
There are two big problems.

  1. the digits being displayed can change between reading the digit enable pin and reading the segments. So this would give you a false value. So you have to read the enable pin after you read the segments to see it has not change in order to see if you have a valid reading.

  2. this display is in a circuit and so the signals you read off it will not be logic levels, so you will need a circuit on each pin that turns what ever signal is there into logic levels.

Hi Grumpy_mike,

I use jumper wire to connect digital pin 1 to 12 to each display pin. This is the arduino code.

int pin1 = 1;
int pin2 = 2;
int pin2 = 3;
int pin2 = 4;
int pin2 = 5;
int pin2 = 6;
int pin2 = 7;
int pin2 = 8;
int pin2 = 9;
int pin2 = 10;
int pin2 = 11;
int pin2 = 12;

void setup() {
// initialize the LED pin as an output:
pinMode(pin1, OUTPUT);
pinMode(pin2, OUTPUT);
pinMode(pin3, OUTPUT);
pinMode(pin4, OUTPUT);
pinMode(pin5, OUTPUT);
pinMode(pin6, OUTPUT);
pinMode(pin7, OUTPUT);
pinMode(pin8, OUTPUT);
pinMode(pin9, OUTPUT);
pinMode(pin10, OUTPUT);
pinMode(pin11, OUTPUT);
pinMode(pin12, OUTPUT);
// initialize the pushbutton pin as an input:
pinMode(buttonPin, INPUT);
}

void loop() {
// read the state of the pushbutton value:
Serial.print(digitalRead(pin1));
Serial.print(" ");
Serial.print(digitalRead(pin2));
Serial.print(" ");
Serial.print(digitalRead(pin3));
Serial.print(" ");
Serial.print(digitalRead(pin4));
Serial.print(" ");
Serial.print(digitalRead(pin5));
Serial.print(" ");
Serial.print(digitalRead(pin6));
Serial.print(" ");
Serial.print(digitalRead(pin7));
Serial.print(" ");
Serial.print(digitalRead(pin8));
Serial.print(" ");
Serial.print(digitalRead(pin9));
Serial.print(" ");
Serial.print(digitalRead(pin10));
Serial.print(" ");
Serial.print(digitalRead(pin11));
Serial.print(" ");
Serial.println(digitalRead(pin12));

}

The output is something like this:
0 1 0 1 0 1 0 0 0 0 0 1

Problem is whether there is a temperature or not temperature shown on the display, there will be no change in the serial.print output.

What should i do ?

Why are you setting all the pins to outputs? If you are reading them they must be inputs.

Do not use pin 1 as this is used for uploading code to the board, along with pin 0.

Please read the how to use this forum sticky post, as the way you are posting code is breaking the forum rules.
your comments do not match what the code is doing.

What should i do ?

Use an array of pins instead of individual pins for one thing

Grumpy_Mike:
Theoretically yes, but practically it is difficult, quite difficult.

And Mike is not kidding! :astonished:

Grumpy_Mike:
2) this display is in a circuit and so the signals you read off it will not be logic levels, so you will need a circuit on each pin that turns what ever signal is there into logic levels.

When you start talking about simply connecting Arduino pins to the display, you have of course, completely overlooked this critical point.

You need to use an oscilloscope to inspect exactly what voltages occur on the display pins, then design an interface circuit to suit.

The output is something like this:
0 1 0 1 0 1 0 0 0 0 0 1

No, there is no output from the sketch you posted because it will not compile:

int pin2 = 2;     
int pin2 = 3;     
int pin2 = 4;     
int pin2 = 5;     
int pin2 = 6;     
int pin2 = 7;     
int pin2 = 8;     
int pin2 = 9;     
int pin2 = 10;     
int pin2 = 11;     
int pin2 = 12;

Minor details! :roll_eyes:

Hi,

I tried with a voltmeter and measure the pins. There is a voltage difference if one of the LEDs lights up. But when i connect one of the pins to the Arduino analog, it cant work.

For eg,
I tried to read 1 digit, LED diode E

Voltage meter
Pin 12 - GND
Pin 1 - VCC
Voltage difference appears in voltmeter

Arduino
Pin 12 - GND
Pin 1 - A0
The values ranges from between 0 to 5 V
Cant seems to catch the voltage

Below is the code from Arduino.

const float referenceVolts = 5.0; // the default reference on a 5-volt board
const int batteryPin = 0;         // battery is connected to analog pin 0

void setup() 
{
Serial.begin(9600);
}

void loop()
{
  int val = analogRead(batteryPin); // read the value from the sensor 
  float volts = (val / 1023.0) * referenceVolts; // calculate the ratio
  Serial.println(volts); // print the value in volts
  delay(200);
  }

3Digit7Segment Pinout and Schematic.pdf (927 KB)

Hi Everyone,

I have an old wall mount thermometer which displays temperature of a person. It uses a 3 digit temperature display to display the values.

I am trying to read of the values using Arduino and display on Serial.pint. After experimenting it for a while, I realised that voltmeter can be used to measure the voltage difference of a particular LED in the digit.

For eg,
1st digit LED E (Using voltmeter)

Connection to voltmeter
Pin 12 to GND
Pin 1 to VCC

Voltmeter readings
Before lights up - 4.91 V
After Light up - 3.01 V

Using Arduino
I tried using Arduino to read the voltage difference using the following connection and code but unable to read the voltage consistently.

Connection to Arduino
Pin 12 to 3.3v
Pin 1 to A0 //analog pin 0

The readings were when LED is off or on
0.00 V
0.00 V
0.00 V
1.00 V
2.00 V
5.00 V
2.00 V
1.00 V
0.00 V

Arduino Code

const float referenceVolts = 5.0; // the default reference on a 5-volt board
const int batteryPin = 0;         // battery is connected to analog pin 0

void setup() 
{
Serial.begin(9600);
}

void loop()
{
  int val = analogRead(batteryPin); // read the value from the sensor 
  float volts = (val / 1023.0) * referenceVolts; // calculate the ratio
  Serial.println(volts); // print the value in volts
  delay(200);
  }

What have i done incorrectly?

3Digit7Segment Pinout and Schematic.pdf (927 KB)

Is that PDF something to do with it? It seems to be a diagram showing how to make the display show numbers controlled by the Arduino. I thought you wanted to read what the display is showing.

I tried to read 1 digit, LED diode E

Voltage meter
Pin 12 - GND
Pin 1 - VCC

If those are how you set up the display then you have two things wrong:-

  1. You have the polarity wrong to light up the segment.
  2. You have no resistors in the circuit to limit the current in the segment so when you do get the polarity right you will probably blow the segment.

Voltage difference appears in voltmeter

And what does that mean? Difference between what?

xingtan10:
Cant seems to catch the voltage

Not at all surprised!

This is the problem - the voltages you are monitoring are not standard logic levels so you might want to use analog measurements, but analog reads are slow and the volltages are changing as the multiplexing occurs in a way that is difficult to synchronise.

The latest code is using analogRead.

but they are changing as the multiplexing occurs in a way that is difficult to synchronise.

Its not as easy as difficult.

Duplicate topics merged

Hi,

I tried for hours So i guess its impossible to read 3 dig 7 segment. i get random 1s and 0s.

volatile int state = HIGH;
volatile int flag12 = HIGH;
volatile int flag9 = HIGH;
volatile int flag8 = HIGH;
int count = 0;

int digit1 = 3; // pin 12 Dig 1
int digit2 = 4; // pin 9 Dig 2
int digit3 = 5; // pin 8 Dig 3
int A = 6;      // pin 11 A
int B = 7;      // pin 7  B
int C = 8;      // pin 4  C
int D = 9;      // pin 2  D
int E = 10;     // pin 1  E
int F = 11;     // pin 10 F
int G = 12;     // pin 5  G 

void setup()
{
  Serial.begin(9600);

  pinMode(digit1, INPUT); // pin 8
  pinMode(digit2, INPUT); // pin 9
  pinMode(digit3, INPUT); // pin 12
  pinMode(A, INPUT); 
  pinMode(B, INPUT); 
  pinMode(C, INPUT); 
  pinMode(D, INPUT); 
  pinMode(E, INPUT); 
  pinMode(F, INPUT); 
  pinMode(G, INPUT); 

  attachInterrupt(digit1, capture12, RISING);
  attachInterrupt(digit2, capture9, RISING);
  attachInterrupt(digit3, capture8, RISING);
  //attachInterrupt(ONE, capture1, FALLING); // Interrupt is fired whenever LEFT goes from low to high
  //attachInterrupt(3, capture2, RISING); // Interrupt is fired whenever RIGHT goes from low to high
}

void loop()
{
    delay(200);

//     int State_A = digitalRead(A); //LED starts ON
//     int State_B = digitalRead(B);
//     int State_C = digitalRead(C);
//     int State_D = digitalRead(D);
//     int State_E = digitalRead(E);
//     int State_F = digitalRead(F);
//     int State_G = digitalRead(G);
//     int State_F = digitalRead(F);
//     int State_G = digitalRead(G);

    Serial.print(digitalRead(digit1));
    Serial.print(" ");

    Serial.print(digitalRead(digit2));
    Serial.print(" ");
  
    Serial.print(digitalRead(digit3));
    Serial.print(" ");
    
    Serial.println(digitalRead(A));
    
//    Serial.print(" ");
//    Serial.println(digitalRead(D));
//    Serial.print(" ");
//    Serial.print(digitalRead(E));
//    Serial.print(" ");
//    Serial.print(digitalRead(F));
//    Serial.print(" ");
//    Serial.println(digitalRead(G));

}

void capture12(){
  flag12 = HIGH;
}

void capture9(){
  flag9 = HIGH;
}

void capture8(){
  flag8 = HIGH;
}
int digit1 = 3; // pin 12 Dig 1
int digit2 = 4; // pin 9 Dig 2
int digit3 = 5; // pin 8 Dig 3


  attachInterrupt(digit1, capture12, RISING);
  attachInterrupt(digit2, capture9, RISING);
  attachInterrupt(digit3, capture8, RISING);

The only pins you can use attachInterrup with are pins 2 and 3 on a Uno

However, the ISR is not doing much but setting a flag high, so it is a little useless using interrupts for that. Especially as you have a socking great delay(200) at the start of the loop. That means by the time you get to read the values from the pins the multiplexer is probably displaying another number. And anyway you are not even using the fact that the flag is set to limit what pin you read, and you are never resting the flag once you used it.

A serial print takes a long time and you make it even longer by using such a slow baud rate.

Are you actually seeing digital signals from both the anode and segment cathodes?

When writing code you should always build up the functionality slowly. Start off with just trying to detect one digit select line. Then add the code to detect a falling edge on that line. Use the state change example in the IDE to see how to do this. Then see if you can capture one segment consistently.

Then build it up to what you want.

As I said in my first post this is not easy. I also said:-

So you have to read the enable pin after you read the segments to see it has not change in order to see if you have a valid reading.

Hi Grumpy_Mike,

I think u hit the jackpot. I tried for hours and its almost there. But i’ve hit the wall.

  1. If my display shows 35.7, my serial.println shows
    3
    3
    5
    7
    7
    3
    3

Also, i have 3 flags for each segment. Flag1 detects segment1/digit1, flag2 detects segment/digit2 and so on. I realised that flag2 display 2 numbers as shown above, 5 and 7 if its 35.7 whereas flag 1 shows 3. Flag 3 is not showing anything.

I want the value displayed on serial.print to be 35.7.

#include <Keyboard.h>

volatile int flag1 = 1;
volatile int flag2 = 1;
volatile int flag3 = 1;

String a = "";
String b = "";
String c = "";
String d = "";
String b1 = "";
String b2 = "";

int dig1 = 3;
int dig2 = 4;
int dig3 = 5;

int A = 6; 
int B = 7;
int C = 8;
int D = 9;
int E = 10;
int F = 11;
int G = 12;


void setup()
{
  Serial.begin(9600);
  Keyboard.begin();             // Begin Keyboard
  pinMode(C, INPUT_PULLUP);
  pinMode(D, INPUT_PULLUP);
  pinMode(E, INPUT_PULLUP);
  pinMode(F, INPUT_PULLUP);
  pinMode(G, INPUT_PULLUP);
  pinMode(B, INPUT_PULLUP);
  pinMode(A, INPUT_PULLUP);

  pinMode(dig1, INPUT_PULLUP);
  pinMode(dig2, INPUT_PULLUP);
  pinMode(dig3, INPUT_PULLUP);

  attachInterrupt(dig1, capture1, CHANGE); // Interrupt is fired whenever RIGHT goes from low to high
  attachInterrupt(dig2, capture2, CHANGE); // Interrupt is fired whenever LEFT goes from low to high
  attachInterrupt(dig3, capture3, CHANGE); // Interrupt is fired whenever LEFT goes from low to high

}

void loop()
{
  a = "";
  b = "";
  c = "";
  d = "";
  delayMicroseconds(10);
  //  Serial.print(flag1);
  //  Serial.print(" ");
  //  Serial.print(flag3);
  //  Serial.print(" ");
  //  Serial.println(flag2);
  //  if (flag3 == 1) {
  //    //      3rd number
  //    Serial.print(digitalRead(C));
  //    Serial.print(digitalRead(D));
  //    Serial.print(digitalRead(E));
  //    Serial.print(digitalRead(F));
  //    Serial.print(digitalRead(G));
  //    Serial.print(digitalRead(B));
  //    Serial.println(digitalRead(A));
  //     if (digitalRead(C) == 1 && digitalRead(D) == 0 && digitalRead(E) == 0 && digitalRead(F) == 0 && digitalRead(G) == 0 && digitalRead(B) == 1 && digitalRead(A) == 0) {
  //      //print 1
  //      b = "1";
  //      Serial.println(b);
  //    }
  //
  //    else if (digitalRead(C) == 0 && digitalRead(D) == 1 && digitalRead(E) == 1 && digitalRead(F) == 0 && digitalRead(G) == 1 && digitalRead(B) == 1 && digitalRead(A) == 1) {
  //      //print 2
  //      b = "2";
  //      Serial.println(b);
  //    }
  //    else if (digitalRead(C) == 1 && digitalRead(D) == 1 && digitalRead(E) == 0 && digitalRead(F) == 0 && digitalRead(G) == 1 && digitalRead(B) == 1 && digitalRead(A) == 1) {
  //      //print 3
  //      b = "3";
  //      Serial.println(b);
  //    }
  //    else if (digitalRead(C) == 1 && digitalRead(D) == 0 && digitalRead(E) == 0 && digitalRead(F) == 1 && digitalRead(G) == 1 && digitalRead(B) == 1 && digitalRead(A) == 0) {
  //      //print 4
  //      b = "4";
  //      Serial.println(b);
  //    }
  //    else if (digitalRead(C) == 1 && digitalRead(D) == 1 && digitalRead(E) == 0 && digitalRead(F) == 1 && digitalRead(G) == 1 && digitalRead(B) == 0 && digitalRead(A) == 1){
  //      //print 5
  //      b = "5";
  //      Serial.println(b);
  //    }
  //    else if (digitalRead(C) == 1 && digitalRead(D) == 1 && digitalRead(E) == 1 && digitalRead(F) == 1 && digitalRead(G) == 1 && digitalRead(B) == 0 && digitalRead(A) == 1){
  //      b = "6";
  //      Serial.println(b);
  //    }
  //    else if (digitalRead(C) == 1 && digitalRead(D) == 0 && digitalRead(E) == 0 && digitalRead(F) == 0 && digitalRead(G) == 0 && digitalRead(B) == 1 && digitalRead(A) == 1){
  //      b = "7";
  //      Serial.println(b);
  //    }
  //    else if (digitalRead(C) == 1 && digitalRead(D) == 1 && digitalRead(E) == 1 && digitalRead(F) == 1 && digitalRead(G) == 1 && digitalRead(B) == 1 && digitalRead(A) == 1){
  //      b = "8";
  //      Serial.println(b);
  //    }
  //    else if (digitalRead(C) == 1 && digitalRead(D) == 1 && digitalRead(E) == 0 && digitalRead(F) == 1 && digitalRead(G) == 1 && digitalRead(B) == 1 && digitalRead(A) == 1){
  //      b = "9";
  //      Serial.println(b);
  //    }
  //    else{
  //
  //    }
  //    flag3 = 0;
  //    delay(10);
  //  }

  if (flag2 == 1) {
    // 2nd number
    //    Serial.print(digitalRead(C));
    //    Serial.print(digitalRead(D));
    //    Serial.print(digitalRead(E));
    //    Serial.print(digitalRead(F));
    //    Serial.print(digitalRead(G));
    //    Serial.print(digitalRead(B));
    //    Serial.println(digitalRead(A));

    if (digitalRead(C) == 1 && digitalRead(D) == 0 && digitalRead(E) == 0 && digitalRead(F) == 0 && digitalRead(G) == 0 && digitalRead(B) == 1 && digitalRead(A) == 0) {
      //print 1
      b = "1";
//      Serial.print(b);
    }

    else if (digitalRead(C) == 0 && digitalRead(D) == 1 && digitalRead(E) == 1 && digitalRead(F) == 0 && digitalRead(G) == 1 && digitalRead(B) == 1 && digitalRead(A) == 1) {
      //print 2
      b = "2";
//      Serial.print(b);
    }
    else if (digitalRead(C) == 1 && digitalRead(D) == 1 && digitalRead(E) == 0 && digitalRead(F) == 0 && digitalRead(G) == 1 && digitalRead(B) == 1 && digitalRead(A) == 1) {
      //print 3
      b = "3";
//      Serial.print(b);
    }
    else if (digitalRead(C) == 1 && digitalRead(D) == 0 && digitalRead(E) == 0 && digitalRead(F) == 1 && digitalRead(G) == 1 && digitalRead(B) == 1 && digitalRead(A) == 0) {
      //print 4
      b = "4";
//      Serial.print(b);
    }
    else if (digitalRead(C) == 1 && digitalRead(D) == 1 && digitalRead(E) == 0 && digitalRead(F) == 1 && digitalRead(G) == 1 && digitalRead(B) == 0 && digitalRead(A) == 1) {
      //print 5
      b = "5";
//      Serial.print(b);
    }
    else if (digitalRead(C) == 1 && digitalRead(D) == 1 && digitalRead(E) == 1 && digitalRead(F) == 1 && digitalRead(G) == 1 && digitalRead(B) == 0 && digitalRead(A) == 1) {
      b = "6";
//      Serial.print(b);
    }
    else if (digitalRead(C) == 1 && digitalRead(D) == 0 && digitalRead(E) == 0 && digitalRead(F) == 0 && digitalRead(G) == 0 && digitalRead(B) == 1 && digitalRead(A) == 1) {
      b = "7";
//      Serial.print(b);
    }
    else if (digitalRead(C) == 1 && digitalRead(D) == 1 && digitalRead(E) == 1 && digitalRead(F) == 1 && digitalRead(G) == 1 && digitalRead(B) == 1 && digitalRead(A) == 1) {
      b = "8";
//      Serial.print(b);
    }
    else if (digitalRead(C) == 1 && digitalRead(D) == 1 && digitalRead(E) == 0 && digitalRead(F) == 1 && digitalRead(G) == 1 && digitalRead(B) == 1 && digitalRead(A) == 1) {
      b = "9";
//      Serial.print(b);
    }
    else {

    }
    Serial.println(b);
    flag2 = 0;
    delay(50);
  }


  else if (flag1 == 1) {
    //      1st number
    //    Serial.print(digitalRead(C));
    //    Serial.print(digitalRead(D));
    //    Serial.print(digitalRead(E));
    //    Serial.print(digitalRead(F));
    //    Serial.print(digitalRead(G));
    //    Serial.print(digitalRead(B));
    //    Serial.println(digitalRead(A));
    if (digitalRead(C) == 1 && digitalRead(D) == 1 && digitalRead(E) == 0 && digitalRead(F) == 0 && digitalRead(G) == 1 && digitalRead(B) == 1 && digitalRead(A) == 1) {
      //Print 3
      c = "3";
      //      Serial.println(c);
      //      Serial.println(b);
      delay(10);
      d = c + b;
      Serial.print(d);
      delay(5000);
      flag1 = 0;
    }
  }
  else{
    
  }


}

void capture1()
{
  // state = !state;
  flag1 = 1;

}
void capture2()
{
  flag2 = 1;

}
void capture3()
{
  flag3 = 1;
}

Hi Grumpy_Mike,

Will you be kind enough to point me the correct direction or how to start reading 1 digit at a time? Any code samples? Should i still use the attachInterrupt to get each digital and its data even if i set the sock delay to delayMicroseconds(400)? How about setting baud to faster rate? Will it be fast enough to capture each segment data?

When writing code you should always build up the functionality slowly. Start off with just trying to detect one digit select line. Then add the code to detect a falling edge on that line. Use the state change example in the IDE to see how to do this. Then see if you can capture one segment consistently.

Then build it up to what you want.

Mike already told you why your code is not working. If there was something you did not understand, you shold ask about it, not ignore it, which you seem to be doing.

and its data even if i set the sock delay to delayMicroseconds(400)?

I think you are not understanding the word socking. It is an adverb describing the size of the delay you have as being very large.
Why do you have this delay anyway? It is not needed at all and is only going to make your code not work.

Your code is a bit of a nonsense at the moment. There is no way anyone is going to follow that with all he commented out code. And what did I tell you about the interrupts? You seem to be ignoring everything I told you.

Forget about trying to decode the digit at the moment, just try to gather all the segment values when you see a rising edge on one enable pin. Just one for the moment you are making a big mess.

 #include <Keyboard.h>

And why are you including this but never using it?