Software for the Original EggBot Kit
This document details the serial command protocol used by the EBB (EiBotBoard). The EBB is an open source USB-based motor control board, designed to drive two stepper motors. The EBB may be used on its own, or found as the control board of such machines as The Original Egg-Bot, The WaterColorBot, or AxiDraw.
The serial protocol described in this document can be used directly, for example from a serial terminal, in order to carry out simple tasks. It can also be accessed from within any program or programming environment that is capable of communicating with a USB serial device. Using this protocol from within high-level computer languages allows one to construct and execute complex motion. All EBB applications and interfaces use this serial protocol, at their lowest levels, in order to manage the motion control.
The serial protocol specifies the fundamental primitives of how the machine operates— for example moving from position (a1,b1) to position (a2,b2) in duration Δt, with the pen-lift servo motor at position z. By contrast, higher level programs may perform tasks such as opening up SVG files and converting their into a set of robotic movements that can be carried out through the serial protocol.
Here are some possible starting points for building higher level applications:
The EBB firmware is based on the UBW firmware. The same basic command processing framework is used, so the same type of commands are used, and the same type of errors are returned. See the UBW command documentation for an introduction to these topics.
This command reference applies to EiBotBoard Firmware v1.8.0 and above. (Any differences between firmware versions are noted below and in release notes.)
Although the EBB firmware is a continuously evolving code base, we have, since version 2.0.1, taken care to avoid compatibility changes that would affect the most common machines using the EBB: The EggBot, WaterColorBot and (more recently,) the AxiDraw. If you are using one of these machines, there is generally no particular benefit or compelling reason for you to update your firmware to a newer version. (Older machines with older firmware will continue to work just fine with that older firmware.)
That said, there have been many smaller changes in the code between the versions that ship preloaded on the EBB (which may be a low as v2.0.1) and the latest versions. Most of the changes have been minor bug fixes and new, minor functions that are helpful for less common applications. If you are developing new applications with the EBB, we do encourage you to update to the newest version. If, on the other hand, you are writing new software that targets machines of various ages (for example, new EggBot software), please be aware that many of the machines out there are still using older firmware revisions.
Be aware that this documentation refers not only to different versions of the EBB firmware, but also in some cases to different versions of the EBB hardware. For example, the "EM" command has different behaviors on different versions of the EBB hardware.
If you discover something that does not work as expected in the EBB firmware, please contact us by e-mail, in our forum, or (preferably) file an issue on GitHub : https://github.com/evil-mad/EggBot/issues.
Please include a clear method to reproduce the issue, the expected behavior as well as the observed behavior, and the version number of the EBB firmware version that you are using.
The following syntax conventions are established to assist with clarity of communication as we describe the EBB commands.
code font
, with a shaded background.code font
.[ ]
) are used to enclose optional items.< >
) are used to represent individual control characters, such as <CR>
for carriage return or <NL>
for newline, in command and query format descriptions.
\r
for carriage return or \n
for linefeed, in the context of literal command examples.
<CR>
.A<CR>
A,channel:value,channel:value
. . . <CR>
Read all analog (ADC) input values.
When one or more analog channels are enabled (see AC
command below), the "A" command will cause the EBB to return a list of all enabled channels and their associated 10 bit values.
The list of channels and their data will always be in sorted order from least (channel) to greatest. Only enabled channels will be present in the list.
The value returned for each enabled channel will range from 0 (for 0.0 V on the input) to 1023 (for 3.3 V on the input).
The channel number and ADC value are both padded to 2 and 4 characters respectively in the A response.
A,00:0713,02:0241,05:0089:09:1004<NL><CR>
if channels 0, 2, 5 and 9 are enabled.
AC,channel,enable<CR>
OK<CR><NL>
Configure an analog input channel.
Use this command to turn on or turn off individual analog channels. Once a channel is turned on, it will begin converting analog values to digital values and the results of the conversions will be displayed in the returned value of the "A" Command. See "A" command above. You can turn on and off any of the 16 analog channels individually on this microcontroller. Once a channel is turned off, it will no longer show up in the "A" packet returned value list.
The channel numbers correspond to lines ANx on the EBB schematic and on the datasheet of the microcontroller. For example, pin 11 of the PIC, which is labeled RB2 and comes out as the RB2 pin on the servo header, has the text "RB2/AN8/CTEDG1/PMA3/VMO/REFO/RP5" next to it on the CPU symbol. This means that this pin is internally connected to Analog Channel 8. See chapter 21 of the PIC18F46J50 datasheet to read more about the ADC converter.
BL<CR>
OK<CR><NL>
Enter bootloader mode.
This command turns off interrupts and jumps into the bootloader, so that new firmware may be uploaded. This particular method of entering bootloader mode is unique in that no physical button presses are required.
Once in bootloader mode, the EBB will not be able to communicate using the same USB serial port method that the normal firmware commands use. A special bootloader PC application (that uses USB HID to communicate with the bootloader on the EBB) must be run in order to upload new firmware HEX files to the EBB.
This command will ONLY work if you have a EBB bootloader version later than 7/3/2010 (the version released on 7/3/2010 has a distinct LED blink mode - the USB LED stays on 3 times longer than the USR LED). With a previous version of the bootloader code, this command may cause the EBB to become unresponsive.
C,PortA_IO,PortB_IO,PortC_IO,PortD_IO,PortE_IO<CR>
OK<CR><NL>
This command takes five bytes worth of parameters, one for each TRISx register in the processor, and writes those values down into the TRIS registers. There is a TRIS register for each 8-bit wide I/O port on the processor, and it controls each pin's direction (input or output). A 0 in a pin's bit in the TRIS register sets the pin to be an output, and a 1 sets it to be an input.
This command is useful if you want to set up the pin directions for each and every pin on the processor at once. If you just one to set one pin at a time, use the PC
command.
This command does not need to be used to configure analog inputs. The AC
command is used for that.
CN<CR>
OK<CR><NL>
Clear the value of the Node Counter.
See the QN
command for a description of the node counter and its operations.
Added in v1.9.3, removed in v1.9.5
CS<CR>
OK<CR><NL>
This command zeroes out (i.e. clears) the global motor 1 step position and global motor 2 step position.
See the QS
command for a description of the global step positions.
Added in v2.4.3
CK,pVal_1,pVal_2,pVal_3,pVal_4,pVal_5,pVal_6,pVal_7,pVal_8<CR>
Param1=
pVal_1<CR><NL>
Param2=
pVal_2<CR><NL>
Param3=
pVal_3<CR><NL>
Param4=
pVal_4<CR><NL>
Param5=
pVal_5<CR><NL>
Param6=
pVal_6<CR><NL>
Param7=
pVal_7<CR><NL>
Param8=
pVal_8<CR><NL>
OK<CR><NL>
This command is used to test out the various parameter parsing routines in the EBB. Each parameter is a different data type. The command simply prints out the values it parsed to allow the developer to confirm that the parsing code is working properly.
For pVal_7, any type-able character is accepted as input.
For pVal_8, any type-able character is accepted, and converted to upper case before printing.
CU,Param_Number,Param_Value<CR>
OK<CR><NL>
This command allows for configuring some run time options. The configuration options chosen with this command do not survive a reboot, and they will return to their default values on a reset or boot.
OK
response to commands is disabled.OK
response to commands is enabled (default).Turning off the OK
response can help speed up the execution of many commands back to back.
SM
command parameter limit checking is disabled.SM
command parameter limit checking is enabled (default).
Turning off the limit checking for the SM
command will prevent error messages from being sent back to the PC, which may make processing of the data returned from the EBB easier.
EM,EnableAxis1[,EnableAxis2]<CR>
OK<CR><NL>
Enable or disable stepper motors and set step size.
Each stepper motor axis may be enabled (energized) or disabled. When disabled, the driver will stop sending current to the motor, so the motor will "freewheel" — it will not be actively driven, but instead will present little resistance to being turned by external torques.
When enabled, the stepper motor axes may be configured to be in whole, half, quarter, or eighth step sizes. In a motor with a native resolution of 200 steps per revolution, these settings would produce effective stepping resolutions of 200, 400, 800, and 1600 steps per revolution, respectively. Using fine sub-steps ("microstepping") gives higher resolution at the cost of decreasing step size reproducibility.
Note that this version of the command is only for EBB hardware v1.1.
EM,1,0\r
Enable Axis 1 in 1/8 step mode, and disable Axis 2EM,2\r
Enable Axis 1 in 1/4 step mode, disable Axis 2EM,Enable1[,Enable2]<CR>
OK<CR><NL>
For each stepper motor (Enable1 or Enable2), an integer in the range of 0 through 5, inclusive. An Enable value of 0 will disable the motor, while a nonzero value will enable the motor.
The allowed values of Enable1 are as follows:
The allowed values of Enable2 are as follows:
Enable or disable stepper motors and set step size.
Each stepper motor axis may be independently enabled (energized) or disabled. When disabled, the driver will stop sending current to the motor, so the motor will "freewheel" — it will not be actively driven, but instead will present little resistance to being turned by external torques.
When enabled, the stepper motor axes may be configured to be in whole, half, quarter, eighth, or sixteenth step sizes. In a motor with a native resolution of 200 steps per revolution, these settings would produce effective stepping resolutions of 200, 400, 800, 1600, and 3200 steps per revolution, respectively. Using fine sub-steps ("microstepping") gives higher resolution at the cost of decreasing step size reproducibility. Note that the microstep mode is set for both motors simultaneously, using the parameter value of Enable1.
Note that this version of the command is only for EBB hardware v1.2 and newer.
EM,1,0\r
Enable motor 1, and disable motor 2EM,2\r
Set both axes to 1/8 step mode and enable motor 1.EM,3,3\r
Set both axes to 1/4 step mode and enable both motors.EM,0,1\r
Enable motor 2, and disable motor 1.EM,0,0\r
Disable both motors (which will freewheel)ES<CR>
interrupted,fifo_steps1,fifo_steps2,steps_rem1,steps_rem2<NL><CR>OK<CR><NL>
Use this command to abort any in-progress motor move (SM) Command. This command will also delete any motor move command (SM) from the FIFO. It will immediately stop the motors, but leave them energized.
Returned values:
0,0,0,0,0<NL><CR>OK<CR><NL>
Indicates that no SM command was executing at the time, and no SM command was in the FIFO.
1,50,1200,18634,9848<NL><CR>OK<CR><NL>
Indicates that a command was interrupted, and that the FIFO had steps of 50 and 1200 steps queued to execute next (in axes 1 and 2), as well as 18634 and 9848 steps remaining to move (in axes 1 and 1) on the current move.
Prior to v2.2.9, this command will return a "1" if it had to stop an in-progress move command, or if it had to delete a move command from the FIFO. This could indicate that some steps might be lost, since the host application may think that moves have already completed, when in fact they were aborted partway through. It will return a "0" if no motor move commands were deleted or aborted.
Returned values:
1<NL><CR>OK<CR><NL>
: If an in-progress move commands was interrupted or removed from the FIFO
0<NL><CR>OK<CR><NL>
: If no in-progress move commands was interrupted or removed from the FIFO
I<CR>
I,PortA,PortB,PortC,PortD,PortE<CR><NL>
This command reads every PORTx register (where x is A through E) and prints out each byte-wide register value as a three digit decimal number. This effectively reads the digital values on each and every pin of the processor and prints them out. If you need the value of a particular pin, you can extract it from the value printed for that port by looking at the binary bit within the byte for that pin. For example, if you wanted to read the value of RB4, you would look at the 5th bit (0x10) of the PortB byte in the return packet.
For pins that are set as outputs, or are set as analog inputs, or are set as something other than digital inputs, this command will still convert the voltage on the pin to a digital value of 1 or 0 (using the standard voltage thresholds specified in the processor datasheet) and return all of their values.
I\r
I,128,255,130,000,007<CR><NL>
LM,RateTerm1,AxisSteps1,DeltaR1,RateTerm2,AxisSteps2,DeltaR2<CR>
OK<NL><CR>
Overview: This low-level command causes one or both motors to move, and allows the option of applying a constant acceleration to one or both motors during their movement. This is a low-latency command where the input values are parsed and passed directly into motion control FIFO of the EBB. No time is lost doing any math operations or limit checking, so maximum command throughput can be achieved. (See GitHub issue #73 for more information about the motivation for this command.)
Methods and consequences: Each axis has a separate 32 bit accumulator to control its timing. When the LM command is called, both accumulators are initialized to zero. Then, every 40 μs (when the 25 kHz ISR executes) a certain sequence of events happens for each channel:
For example, if the RateTerm value is 2147483648, then a step is taken every 40 μs. If the RateTerm value is 1, then a step is taken every 85899 seconds. If the RateTerm value is 0, then no steps are taken on that axis. Each time a step is taken, the AxisSteps count for that axis is decremented. Once both move counters reach zero after a step has been taken, the move is complete.
A practical restriction on the parameters is that you must ensure that motion is possible on at least one axis. That is to say, you must ensure that both AxisSteps is nonzero and that either RateTerm or DeltaR are nonzero for at least one axis of motion, or no motion will occur.
Because the parameters for each axis determine how long the move will take for that axis, one axis will (in most cases) finish stepping before the other. In extreme cases, one axis will finish moving well before the other, which can lead to (correct but) unintuitive behavior. Imagine for example that you have an XY movement command where both axes move the same distance, but the movement along axis 1 finishes in half the time of the movement along axis 2. The apparent motion along this path will be a diagonal XY movement for the first half of the transit time, and then a straight movement along axis 2 for the second half of the transit time. To the eye, that transit appears as a "bent" line, or perhaps as two distinct movement events. If you don't want this to happen, be careful to compute your parameters correctly so that both axes step continuously throughout the whole move.
Computing values: The equation for computing RateTerm given a number of motion steps to travel (the AxisSteps value) and a duration of movement for that axis is as follows, where T is the total time duration in seconds:
RateTerm = (AxisSteps << 31)/(25 kHz * T)
This division should be performed as a floating point operation, or at least as a 64 bit divide, since AxisSteps shifted left by 31 bits may take up to 63 bits.
The equation for computing the RateTerm given a motor step rate F in Hz is:
RateTerm = (2^31 / 25 kHz) * F, which can be approximated as RateTerm = 85,899.35 s * F.
The DeltaR value is added to RateTerm every 40 μs. It can be positive or negative. This is used to cause an axis to accelerate or decelerate during a move.
To compute the DeltaR values, calculate the desired starting and ending step speed using the above RateTerm formula, then divide the difference up by the number of 25 kHz ISRs that will happen during the move. See the Move Time formula below to get the amount of time the move will take.
To compute the total time of a move involving acceleration/deceleration (where DeltaR is non-zero), use the average step rate. For example, if we have a starting step rate (in Hz) of F1 and an ending step rate of F2, and the move is AxisSteps motor steps long, then the total move time in seconds is given by:
Move Time = AxisSteps/((F1 + F2)/2) = 2 * AxisSteps / (F1 + F2)
LM,3865470,60,1732,0,0,0
LM,3865481,1000,0,0,0,0\r
This simple example will move axis 1 at a constant speed of 45 steps/second for 1000 steps. Axis 2 does not move.
LM,85899346,10,0,17179869,2,0\r
This example will cause a 10 ms long move, where axis 1 takes a step every 1 ms, and axis 2 takes a step every 5 ms. Axis 1 will step for 10 steps, and axis 2 will step for 2 steps, and they will both finish together at the end of the 10 ms. This is a constant-rate move without acceleration or deceleration on either axis.
LM,85899346,10,0,85899346,2,0\r
This example will step both axis at a 1 ms/step rate, and axis 1 will step for 10 steps and axis 2 will step for 2 steps. Note that you normally don't want this - one normally prefers to have both axes stepping for the whole length of the move. This is a (poor, jerky) "constant-rate" move without acceleration or deceleration on either axis.
LM,17179869,6,0,57266231,20,0\r
This example will create a 30 ms long move, with axis 1 stepping 6 times and axis 2 stepping 20 times. There is no acceleration or deceleration on either axis. LM,42950000,50,13400,0,0,0\r
This example will start with axis 1 stepping at 500 steps/second and end with axis 1 stepping at 800 steps/second. It lasts for a duration of 50 steps. Axis 2 does not move. The move will take 77 ms to complete.
LM,17179869,75,-687,8589934,75,687\r
This example will start with axis 1 at 200 steps/second, and axis 2 at 100 steps/second. Over the course of 75 steps each, they will end at a speed of 100 steps/second for axis 1 (that is, decelerating) and 200 steps/second for axis 2. The move will take 500 ms.
MR,Address<CR>
MR,Data<CR><NL>
This command reads one byte from RAM and prints it out. The Data is always printed as a three digit decimal number.
MR,422\r
This command would read from memory address 422 and print out its current value.
MR,071<CR><NL>
MW,Address,Data<CR>
OK<CR><NL>
This command writes one byte to RAM. In order for this command to be useful, you will need to know what addresses in RAM are useful to you. This would normally be available by reading the source code for the EBB firmware and looking at the .map file for a particular version build to see where certain variables are located in RAM
Writing to areas in RAM that are currently in use by the firmware may result in unplanned crashes.
ND<CR>
OK<CR><NL>
This command decrements the 32 bit Node Counter by 1.
See the QN
command for a description of the node counter and its operations.
NI<CR>
OK<CR><NL>
This command increments the 32 bit Node Counter by 1.
See the QN
command for a description of the node counter and its operations.
O,PortA,[PortB,PortC,PortD,PortE]<CR>
OK<CR><NL>
This command simply takes its arguments and write them to the LATx registers. This allows you to output digital values to any or all of the pins of the microcontroller. The pins must be configured as digital outputs before this command can have an effect on the actual voltage level on a pin.
PC,Length0,Period0[,Length1,Period1,Length2,Period2,Length3,Period3]<CR>
OK<CR><NL>
This command sets up the internal parameters for the PG
command. The parameters come in pairs, and the first number in the pair represents the number of milliseconds that a pin (one of RB0, RB1, RB2 and RB3) goes high for, and the second number represents the number of milliseconds between rising edges for that pin. The first pair, for RB0, is required. The other three pairs (for RB1, RB2 and RB3) are optional.
When the PG,1
command is sent, any pairs from the PC
command where neither value is zero and the Rate is greater than the Length will create pulses on that pin.
While the pulses are going, new PC
commands can be sent, updating the pulse durations and repetition rates.
This command is only available for pins RB0, RB1, RB2 and RB3. If you wish to leave a pin alone (i.e. not create pulses on it) just set its Length and Period values to zero.
PD,Port,Pin,Direction<CR>
OK<CR><NL>
This command sets one of the processor pins to be an input or an output, depending on the Direction parameter.
This command is a very low-level I/O command. Higher level commands (like SM
, S2
, etc.) will not change the direction of pins that they need after boot, so if this command gets used to change the pin direction, be sure to change it back before expecting the higher level commands that need the pin to work properly.
PD,C,3,0\r
This command would set pin PC3 (or Port C, pin 3) as a digital output.
PG,Value<CR>
OK<CR><NL>
This command turns on (PG,1
) or turns off (PG,0
) the Pulse Generation on pin RB0 (and optionally on RB1, RB2 and RB3). It uses the parameters from the PC
command to control the pulse width and repetition rate on each pin.
This command does not turn off any other commands. So if you want to use the Pulse Generation on pins that already have S2
RC Servo outputs or other outputs on them, be sure to turn those other outputs off yourself before starting the Pulse Generation, or the two signals will get mixed together and create outputs you do not
desire.
PD,C,3,0\r
This command would set pin PC3 (or Port C, pin 3) as a digital output.
PI,Port,Pin<CR>
PI,Value<CR><NL>
This command reads the given port and pin as a digital input. No matter what direction the pin is set to, or even if the pin is being used as an analog input, the pin can still be read as a digital input.
PI,D,2\r
This command would read pin RD2 (or Port D, pin 2) as a digital input and return the pin's value.
PI,1<CR><NL>
PO,Port,Pin,Value<CR>
OK<CR><NL>
This command outputs a digital value of a 0 (0V) or 1 (3.3V) on one of the pins on the processor, as specified by Port and Pin.
This command will not change a pin's direction to output first, so you must set the pin's direction to be an output using the PD
command first if you want anything to come out of the pin.
This command is a very low-level I/O command. Many other higher level commands (like SM
, S2
, etc.) will over-write the output state of pins that they need. This commands allows you low-level access to every pin on the processor.
PO,C,7,1\r
This command would set the pin RC7 (or Port C, pin 7) to a high value.
QB<CR>
state<CR><NL>OK<CR><NL>
This command asks the EBB if the PRG button has been pressed since the last QB query or not.
The returned value state is 1 if the PRG button has been pressed since the last QB query, and 0 otherwise.
QC<CR>
RA0_VOLTAGE,V+_VOLTAGE<CR><NL>OK<CR><NL>
This command reads two analog voltages and returns their raw 10 bit values. You can use this to read the current setpoint for the stepper motor, and to read the input power that the board is receiving.
The two returned values are:
This value yields the voltage level at the REF_RA0 input to the stepper driver chip. This is the control voltage that sets the maximum instantaneous (not average) current that the driver chips allow into the motor coils.
The maximum current is given approximately by I_max = RA0_VOLTAGE/1.76. Thus, a voltage of 3 V at REF_RA0 would correspond to a maximum motor current of about 1.7 A.
This value yields the voltage level at on the EBB's V+ power net, which is the "motor" power coming into the board, as measured after the first input protection diode.
The value of V+_VOLTAGE as read on the ADC pin is scaled so that it does not exceed the 3.3 V maximum analog input level for the MCU. The scaling is performed by a voltage divider (comprised of R13 and R18 on the EBB), which gives a scaling factor of (1/11) on EBB boards v2.2 and earlier, and a scaling factor of (1/9.2) on EBB boards v2.3 and newer. As there is tolerance on the resistors, these scaling factors should be considered to be only approximate.
If one also wishes to compare the to the voltage read to that at the power input, it is necessary to also account for both the forward voltage across the input diode: the "diode drop" across the input diode is about 0.3 V at the current levels typically encountered.
The value of V+_VOLTAGE may be very useful in determining whether or not the EBB is plugged into power. One might also compare the value of this voltage with and without the motors enabled, in order to monitor and detect if the power supply voltage should droop due to load on the motors.
0394,0300<CR><NL>OK<CR><NL>
This query has returned values of 394 for RA0_VOLTAGE and 300 for V+_VOLTAGE.
The first returned value, 0394, indicates a voltage of 1.27 V at REF_RA0. This indicates that the maximum motor current is currently set to 0.72 A.
The second returned value, 0300, indicates a voltage of 0.96 V at the V+ ADC input. Scaling by 9.2 (for the voltage divider on an EBB v2.3) and adding 0.3 V (for the diode drop), this indicates that the "actual" input voltage is about 9.1 V.
This command was originally introduced in v2.0.0, but should not be considered functional until version 2.2.3.
Note also that this command only works properly on EBB hardware v1.3 and above. (White EBBs from Evil Mad Scientist are v2.0 or newer, and EBBs from SparkFun are v2.0 and above.)
QL<CR>
CurrentLayerValue<CR><NL>OK<CR><NL>
This command asks the EBB to report back the current value of the Layer variable. This variable is set with the SL
command, as a single unsigned byte.
QL<CR>
4<CR><NL>OK<CR><NL>
QM<CR>
QM,CommandStatus,Motor1Status,Motor2Status<NL><CR>
Use this command to see what the EBB is currently doing. It will return the current state of the 'motion system' and each motor's current state.
The definition of a "motion command" is any command that has a time associated with it. For example, all SM
commands. Also, any Command (like S2
, SP
, or TP
) that uses a delay or duration parameter. All of these commands cause the motion processor to perform an action that takes some length of time, which then prevents later motion commands from running until they have finished.
It is important to note that with all existing EBB firmware versions, only a very limited number of "motion commands" can be executing or queued simultaneously. In fact, there can only be three. One (the first one) will be actually executing. Another one (the second) will be stored in the 1-deep FIFO buffer that sits between the USB command processor and the motion engine that executes motion commands. Then the last one (the third) will be stuck in the USB command buffer, waiting for the 1-deep FIFO to be emptied before it can be processed. Once these three motion commands are "filled," the whole USB Command processor will block (i.e. lock up) until the FIFO is cleared, and the third motion command can be processed and put into the FIFO. This means that no USB commands can be processed by the EBB once the third motion command gets "stuck" in the USB Command processor. Using the QM command can help prevent this situation by allowing the PC to know when there are no more motion commands to be executed, and so can send the next one on.
QM<CR>
QM,CommandStatus,Motor1Status,Motor2Status,FIFOStatus<NL><CR>
Use this command to see what the EBB is currently doing. It will return the current state of the 'motion system', each motor's current state, and the state of the FIFO.
The definition of a "motion command" is any command that has a time associated with it. For example, all SM
commands. Also, any Command (like S2
, SP
, or TP
) that uses a delay or duration parameter. All of these commands cause the motion processor to perform an action that takes some length of time, which then prevents later motion commands from running until they have finished.
It is important to note that with all existing EBB firmware versions, only a very limited number of "motion commands" can be executing or queued simultaneously. In fact, there can only be three. One (the first one) will be actually executing. Another one (the second) will be stored in the 1-deep FIFO buffer that sits between the USB command processor and the motion engine that executes motion commands. Then the last one (the third) will be stuck in the USB command buffer, waiting for the 1-deep FIFO to be emptied before it can be processed. Once these three motion commands are "filled," the whole USB Command processor will block (i.e. lock up) until the FIFO is cleared, and the third motion command can be processed and put into the FIFO. This means that no USB commands can be processed by the EBB once the third motion command gets "stuck" in the USB Command processor. Using the QM command can help prevent this situation by allowing the PC to know when there are no more motion commands to be executed, and so can send the next one on.
QP<CR>
PenStatus<NL><CR>OK<CR><NL>
This command queries the EBB for the current pen state. It will return PenStatus of 1 if the pen is up and 0 if the pen is down. If a pen up/down command is pending in the FIFO, it will only report the new state of the pen after the pen move has been started.
QP\r
1<NL><CR>OK<CR><NL>
QS<CR>
GlobalMotor1StepPosition,GlobalMotor2StepPosition<NL><CR>OK<CR><NL>
This command prints out the current Motor 1 and Motor 2 global step positions. Each of these positions is a 32 bit signed integer, that keeps track of the positions of each axis. The CS
command can be used to set these positions to zero.
Every time a step is taken, the appropriate global step position is incremented or decremented depending on the direction of that step.
The global step positions can be be queried even while the motors are stepping, and it will be accurate the instant that the command is executed, but the values will change as soon as the next step is taken. It is normally good practice to wait until stepping motion is complete (you can use the QM
command to check if the motors have stopped moving) before checking the current positions.
QS\r
1421,-429<NL><CR>OK<CR><NL>
Added in v2.4.3
R<CR>
OK<CR><NL>
This command reinitializes the EBB to its power on state. This includes setting all I/O pins in their power on states, stopping any ongoing timers or servo outputs, etc.
R<CR>
OK<CR><NL>
SC,value1,value2<CR>
OK<CR><NL>
This command allows you to configure the motor control modes that the EBB uses, including parameters of the servo or solenoid motor used for raising and lowering the pen, and how the stepper motor driver signals are directed.
The set of parameters and their allowed values is as follows:
SC,1,value2
Pen lift mechanism. value2 may be 0, 1 or 2. Early EggBot models used a small solenoid, driven from an output signal on pin RB4.
SC,1,0
Enable only the solenoid output (RB4) for pen up/down movement.SC,1,1
Enable only the RC servo output (RB1) for pen up/down movement.SC,1,2
Enable both the solenoid (RB4) and RC servo (RB1) outputs for pen up/down movement (default)SC,2,value2
Stepper signal control. value2 may be 0, 1 or 2.
SC,2,0
Use microcontroller to control on-board stepper driver chips (default)SC,2,1
Disconnect microcontroller from the on-board stepper motor drivers and drive external step/direction motor drivers instead. In this mode, you can use the microcontroller to control external step/direction drivers based on the following pin assignments:
SC,2,2
Disconnect microcontroller from both the built-in motor drivers and external pins. All step/dir/enable pins on the PIC are set to inputs. This allows you to control the on-board stepper motor driver chips externally with your own step/dir/enable signals. Use the pins listed in the schematic from J5 and J4.
SC,4,servo_min
Set the minimum value for the RC servo output position. servo_min may be in the range 1 to 65535, in units of 83 ns intervals. This sets the "Pen Up" position. SC,5,servo_max
Set the maximum value for the RC servo output position. servo_max may be in the range 1 to 65535, in units of 83 ns intervals.
This sets the "Pen Down" position.
SC,8,maximum_S2_channels
Sets the number of RC servo PWM channels, each of S2_channel_duration_ms before cycling back to channel 1 for S2 command. Values from 1 to 24 are valid for maximum_S2_channels.
SC,9,S2_channel_duration_ms
Set the number of milliseconds before firing the next enabled channel for the S2 command. Values from 1 to 6 are valid for S2_channel_duration_ms.
SC,10,servo_rate
Set rate of change of the servo position, for both raising and lowering movements. Same units as rate parameter in S2
command.
SC,11,servo_rate_up
Set the rate of change of the servo when going up. Same units as rate parameter in S2
command.
SC,12,servo_rate_down
Set the rate of change of the servo when going down. Same units as rate parameter in S2
command.
SC,13,use_alt_pause
- turns on (1) or off (0) alternate pause button function on RB0. On by default. For EBB v1.1 boards, it uses RB2 instead.
SC,4,8000\r
Set the pen-up position to give a servo output of 8000, about 0.66 ms.SC,1,1\r
Enable only the RC servo for pen lift; disable solenoid control output.SC,11,servo_rate_up
added in v1.9.2SC,12,servo_rate_down
added in v1.9.2SC,13,use_alt_pause
added in v2.0SC,8,maximum_S2_channels
added in v2.1.1SC,9,S2_channel_duration_ms
added in v2.1.1SC,2,2
added in v2.2.2.SE,state[,power[,use_motion_queue]]<CR>
OK<CR><NL>
This command is used to enable and disable the engraver PWM output on RB3 (called B3 on the board), and also set its output power. Use SE,0 to disable this feature.
The power argument represents the power (duty cycle of the PWM signal), where 0 is always off and 1023 is always on. If this optional argument is not included, then the power will be set at 512 (50%) duty cycle.
If the use_motion_queue parameter has the value of 1, then this SE command will be added to the motion queue just like SM and SP commands, and thus will be executed when the previous motion commands have finished. Note that if you need to use this argument, the power argument is not optional. If use_motion_queue has value 0 (or if it is omitted) the command is executed immediately, and is not added to the queue.
SE,1,1023\r
Turns on the engraver output with maximum powerSE,0\r
Turns off the engraver outputSE,0,0,1\r
Adds a command to the motion queue, that (when executed) turns off the engraver output.SE,state[,power]<CR>
SL,NewLayerValue<CR>
OK<CR><NL>CR>
This command sets the value of the Layer variable, which can be read by the QL
query.
This variable is a single unsigned byte, and is available for the user to store a single variable as needed.
SL,4\r
Set the Layer variable to 4.SL,125\r
Set the Layer variable to 125.SM,duration,AxisSteps1[,AxisSteps2]<CR>
OK<CR><NL>
Use this command to make the motors draw a straight line at constant velocity, or to add a delay to the motion queue.
If both AxisSteps1 and AxisSteps2 are zero, then a delay of duration ms is executed. AxisSteps2 is an optional value, and if it is not included in the command, zero steps are assumed for axis 2.
The sign of AxisSteps1 and AxisSteps2 represent the direction each motor should turn.
The minimum speed at which the EBB can generate steps for each motor is 1.31 steps/second. The maximum speed is 25,000 steps/second. If the SM command finds that this speed range will be violated on either axis, it will output an error message declaring such and it will not complete the move.
Note that internally the EBB generates an Interrupt Service Routine (ISR) at the 25 kHz rate. Each time the ISR fires, the EBB determines if a step needs to be taken for a given axis or not. The practical result of this is that all steps will be 'quantized' to the 25 kHz (40 μs) time intervals, and thus as the step rate gets close to 25 kHz the 'correct' time between steps will not be generated, but instead each step will land on a 40 μs tick in time. In almost all cases normally used by the EBB, this doesn't make any difference because the overall proper length for the entire move will be correct.
A value of 0 for duration is invalid and will be rejected.
The EBB firmware can sustain moves of 3 ms of more continuously without any inter-move gaps in time.
SM,1000,250,-766\r
Move axis 1 by 250 steps and axis2 by -766 steps, in 1000 ms of duration.
SN,value<CR>
OK<CR><NL>
This command sets the Node Counter to value.
See the QN
command for a description of the node counter and its operations.
SN,123456789\r
Set node counter to 123456789.SP,value[,duration[,portBpin]]<CR>
OK<CR><NL>
This command instructs the pen to go up or down.
Note that conventionally, we have used the servo_min ("SC,4") value as the 'Pen up position', and the servo_max ("SC,5") value as the 'Pen down position'.
The duration argument is in milliseconds. It represents the total length of time between when the pen move is started, and when the next command will be executed. Note that this is not related to how fast the pen moves, which is set with the SC
command. Rather, it is an intentional delay of a given duration, to force the EBB not to execute the next command (often an SM
) for some length of time, which allows the pen move to complete and possibly some extra settling time before moving the other motors.
If no duration argument is specified, a value of 0 milliseconds is used internally.
The optional portBpin argument allows one to specify which portB pin of the MCU the output will use. If none is specified, pin 1 (the default) will be used.
Default positions:The default position for the RC servo output (RB1) on reset is the 'Pen up position' (servo_min), and at boot servo_min is set to 12000 which results in a pulse width of 1.0 ms on boot. servo_max is set to 16000 on boot, so the down position will be 1.33 ms unless changed with the "SC,5" Command.
Digital outputs: On older EBB hardware versions 1.1, 1.2 and 1.3, this command will make the solenoid output turn on and off. On all EBB versions it will make the RC servo output on RB1 move to the up or down position. Also, by default, it will turn on RB4 or turn off RB4 as a simple digital output, so that you could use this to trigger a laser for example.
SP,1<CR>
Move pen-lift servo motor to servo_min position.
SP,value[,duration]<CR>
T,duration,mode<CR>
OK<CR><NL>
This command turns on (or off) the timed digital (I packet) or analog (A packet) reading of pins. Using the T command you can set up a repeated reading of input pins, and the generation of an I or A packet back to the PC. Each of the two modes (analog/digital) is independent of the other and can have a different duration time.
For example, to turn the digital reading of all pins on, with a time of 250 ms between reads, use "T,250,0". Then, every 250 ms, the EBB will read all of the pins, and send an I response packet to the PC. This I response packet is exactly the same as the response to an "I" command, and simply contains the binary values of each pin of each port. To turn on the analog reading of any enabled analog inputs every 400 ms, use "T,400,1". This will cause the EBB to read all enabled analog inputs every 400 ms and send back an A packet (exactly the same as the reply to the "A" command) repeatedly. Note that while digital mode will read every pin, analog mode will only read (and report) the pins that are current configured as analog inputs. Pins do not have to be set to be digital inputs to be read by this command - no matter what the pin is set to, the "I" response packet will read the pin's digital state.
To turn off a mode, use 0 for the duration parameter. Thus "T,0,0" will turn off digital mode, and "T,0,1" will turn off analog mode.
The EBB is actually sampling the digital input pins at an extremely precise time interval of whatever you sent in the T command. The values of the pins are stored in a buffer, and then packet responses are generated whenever there is 'free time' on the USB back to the PC. So you can count the I packet responses between rising or falling edges of pin values and know the time between those events to the precision of the value of duration. This is true for digital mode. For analog mode the inputs are sampled every 1 ms. Each time the "A" timer times out, the latest set of analog values is used to create a new "A" packet and that is then sent out.
Just because the EBB can kick out I and A packets every 1 ms (at its fastest) doesn't mean that your PC app can read them in that fast. Some terminal emulators are not able to keep up with this data rate coming back from the EBB, and what happens is that the EBB's internal buffers overflow. This will generate error messages being sent back from the EBB. If you write your own custom application to receive data from the EBB, make sure to not read in one byte at a time from the serial port - always ask for large amounts (10K or more) and then internally parse the contents of the data coming in. (Realizing that the last packet may not be complete.)
If an attempt is made to have all 13 channels of analog be reported any faster than every 4 ms, then an internal EBB buffer overflow occurs. Be careful with the speed you choose for A packets. The maximum speed is based upon how many analog channels are being sent back.
T,250,0<CR>
Turn on digital reading of pins and generation of I packet every 250 ms.
S2,channel,position,output_pin[,rate]<CR>
S2,0<CR>
OK<CR><NL>
A value of 1 through 7 chooses a software-defined channel.
A value of 0 disables all S2 outputs.
The "on time" of the signal, in units of 1/12,000,000th of a second (about 83 μs).
The physical RPx pin number to assign this channel to.
The rate at which to change to the new setting.
This command allows you to control the RC servo output system on the EBB, to configures a generic RC servo output.
Servo channels and time slices: There are eight software-defined RC servo 'channels', which have no physical meaning other than we can (by default) output up to 8 separate signals at once. The available channels are numbered 1 though 8. Channel 1 is normally used as the "pen lift" servo motor, controlled through the SP and TP commands.
(A selection of channel equal to 0 is a special command, used to disable all S2 functionality.)
Many I/O pins on the MCU have RPx numbers (please refer to the schematic), and you can output RC servo pulses on up to 8 of these RPx pins. You can assign any channel to any RPx pin.
The RC servo system will cycle through each of the 8 channels. Each gets a 3 ms "slice" of time, thus giving a 24 ms repeat period for the full RC system.
If the current channel is enabled, then at the beginning of its 3 ms time slot, its RPx pin is set high. Then, position time later, the RPx pin is set low. This time is controlled by hardware (the ECCP2 in the CPU) so there is very little jitter in the pulse durations. position is in units of 1/12,000 of a second, so 32000 for position would be 2.666 ms. A value of 0 will produce zero length, without any pulse.
The number of available channels is normally (by default) 8. This can be reduced with the SC,8 command. The S2 RC servo output command cycles from channel 1 through channel maximum_S2_channels (normally 8), outputting any enabled channel's pulse from 0 ms to 3 ms. For a given channel, the repetition rate is determined by maximum_S2_channels * S2_channel_duration_ms which is normally 8 * 3 or 24 ms. Thus, each channel's output pulse will be repeated every 24 ms. However, if you change the maximum_S2_channels you will change the repetition rate of the pulses. The S2_channel_duration_ms parameter can also be adjusted with the SC,9 command.
Slew rate: The rate argument is used to control how quickly the output changes from the current pulse width (servo position) to the new pulse width. If rate is zero, then the move is made on the next PWM cycle (i.e. the next time the pin is pulsed). If rate is nonzero, then the value of rate is added to (or subtracted from) the current pulse width each time the pulse is generated until the new target is reached. This means that the units of rate are 1/12,000th of a second per maximum_S2_channels * S2_channel_duration_ms or 1/12,000th of a second per 24 ms.
Collisions with SP and TP: The normal pen up/down servo control (SP and TP) commands internally use S2 channel 1. If you wish to to use SP and TP, then ignore channel 1 and start with channel 2. If you do not need the SP and TP commands, then you can use channels 1 through maximum_S2_channels.
Turn-on condition: Note that the S2 command will always make output_pin an output before it starts outputting pulses to that pin.
Disabling S2 servo outputs: The special command S2,0<CR>
will turn off all RC servo support (freeing up CPU time, if that's important to you).
S2,3,24000,6\r
Use RP6 as a RC servo output, and set its on-time to 2 ms, and using channel 3 of the RC system, including a rate argument of 6.
S2,0\r
Turn off all RC servo support.
S2,3,0\r
Turn off the output on whatever pin channel 3 was assigned to.
S2,position,output_pin[,rate[,delay]]<CR>
S2,0<CR>
OK<CR><NL>
The "on time" of the signal, in units of 1/12,000,000th of a second (about 83 μs).
The physical RPx pin number to use for generating the servo pulses.
The rate at which to change to the new setting.
Delay before next command, milliseconds.
This command allows you to control the RC servo output system on the EBB, to configure generic RC servo outputs.
Servo channels and time slices: Including the pen-lift servo, there are (by default) eight software-defined RC servo 'channels', which have no physical meaning other than we can output up to 8 separate signals at once. These channels are internally assigned as you use the S2 command to create additional servo outputs, up to a maximum of 8 (this maximum can be changed with the SC,8,X command).
Many I/O pins on the MCU have RPx numbers (please refer to the schematic), and you can output RC servo pulses on up to 8 of these RPx pins at once.
The RC servo system will cycle through each of the 8 channels. Each gets a 3 ms "slice" of time, thus giving a 24 ms repeat period for the full RC system.
If a given servo output is enabled, then at the beginning of its 3 ms time slot, its RPx pin is set high. Then, position time later, the RPx pin is set low. This time is controlled by hardware (the ECCP2 in the CPU) so there is very little jitter in the pulse durations. position is in units of 1/12,000 of a second, so 32000 for position would be about 2.666 ms. A value of 0 will produce zero output only, with no pulse created. If the position value is greater than the amount of time allocated for each channel (by default, 3 ms) then the smaller of the two values will be used to generate the pulse.
The number of available channels is normally (by default) 8. This can be changed with the SC,8 command. The S2 RC servo output command cycles from channel 1 through channel maximum_S2_channels (normally 8), outputting any enabled channel's pulse from 0 ms to 3 ms. For a given channel, the repetition rate is determined by maximum_S2_channels * S2_channel_duration_ms which is normally 8 * 3 or 24 ms. Thus, each channel's output pulse will be repeated every 24 ms. However, if you change the maximum_S2_channels you will change the repetition rate of the pulses. The S2_channel_duration_ms parameter can also be adjusted with the RC,9 command.
Delay: The delay argument gives the number of milliseconds to delay the start of the next command in the motion queue. This is an optional argument that defaults to 0, giving no added delay, thus allowing the next motion command to begin immediately after the S2 command has started.
Motion Queue: All S2 commands are added to the motion queue, even if their delay parameters are 0. This means that they will always execute in their correct place in the stream of SM, TP, etc. commands.
Slew rate: The rate argument is used to control how quickly the output changes from the current pulse width (servo position) to the new pulse width. If rate is zero, then the move is made on the next PWM cycle (i.e. the next time the pin is pulsed). If rate is nonzero, then the value of rate is added to (or subtracted from) the current pulse width each time the pulse is generated until the new target is reached. This means that the units of rate are 1/12,000th of a second per maximum_S2_channels * S2_channel_duration_ms or 1/12,000th of a second per 24 ms. The slew rate is completely independent of the delay.
Collisions with SP and TP: The normal pen up/down servo control (SP and TP) commands internally use the S2 command to manage their actions through one of the software-defined channels. If desired, you can use the S2 command to disable this channel, for example if you need access to all eight channels.
Turn-on condition: Note that the S2 command will always make output_pin an output before it starts outputting pulses to that pin.
Disabling S2 servo outputs: The special command S2,0<CR>
will turn off all RC servo support (freeing up CPU time, if that's important to you).
RPx |
RP0 |
RP1 |
RP2 |
RP3 |
RP4 |
RP5 |
RP6 |
RP7 |
Pin |
REF_RA0 |
RA1 |
RA5 |
RB0 |
RB1 |
RB2 |
RB3 |
RB4 |
Label |
B0 |
B1 |
B2 |
B3 |
B4 |
RPx |
RP8 |
RP9 |
RP10 |
RP11 |
RP13 |
RP17 |
RP18 |
Pin |
RB5 |
RB6 |
RB7 |
RC0 |
RC2 |
RC6 |
RC7 |
Label |
B5 |
B6 |
B7 |
S2,24000,6\r
Use RP6 as a RC servo output, and set its on-time to 2 ms.
S2,0\r
Turn off all RC servo support.
S2,0,5\r
Turn off the output on RP5 (which is pin RB2) so it stops sending any pulses.
S2,10000,5,100\r
Send a 0.83 ms pulse out pin RB2, and force a pause of 100 ms before the next motion command can start.
S2,27500,5,10,50\r
Start the pulse on RB2 moving from wherever it is at now towards 2.28 ms at a rate of 0.173 ms/S, with a 10 ms delay before the next motion command can begin.
TP[,duration]<CR>
OK<CR><NL>
This command toggles the state of the pen (up->down and down->up). EBB firmware resets with pen in 'up' (servo_min) state.
Note that conventionally, we have used the servo_min ("SC,4") value as the 'Pen up position', and the servo_max ("SC,5") value as the 'Pen down position'.
The optional duration argument is in milliseconds. It represents the total length of time between when the pen move is started, and when the next command will be executed. Note that this is not related to how fast the pen moves, which is set with the SC
command. Rather, it is an intentional delay of a given duration, to force the EBB not to execute the next command (often an SM
) for some length of time, which allows the pen move to complete and possibly some extra settling time before moving the other motors.
If no duration argument is specified, a value of 0 milliseconds is used internally.
QN<CR>
NodeCount<CR><NL>OK<CR><NL>
This command asks the EBB what the current value of the Node Counter is. The Node Counter is an unsigned long int (4 bytes) value that gets incremented or decremented with the NI
and ND
commands, or set to a particular value with the SN
command. The Node Counter can be used to keep track of progress during various operations as needed.
The value of the node counter can also be manipulated with the following commands:
SN
— Set Node countNI
— Node count IncrementND
— Node count DecrementCN
— Clear node count [obsolete]1234567890<CR><NL>
then OK<CR><NL>
V<CR>
EBBv13_and_above EB Firmware Version 2.4.2<CR><NL>
This command prints out the version string of the firmware currently running on the EBB. The actual version string returned may be different from the example above.
XM,duration,AxisStepsA,AxisStepsB<CR>
OK<CR><NL>
This command takes the AxisStepsA and AxisStepsB values, and creates a call to the SM
command with the SM command's AxisSteps1 value as AxisStepsA + AxisStepsB, and AxisSteps2 as AxisStepsA - AxisStepsB.
This command is designed to allow cleaner operation of machines with mixed-axis geometry, including CoreXY, H-Bot gantry machines, and current AxiDraw models.
If both AxisStepsA and AxisStepsB are zero, then a delay of duration ms is executed.
The minimum speed at which the EBB can generate steps for each motor is 1.31 steps/second. The maximum speed is 25 kSteps/second. If the XM command finds that this speed range will be violated on either axis, it will output an error message declaring such and it will not complete the move. Note that the range is checked on Axis 1 and Axis 2, NOT on Axis A and Axis B. (That is, the range is checked after performing the sum and difference.)
Note that internally the EBB generates an ISR at the 25 kHz rate. Each time the ISR fires, the EBB determines if a step needs to be taken for a given axis or not. The practical result of this is that all steps will be 'quantized' to the 25 kHz (40 μs) time intervals, and thus as the step rate gets close to 25 kHz the 'correct' time between steps will not be generated, but instead each step will land on a 40 μs tick in time. In almost all cases normally used by the EBB, this doesn't make any difference because the overall proper length for the entire move will be correct.
A value of 0 for duration is invalid and will be rejected.
XM,1000,550,-1234\r
Move 550 steps in the A direction and -1234 steps in the B direction, in duration 1000 ms.
Q1) How can I calculate how long it will take to move from one RC servo position to another? Specifically in relation to the standard pen-arm servo that is activated with the SP,1 and SP,0 commands.
A1) By default, with the latest version of EBB firmware, we add (or subtract) the rate value from the current pulse duration every time the pulse fires until the current pulse duration equals the target duration. Normally we have 8 servo channels available, and each gets 3 ms, so that means that each channel can fire once every 24 ms. So the rate value gets added or subtracted from the current pulse duration every 24ms.
For example, if you're currently at a position (pulse duration) of 10000 and you send a new command to move to position 15000, then you have a 'distance' of 5000 to go. So when we start out, our current duration is 10000 and our target is 15000. If our rate value is 100, then it will take 50 of these 24ms periods to get from 10000 to 15000, or 1.2 seconds total.
Now, when you're using the SP,0 and SP,1 commands, the servo_min (defaults to 16000, or 1.33 ms) and servo_max (defaults to 20000, or 1.6 ms) get used as the positions. And the servo_rate_up and servo_rate_down get used as the rates. So the formula is as follows:
((servo_max - servo_min) * .024)/servo_rate = total time to move
For the example above. ((15000 - 10000) * .024)/100 = 1.2 seconds.
Extended EggBot documentation available at: http://wiki.evilmadscientist.com/eggbot