user2166351
user2166351

Reputation: 183

Incrementing integer from 0 becomes negative

I'm working on an embedded systems project where I'm trying to demodulate data from an IR sensor (which uses 'pulse width modulation'). The code below simply waits for the IR Sensor to start pulsing, and then measure the width (duration) of each high and low pulse.

In this code, I have a loop where I'm incrementing an integer:

irPulseSet irReadPulse()
{
irPulseSet outputPulseSet;
int pulseCount = 0;

int finished = 0;

while(1)
{
    int lowPulse = 0;
    int highPulse = 0;

    while( bit_is_clear( irSensorPin , irSensorPinNo ) )
    {
        highPulse++;
        _delay_us( 20 );
    }

    while( !bit_is_clear( irSensorPin , irSensorPinNo ) )
    {
        if ( lowPulse > 3250 )
        {
            finished = 1;
            break;
        }
        lowPulse++;
        _delay_us( 20 );
    }

    if ( finished )
        break;

    outputPulseSet.pulses[pulseCount][0] = highPulse * 20;
    outputPulseSet.pulses[pulseCount][1] = lowPulse * 20;

    pulseCount++;
}

// Assign pulse count to output pulse set
outputPulseSet.pulseCount = pulseCount;

return outputPulseSet;
}

Because this is an embedded systems project, and my resources are limited, I'm doing my debugging with an LCD display (as the circuit cannot be connected to a computer)

Printing each pulse

int irPrintPulses( irPulseSet pulseSet )
{
    int counter;
    for( counter = 0; counter <= pulseSet.pulseCount; counter++ )
    {

       LCDClearScreen();
        char printStr[100];

        sprintf( printStr , "H%iL%i;%i " , pulseSet.pulses[counter][0] , pulseSet.pulses[counter][1] , counter  );
        LCDSendString( printStr );
        _delay_ms(1000);
    }

    _delay_ms(5000);
    LCDClearScreen();
    LCDSendString( "Finished pulse print!" );
    _delay_ms(1000);
    LCDClearScreen();

    return 0;
}

The lowPulse int seems to sometimes be negative (eg value of -1054). I'm totally puzzled as it's first defined as 0 and all I ever do to it is increment it, so how can it become negative?

Upvotes: 0

Views: 1514

Answers (2)

david.pfx
david.pfx

Reputation: 10853

Since this is embedded I am going to assume that you are working with 16 bit integers. As a result, if you increment highPulse 32,768 times it will overflow and become negative. The value transitions from 0x7fff (positive) to 0x8000 (negative).

Given a delay loop of 20 usec, this will take 655.36 msec. Any time the first loop has to wait for this long for the bit to transition you will get negative numbers. I would have thought this is quite possible.

Do you have 32 bit longs? If so, the simplest solution is probably to use them for these counters. Then it will take about 40,000 seconds to overflow, which should be enough.

Upvotes: 0

nightshade
nightshade

Reputation: 638

You have X bits to represent a number: 1 bit is for the signal and X - 1 bits is for the value

lets say you have a number that is represented with 4 bits:

0000 = 0

0001 = 1

...

0111 = 7

If you increment 1 here, you will change the first bit (the signal bit)

1000 = -8

Try the code bellow

#include <stdio.h>
#include <limits.h>
int main()
{
   int i = INT_MAX;

   printf("%d\n", i);   
   printf("%d\n", i + 1);
   printf("%u\n", i + 1);

   if(i > 0)
      printf("greater\n");

   i++;

   if(i < 0)        
      printf("what kind of witchcraft is that?");
}

Once you add one after the maximum value it will flip to the maximum negative value, the 3rd printf is printing as an unsigned value (using the 1st bit not for the signal but for value)...

Upvotes: 3

Related Questions