Arduino Library consumes lots of sketch memory

General discussion of using Roboclaw motor controllers
Post Reply
SouthernAtHeart
Posts: 32
Joined: Fri Jan 29, 2016 4:00 pm
Arduino Library consumes lots of sketch memory

Post by SouthernAtHeart »

In my Arduino sketch, just uncommenting these lines uses up 2784 bytes! This seem excessive.

Code: Select all

//configure roboClaw //uses 2784 bytes!
  roboclaw.ResetEncoders(address);
  roboclaw.SetMainVoltages(address, 220, 260); //22.0 volt min, 28.0 volt max
  roboclaw.SetLogicVoltages(address, 220, 260); //22.0 volt min, 26.0 volt max
  roboclaw.SetM1MaxCurrent(address, 2500); //max current = 25.00 amps
  roboclaw.SetM2MaxCurrent(address, 2500); //max current = 25.00 amps
  roboclaw.SetM1VelocityPID(address, Kp, Ki, Kd, qpps);
  roboclaw.SetM2VelocityPID(address, Kp, Ki, Kd, qpps);
  roboclaw.SetM1PositionPID(address, kp, ki, kd, kiMax, deadzone, positionMin, positionMaxM1);
  roboclaw.SetM2PositionPID(address, kp, ki, kd, kiMax, deadzone, positionMin, positionMaxM2);
  roboclaw.SetPinFunctions(address,  S3mode, S4mode, S5mode);
  roboclaw.WriteNVM(address);
I really need my sketch to initiate the roboclaw on startup, in the event that the end user replaces the roboclaw, the new one will be properly configured by the arduino code.

And every time I send a position command with this line, it uses another 300 bytes of memory.

Code: Select all

    valid = roboclaw.SpeedAccelDeccelPositionM2(address, accel, maxSpeed, deccel, distance, bufClear);
I put my sendPos command in a function so everytime I call the function to send a position command, it only uses 16 bytes instead of 300 bytes.

Is there a good reason for this, or do I have something wrong? I don't know enough about the inner workings of the library and how it does all the serial commicating, and checksums, etc, to not use the library. It's functioning great. Just eating up previous memory.
User avatar
Basicmicro Support
Posts: 1594
Joined: Thu Feb 26, 2015 9:45 pm
Re: Arduino Library consumes lots of sketch memory

Post by Basicmicro Support »

Since most of the heavy work is done with a handful of helper functions most code shouldnt increase in size significantly after a few commands have been used(once the helper functions are linked into the code). The actual function calls for most commands are single lines of code calling the helper functions.

You can look at the roboclaw source code if you want to compare why yours is so different. My guess based on your 16 byte size statement is all you are doing is sending the command bytes. The serial write command is probably already in your program somewhere so when you added the serial write to send the command bytes you only see a very small increase in size. Since the SpeedAccelDeccelPosition packet serial command takes 18 bytes as its arguments I think you mis-read the 16 bytes size increase though.

Since there is zero chance you are dynamically calculating the CRC16 checksum or doing any error detection/correction in only 16 bytes of code space, Id say that is why your code size is so small(though I'd like to know why its only 16 byes when it has to send 18 bytes over the serial port, Im not aware of the GNU compiler compressing data).

Here are some size tests:

Empty Setup/Loop functions arduino program(eg smallest functional sketch you can make) 450 bytes
Roboclaw.h include 744 bytes
Roboclaw constructor 1988 bytes
roboclaw.begin 2762 bytes
roboclaw.SpeedAccelDeccelPositionM1 3548 bytes
second roboclaw.SpeedAccelDeccelPositionM1 3604 bytes(note how adding a second use of the same command doesnt add much).

second example sizes:
starts at roboclaw.begin 2762 bytes
roboclaw.ResetEncoders(address) 3352 bytes
roboclaw.SetMainVoltages(address, 220, 260); 3436 bytes
roboclaw.SetLogicVoltages(address, 220, 260); 3520 bytes
roboclaw.SetM1MaxCurrent(address, 2500); 3612 bytes
roboclaw.SetM2MaxCurrent(address, 2500); 3704 bytes
roboclaw.SetM1VelocityPID(address, Kp, Ki, Kd, qpps); 4556 bytes(also adds floating point library)
roboclaw.SetM2VelocityPID(address, Kp, Ki, Kd, qpps); 4914 bytes
roboclaw.SetM1PositionPID(address, kp, ki, kd, kiMax, deadzone, positionMin, positionMaxM1); 5412 bytes
roboclaw.SetM2PositionPID(address, kp, ki, kd, kiMax, deadzone, positionMin, positionMaxM2); 5906 bytes
roboclaw.SetPinFunctions(address, S3mode, S4mode, S5mode); 5980 bytes
roboclaw.WriteNVM(address); 6054 bytes

I then did a test where I wrote 18 bytes to the hardware serial port using Serial.write(data,len). 104 bytes added by this one command. This was with a bare bones arduino program so the write command was not already loaded by another call.

To shave code size off your init code you could replace the commands that use floating point(eg SetM1VelocityPID etc...) with precalculated fixed point values. You would need to modify the roboclaw library to expose the write_n function and then make calls like this:

write_n(18,address,SETM1PID,SetDWORDval(kd),SetDWORDval(kp),SetDWORDval(ki),SetDWORDval(qpps));

I expect if you removed the floating point code it would reduce the usage by around 2k.

Post Reply