Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor SerialController to be easier to use #25

Open
wants to merge 14 commits into
base: master
Choose a base branch
from

Conversation

sanine-a
Copy link
Member

The version of SerialController we've been using has a somewhat complex and fiddly setup required to use it. You have to write a single callback function that handles every correctly formatted serial message and manually distinguish the strings using arcane string.h functions like strcmp or atof, rather than more readable and natural things like the == operator or string.toFloat().

I've rewritten the SerialController class to instead

  1. Use the Arduino String type instead of char arrays, so that operations like concatenation, ==, and data type conversion are significantly easier.
  2. Allow you to bind a callback function to a key string, accepting either a String, an int, or a float as its single argument. SerialController automatically detects the type of the argument required and handles the necessary type conversions behind the scenes.
  3. Optionally (and by default) automatically respond to "wake-arduino" messages appropriately and send "unknown-command" messages in response to key strings with no associated callback.

I think that this setup is much easier to work with than the current version, so I hope that we can use it moving forward! You can take a peek at it in action in the example sketch.

Copy link
Contributor

@twsdbailey twsdbailey left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I might be wrong, but I recall reading in lots of forums that it is highly recommended to not rely on the String class in Arduino too much, as it uses a lot of RAM, and can lead to heap fragmentation and eventual crashes. May be worth looking more into this a bit more to see what the issues really are.

@sanine-a
Copy link
Member Author

The rest of this could certainly still work with char arrays rather than Strings. I'll look into whether or not the String class could be a problem in the long run.

@brandonwkipp
Copy link
Contributor

brandonwkipp commented Mar 15, 2021

@sanine-a I've had a chance today to review this and I think it looks great! It feels more intuitive to break up the callbacks into the setup function rather than have everything live in a giant onParse function. One thing that tripped me up when trying to convert my derby track sketch to use this, was the addCallback function not having a void signature (I hope I'm saying that right).

For instance, I had a callback that doesn't return anything, but executes the sendMessage function like this:

serialController.addCallback("get-beam-states", []() {
  serialController.sendMessage("track-1-start", track1_start_state);
  serialController.sendMessage("track-1-finish", track1_finish.getState());
});

I was getting errors until I switched the lambda from []() { ... } to [](int s) { ... } and I'm wondering if the lack of a void callback like that is standard? If it is supposed to be like that, I'll mark this as approved.


Regarding @twsdbailey's comment about memory usage, I'm not totally familiar with how every board is setup, but the SerialControllerExample.ino and my derby track .ino file took up 25% and 28% of the storage space on a MetroMini respectively, fwiw.

@sanine-a
Copy link
Member Author

I've updated this to use char *s instead of Strings in the callbacks, and behind-the-scenes it now uses fixed size strings. These sizes can be overridden by a sketch by just #defineing MAX_KEY_LEN and MAX_VAL_LEN before including the header file. This should alleviate any memory fragmentation concerns that the String class may have raised. I've also added a voidCallback type since I think that it does make a lot of sense to have one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

3 participants