I feel like I am missing something. I have a Particle Cloud Variable set in code to an enum variable. But when I pull that variable, even though I have hard-coded values 0 through 4, it always returns a six-digit number.
enum EnumState {Off=0, On=1, Up=2, Down=3, Unknown=4}enumState;
void setup() {
Particle.variable("enumState", enumState);
Particle.function("changeEnumState", changeEnumState);
}
void loop() {
}
int changeEnumState(String enumStateValue) {
if (enumStateValue.toLowerCase() == "off")
enumState = Off;
else if (enumStateValue.toLowerCase() == "on")
enumState = On;
else if (enumStateValue.toLowerCase() == "up")
enumState = Up;
else if (enumStateValue.toLowerCase() == "down")
enumState = Down;
else
enumState = Unknown;
return enumState;
}
Interestingly, I return the “enumState” value as the return value for the Particle Function and it seems to work as expected.
Any thoughts?
That’s probably because the enum is not typed as full 32 bit integer but something shorter.
e.g. your 220929 would suggest it’s implicitly typed as uint16_t rather than int32_t.
Maybe the -fshort-enum
switch is set by default.
You can try to explicitly type your enum like this
enum EnumState : int32_t { ... };
or implicitly forcing it to that like this
enum EnumState {Off=0, On=1, Up=2, Down=3, Unknown=0xFFFFFFFF} enumState;
1 Like
I was able to test your suggestions. The explicit type for the enum didn’t have any effect (same outcome as before.) The implicit forcing actually threw a compiler exception as the call to the Particle Variable registration resulted in a “ambiguous call”.
../wiring/inc/spark_wiring_cloud.h:81:25: error: call of overloaded '_variable(const char [10], EnumState&)' is ambiguous
return _variable(name, std::forward<ArgsT>(args)...);
Hmm, the ambiguity does make sense since there are now three possible overloads (int
, int32_t
and uint32_t
) which would all fit the 0xFFFFFFFF
- I only knew about int
However, I don’t quite see why the typed enum still doesn’t get the desired result.
Maybe @rickkas7 can enlighten us both.
1 Like
I think I am going to chalk this up to the Particle Variable function having issues with enums.
I was able to find two different way to get this working.
The first working version is creating a new “currentEnumState” integer variable and then connected the Particle Variable to that. Then when the enumState changes, I just set the currentEnumState variable to the enumState (straight up, no casting on my part.)
This works. I am not sure why Particle Variable isn’t being handled the same way as I would figure it would perform the same internal conversion as assigning an enum to an int like I am doing here.
enum EnumState {Off=0, On=1, Up=2, Down=3, Unknown=4}enumState;
int currentEnumState = 0;
void setup() {
currentEnumState = enumState;
Particle.variable("enumState", currentEnumState);
Particle.function("changeEnumState", changeEnumState);
}
void loop() {
}
int changeEnumState(String enumStateValue) {
if (enumStateValue.toLowerCase() == "off")
enumState = Off;
else if (enumStateValue.toLowerCase() == "on")
enumState = On;
else if (enumStateValue.toLowerCase() == "up")
enumState = Up;
else if (enumStateValue.toLowerCase() == "down")
enumState = Down;
else
enumState = Unknown;
currentEnumState = enumState;
return enumState;
}
The second way was to utilize the calculated Particle Variable and the ability to assign a function to a variable. I created a “getEnumState” function and assigned that to the variable. The function type was int and I just return the enum (without any cast.) This worked as well.
enum EnumState {Off=0, On=1, Up=2, Down=3, Unknown=4}enumState;
void setup() {
Particle.variable("enumState", getEnumState);
Particle.function("changeEnumState", changeEnumState);
}
void loop() {
}
int getEnumState() {
return enumState;
}
int changeEnumState(String enumStateValue) {
if (enumStateValue.toLowerCase() == "off")
enumState = Off;
else if (enumStateValue.toLowerCase() == "on")
enumState = On;
else if (enumStateValue.toLowerCase() == "up")
enumState = Up;
else if (enumStateValue.toLowerCase() == "down")
enumState = Down;
else
enumState = Unknown;
return enumState;
}
1 Like
While this is a workaround, it’s still odd and I’d be interested to learn the reason for that.
1 Like