2

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 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 is the main goal.

Another picture of the main goal.![][2]

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.

  • Have you checked (eg with a DMM or an oscilloscope) the voltage between the anode and cathode for one lit segment of the display? This will tell you if this can be directly used as a digital input of Arduino or it it requires additional circuitry. – jfpoilpret Aug 12 '14 at 5:00
  • In order to get the value from any display pin, you will also need a ground that you can plug to Arduino GND, do you have such a pin onn the display board, or you just have 8+2 pins, 8 for the 7 segments + DP, 2 for each common anode? – jfpoilpret Aug 12 '14 at 5:07
3

Your display is multiplexed, so you will need to monitor not only the segment lines but also the digit lines.

First figure out if your display is "common anode" or "common cathode" as the logic in one case will be inverted from that of the other.

For your test case, you can write the driving and reading arduinos to the display in the same way, but configure all the connected pins on the reading one as inputs.

The tricky part is going to be detecting when the segment select has changed, but you could do it by storing the current value of each select pin, and then reading the new value. If you see that the old value was inactive and the new value active, then wait a tiny amount of time and read all of the segment lines. You want to wait long enough to make sure that the data lines have been driven to match, but no so long that you get the data for the next digit instead. If you have access to a scope, you can find the best value, but you could also experiment by making the delay short until you get wrong data, making it long until you get wrong data, and then picking an intermediate value.

You may find it easiest to read all 7 or 8 segment lines into a single byte value, and then compare it to each element in the lookup table you used in the driver code until you find a match.

If you don't know the exact wiring of the segments on the unknown target board, consider printing the bytes to the serial monitor as you cause the displayed values to change (cup of ice water, cup of hot water...) and taking notes of the segment values vs. the digits you see display. It will be a puzzle, but one you should be able to figure out.

  • I have a common anode setting. I am really new to code, is there an example anywhere that i could go over? – user3537 Aug 11 '14 at 17:50
1

First of all, make sure that the voltage is below 5V (but above 2.5V so it can register as HIGH on a digital pin). If not, it will either fry your Arduino or won't work.

As for the code, you can do one of the two following things:

  • Use a library like PinChangeInt to help you detect when and what changed.
  • Store the data and check every so often.

Chris Stratton had a good idea with the byte and compare it. To do this, you would do something like this:

byte data = 0;
if(digitalRead(10) == HIGH) {
  data |= B00000001;
}
if(digitalRead(11) == HIGH) {
  data |= B00000010;
}
if(digitalRead(12) == HIGH) {
  data |= B00000100;
}
//...

Basically, this is bit-wise math that sets one bit of your byte to a 1. If it is a 0, then you leave it alone (all bits default to 0 because of how I declared data).

If pins 10 and 12 were HIGH, the byte would look like this in binary:

00000101
  • Hi! 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 'code' – user3537 Aug 12 '14 at 0:27
  • @user3537 Do you need help with that? If so, what I can I help you with? – Anonymous Penguin Aug 12 '14 at 1:00
  • 1
    It would be so much more efficient to read an entire AVR port register, even if a few bits spill into the next. Does Arduino support that cleanly, or only by ignoring it and doing a raw read? – Chris Stratton Aug 12 '14 at 4:13
0

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. Im not sure how to use that library.

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 add that for every digit. is there any easier way to do that?

  • 1
    This should be edited into your question, as it is not an answer. – Chris Stratton Aug 12 '14 at 4:11
  • I would personally tie the two select pins to an level changing interrupt input on Arduino. Then when you receive an interrupt from one of the digits you have 'all the' time to read the segments. When you don't do the interrupt thing, you may read segments from different digits. A further optimization would be to replace all digitalRead's with a single segments = PINB which would read 8 input lines in a single go. – jippie Aug 12 '14 at 5:29
  • Using port registers would be cleaner, but much less portable. The port assignments are different between Arduino models. – Duncan C Aug 12 '14 at 11:48
  • "segments = PINB" how does this work? if i have all 7 pins a-g – user3537 Aug 12 '14 at 14:48
0

What you are trying to do is tricky and awkward, and probably not worth the trouble.

It's also above your current skill level, both in hardware and software.

As the other poster has said, the display is likely multiplexed. If so, it sends a value to 1 digit, then to the next, and alternates them quickly. Only one digit at a time is actually lit.

It's also possible that the digits are latched. The processor sends a value to one digit at a time and that digit's circuitry remembers the value until it changes again. However that's less likely because it's more complex and expensive to do

To decode a multiplexed display you'll need to figure out how the multiplexing is done. There are lots of different ways it could be done.

You say it's common anode. It might have the anodes of a digit wired together, and have them both connected to the controller. The anode that's currently being displayed would be connected to +5, and the cathodes of like segments from each digit would be wired together in parallel. To drive a digit, the control circuitry would connect the anode of that digit to the positive supply, and connect the segments to be displayed to ground. All other connections would be left floating. Then it would disconnect the anode of the first digit and connect the anode of the other digit to the positive supply.

The display may also have a logic level that determines which segment is being driven. For a 2 digit display all you'd need is one line, and a HIGH would drive 1 digit and a LOW would drive the other digit.

A logic analyzer would help you sort this out, but you need to know how to use it.

You might also try researching the thermometer you're using and see if you can find a schematic for it, in the documentation, the manufacturer website, or in a patent

Once you figure out how to read the segment values from each digit, you will need a truth table that maps segment values to numbers, and will need to do a lookup. That is intermediate level C programming.

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.