Help in count logic for displaying digit

A count increments/ decrements depending on the direction of magnet passing by.

Here is my current code:

/******************** Macros ********************/
define BUTTON_2                    BIT3
define UNIT_CHANGE_BUTTON_TIME     20         // Time to change units in seconds
define METERS                      0
define FEET                        1          // Set FEET as default unit

/****************** variables *******************/

volatile unsigned char selectedUnit = FEET; 
volatile unsigned char unitChanged = 1; 
volatile signed long count = 0;

/****************** Functions *******************/

void Update_Unit (void) 
{ 
    if (selectedUnit == FEET) 
    { 
        M_OFF;			// M segment off 
        F_ON;			// F segment on to indicate unit in feet 
    } 
    else if (selectedUnit == METERS) 
    { 
        F_OFF;			// F segment off 
        M_ON;			// M segment on to indicate unit in meters 
    } 
}

void updateDisplay(signed long counter_value) 
{
    if (counter_value<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;
uint8_t d4= (counter_value/10)%10;
uint8_t d5= counter_value%10;

// Display the digits without leading zeroes
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 {
	// Turn off the digit if it's zero
	DIGIT3_OFF;
}

//    if (d4 != 0 || d3 != 0) {
if (counter_value >= 10) {
	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;
}
else {
	// Turn off the digit if it's zero
	DIGIT4_OFF;
}

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;
    }
}
/******************* Interrupts *****************/
pragma vector=PORT1_VECTOR
__interrupt void Port_1 (void) 
{ 
    if (P1IFG & BUTTON_2) 
    { 
        button2Pressed = 1;
    }
    
    P1IFG &= ~BUTTON_2;
}

pragma vector=TIMERA1_VECTOR
__interrupt void Timer_A (void) 
{ -----
}

/***************** Main function ****************/

int main(void) {
volatile unsigned char ab = 0;
WDTCTL = WDTPW | WDTHOLD;                          // stop watchdog timer

FLL_CTL0 = XCAP10PF;                                            // internal capacitor

Init_LCD();
GPIO_init();
Init_Timer_A();
LCD_on();
clearDisplay();
updateDisplay(count);

ab |= (((P2IN & BIT5)>>3)|((P2IN & BIT4)>>1));
ab = ab >>2;

__enable_interrupt();

while (1)
{
	// Check if units are changed
	if (tickButton2 >= UNIT_CHANGE_BUTTON_TIME)
	{
		if (selectedUnit == METERS)
		{
			selectedUnit = FEET;
			unitChanged = 1;
		}
		else if (selectedUnit == FEET)
		{
			selectedUnit = METERS;
			unitChanged = 1;
		}
		tickButton2 = 0;
	}

	ab |= (((P2IN & BIT5)>>3)|((P2IN & BIT4)>>1));

	if (ab == 0b000000111)
	{
		count++;
		if (count > 999)
		{count = 0;}
		updateDisplay(count);
	}

	if (ab == 0b00001011)
	{
		count--;
		if (count < -999) 
		{ count = -1;}

		updateDisplay(count);
	}

	ab = ab >> 2;

	if (unitChanged)
	{
		Update_Unit();
		unitChanged = 0;
	}
	else
	{
		Update_Unit();
	}

	if (resetcountFlag)
	{
		count = 0;
		updateDisplay(count);
		resetcountFlag = 0;
	}
    }
}

So when the count is passed 999, adding +1 should reset the count to 0. Now that the count is 0 there are two possibilities:

a. adding a +1 would make the count be "1"

b. but subtracting a 1, would make the count back to "999"

The same goes when count is -999, subtracting a 1 would make it to 0. Now that count is 0, two instances can occur:

a. adding a +1 would make it back to -999, adding another +1 will make it -998 (so on and so forth)

b. subtracting a 1 would make it to -1, then another minus 1 will make it -2

Here's a diagram of how I explained it
count_condition

It's not clear if you are asking the forum for help or presenting your code as a demonstration for others to follow.

If the latter, I don't think others will be able to follow or understand the code, the style is not Arduino. Does it compile?

Your two scenarios are not compatible. If subtracting 1 from 0 will give 999 then there is no way for the number to ever be negative. So you can throw away the whole bit about -999.

To make the first part work just use a couple of if statements. If the value is greater than 999 then subtract 1000 from it. If the value is less than 0 then add 1000 to it.

1 Like

Every time I see code like this, it seems to me that the author forgot about the existence of arrays in C/С++.
What is DIGIT5_DISP_9 and why are you calling each case separately? It wouldn't be easier to write a function that takes a number as a parameter?

1 Like

Hi, I'll be honest that I am not that confident in making logic for array to process this display. I know that the number and position should be handled if I were to use an array but coding it, I am not sure how to.

Thanks for this. But I came to realize that the logic itself should handle a thousand value but it will only display hundreds to ones only (3-digit).

So the code works and the only thing I changed is the function void updateDisplay(signed long counter_value)

specifically this line:
uint8_t d3= (counter_value/100) %10;

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