Go Down

Topic: How to make a counter from 0 to 999 (Read 482 times) previous topic - next topic


Good I am learning to program and I want to do an accountant from 0 to 999 employing units tens and hundreds would be very useful to help me since I am new to this.
  I need to do it with three seven segment displays


Please show us what code you have so far.

A schematic of your proposed circuit helps us help you.

Are the displays common cathode or anode?

No technical PMs.
The last thing you did is where you should start looking.


Aug 10, 2017, 06:05 pm Last Edit: Aug 20, 2017, 01:00 pm by GolamMostafa

This post is made being inspired by the Post #1. Therefore, please wake up by making a reply post.

It looks like that you are facing difficulties to draw a 'Schematic' of your display unit.

(1)  A schematic of a display unit is a diagram on paper in which we clearly indicate the correct wiring connections among the physical pins of all the devices.

(2) The proposed display unit consists of:
(a)  Arduino UNO (I believe!).
(b)  3 pieces of cc(common cathode)-type 7-segment display device.  

(3)  The schematic diagram of the 3-digit cc(common cathode)-type 7-segment display unit

(4) Now, place the display devices on a breadboard. Connect the devices together to form a multiplexed display unit. Connect the segment pins of the display devices with the digital pins of the Arduino UNO Learning Kit.

(5)  The current limiting resistors for the segment lines are omitted for simplicity. It is recommended that you put 220 - 680 ohm resistor in series with each segment lines. However, if the experiment is for a short you may continue without these resistors.

(6) Now, you need a program (called sketch in the vocabulary of Arduino) to upload into the Flash Memory of the ATmega328 MCU (Microcontroller) of the Arduino; this program will drive your display counter 0, 1, 2, ..., 9, 10, ..., 99, 100, ..., 999, 0, ........

(7) You have said that you are a beginner; so, start from very rudimentary tasks.
(a) Connect 220-680 ohm resistor in series with cc0-pin of DP0, cc1-pin of DP1, and cc2-pin of DP2. These are the simplified non-standard connections of current limiting resistors.
(b) Write sketch and upload it to see digit 2 on DP0 only.
Code: [Select]
void setup()
   //set directions of IO lines of PORTD as outputs using pinMode() command
   //set directions of IO lines of PB0-PB3 as output

   //send cc-code of digit 2 on PORTD using digitalWrite() command or PORTD = 0xnn command
   //send LL at PB0-pin of PORTB using digitalWrite() command

void loop()
    //MCU will wait here ! (for how long?)

(c) Now write sketch to see digit 3 at DP1 position only.
(d) Write sketch to show 23 on DP0 and DP1 simultaneously.

(8) Proceed to write program for the Counter of your 'Dream.'
(a) Write something; test it; see the result; modify the codes; test again.

Forum will help you to go ahead!!


Its been a while (going all the way back to sophomore year of college here) since I've dealt with a hardware 7 segment display. Off the top of my head I would use 3 74LS47 decoding IC's and for loop through the port level addressing and increment to the next digit after the first one is greater than 9. This will use 12 pins, so theres probably a better way to do it but that is a pretty simple way and a good exercise.


Aug 11, 2017, 05:01 am Last Edit: Aug 11, 2017, 05:16 am by GolamMostafa
I appreciate your participation and presentation of another way of making the counter. Accompaniment of a schematic of your proposal would make the idea more vivid.

In fact, there are many ways of doing the same thing. We need to start with 'something' which is 'Basic (Simple and Elementary)'. It is difficult to judge which one is simplest among many options until we really make the things.

The OP has made the post at 1:48 am; @larryd responded at 4:17 am with some advice for the OP; @GolamMostafa came up at 4:05 pm with something that could be built and tested; @dustion02rsx has come up at 7:58 pm with an alternative method that could also be built and tested; but, the OP is not here!


There are three problems to solve:
  • Implement a counter.
  • Divide the counter value into three individual digits.
  • Display the digits on your display.

(1) should be relatively trivial.
(2) has widely published algorithms, or can be done with just some division and modulus operations, when you only have 3 digits, or you can use one of the functions that already exists.
(3) is highly dependent on your hardware, or what hardware you intend to implement.  Which you haven't specified, yet.


(2) has widely published algorithms, or can be done with just some division and modulus operations, when you only have 3 digits, or you can use one of the functions that already exists.
I was very amazed when I observed that my pupils just used division and modulus operations to present decimal digits on 7-segment display unit for binary numbers up to 32-bit (limit of Arduino UNO plain data type).

But when I asked them to present the decimal digits of a 40-bit binary number using Arduino UNO platform, they were taking time! In fact, they could not do it.

I can do it very easily and very fast using Assembly and ATmega328. Using Arduino UNO and IDE, my procedures are very messy!!


Arduino (avr-gcc) has support for 64-bit "long long" datatype for the basic math functions.  (not in the existing conversion or print functions, though.)


Aug 11, 2017, 07:05 am Last Edit: Aug 11, 2017, 07:31 am by GolamMostafa
[...] 64-bit "long long" datatype for the basic math functions.
And that is for the Arduino DUE which is too advanced for my pupils as a Learning Tool. I believe that the Arduino DUE is basically intended for the Engineers to be working in the industries and for the academicians with deep research interests. For professional, promising, and practicing Engineers/Programmers anything of any kind is always welcome.


Nope, even the AVR has 64-bit longs.  (it does NOT have 64-bit "double" floating point.)

Code: [Select]
void setup() {

void decout(long long n)
  byte rem = n % 10;
  n /= 10;
  if (n > 0) {
  Serial.write(rem + '0');

void loop() {

  long long bignum = 1;
  for (int i = 2; i <= 15; i++) { // calculate factorial(15)
    bignum *= i;

(on an Uno):
Code: [Select]

The recursive version of decout() is probably not recommended for real programs...  :-)


Aug 11, 2017, 02:45 pm Last Edit: Aug 12, 2017, 05:17 am by GolamMostafa
[...] even the AVR has 64-bit longs.
Yes! This is now TRUE after hearing from you, looking at your sample example/result , and experimenting on my own 64-bit binary number (123456789ABCDEF12h) using ATmega328P based ArduinoNANO and IDE 1.8.0. I have extracted the decimal digits (1311768467750121234) for the given 64-bit binary (plain) number (123456789ABCDEF12h), and I have displayed them on a cc-type 7-segment display unit.

Code: [Select]
byte decDigit[19];
byte ccCode[19];
void setup()
 DDRB = 0xFF;      //all IO lines of PORTD will work as output lines
 DDRC = 0xFF;      //directions of IO lines are made output
 DDRD = 0xFF;      //to set direction of a single IO line as output, the command: pinMode(6, OUTPUT);
 unsigned char lupTab[] = {
 0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71
 unsigned long long x = 0x12345678ABCDEF12; //64-bit binary ---> decimal: 1311768467750121234
 for (int n = 0; n<=18; n++)  //extract decimal digits of the given binary by modulus and division operations
    byte r = x%10;       //extracing BCD code for the LS-digit of the decimal value of the binary
    decDigit[n] = r;     //saving the BCD code of the LS-digit into an array
    x = x/10;            //getting the partial quotient
    ccCode[n] = lupTab[r]; //getting and saving cc-codes of the decimal digits.

void loop()   //showing the decimal digits on cc-type 7-segment multi[lxed display unit
  for (int p=0, ccpin = 0x0F; p<=15; p++, ccpin--)  // ccpin = common cathode pin
    digitalWrite(7, bitRead(ccCode[p], 7));   //p-segment of 7-segment display dvice
    digitalWrite(6, bitRead(ccCode[p], 6));   //g-segement og 7-segment display device
    PORTB = ccCode[p];                        // segments: f - a of 7-segment display device
    PORTC = ccpin;                            //cc-pin of desplay devices: from right-most to left-most                  
    delay(1);                                 //delay to avoid ghost charcaters



Why was it TRUE for me and my pupils that Arduino UNO/NANO (corresponding IDE/Compiler) did not support 64-bit data type? This is the Arduino Programming Language Reference Manual which has not documented long long as a data type for the Arduino Boards! Double has been explicitly referred to as 32-bit float for Arduino UNO and 64-bit float for Arduino DUE.

Now, the question comes on Engineering/Technical Ethics. The data type (long long) is not officially documented; but, practically it seems to be working. Should we use it or not?

In this connection, we may remember that the Intel did not document the meanings of the following (apparently powerful) opcodes: 08h, 10h, 18h, 28h, 38h, CBh, D9h, DDh, EDh, and FDh in the instruction template of 1979 for the 8085 Microprocessor. Later on, someone challenged it and Intel was bound to release the following mnemonics/syntax for these opcodes: DSUB, ARHL, RDEL, LDHI, LDSI, SHLX, LHLX, JNX5, JX5, and RSTV. However, Intel clearly announced that these opcodes were belonging to 'Classified Category' and one should be using them at his/her own responsibility.


This is now TRUE after hearing from you
No, that is incorrect, wooly thinking.
It was true before.
Your hearing about it does not somehow validate the truth.

In this connection
Again, no.
Undocumented opcodes do not follow-on from this.
Zilog did the same with IX and IY register operations on the Z80, and so, I imagine, did just about every other manufacturer.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.
I speak for myself, not Arduino.


Aug 11, 2017, 03:30 pm Last Edit: Aug 11, 2017, 03:31 pm by GolamMostafa
When @westfw has said ' [...] AVR has 64-bit longs', I have wanted to understand that the Arduino IDE/Compiler supports 64-bit data type for the ATmega. This information has not been documented in the Arduino Programming Language Reference Manual. Therefore, I must not be termed as someone who thinks 'woolly'; rather, the charge should be diverted to the APLRM.



This information has not been documented in the Arduino Programming Language Reference Manual.
There is a lot of C, C++, and AVR-specific stuff that is NOT documented by the Arduino reference, because the Arduino Reference only covers what might be called a "beginner subset" of the available features.  To get more complete information, you need to refer to to C and C++ language specifications, avr-gcc documentation, avr-libc documentation, Chip datasheets, and the AVR Instruction set manual.

This is many hundreds of pages, and is one of the reasons that microcontrollers were so unapproachable before Arduino came along.

For example, Arduino docs mention sin() but not asin(), #define but not #if, don't mention the comma or ternary operations, don't mention "struct" or "class", and avoid the standard C string functions, even though most forum contributors will advise you to use them instead of the C++ "String" features.


Aug 12, 2017, 05:07 am Last Edit: Aug 12, 2017, 05:41 am by GolamMostafa
That's why there are strong directives to the mankind: Learning is a process that spans from cradle to grave. We learn and we forget and we argue again. There are people who accept this profile of mankind and work to re-educate them rather than vexing them!

Go Up