Problems with return variable not matching variable in the returning function

I’m going a little crazy here and need someone to validate what I am doing.

I am implementing a simple Sonos controller using an ESP32 (A Sparkfun ESP32 Thing to be specific). I am using this library, https://github.com/joeybab3/sonos/.

My code is here…
https://github.com/securitypedant/ard-sonos-controller

Specifically I am calling the .getVolume method on an instance of the Sonos object.

auto volume = g_sonos.getVolume(g_SonosIP);
 
  Serial.println("Volume is...");
  Serial.println(volume);

this is what getVolume does…

uint8_t SonosUPnP::getVolume(IPAddress speakerIP, const char *channel)
{
  PGM_P path[] = { p_SoapEnvelope, p_SoapBody, p_GetVolumeR, p_CurrentVolume };
  char result[5] = "0";
  upnpGetString(
    speakerIP, UPNP_RENDERING_CONTROL, p_GetVolumeA,
    SONOS_TAG_CHANNEL, channel, path, 4, result, sizeof(result));
 Serial.print("Result:");
 Serial.println(result);
  return constrain(atoi(result), 0, 100);
}

This is the result I get in the serial monitor…

01:07:11.145 -> *SONOS: <u:
01:07:11.145 -> *SONOS:  xmlns:u="urn:
01:07:11.145 -> *SONOS: ">
01:07:11.145 -> *SONOS: <Channel>
01:07:11.145 -> *SONOS: Master
01:07:11.145 -> *SONOS: 
01:07:11.145 -> *SONOS: </Channel>
01:07:11.145 -> *SONOS: </u:
01:07:11.145 -> *SONOS: >
01:07:11.145 -> Result:23
01:07:11.145 -> Volume is...
01:07:11.178 -> 36

So inside the function I get the correct value, 23. Yet in the calling code, I get 36. I’ve tried all sorts. I’ve tried typing the returned variable as uint8_t, i’ve tested in the code that the use of constrain and atoi doesn’t mess things up. It doesn’t.

What am I missing here? Driving me nuts.

in a 30 year career, i've never seen auto used.

36 == 0x23 ? ??

don't know why. you could use sprintf to unambiguously specify the output format.

gcjr:
in a 30 year career, i’ve never seen auto used.

:o

gcjr: in a 30 year career, i've never seen auto used.

36 == 0x23 ? ??

don't know why. you could use sprintf to unambiguously specify the output format.

0x23 = 16 * 2 + 3 = 35 decimal

right sorry

It could be that your constraint() is not working. Try this:

 uint8_t ret = constrain(atoi(result), 0, 100);
 Serial.println(ret);
 return ret;

all i can offer is the the following appears to work as expected

uint8_t
constrained (
    const char *s )
{
    Serial.print    (" constrained: ");
    Serial.println  (s);
    return constrain(atoi(s), 0, 100);
}

// -----------------------------------------------------------------------------
void
setup (void)
{
    Serial.begin (9600);

    auto vol = constrained ("23");
    Serial.print    (" setup: ");
    Serial.println  (vol);
}

suggest you do something similar and work towards the final function

arduino_new: It could be that your constraint() is not working. Try this:

 uint8_t ret = constrain(atoi(result), 0, 100);
 Serial.println(ret);
 return ret;

Sorry, took me a while to get chance to debug this... but nope, it prints the correct "ret", but my calling code still gets the wrong value.

securitypedant: Sorry, took me a while to get chance to debug this... but nope, it prints the correct "ret", but my calling code still gets the wrong value.

It's not very likely.

However, "result" didn't seem to be properly null-terminated.

Hello securitypedant

Maybe ???

From Arduino Reference :

Because of the way the constrain() function is implemented, avoid using other functions inside the brackets, it may lead to incorrect results.

This code will yield incorrect results:

int constrainedInput = constrain(Serial.parseInt(), minimumValue, maximumValue); // avoid this
Use this instead:

int input = Serial.parseInt(); // keep other operations outside the constrain function
int constrainedInput = constrain(input, minimumValue, maximumValue);

Regards,
bidouilleelec