BCD math routines instead of using division and modulo

I have this code below to extract, ones digit (d5), tens digit (d4), and hundreds digit (d3). However, I want to get rid of division and modulo operation when doing this. However, I am a bit sluggish in implementing bit shifting and bitwise operation to change the code. Any help would be appreciated.

void updateDisplay(signed long counter_value) {

    if (count<0)
    {
        NEG_ON;
    }

    else
    {
        NEG_OFF;
    }

    D3_NULL;
    D4_NULL;
    D5_NULL;

    // Ensure that counter_value is positive or zero for further processing
    counter_value = abs(counter_value);

    // Display the appropriate digit on the LCD based on the count value
    uint8_t d3= (counter_value/100)%10;
    uint8_t d4= (counter_value/10)%10;
    uint8_t d5= counter_value%10;

    if (d3 != 0)
    {
        switch (d3)
        {
            case 1: DIGIT3_DISP_1; break;
            case 2: DIGIT3_DISP_2; break;
            case 3: DIGIT3_DISP_3; break;
            case 4: DIGIT3_DISP_4; break;
            case 5: DIGIT3_DISP_5; break;
            case 6: DIGIT3_DISP_6; break;
            case 7: DIGIT3_DISP_7; break;
            case 8: DIGIT3_DISP_8; break;
            case 9: DIGIT3_DISP_9; break;
        }
    }
    else
    {
        DIGIT3_OFF;
    }

    if (d4 != 0 || d3 != 0)
    {
        switch (d4)
        {
            case 0: DIGIT4_DISP_0; break;
            case 1: DIGIT4_DISP_1; break;
            case 2: DIGIT4_DISP_2; break;
            case 3: DIGIT4_DISP_3; break;
            case 4: DIGIT4_DISP_4; break;
            case 5: DIGIT4_DISP_5; break;
            case 6: DIGIT4_DISP_6; break;
            case 7: DIGIT4_DISP_7; break;
            case 8: DIGIT4_DISP_8; break;
            case 9: DIGIT4_DISP_9; break;
        }
    }

    else if (d3 != 0)
    {
        DIGIT4_DISP_0;
    }

    switch (d5)
    {
        case 0: DIGIT5_DISP_0; break;
        case 1: DIGIT5_DISP_1; break;
        case 2: DIGIT5_DISP_2; break;
        case 3: DIGIT5_DISP_3; break;
        case 4: DIGIT5_DISP_4; break;
        case 5: DIGIT5_DISP_5; break;
        case 6: DIGIT5_DISP_6; break;
        case 7: DIGIT5_DISP_7; break;
        case 8: DIGIT5_DISP_8; break;
        case 9: DIGIT5_DISP_9; break;
    }
}

Where is that recommended?
Which board are you using?
Please provide full code.

To speed things up, you can use:

    // uint16_t is enough to hold three digits
    uint16_t leftover = abs(counter_value);

    // What do you want to happen if counter_value is greater than 999, or less than -999 ?
    // Or do you have some way of ensuring that that will never happen?

    // Declare variables for digits
    //      hundreds  tens    ones
    uint8_t d3 = 0,   d4 = 0, d5 = 0;

    // Extract digits
    while (leftover >= 100) {leftover -= 100; d3++; }
    while (leftover >=  10) {leftover -=  10; d4++; }
    d5 = leftover;

why?
If I were you, I would be more concerned about the duplicated code. For example the switch case which call very similar

DIGIT5_DISP_0
1 Like

Se

This routine works, but it is not as "elegant" and practical in terms of module use.

void setup() {
  Serial.begin(115200);
  delay(10);
  int counter_value = 218;

  String temp = String(counter_value);
  uint8_t d3 = (temp.substring(2,3)).toInt();
  uint8_t d4 = (temp.substring(1,2)).toInt();
  uint8_t d5 = (temp.substring(0,1)).toInt();
  Serial.println(d5);
  Serial.println(d4);
  Serial.println(d3);
}

void loop() {}

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.