Page 1 of 1

Cube Library Code - User Defined Function

Posted: Mon Sep 28, 2015 11:18 am
by neographophobic
When playing with my cube, I like the ability to control it via the serial command interface. However this is limited to a basic set of commands. When demonstrating items to people, you are limited to either loading different sketches, writing a sketch that cycled through different patterns, or adding some form of hardware input device that could be used to pick a sketch.

I wanted the ability to call a custom function from the serial interface, so have added code to allow this. I've structured the code so that the library does not know about the users code. This means that any user defined functions can be run, and that there is only a one way dependency on the library (as it currently is), and not a two way dependency. This is achieved by using a callback function within the library, that takes a pointer to a function within the sketch.

When you setup the sketch, you call setDelegate from within the sketch with the name of the function that should be called to handle user defined functions. Within parser.cpp, I've added a "user" option, which takes two parameters. The first is a number, and the second which is optional is a colour. Within the function you created within the sketch, you do whatever action you wish based on the number and optional colour that is received (I typically set a global variable that is then referenced during the run loop, and within the run loop I call a function based on what action is set).

To demonstrate this in action, I've added a new example "UserDefinedFunctions", which is available via the examples menu. This example allows you to use all of the existing commands you are familiar with, and a new "user" function. The options available are:-
  • user 1 BLUE;
    A "ZigZag" style patten that lights up every second LED with the provided colour, and then alternates by lighting up the LED that was off.
  • user 2;
    Runs the Random Pastels example
  • user 3;
    Runs the Random Colours example
  • user 4;
    Runs the Random Primaries example
A summary of the memory changes that this introduces (all tested with the TestPattern Sketch):-
  • Original Library - 16,108 bytes (Program Storage Space) and 1,633 bytes (Dynamic Memory)
  • With User Defined Functions - 16,312 bytes (Program Storage Space) and 1,646 bytes (Dynamic Memory). This is an increase of 204 bytes (0%) Program Storage Space and 13 bytes (1%) of Dynamic Memory.
I've posted the changes to my clone of the Cube4 library on Github at ... d_function.

I've tested the above with the new UserDefinedFunctions example, but would love to know if it works for you or if these changes introduce errors that I'm not aware of. I haven't written much Arduino code, so any improvements, comments, bugs, or suggestions are welcomed (including pull requests), but please bear with me as it may take me a while to incorporate any changes.

P.S. I've also posted a combined version of these changes, and the changes I made to reduce memory usage to the serial command line parser at ... ary_master. Please see the post Cube Library Code - Reduce Memory Usage for more information on this. When combined with those changes, the memory changes are 15,842 bytes (Program Storage Space) and 742 bytes (Dynamic Memory). This is an decrease of 266 bytes (1%) Program Storage Space and 891 bytes (35%) of Dynamic Memory.

Re: Cube Library Code - User Defined Function

Posted: Sat Dec 05, 2015 10:14 am
by andrew
Well done, thank you for sharing that with us as well. :)

Re: Cube Library Code - User Defined Function

Posted: Mon Mar 07, 2016 9:59 am
by neographophobic
I’ve revisited the user defined functions modification I made to the library and made a small modification, and rewritten the example sketch.

All of the example patterns have been changed so that they are contained in their own classes instead of the main sketch (making it easier to copy them between sketches), and are now non-blocking (using state machines and millis() instead of relying on delay()). This allows the user to change which pattern is being displayed while it is running.

I have also changed the setDelegate method to be a public member of the Cube class, instead of an external. This means that you now need to call it with cube.setDelegate(functionName) instead of just setDelegate(functionName). This change is not backwards-compatible, so if you were using the previous version of my library and upgrade to this version, you will need to make this change in your sketch.

You can grab the latest version of the library from This version includes the memory reduction change I mentioned at viewtopic.php?f=32&t=6418 and a rewrite of the ReadMe file to explain how to install the library, and how to use the API, both within a sketch and also from the serial interface.