Question: No matter how I rearrange this, the increment compare always returns false....

I have even taken it out of the if, and put it in its own if:

```
int buttonFSM(button *ptrButton)
{ 
    int i;
    i = digitalRead(ptrButton->pin); 
    switch(ptrButton->buttonState)
    {
    case SW_UP:
        if(i==0 && ++ptrButton->debounceTics == DBNC_TICS) //swtich went down
        {
            ptrButton->buttonState = SW_DOWN;
            ptrButton->debounceTics = 0;
            return SW_TRANS_UD;       
        }
        ptrButton->debounceTics = 0;
        return SW_UP;
    case SW_DOWN:
        if(i==1 && ++ptrButton->debounceTics == DBNC_TICS) //switch is back up
        {
            ptrButton->buttonState = SW_UP;
            ptrButton->debounceTics = 0;
            return SW_TRANS_DU;       
        }
        ptrButton->debounceTics = 0;
        return SW_DOWN;   
    }
}

```

Answer: 
Looks to me like the path where the if doesn't happen are getting you. You don't show what DBNC\_TICS is set to, but I'm assuming it's > 1.

ptrButton->debounceTics will never be greater than 1 because you always:

```
    ptrButton->debounceTics = 0;

```
The error is due to wrong expectations on operators precedence:
++ and -> have the same precedence, so they are evaluated left to right.
See <http://en.cppreference.com/w/c/language/operator_precedence> .

Overall, the lack of parenthesis makes the readability poor.

The code can be improved by dropping the switch and simply checking that the current value is equal to the previous value through the duration of the sampling period.
Then read the value and decide if it's high or low.

But even this might be a poor choice, because it simply samples the value periodically and can miss changes that are not intercepted by the sampling.

Depending on the application, it might be preferrable (certainly it is more precise) to use interrupts on both edges (rising and falling) and a timeout: reset the timer at every interrupt. If the timer expires undisturbed, use the level read at the last interrupt.