Reading a 10 pin 7 segment (2 digits) using Arduino uno. Please Help!

Hello everyone, thanks for taking the time to read this, I really appreciate it. I am very new to Arduino and the Micro controller world so please forgive my ignorance.

So I have an old dual 7 segment display that displays outside temperature, what i want to do is read the temp into the Arduino and light up an LED if the temperature gets high, and a different color if the temp gets low.

I know i can use a thermometer and plug it into the Arduino and go from there, but that would be cheating. So my question is, can i read each pin of the 7 segment display and translate that into a number into the Arduino?

please see pictures.

Any help would be very very appreciated!!

Thanks again for reading.

This last picture shows "21" using the code and set up on the above link. I want to jump another Arduino into the breadboard and read "21" or any other temperature (depends on outside thermometer) into the serial monitor. Now the challenging part is the code, Im not really good at coding but i understand if this had 1 pin for each LED i would just read each one and translate it into the serial monitor. However this only has 10 pins therefore represents a challenge.

Any input is greatly appreciated, I dont even know how to start.

If the display is multiplexed, meaning the anodes are share between digits and there is a common cathode for each digit (or shared cathodes, and a common anode per digit) then you will need a way to signal when to capture data. Perhaps use an interrupt from the 2 common signals to capture the state of the shared segments.

This is what i have, It is common anode. I'm not sure how to add an interrupt, I've been trying to just read high and low but I'm not having too much luck :/

Interrupt on pins 9 and 6 going Low to High.

I might be trying to do something way beyond my scope of coding, im a bit familiar with interrupts. How would I even begin? Im using a voltmeter and i see that all pins are mostly high all the time even tho im just displaying a "1"

What you don’t see with a meter is that 30 times a second or so the data is being updated, first one digit than the other.
Read up on interrupts in the Reference section.
In your ISR, when the interrupt occurs, read/save the input pins.
I would use direct port manipulation and read them in 2 groups.
Say you had segments a-b-c-d-e-f on D2-3-4-5-6-7, and g on D8 then a read could be

segAtoF = PIND >>2; // capture segments A-F move to bits 0-5
segG = (PINB & 0b00000001) << 6; // capture G and move to 6
//then put together:
segmentAtoG = segG | segAtoF;

Something along those lines.

Thank you so much! let me play with this and see what i can come up with.

so I realized that the 2 pins that are driving this toggle at 4kHz, when one is on the other is off, but there is a 6usec time when both pins are on. So what im trying to do now is adding "if right bit is == 1, if A=1 b=0 c=1 d=1... and so on" then number = 6 then scan for it.

void loop() {
  // read the input pin:
  //int buttonState = digitalRead(pushButton);
  int State_A = digitalRead(A);
  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_DP = digitalRead(DP);
    int State_RIGHT = digitalRead(RIGHT);
    int State_LEFT = digitalRead(LEFT);

 if (State_LEFT==1)
 {
   if(State_A==0 & State_B==1 & State_C==0 & State_D==0 & State_E==0 & State_F==0 & State_G==0)
 {
   number=6;
   Serial.println(number);
// Serial.print(State_LEFT);
}

i plan to do this for every digit. I know there has to be an easier way.

Shouldn't care when both are on. Just when one first turns on - so use an interrupt with RISING and capture the data then. I don't see interrupts in your code at all. All those digitalReads - you'll never get there. I think a digitalRead takes about 4uS by itself. 4 KHz, I guess you have 250uS to read them, so it might work. Direct port read using value = PIND; is 1 instruction, 62.5nS. Much faster.

I have created interrupts so that when my 2 pins go from low to high "capture" happens. I want to see if im reading all the pins when capture happens, but it seems i cant capture any, the serial monitor is empty. Im not familiar with "Value = PIND" does this read all pins at once?

volatile int state = HIGH;
volatile int flag = HIGH;
int count = 0;


int A = 2;
int B = 5;
int c = 6;
int D = 7;
int E = 8;
int F = 9;
int G = 10;
int DP = 11;
int RIGHT = 19;
int LEFT = 18;
void setup()
{
  Serial.begin(9600);

  pinMode(RIGHT, INPUT_PULLUP);
  pinMode(LEFT, INPUT_PULLUP);
  pinMode(A, INPUT_PULLUP);
  pinMode(B, INPUT_PULLUP);
  pinMode(C, INPUT_PULLUP);
  pinMode(D, INPUT_PULLUP);
  pinMode(E, INPUT_PULLUP);
  pinMode(F, INPUT_PULLUP);
  pinMode(G, INPUT_PULLUP);
  
  attachInterrupt(RIGHT, capture, RISING); // Interrupt is fired whenever RIGHT goes from low to high 
  attachInterrupt(LEFT, capture, RISING); // Interrupt is fired whenever LEFT goes from low to high 
}

void loop()
{


}

void capture()
{
  int State_A = digitalRead(A);
  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);
  
  
Serial.print(State_A);
Serial.print(State_B);
Serial.print(State_C);
Serial.print(State_D);
Serial.print(State_E);
Serial.print(State_F);
Serial.print(State_G);

}

Also, my void is empty, should i print my pins in this void?

PS. thanks so much for all your help!

Hi, don't put all those Serial.print in your interrupt code. It is much too slow. Do that in loop(). You will need 8 variables for each digit.

Paul

Also, my void is empty, should i print my pins in this void?

You do not have any voids.
You have functions that do not return a value.
Void means the “following function does not return a value”.

valueD = PIND; // captures the state of all bits of PORTD, which is D7-6-5-4-3-2-1-0. You have to pick out bits you want, i.e.2,5,6,7 valueB = PINB; // captures the state of all bits of PORTB, which is x-x-D13-12-11-10-9-8. You have to pick out the bits you want, i.e. 8,9,10,11

What you can do is just set a 'flag' in the ISR:

void capture() { flag = 1; }

Then in loop , wait for the flag to be set. need this before setup (I think this is correct syntax)

volatile byte flag; // lets 'flag' be used in ISR and in loop
// void setup stuff you have now

void loop(){

if (flag ==1){
flag = 0;
valueD = PIND;
valueB = PINB;
Serialprint(valueB);
Serialprintln(valueD);
} // end flag test

} // end loop

You may want to add some delay in there to not flood out your PC serial port. bytes coming in at 4 KHz will swamp it.

Here is what i got so far.

volatile int state = HIGH;
volatile int flag1 = HIGH;
volatile int flag2 = HIGH;
int count = 0;

int A = 2;
int B = 5;
int c = 6;
int D = 7;
int E = 8;
int F = 9;
int G = 10;
int DP = 11;
int TWO = 19;
int ONE = 18;

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


 pinMode(TWO, INPUT_PULLUP);
  pinMode(ONE, INPUT_PULLUP);
  pinMode(A, INPUT_PULLUP);
  pinMode(B, INPUT_PULLUP);
  pinMode(c, INPUT_PULLUP);
  pinMode(D, INPUT_PULLUP);
  pinMode(E, INPUT_PULLUP);
  pinMode(F, INPUT_PULLUP);
  pinMode(G, INPUT_PULLUP);
  
  //attachInterrupt(ONE, capture1, FALLING); // Interrupt is fired whenever LEFT goes from low to high 
  attachInterrupt(TWO, capture2, RISING); // Interrupt is fired whenever RIGHT goes from low to high
}

void loop()
{
    delay(0.4);
  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);
  
 if(flag2) {
   
    // Serial.print("digit 2");
      //Serial.print("  ");
if(State_A==0 & State_B==0 & State_C==0 & State_D==0 & State_E==0 & State_F==0 & State_G==1){Serial.println("0");}
if(State_A==1 & State_B==0 & State_C==0 & State_D==1 & State_E==1 & State_F==1 & State_G==1){Serial.println("1");}
if(State_A==0 & State_B==0 & State_C==1 & State_D==0 & State_E==0 & State_F==1 & State_G==0){Serial.println("2");}
if(State_A==0 & State_B==0 & State_C==0 & State_D==0 & State_E==1 & State_F==1 & State_G==0){Serial.println("3");}
if(State_A==1 & State_B==0 & State_C==0 & State_D==1 & State_E==0 & State_F==0 & State_G==0){Serial.println("4");}
if(State_A==0 & State_B==1 & State_C==0 & State_D==0 & State_E==1 & State_F==0 & State_G==0){Serial.println("5");}
if(State_A==0 & State_B==1 & State_C==0 & State_D==0 & State_E==0 & State_F==0 & State_G==0){Serial.println("6");}
if(State_A==0 & State_B==0 & State_C==0 & State_D==1 & State_E==1 & State_F==1 & State_G==1){Serial.println("7");}
if(State_A==0 & State_B==0 & State_C==0 & State_D==0 & State_E==0 & State_F==0 & State_G==0){Serial.println("8");}
if(State_A==0 & State_B==0 & State_C==0 & State_D==0 & State_E==1 & State_F==0 & State_G==0){Serial.println("9");}
    delay(10);
   flag2 = LOW;
  } //delay();
  /* if(flag1){
      //delay(0.5);
      Serial.print("digit 1");
      Serial.print("  ");
     Serial.print(State_A);
    Serial.print(State_B);
    Serial.print(State_C);
    Serial.print(State_D);
    Serial.print(State_E);
    Serial.print(State_F);
    Serial.println(State_G);
   
    flag1 = LOW;
    //delay(100);
  }
     
      */

  
}

void capture()
{
 // state = !state;
  flag1 = HIGH;
}
void capture2()

{
flag2=HIGH;
}

i can read one of the digits. Im not sure if this is the most efficient way. Also when i add the segment to read the other digits (the commented section) everything goes crazy. Could that be due to timing?

delay(0.4);

That works? I think perhaps you meant

delayMicroseconds(400); // delay 0.4mS

delay( ) only accepts integer numbers.

Not consistent in naming:

void capture()
vs
//attachInterrupt(ONE, capture1, FALLING);

May compile ok, but will not perform as intended.

These can by byte instead of int

  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);

and why read if the interrupt has not occurred? There's no timing sync that way. Read them after the interrupt has occcured.

if (flag1 == HIGH){
flag1 = 0;
State_A = digitalRead(A); 
etc
}
if(State_A==0 & State_B==0 & State_C==0 & State_D==0 & State_E==0 & State_F==0 & State_G==1){Serial.println("0");}
if(State_A==1 & State_B==0 & State_C==0 & State_D==1 & State_E==1 & State_F==1 & State_G==1){Serial.println("1");}
if(State_A==0 & State_B==0 & State_C==1 & State_D==0 & State_E==0 & State_F==1 & State_G==0){Serial.println("2");}
if(State_A==0 & State_B==0 & State_C==0 & State_D==0 & State_E==1 & State_F==1 & State_G==0){Serial.println("3");}
if(State_A==1 & State_B==0 & State_C==0 & State_D==1 & State_E==0 & State_F==0 & State_G==0){Serial.println("4");}
if(State_A==0 & State_B==1 & State_C==0 & State_D==0 & State_E==1 & State_F==0 & State_G==0){Serial.println("5");}
if(State_A==0 & State_B==1 & State_C==0 & State_D==0 & State_E==0 & State_F==0 & State_G==0){Serial.println("6");}
if(State_A==0 & State_B==0 & State_C==0 & State_D==1 & State_E==1 & State_F==1 & State_G==1){Serial.println("7");}
if(State_A==0 & State_B==0 & State_C==0 & State_D==0 & State_E==0 & State_F==0 & State_G==0){Serial.println("8");}
if(State_A==0 & State_B==0 & State_C==0 & State_D==0 & State_E==1 & State_F==0 & State_G==0){Serial.println("9");}

There is a rule in computing that if you find yourself writing the almost identical thing over and over you are doing it very wrong. You need arrays. http://www.thebox.myzen.co.uk/Tutorial/Arrays.html

Need && there also, yes?

cacn: This last picture shows "21" using the code and set up on the above link.

I'm a little reluctant to help more here because of that picture in the first post with a sheet of paper, containing a very carefully cut-out hole, hiding the rest of the circuit board. If this is just an outside temperature gauge, why hide the rest of the board so carefully?

delay(0.4) worked just fine, also only one "&". I'm currently reading the array demo and it seems that's the way i should go about figuring out what pins are on, thanks so much for the help.