function return code is limited to one byte?

Status
Not open for further replies.

albertr

Member
Hello,

Newbie with a first post here... We are using teensy 3.2 and have a simple function below to read PWM pulses:
Code:
uint32_t read_afew( uint32_t howmany) {
  uint32_t val = 0;
  uint8_t i;

  for (i = 0; i < howmany; i++) {
      val=val+pulseIn(PWM_input,HIGH,21000);  
  }
  return (val/howmany);
}

We expect it to return a 32bit integer and we know the PWM pulse values it reads are around 1500. However, the function seems to returns the value of lowest byte (< 255) instead of 32bit integer. Can someone glance it over and let us know what we are doing wrong here? If we inline this function, it still returns the lowest byte. However if we move the for-loop into the main processing loop in our code and don't use a function call , then it works as expected (32bit integer value is obtained). I suspect there's something obviously wrong we done and hoping an extra pair of eyes can spot it, thanks!

-albertr
 
Here's a code snipped demonstrating how we are calling it:

Code:
  uint32_t pwm_neut = 0,
  uint8_t  pwm_low_byte;

    pwm_neut = read_afew(20);

    Serial.printf("Neutal position: %d\n", pwm_neut);
    pwm_low_byte = pwm_neut & 0x000000FF;
    Serial.printf("%d\n",  pwm_low_byte);
    pwm_neut = pwm_neut >> 8;
    pwm_low_byte = pwm_neut & 0x000000FF;
    Serial.printf("%d\n",  pwm_low_byte);
    pwm_neut = pwm_neut >> 8;
    pwm_low_byte = pwm_neut & 0x000000FF;
    Serial.printf("%d\n",  pwm_low_byte);
    pwm_neut = pwm_neut >> 8;
    pwm_low_byte = pwm_neut & 0x000000FF;
    Serial.printf("%d\n",  pwm_low_byte);

Let us know what is wrong there, thanks!

-albertr
 
The problem is that your for-variable is declared as uint8_t. Declare it as uint32_t, too, so that the compiler won't simply the division result.
 
I can not reproduce your problem. To check, I replaced your call to pulseIn(...) by a constant (1500 as you said...)

Code:
uint32_t read_afew(uint32_t howmany)
{
  uint32_t val = 0;
  uint8_t i;

  for (i = 0; i < howmany; i++)
  {
    val = val + 1500;
  }
  return (val / howmany);
}

For howmany = 20, this returns 1500 as it is supposed to do. How is pulseIn(...) declared and are you sure it returns values around 1500? @Theremingenieur is right of course that you should declare the for variable as uint32_t if your condition is also uint32_t, but this doesn't limit the return value to 8bit.
 
Last edited:
pulseIn() is declared in pins_teensy.c. It's a blocking function waiting for a pin going first high and then low and to return the time in-between. It looks a little outdated and clumsy as if it were only there for backwards compatibility.
 
Ok, tried it with pulseIn, worked as well. It is a bit difficult to obtain a return value > 255 by just touching a pin with a wire but it finally gave me a result of 601.
 
I would be suspicious of your printf statement. %d expects a signed argument. %u would be appropriate for unsigned.
 
Status
Not open for further replies.
Back
Top