Driving a 14V common anode 7 segment Display

It can drive an 8x8 LED matrix. Updating the "wrong" 7-seg display will be a pain but fixable in software... I'm not sure about the 14V requirement of your display.

Do you have an updated schematic? (Assuming you are using 3 shift register)

You need to

  • Calculate the value of each digit
  • Use a lokuptable to convert the value to "segment-data"
  • Shift the segment data out into the shift register

//  AA
// F  B
// F  B
//  GG
// E  C
// E  C
//  DD
//
//  AFEDBGCx
static const uint8_t lookup[10] = {
  0b11111010, // 0
  0b00001010, // 1
  0b10111100, // 2
  0b10011110, // 3
  0b01001110, // 4
  0b11010110, // 5
  0b11110110, // 6
  0b10001010, // 7
  0b11111110, // 8
  0b11011110, // 9
};


void doit(){
int value = 123;

int a = value % 10;
int b = (value / 10) % 10;
int c = (value / 100) % 10;

uint8_t as = lookup[a];
uint8_t bs = lookup[b];
uint8_t cs = lookup[c];

shiftOut(dataPin, clockPin, bitOrder, as);
shiftOut(dataPin, clockPin, bitOrder, bs);
shiftOut(dataPin, clockPin, bitOrder, cs);

// and here pulse the latchPin
 
}

It can be wired to accept common Anode displays. There are plenty of people who have done this in the past. Just search the forum for it.

The only drawback is you can't use the internal binary to seven segment conversion you have to do in in software. This is a small price to pay, which you will have to do anyway once you get your current arrangement working.

Here's the final wiring of the circuit.

Is power and ground connected to the shift register and the ULNs?

They are hidden in proteus but I think they are internally connected

595

Try the following setup using SevSeg.h Library.

1. Build the following multiplexed display unit as per Fig-1. In a multiplexed display unit, the identical segments pins are shorted together and the CA-pin are kept isolated. Adjust R1 = R2 = R3 for acceptable brightness of the CA-type display units. Note that the use of inverting type buffer ULN2003 has made the CA-type display unit to have been seen by UNO as CC-type display unit.


Figure-1:

2. Upload the following Sketch. do not forget to include the SevSeg.h Library in your IDE.

#include <SevSeg.h>
SevSeg sevSeg; 

void setup()
{
  Serial.begin(9600);
  byte ccDPins[] = {9, 10, 11}; //9 = cc0-pin/CA0-pin, 10 = cc1/CA1-pin, ...
  byte segDPins[] = {2, 3, 4, 5, 6, 7, 8}; //2 = seg-a, 3 = seg-b ...
  sevSeg.begin(COMMON_CATHODE, 3, ccDPins, segDPins, false, false, false, false);
  analogReference(INTERNAL); //1.1V Vref for ADC
}

void loop()
{
  unsigned long prMillis = millis();
  while (millis() - prMillis < 2000) //temperature sampling interval is 2-sec
  {
    sevSeg.refreshDisplay();  //keep refreshing display until 2-sec has elapsed
  }
  float rawTemp = 100 * ( 1.1 / 1023) * analogRead(A4);// 31.25xxxx...
  rawTemp = rawTemp*100.00; //myTemp = 3125.xxxx.......
  unsigned int myTemp = (unsigned int)rawTemp; //myTemp = 3125(.(xxxx...) takes onlyinteger part
  sevSeg.setNumber(myTemp, 1, LOW); //arg2=digit after point, arg3=base-10
}

3. To know about SevSeg.h Library, you may read the post of this link.

@PaulRB
Hi Paul,
I just saw your replies on that forum and I wish u could help me.

I have the same circuit counting 0 to 999 but no flex sensor in the Input, I have a limit switch sensor ( just like a push button pressed or not pressed )
I have a 6 14V common Anode 7-segments each 2 display the same number
I'm using 74HC595 with ULN2803 Driver and each ULN2803 drive will be connected with separate resistors to 2 7 segments

Here's my schematic

I need ur help with the code to make its sequence right as I'm confused trying to make it work.
Thank you.

Your diagram shows only 3, not 6. Are the other 3 wired with a further 3 74hc595+uln2803? Or in some other way?

Please explain what you mean by this, it is confusing.

Your circuit counts up to 999 on 3 digits and the other 3 digits show the same count?

What is "right"? On the topic you linked, the code was said to be working.

You do not need to connect the COM pins of the uln2803, it is not important with LEDs.

You could replace each 74hc595+uln2803 with one chip tpic6b595 to simplify your circuit. The resistors would still be required.

Whether you use 74hc595 or tpic6b595, you must have a 0.1uF ceramic bypass cap connected between the Vcc and GND pins of each chip.

Yes they show the same count, here they are
7 seg
the other two are like this

const int buttonThreshold = 500;
int lastButton = 1023;

I dont understand what these values are, and will it work in my case using a push button not a flex sensor?
I didnt connect it as hardware yet, I'm trying to make the simulation work 1st
Or the simulation in proteus maybe have some bugs thats why not working on it?

I can't find it here unfortunately

when I upload it in Proteus the segments appear like this and its not counting
Could u help me find out what the problem is in my case?

Neither can I, same for most people I think. You have to buy most components on-line if you work on Arduino projects.

Those values are related to the flex sensor. Some changes to the sketch will be needed for use with a button, but they are not difficult. The flex sensor gives a value between 0 and 1023 (analogRead()), but with a button you get only HIGH or LOW (digitalRead()).

I don't use Proteus. Maybe we should wait to see what happens when you use a real Arduino and hardware.

Okay, I'll let you know if anything happens.

So, with a button instead of that part

int buttonNow = analogRead (Button);
  unsigned long timeNow = millis();

  if (buttonNow <= buttonThreshold && lastButton > buttonThreshold && timeNow - lastPressed > 50) {
    if (++num > 999) num = 0;
    lastPressed = timeNow;
  }
  lastButton = buttonNow;

It'll will be

 int buttonNow = analogRead (Button);
  unsigned long timeNow = millis();

  if (buttonNow == HIGH)
      num = num + 1; 
    if (num > 999) num = 0;
    
  if (reset == HIGH)
      num = 0;

Will that count on every time I push the button? Even if the button is still pressed, the count will remain as it is right?

Why do you think it would it do that?

Yes, I got it wrong my mistake
It'll be like that, I tried it in Proteus and it worked.
But there's something, when I push the reset button, The counter gets to 0
when I push the button to count again It doesn't count, Once I push the reset the counter remains 0

currState = digitalRead(upPin);
  
  if (prevState != currState)        
  {                                         
    prevState = !prevState;    

    if (currState == HIGH && counter < 999)   
    
      counter++;                     

    if(counter == 999) counter = 0;    
  }

  resetState = digitalRead(resetPin);
    if (resetState == HIGH) counter = 0;

Do you still have these lines?

void setup(){ // put your setup code here, to run once  
  
 pinMode(bt_up,    INPUT_PULLUP);
 pinMode(bt_reset, INPUT_PULLUP);

I can see you changed the pin names: bt_reset to resetPin.

Here's the Full code, They are defined as INPUT

const byte latchPin = 5;   // Pin connected to Pin 12 of 74HC595 (Latch)
const byte dataPin  = 4;   // Pin connected to Pin 14 of 74HC595 (Data)
const byte clockPin = 3;   // Pin connected to Pin 11 of 74HC595 (Clock)

const byte upPin =    6;     // pushbutton  attached to pin 6
const byte resetPin = 7;    //  resetbutton attached to pin 7

int prevState = 0;
int currState = 1;
int resetState =  0;

int counter = 0;           // initialise counter as zero

byte numberOfDigits = 3;

const byte numbers[10] =  
{
 //XABCDEFG
  B01111110, //0
  B00110000, //1
  B01101101, //2
  B01111001, //3
  B00110011, //4
  B01011011, //5
  B01011111, //6
  B01110000, //7
  B01111111, //8
  B01111011, //9
};

void setup()
{
  pinMode(latchPin, OUTPUT);   // set SR pins to output
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  pinMode(upPin, INPUT);      // sets pin 6 as pushbutton INPUT
  pinMode(resetPin, INPUT);   // sets pin 7 as resetbutton INPUT
}

void loop()
{
  //counter part
  currState = digitalRead(upPin);
  
  if (prevState != currState)           // has the state changed from HIGH to LOW or vice versa
  {                                         
    prevState = !prevState;    //invert

    if (currState == HIGH && counter < 999)   // If the button was pressed AND not reached 999

      counter++;                     // increment the counter by one

    if(counter == 999) counter = 0;    
 
  }
  resetState = digitalRead(resetPin);
    if (resetState == HIGH) counter = 0;

  showNumber(counter); // display the current digit
}

void showNumber(int number)
{

  digitalWrite(latchPin, LOW);     // Set latchPin LOW while clocking bits in to the register

  for(byte i = 0; i < numberOfDigits; i++)
{
    shiftOut(dataPin, clockPin, LSBFIRST, numbers[number % 10]);
    number /= 10;
  }

  digitalWrite(latchPin, HIGH);    //set latchPin to high to lock and send data
}

That is the problem. The previous version was correct to use INPUT_PULLUP.

Your buttons will read LOW when pressed, HIGH when not pressed.

It worked, Thanks man :heart:
I understand nw, INPUT only it doesn't know the state of the button pressed or not pressed, so the counter remains 0 after I push the resetButton.
When I defined it as INPUT_PULLUP and check if its low, the counter gets to 0 only if it's pressed

  resetState = digitalRead(resetPin);
    if (resetState == LOW) counter = 0;

Thanks Paul