How to pick each digit from a integer?

Hello there,

I built a interface display that consist of 4x 7 segment displays so I can display number from 0 to 9999.
I'm making the code to display a int number in the display and I got it working but Im pretty sure that there are simpler ways of doing it. I was searching on internet about some type of a number mask so to pick each digit in a integer number and store that into new integers (each new integer being a single number digit).

My working code for this part is:

if(DSP < 10) { d4=DSP; d3=10; d2=10; d1=10; } ;

if(DSP > 9 && DSP < 100) { d3=DSP/10 ; d4=DSP-d3*10; d2=10;d1=10; }

if(DSP > 99 & DSP < 1000) { d2=DSP/100;d3=(DSP-d2*100)/10;d4=(DSP-d2*100)-d3*10;d1=10; }

if(DSP > 999 & DSP < 10000) { d1=DSP/1000;d2=(DSP-d1*1000)/100;d3=((DSP-d1*1000)-d2*100)/10;d4=((DSP-d1*1000)-d2*100)-d3*10; }

Where DSP is the original integer from 0 to 9999 and d1,d2,d3,d4 are integers representing each digit on the display. When d1=10 (or d2,d3,d4) nothing is displayed on the 7 segment display. When d1=3 means that number 3 will be displayed on the 3rd segment display and so on.
Im going to display floats also (they are really 8segment, 7 ususal and the period).

Any clues on how to simplify this code using masks ?

Thanks !

Any clues on how to simplify this code using masks ?

You can't. Masks are binary operations, not suitable for base 10 operations. The modulo operator (%) is, though.

This code is much shorter:

byte d[4] = {0,0,0,0};

void translate2digits(int v) {
  byte i;
  if (v == 0) {
    d = {10, 10, 10, 0};
    return;
  }
  for (i = 0; i < 4; i++) {
    d[3-i] = v ? v % 10 : 10;
    v /= 10;
  }
}

Edit: correct digit calculation.

DanDare:
Hello there,

I built a interface display that consist of 4x 7 segment displays so I can display number from 0 to 9999.
I'm making the code to display a int number in the display and I got it working but Im pretty sure that there are simpler ways of doing it. I was searching on internet about some type of a number mask so to pick each digit in a integer number and store that into new integers (each new integer being a single number digit).

        print(seven_seg_digit_0, ((uint16_t) value / 1000) % 10);
        print(seven_seg_digit_1, ((uint16_t) value /  100) % 10);
        print(seven_seg_digit_2, ((uint16_t) value /   10) % 10);
        print(seven_seg_digit_3, ((uint16_t) value /    1) % 10);

Hope this helps

Hello,

Many thanks for these examples. I don't fully understand the code yet but sure now I have a direction (and correct keywords), to start trying it on IDE and search web references like http://en.wikipedia.org/wiki/Modulo_operation or http://www.cplusplus.com/reference/cmath/fmod/

Many thanks !

Hi there,

Im back to this post just to note a interesting fact:

Using code like "(value / 1000) % 10);" four times (each display) is actually 4.5 times slower than doing it using raw math like in my code example.

I know using the modulo operator can be more convenient and resulting in a smaller code but well, like I said, just a note about a test I did here.

pylon

d[3-i] = v ? 10 : v % 10;

I would appreciate if you would explain "= v ? 10 : v % 10;" in the above line..

Thanks in advance

if (d[3-i] = v)
{
d[3-i]= 10;
}
else
{
d[3-i] = v % 10;
}

Almost, with the correct code

d[3-i] = v ? v % 10 : 10;

it's translated to this

if (v != 0)
{
  d[3-i] = v % 10;
}
  else
{
  d[3-i]= 10;
}

and that means that the digit is set to 10 if "v" is 0, in all other cases the digit holds the rest of a division of "v" by 10.

The algorithm is explained easily: Check if the whole value is 0, if yes set the display to "___0" and return (if I don't check that the display is empty in this special case).
Then I handle digits backwards. The last digit is the value mod 10. The the value is divided by 10. Next round (the tens) I do the same, the digits is the current value (hold all tens) mod 10. As soon as I reach 0 I fill the rest of the digits with spaces.

DanDare:
Hi there,

Im back to this post just to note a interesting fact:

Using code like "(value / 1000) % 10);" four times (each display) is actually 4.5 times slower than doing it using raw math like in my code example.

I know using the modulo operator can be more convenient and resulting in a smaller code but well, like I said, just a note about a test I did here.

So you can update your display only 10,000 times per second rather than 45,000 times per second. Seems like a MAJOR problem to me..........

@pylon:

This code is much shorter:

    d = {10, 10, 10, 0};
I'm afraid that code that cannot compile doesn't count, even if it is shorter - if it is pseudocode, you ought to state it.

AWOL is right, here's a better version for that line:

    d[0] = 10; d[1] = 10; d[2] = 10; d[3] = 0;