Firmware wishlist

Listed below are some initial observations about the Maslow firmware, and features I would like to see eventually.

The intent of this thread is to start a community discussion that clarifies the direction in which the community would like the firmware to go, so please add to the list if there is something you want. Including a use case generally helps people understand why you want a specific feature and lets people consider whether there is a better way to achieve the goal than the feature proposed.

Currently I see 73 forks. So people are working on modifying the code. If we can get on the same page, we will minimize duplication of effort and maximize contributions back to the public project.

  • First and foremost, endless appreciation to the original and subsequent code authors that created a thoughtful solution that really WORKS!

  • [quote=“MeticulousMaynard, post:131, topic:3319”]
    Do we know where the setting in the firmware is to enable them? I just took a quick look through the firmware but there’s so much to it now that it’s like looking for a needle in a haystack.
    Program flow and configuration options are unnecessarily complex and under commented. A flowchart, or general description of program flow would be helpful until the following changes can be implemented. Comments at the top of a header file should describe the logical intent of the file. If the contents do not lend themselves to a concise description, perhaps the contents are better located somewhere else.

  • The first file a person will look at is the one and only .ino file, currently called cnc_ctrl_v1.ino. Why not simply Maslow.ino? Version info should be in the opening comment and within VCS (git).

  • A valid reason to include a file which does nothing except include other files is if that set of included files represents one of several different configurations. maslow.h is not that, however, maslowRing.h, maslowLink.h, maslowDueEthernetQuartersheetParallelogramSpeedcontrolSharpieLaserProgramtoolpath.h as mutually exclusive files could be useful in selecting only the specific files and #defines required for the desired feature set and target arduino.

  • .ino should directly contain the highest level global #define statements such as debug verbosity, version, machine ID(name).

  • It should be possible from .ino file alone, to determine all arduino pins which will be used in the project.
    #define SOME_PIN 1
    static const int X_PIN = 1;
    // someclassfile.h someclass.begin(int x_pin, int y_pin, char* something);
    someclass.begin(1, 2, “fred”);
    // if not otherwise obvious, a comment helps.
    // otherfile.h uses pin 0 for Rx, 1 for Tx, and 13 for onboard LED

  • .ino should directly include any libraries under different source control, to keep them current.
    #include Encoder.h

  • Do not modify external libraries without a darn good reason. The published external code is extensively tested and debugged. It already works. Try not to break it.

  • If you have a darn good reason, submit an issue or pull request to the original author to benefit the wider community. I know for a fact that PaulStoffregen works very hard to keep his libraries compatible with a wide range of Arduino hardware. If something as popular as Maslow requires a modification of his library, chances are he will be receptive to updating his source, or showing you a better way to use his libraries to accomplish the same thing.

  • Arduino compatibility. There is nothing special about Maslow that requires it to run on any specific arduino, yet the code is written in a narrow way that prohibits using anything but the Mega. Take advantage of the Arduino hardware abstraction layer to maintain compatibility with a wide variety of hardware. A target specific include file can bring in any native code required for the chosen target. Example: timer1 setup for Mega vs PIT for arm based micros.

  • Compatibility with external hardware and software need not require having the external hardware or software. Ground control is great, but some jobs could run just from the arduino program.

Example1: #ifdef PROGRAMTOOLPATH_NC // file exists, so record this toolpath in program flash to become machine’s default toolpath, run at the touch of a button. Good for a dedicated mass production oriented machine. Cut the maximum number of 5" square shapes that will fit a full sheet. No host required.

Example2: dialAcut Coded Rotary Switch selects which of several programs to run from an attached SD card.

Example3: Self test. When button is pressed, Move to top left of workpiece, pen down, alternately command takeup 1 encoder count from right motor, pause for settling, then release 1 encoder count from left motor, pause for settling, repeat. When encoder count near edge of work is reached, pen up. Repeat for remaining corners. Resulting plot is edge case limit of precision test. This is theoretically the most precise line segment Maslow could ever draw. Now draw a very large rectangle on the workpiece 1 inch in from the edge. This test is for accuracy. Variance from 1" distance, straightness of line, angle of line are error. Change pen color(transparent highlighter?), continue program which starts at end points of previous tests and reverses path. Difference in position of ink colors represents repeatability error plotted over entire workpiece. No G code required, no host, no router even.

  • It would be helpful if the .ino file describes the overall program flow. That means(as far as practical) any calls to functions in included files should come from .ino, NOT from other included files. Once program flow enters those include files and starts ping ponging around it becomes very difficult for a human to follow.

73 forks does not indicate duplication of effort, the way you contribute is to
fork, modify your fork, and then submit a patch request to merge your work back
into the main codebase. This is happening quite a bit.

we really should not be so dependent on the arduino IDE (which is where the .ino
comes from). We should have a real .c/.h codebase with the proper includes so
that it can be compiled without the arduino IDE, and will be better positioned
to work ith other chipsets.

some of your other suggestions make sense, some reflect a misunderstanding of
the maslow (ring vs link are meaningless to the firmware, they are purely
mechanical differences of achieving the same thing)

Most of the organization is due to historical accidents.

I think the best long-term thing that could happen for the Maslow Firmware would
be to add code to grbl to support encoder/motors and triangular kinematics and
then scrap the existing firmware.

The existing firmware works, but it is years behind grbl for many important
things (g-code understanding and acceleration to name a couple big features)

There was a recent PR for this, but it ran into trouble because the changing file name caused an issue in the Community Garden bot. It was rolled back pending further study.

With respect, there are assets that the Arduino Mega has that make it the preferred platform. I’ve worked on porting the firmware to the Teensy3.5, Teensy3.6, Sparkfun ‘ESP32 Thing’ and Arduino Due. Each requires compromise in some important aspect - EEPROM storage that doesn’t survive firmware update (Due), a greatly reduced number of pins, or a lack of software reset mechanism. The firmware can be made to compile for any of these. Send me a forum message if you’re interested in carrying one of those forward.

There’s an ongoing thread here that discusses porting to faster platforms. Join in on the discussion there.

1 Like

Yes, I see the problems with the hardware you mention now that you point it out.

SD card seems a reasonable substitute for EEPROM in platforms that are lacking. A good candidate for the alternate maslow .h file to choose different platform, native code, peripherals, and libraries.

I have suffered from the program button instead of reset button on Teensy way too often. It does have a very small reset pad, but it is not user friendly.

I would be very nervous to use a microprocessor such as Raspberry pi, or a PC vs a microcontroller. The problem is real time determinism. Arduino might be slow, but it is consistent. It won’t decide to do a garbage collection cycle in the middle of a critical cut, or start thrashing the swap file because too many browser tabs are open.

1 Like

That, and the fact that the stock Maslow board uses the pins needed for the SD Library contribute to the problems using SD with the Maslow. The TLE5206 board frees them up, though. I think that the SD library interrupt usage might cause trouble unless the SD is only accessed when the encoders aren’t moving.

1 Like

Thanks, I did not intend to imply that forks always = duplication of effort. Just that there are lots of people working on it. Whenever that happens, coordination is a good idea. For example, I was about to fork the project to begin a 'Teensy port, but now I know that blurfl has already done that, so it sames me effort.

There is no need to be “dependent” on the arduino IDE at all. Personally I think it is a terrible IDE. There are ways to compile directly to object code without arduino IDE. One way is to just use the tools manually that Arduino IDE uses programatically. I knew more about this before the change to GO build tools, but I assume it is still possible.

Imo, it would be unwise to be “incompatible” with the arduino IDE. Many reasonably good arduino programmers only know that IDE. It is a good least common denominator. Existing documentation suggesting notepad++ in conjunction with arduino toolchain seems like a reasonable compromise. Being Arduino compatible seems to be the best way to be portable since the micro manufacturers are already working so hard to be arduino compatible. I am curious why you think you will be “better positioned
to work ith other chipsets” by breaking compatibility. Yes, Arduino has some weird mangler/precompiler behavior, but there are workarounds. Seems you are already using them. You already use .h/.cpp structure. .ino is just a ‘template’(not the right word, but close) for main. There is a real main behind the scenes. It uses standard gcc compilers with standard syntax as far as I know. So what specific changes are you looking for?

Ring vs Link was a bad choice on my part. What I should have said was ring or link vs original. That is triangular vs trapezoid kinematics which is what I intended to illustrate. The common person that doesn’t care about the math is more likely to refer to the hardware than the kinematics. I felt the file names should reflect that.

Using grbl does sound like the right move to me as well. With an Arduino wrapper for some convenience features.

To be fair, the grbl firmware was hand coded and carefully crafted it to make full and clever use of a specific platform (Arduino Uno, yes?). It looks to me like efforts to port it to other platforms have stalled, and vocal interest in adding support for a Maslow-like capability hasn’t shown many results.

Since Paul( has written a translation layer that lets code written for registers on the uno actually run on the Teensy, that may be a good place to start the grbl transition. It is far from optimal, but may provide a working starting point, from which we hand optimize at our leasure. I say we, but I probably mean you, as I am actually not a very good coder.

many projects use to compile as well as the arduino IDE. It’s pretty
much a wrapper around gcc.

the key thing is to not become dependent on Arduini IDE specifics (like the fact
that it wants .ino files and mashes them all together instead of doing proper

how do you suggest that the coordination happen? yet another thread of the forum
to get missed? (like you missed the one on supporting faster hardware) or
something else.

vocal interest in adding support to any opensource project very rarely shows
results. Submitting patches for the added features show results.

While it doesn’t look like it’s moving quickly to other hardware, it looks like
it is moving.

That’s good news - is there a link I could follow?

Not great news, or current, but something.

I’m just watching the github repo and a couple of the threads about the new
version, and I’m seeing progress being made.

I see the housekeeping in the github repo, nothing recent about a version newer than v1.1f?

unfortunantly, I delete mails quickly (I get over a thousand a day), so I can’t
point at anything directly, I’ll try to remember to keep some around.

Yes! I think these are all excellent points and ideas. I’m glad to see firmware getting some love. I’ve been consumed with packing boxes and working on the garden this past couple weeks.

Pull requests for any of these ideas would be more than welcome. The documentation improvements are particularly welcome! :+1: :+1: :heart:

1 Like

I would love to help, that is a reason for this thread. However, like many others willing to help, I am new to Maslow and do not yet have an understanding of the program flow of the current firmware. We will need that understanding before we can substantially modularize the firmware. Can anyone point us to “A flowchart, or general description of program flow” as requested in the opening post.

The process of making the code modular, so that we can support different features or different target by just including different files with maslow.h is a major restructuring that will likely involve many breaking changes. That calls for a new major version number, on a new unstable development branch imo. That way incomplete pull requests on the development branch are temporarily allowed to break functionality without affecting users ability to download functioning firmware on the master branch.

Rather than beginning with a clone of master on the development branch, I suggest starting with a clean slate, and copy/paste/massage the old code as needed.
maslowMain.cpp can serve as the root of a

maslow.ino will be generated based on maslowMain.cpp with a set of rules we will need to define. If we do our job right, maslow.ino can be generated programatically, but will likely require a few hand tweaks from time to time to compile with Arduino IDE. This should give dlang and other traditionalist devs the format they desire with the added constraint that they cannot stray so far from Arduinoese that an equivalent .ino is no longer possible. Likewise, those that prefer the Arduino process can create maslow.ino and have the same rules applied in reverse to pragmatically generate maslowMain.cpp Comments?

// maslowMain.cpp
// The primary maslow firmware source file when using a makefile or commandline build system.

// When using maslowMain.cpp, you should not also use maslow.ino
// maslow.ino is only to be used with the Arduino IDE build system.
/* In order to generate files compatible with that Arduino IDE, maslowMain.cpp should, at minimum, contain
  Arduino license declaration? 
  Main loop for Arduino sketches
#include <Arduino.h>

// Declared weak in Arduino.h to allow user redefinitions.
int atexit(void (* /*func*/ )()) { return 0; }

// Weak empty variant initialization function.
// May be redefined by variant files.
void initVariant() __attribute__((weak));
void initVariant() { }

void setupUSB() __attribute__((weak));
void setupUSB() { }

int main(void)


#if defined(USBCON)
	for (;;) {
		if (serialEventRun) serialEventRun();
	return 0;


And for the Arduino equivalent, something like

// maslow.ino
// The primary maslow firmware source file when using the Arduino build system.

// When using maslow.ino, you should not also use maslowMain.c
// maslowMain.c is only to be used with an alternate makefile based build system.
// In that system, maslow.ino is similarly unused.

// Global defines
#define DEBUG_LEVEL 0
#define MACHINE_ID 1 /* in case of multiple Maslows connected to same workstation */
#define MACHINE_NAME FRED /* just for fun */

// Between here and endFileSelection, only a single line should be uncommented. 
// link or ring type sled.  Uses Triangular kinematics.
#include maslowDefault.h
// original type sled.  Uses Trapezoidal kinematics.
//#include maslowOriginalsled.h
// adds self test to firmware
//#include maslowSelftest.h
// requires a Teensy 3.5 or 3.6 in place of ArduinoMega
//#include maslowTeensy.h
// endFileSelection


#ifdef DIAL_A_CUT
#endif /* DIAL_A_CUT */

#ifdef SELF_TEST
#endif /* SELF_TEST */

maslow.ino can look like pseudo code. Just a list of the major tasks that need to be accomplished in the correct order, looping as required. The names of those tasks call code

  • in files with related names so it is easy to follow execution.
  • or in files named for the class if a member function call
  • otherwise place a comment with the filename

As the fileSelection portion could grow a bit large, it might be best to do something different with it like this.

// link or ring type sled.  Uses Triangular kinematics.
#include maslowDefault.h
/* Alternatively, instead of maslowDefault.h you can choose different features or run on different hardware by including one of the configuration files at github~/configuration */

the /configuration folder would likely be an area of the repo most frequented by inexperienced users. A common vehicle for support on the forum could be to provide a user in unique situation with an appropriate maslowXXX.h file for their configuration. That maslowXXX.h file can #include files, #define values, even some code fixes.

More additions to the firmware wishlist made possible by modularization, alternate motor drivers.
Servo,Stepper, Brushless, Serial or CAN motor controllers.
Motor profiles, including preferred ramp rates, stall detection limits, minimum starting current.
Encoder profiles, max rpm
Analog, turns?, continuous rotation behavior, B linear profile end limits, other profile full characterization, mV per mm of chain
Digital, voltage range supported, absolute/incremental, battery backed?, PPR, index pulse? , pulses per mm of chain,
Machine Geometry, chain route, sprocket/timing pulley pitch, Automatic TLO(Tool Length offset ), etc

With respect, take some time to really read the code and see the reasons for the present arrangement before looking for major re-arrangements.
The present arrangement was done within the last year as a part of a major contribution to the real-time performance, and does a good job of separating the tasks into functions.


And for sure, if you want to get your work accepted in an open source project, you have to clone. You have to make a series of small changes so that they can be reviewed and tested in isolation, A big cut-n-paste reorganization just is not possible where a more-or-less loosely knit set of people are working on the code.

As far as understanding the code. Start with the ino fiile. When the Mega is powered up, the setup() function is run. After that is over, the loop function is run. It never ends – it just keeps running until the Mega is reset or
powered down. The code is actually commented reasonably well.