While this can be confusing // [functionName],[motorNumber],[direction],[speed]
the format string suggests the sqare brackets are just there to denote "the content of the variable" (e.g. like often used in SQL syntax samples).
But the square brackets in the format string are place holders meaning "scan a string of max 20 characters not containing a comma" - that's required since "%s"
would read till if finds a whitespace or when it exceedes 20 characters.
But the "%d[^,]
is wrong, since the format place holder already ends with d
, so the format string should rather look like this
"%20[^,],%d,%20[^,],%d"
(as Nathan already pointed out)
BTW, when using sscanf()
it is good style to catch the return value and check how many variables could successfully be populated and only act when you get the anticipated result.
Especially when not initialising your token items you may end up with garbage data in an unpopulated variable.
And please don't spam the public event stream but rather use
Particle.publish("functionName", functionName, PRIVATE);
PUBLIC
is the default scope but should be avoided when not explicitly required.
Another style tip would be to make most use of the return value of a function (and reorder some things)
int moveMotor(int motorNumber, const char *direction, int speed)
{
int retVal = 0;
char msg[32];
snprintf(msg, sizeof(msg), "%d: %s (%d)", motorNumber, direction, speed);
Particle.publish("moveMotor", msg, PRIVATE);
analogWrite(motor1_speedPin, 0); // stop before changing things
switch(motorNumber) // I'd expect more than just one motor
{
case 1:
if (strcmp(direction, "forwards") == 0)
{
digitalWrite(motor1_IN2, LOW); // for safety first off as we don't know which H-bridge is used
digitalWrite(motor1_IN1, HIGH); // then the other on
retVal = speed;
}
else if (strcmp(direction, "backwards") == 0)
{
digitalWrite(motor1_IN1, LOW);
digitalWrite(motor1_IN2, HIGH);
retVal = -speed;
}
analogWrite(motor1_speedPin, speed); // after direction is set engage new speed
break;
default:
break;
}
}
return retVal;
}
(when more motors are expected to be added, probably doing mostly the same things I'd put the pins for each motor into an array and then use the motorNumber
as index to that array to avoid copy/pasting the same logic over and over just to replace the pin names
I'd also do away with the direction
string in moveMotor()
and rather let the sign of speed
hold that info)