Skip to content
firepick1 (localhost) edited this page Dec 27, 2016 · 124 revisions

JSON Commands

FireStep requests and responses use JSON syntax. JSON provides tremendous flexibility of expression using an industry standard syntax. The JSON requests can be used to control up to six axes (i.e., x,y,z,a,b,c) that can be individually mapped to one of four virtual motors (i.e., 1,2,3,4) for synchronized motion.

Individual FireStep commands are JSON objects. In this example, we disable the x axis:

{"xen":false}

FireStep also supports arrays of JSON commands, which are executed in sequence. In the following, FireStep executes two separate commands, which are combined into a single JSON array for host computer convenience. The first command in the JSON array will home three motors and set the homed stepper coordinates to (-9000,-9000,-9000). The second command in the JSON array will move the first three motors to stepper coordinate (0,0,0):

[ {"hom":{"1":-9000,"2":-9000,"3":-9000}}, {"mov":{"1":0,"2":0,"3":0}} ]

Raw Stepper Coordinates

Unlike other stepper drivers that automatically convert real-world Cartesian coordinates to stepper pulse coordinates, FireStep works primarily with raw stepper coordinates. For example, position '1' is one microstep pulse away from position '2'. Raw stepper coordinates provide great application flexibility. Raw stepper coordinates are enabled by default as machine topology (0:MTO_FPD).

Delta Machines

Delta coordinate conversion has traditionally been treated as an afterthought tacked onto existing Cartesian drivers (e.g., Marlin). For Cartesian drivers, there is close correspondence between stepper motion and real-world effect. A Cartesian X-stepper moves the effector in the real-world X-direction. This one-to-one approach does not work with the three-to-one geometry of delta machines.

FireStep is designed for use with FirePick Delta, which has a delta real-world coordinate system. For delta machines, THREE steppers are normally required for movement along a Cartesian real-world axis. We have noticed that existing Cartesian stepper drivers don't really handle delta coordinate conversion/movement quickly or smoothly. Cartesian drivers typically perform delta coordinate conversion point by point in their motion planners. This piecemeal approach functions, but not optimally, since it burdens the embedded MCU and requires many commands to handle complex paths smoothly. This verbose complexity suggests that a different approach should be considered for delta machines.

FireStep abandons the point-by-point approach and focuses on paths for specifying movement. FireStep is stroke-based, not point-based, and relies on a host computer for path planning and delta conversion. Path calculation is CPU intensive and not really suited for current embedded MCUs. FireStep movement requests therefore specify strokes in raw stepper coordinates, not real-world coordinates.

FireStep has dedicated support for the FPD machine topology (1:MTO_FPD). It even has a kinematic model for Sliced Pulley Error.

Flow Control

FireStep uses a simple line protocol for flow conrol. A JSON request occupies a single line. The corresponding JSON response is also a single line by default (except when pretty-printed) and is sent when FireStep is ready for the next request.

See Flow Control

GCODE

For the reasons given above, FireStep does not implement GCODE. The memory required for GCODE motion planning and buffering conflicts with FireStep's primary goal of supporting smooth, complex paths using a single stroke. FireStep uses memory for path storage and relies on a host computer for path calculation and optimization. Future embedded processors with enhanced CPUs may well allow GCODE support in FireStep, but not at this time.

Primary Attributes

Each FireStep JSON request has a two-level hierarchy of primary and secondary attribute groups. The top-level primary attributes are:

Category Attribute Description
Axis 1 Motor 1
Axis 2 Motor 2
Axis 3 Motor 3
Axis 4 Motor 4
Axis x X-axis
Axis y Y-axis
Axis z Z-axis
Axis a A-axis
Axis b B-axis
Axis c C-axis
General cmt Comment
General dim Machine Dimensions (MTO_FPD only)
General dpy Display Configuration
General eep read/write EEPROM
General id system identification
General io read/write pin
General idl delay milliseconds
General mpo Motor Position
General msg Serial.println(text)
General pgmx Run pre-defined program (MTO_FPD only)
General sys System Configuration
General tst Test and Calibrate
Motion cal Calibrate (MTO_FPD only)
Motion dvs Delta-V Stroke
Motion hom Home
Motion mov Move To Position
Motion mrk Mark Position (MTO_FPD only)
Motion prb Probe To Position
Motion prbd Return Probe Data (MTO_FPD only)

For example, the sys primary attribute can be used to show system configuration:

{"sys":""}

You can use secondary attributes for more precise JSON queries

{"sys":{"v":""}}

Axis:1,2,3,4 Motor Mapping

FireStep can coordinate the movement of up to 4 virtual motors simultaneously. Each motor is mappable to one of six axes. The mapping can be changed at any time, allowing you to control all six axes. However, do not map two motors to the same axis.

Attribute ✏️ Description
ma ✏️ motor axis (0:X, 1:Y, 2:Z, 3:a, 4:b, 5:c)

The initial motor mapping is:

Motor ✏️ Default
1ma ✏️ 0:X-axis
2ma ✏️ 1:Y-axis
3ma ✏️ 2:Z-axis
4ma ✏️ 3:A-axis

For example, we can map the fourth motor to the C axis:

{"4ma":5}

Axis:x,y,z,a,b,c Axis Configuration

F1ireStep can drive up to six stepper axes (i.e., X,Y,Z,A,B,C). Each axis supports the following configuration parameters:

Attribute ✏️ Default Description
dh	| :pencil2:	| true	| direction pin value for clockwise rotation (invert this to change direction) 
en	| :pencil2:	| true	| enable/disable stepper. Disabled steppers are unpowered and free to rotate 
ho	| :pencil2:	| 0	| homing position
is	| :pencil2:	| 0	| idle snooze "cat nap" power-off delay (microseconds)
lb	| :pencil2:	| 200 | latch backoff in microstep pulses
lm	| :pencil2:	| false	| *pinMax* limit switch tripped
ln	| :pencil2:	| false	| *pinMin* limit switch tripped
mi	| :pencil2:	| 16¹	| microsteps 
mp	| :pencil2:	| 1	| microstep pulse multiplier for stepper drivers such as TM2100 that can't change microstep count easily 
pd	| :pencil2:	| [pins.h](https://github.com/firepick1/FireStep/blob/master/FireStep/pins.h)	| direction pin
pe	| :pencil2:	| [pins.h](https://github.com/firepick1/FireStep/blob/master/FireStep/pins.h)	| enable pin (see *syslh*)
pm	| :pencil2:	| NOPIN	| maximum limit pin
pn	| :pencil2:	| NOPIN	| minimum limit pin
po	| :pencil2:	| 0	| stepper position 
ps	| :pencil2:	| [pins.h](https://github.com/firepick1/FireStep/blob/master/FireStep/pins.h)	| step pin
sa	| :pencil2:	| 1.8¹	| step angle
tm	| :pencil2:	| 32000	| step travel maximum limit (int16_t)
tn	| :pencil2:	| -32000	| step travel minimum limit (int16_t)
ud	| :pencil2:	| 0	| pulse-to-pulse microsecond delay (suggest >80 if microsteps=1)
  • ¹ attributes are only used for tstrv

General:dpy Display Configuration

FireStep has a customizable and configurable display. The default driver is for a 16-LED NeoPixel ring. All display drivers must support the following display configuration attributes:

Attribute ✏️ Description
cb	| :pencil2:	| [camera blue level](Display) [0,255] 0 => display intensity
cg	| :pencil2:	| [camera green level](Display) [0,255] 0 => display intensity
cr	| :pencil2:	| [camera red level](Display) [0,255] 0 => display intensity
dl	| :pencil2:	| [display level](Display) level (0:off, 127:default, 255:brightest)
ds	| :pencil2:	| [displayed status](Display)

General:eep Read/Write EEPROM

FireStep normally resets configuration values on startup. If you made configuration changes, they will be lost. However, you can save your configuration changes using auto-sync:

{"sysas":true}

Auto sync will remain enabled until you turn it off (or reset your Arduino):

{"sysas":false}

Given the general utility of auto-sync (which uses EEPROM), EEPROM commands are rarely used on their own. However, if you need to read/write EEPROM, you can do so with FireStep.

The Arduino Mega2560 has 4096 bytes of EEPROM that will persist through power-off cycles. The eep command lets you read/write EEPROM.

Here we write "hello" to EEPROM address 3000:

{"eep3000":"hello"}

Using the standard FireStep JSON query syntax, we read our saved EEPROM value with either of the following commands:

{"eep3000":""}
{"eep":{"3000":""}}
EEPROM boot addresses

Some EEPROM addresses are reserved for JSON commands to be executed on startup.

EEPROM address 0 is special. If you write a JSON string to EEPROM address 0, it will be executed when FireStep starts up. This is the system boot area reserved for FireStep calibration commands and persistent system configurations.

EEPROM address 2000 is special by default. If you write a JSON string to EEPROM address 2000, it will be executed when FireStep starts up AFTER the EEPROM address 0 commands. This is the user EEPROM area. The user EEPROM area is ideal for power up demo scripts, etc.

Let's create a user EEPROM command to say, "hello", on startup:

{"eep":{"2000":"{\"msg\":\"hello\"}}"}

The backslashes are required to escape the double quotes. More conveniently, you can avoid those backslashes and just type in the JSON object or array of your startup command. FireStep will convert your JSON to an EEPROM string automatically:

{"eep2000":{"msg":"hello"}}

To enable your user EEPROM:

{"sysas":true,"syseu":true}

Here are the eep JSON attributes:

Attribute ✏️ Description
AAA ✏️ read/write EEPROM address AAA

Although the EEPROM is large, the FireStep JSON RAM buffer is not. Limit your EEPROM strings to less than 512 bytes each and you'll be fine.

General:id Identification

The id group provides general identification information:

Attribute ✏️ Default Description
app | | FireStep | name of application
ch	| | (varies) | configuration hash 
git	| | (varies) | 40 character git hash of FireStep build source
ver | | (varies) | M.NNP  M:major, N:minor, P:patch version

General:io Read/Write Pin

You can read or write the value of a digital pin. Here we set the value of digital pin 22 using the io short form:

{"iod22":true}

With the long form of io, you can read/write multiple pins. Here we clear digital pin 22 and read digital pin 23:

{"io":{"d22":0, "d23":""}}

IMPORTANT: You should not use io to read/write any of the core pins (e.g., axis direction pin). Doing so would potentially turn an input pin into an output pin or vice versa, which could damage your machine.

Attribute ✏️ Description
dNNN	| :pencil2:	| read/write digital pin NNN
aNNN	| :pencil2:	| read/write analog pin NNN (UNTESTED)
pu		| :pencil2: | true implies INPUT_PULLUP (default is false)

WARNING The use of pu may not be supported by all MCUs. Arduino has internal pullup resistors. Using this parameter may make your application non-portable.

General:mpo Motor Position

The mpo command provides machine position. Example:

{"mpo":""}

Although rarely used, you can set the motor position as well. Setting the motor position does not move any stepper, it just changes the coordinates. See mov for comparison.

The mpo command is implemented differently for each machine topology:

General:sys System Configuration

The sys group provides general system information and some configuration capabilities:

Attribute ✏️ Default Description
ah	| :pencil2:	| false | auto-home on startup 
as	| :pencil2:	| false | auto-sync configuration to EEPROM
eu	| --	| 2000 | end user EEPROM commands 
fr	| --	| -- | free ram in bytes
hp	| :pencil2:	| 3 | homing pulse group size (i.e., homing speed)
jp	| :pencil2:	| false | JSON pretty print (see below)
lh	| :pencil2:	| false | limit tripped when HIGH 
lp	| :pencil2:	| reserved | reserved
mv	| :pencil2:	| 12800 | maximum velocity (pulses/second)
om	| :pencil2:	| 0 | JSON output mode (see below)
pb	| :pencil2:	| (see pc) | z-probe pin (pin-configuration dependent)
pc	| :pencil2:	| 1 | [dynamic pin configuration](https://github.com/firepick1/FireStep/blob/master/FireStep/pins.h) (0:NOPIN; 1:EMC02, 2:RAMPS-1.4)
pi	| :pencil2: | (see pc) | display information/status pin (e.g., NeoPixel)
pu	| :pencil2:	| 0 | pullup bit mask (0x1:probe, 0x2:limitMin, 0x4:limitMax)
sd	| :pencil2:	| 800 | minimum search pulse period for homing/probing (microseconds)
tc	| --	| -- | thread clock ticks (@64microseconds)
to	| :pencil2:	| 0 | machine topology (0:[[MTO_RAW]], 1:[[MTO_FPD]])
tv	| --	| 0.35 | time to maximum velocity (seconds)
v	| --	| JJJNN.PP | version (JJJ:major, NN:minor, PP:patch)
Configuration Auto-sync

FireStep configuration is normally reset on startup. This provides consistent startup behavior and assumes that the FireStep client (e.g., OpenPnP) wishes to have complete control over the configuration.

You can also create and save your own custom configuration by turning on configuration auto-sync to EEPROM:

{"sysas":true}

Auto-sync will save almost 1KB of JSON configuration information to EEPROM address 0. When FireStep restarts it will automatically restore your custom configuration. In addition, with auto-sync enabled, FireStep will track machine configuration changes an update EEPROM when the machine is idle. You can review your custom configuration:

{"eep0":""}

Auto-sync itself is a configuration parameter, but is NOT saved to EEPROM. On startup, auto-sync will therefore be off even though you may have enabled it before resetting your machine. The clearing of auto-sync on startup is actually by design to prevent unintentional saving of bad configurations.

JSON Output

You can customize JSON output:

  • "sysjp":true will pretty print and indent the JSON response. This is useful when you type FireStep commands directly.
  • "sysom":1 will emit the JSON responses for each command in a JSON command array. Normally, only the last array response is emitted. This mode can be therefore be useful for debugging JSON command arrays. It might also be useful for certain clients, who can detect the final response by checking the "t" attribute.

General:tst Testing and Diagnosis

When setting up a new CNC system, it is helpful to have a way to exercise steppers precisely for tasks such as verifying pin assignments, tuning stepper driver trimpots, etc. FireStep provides a set of requests that can be used for such hardware testing and diagnosis.

tstrv:[r1,r2,r3,r4] Move steppers by one revolution

Use the tstrv request to repeatedly move stepper(s) by one or more revolutions. This lets you inspect the effect of configuring various axis parameters (e.g., "en", "dh", "mi", "sa", "ud"). Internal axis motor positions will not change during the test, and travel min/max limits will therefore not interrupt motion. However, the test will be interrupted by limit switches. Specifying a positive number of revolutions provides feedback about stepper physical movement for increasing step position. Specifiying negative revolutions causes FireStep to alternate direction on each revolution, which can provide information about direction reversal.

WARNING: This test repeats indefinitely until cancelled or interrupted. 
Disconnect all motor belts before sending this command. Failure to do 
so may damage your machine.
Parameter ✏️ Required Description
r1	| :pencil2:	| Required	| motor 1 revolutions per cycle 
r2	| :pencil2:	| Optional	| motor 2 revolutions per cycle
r3	| :pencil2:	| Optional	| motor 3 revolutions per cycle
r4	| :pencil2:	| Optional	| motor 4 revolutions per cycle

Use the following test to check that all motors are turning clockwise, and that the step pins work. Each motor will spin a different amount so that you can distinguish one motor from another:

{"tstrv":[1,2,3]}

Use the following test to check that the direction pin for each motor functions properly. Each motor will spin a different amount so that you can distinguish one motor from another. The motors will alternate directions:

{"tstrv":[-1,-2,-3]}

tstph: Test PHFeed

The tstph command continuously sends out pulses for traversing a PH5Curve using a PHFeed to all enabled motor axes.

WARNING: This test repeats indefinitely until cancelled or interrupted. 
Disconnect all motor belts before sending this command. Failure to do 
so may damage your machine.
Parameter ✏️ Default Description
lp	| --	| :arrow_right:	| number of loop() calls (for calculating pulses/loop)
mv	| :pencil2:	| sysmv	| maximum velocity (pulses/second).
pp	| --	| :arrow_right:	| peak rate (pulses/second)
pu	| :pencil2:	| 6400	| number of pulses in path
sg	| :pencil2:	| 0	| number of segments in path (0:auto)
ts	| --	| :arrow_right:	| actual stroke traversal time (seconds)
tp	| --	| :arrow_right:	| planned stroke traversal time (seconds)
tv	| :pencil2:	| systv	| seconds to reach maximum velocity 
  • ➡️ output value only

You can accelerate faster by decreasing tv and/or increasing mv. Practically speaking, conventional steppers become erratic at 20-22kHz without any load (performance degrades with increased load). Likewise, decreasing tv leads to greater forces, roughness and loss of precision. FireStep will automatically adjust actual stroke velocity and acceleration time according to stroke length. Specifically, shorter strokes will maintain the maximum acceleration force implied by mv/tv, even though they may never attain the specified maximum velocity.

Use the following test for tuning your stepper driver trimpots. The varying velocity of the PH curve used by this test will exercise the stepper thoroughly. You can also use this test to maximum no-load velocity for each stepper.

{"tstph":{"tv":0.35,"mv":16000}}

tstsp:[p1,p2,p3,p4] Send microstep pulses

Send specified number of pulses to given motors. This can help diagnose pulse delay issues.

Parameter ✏️ Required Description
p1	| :pencil2:	| Required	| number of pulses to send to motor 1
p2	| :pencil2:	| Optional	| number of pulses to send to motor 2
p3	| :pencil2:	| Optional	| number of pulses to send to motor 3
p4	| :pencil2:	| Optional	| number of pulses to send to motor 4

For example, you can send a single pulse to the second motor:

{"tstsp":[0,1]}

Motion:dvs Delta-Velocity Stroke

The Delta V Stroke moves along a path of up to 4 axes determined by the motor-axis mappings. The dvs request is difficult to construct manually. It is normally generated by host software that computes the velocity increments for the stroke. See mov for a human-readable alternative.

Attribute ✏️ Default Description
sc	| :pencil2:	| 1	| delta velocity scale
us	| :pencil2:	| required	| planned traversal microseconds
dp	| :pencil2:	| (optional)	| final relative microstep displacement (JSON array of 1-4 elements). Useful for exact final positioning if scale > 1
1	| :pencil2:	| required	| motor 1 JSON array of velocity deltas
2	| :pencil2:	| (optional)	| motor 2 array of velocity deltas
3	| :pencil2:	| (optional)	| motor 3 array of velocity deltas
4	| :pencil2:	| (optional)	| motor 4 array of velocity deltas
x	| :pencil2:	| (optional)	| array of velocity deltas
y	| :pencil2:	| (optional)	| array of velocity deltas
z	| :pencil2:	| (optional)	| array of velocity deltas
a	| :pencil2:	| (optional)	| array of velocity deltas
b	| :pencil2:	| (optional)	| array of velocity deltas
c	| :pencil2:	| (optional)	| array of velocity deltas

Notes:

  • When multiple axes are specified, they must have equal-length velocity vectors
  • Specific axes (e.g., "x") can be used in place of motor specifications provided that they are mapped to motors
  • The JSON response has the same structure except that the motor/axis attributes are replaced by the total step displacement

For example, if the x-axis is mapped, you can move along the x-axis in 0.1 seconds using a specific acceleration profile:

{"dvs":{"us":0.1,"x":[10,50,0,-10,-50]}}
Array of Velocity Deltas

The array of velocity deltas can be specified as:

  1. A JSON array (e.g., [10,20])
  2. A JSON hex string (e.g., "0a14")

The first form is human readable but so verbose that long strokes having many segments may not fit in the serial buffer. Always use the second form for machine-generated commands.

Motion:hom Home Motor(s)

The hom request moves of 1,2,3 or 4 motors simultaneously to their individual axis homing limit switches with configurable latch backoff. Homing pulses are sent in pulse groups (i.e., syshp) that should mesh evenly with stepper driver microsteps for maximum smoothness (powers of two work well). Homed axes will have their positions set to the axis home coordinate (e.g., xho). Un-homed axes will be unchanged.

Attribute ✏️ Default Description
1	| :pencil2:	| 1ho	| motor 1 home position
2	| :pencil2:	| 2ho	| motor 2 home position
3	| :pencil2:	| 3ho	| motor 3 home position
4	| :pencil2:	| 4ho	| motor 4 home position
x	| :pencil2:	| xho	| X-axis home position
y	| :pencil2:	| yho	| Y-axis home position
z	| :pencil2:	| zho	| Z-axis home position
a	| :pencil2:	| aho	| A-axis home position
b	| :pencil2:	| bho	| B-axis home position
c	| :pencil2:	| cho	| C-axis home position

NOTES:

  • Homing ignores axis minimum travel limits
  • Increase axis sd attribute to slow down search speed
  • Increase system hp attribute to increase search speed

Example: home all enabled motors simultaneously and return their home coordinates:

{"hom":""}

Example: home x-axis and set x-home coordinate to 10:

{"homx":10}

Motion:mov Move To Position

FireStep supports simple direct motion via the mov request, which can be used for positioning to a specified coordinate. The mov request is not designed for continuous complex path traversal. However, it can be used to specify single moves easily.

The mov command is implemented differently for each machine topology (see systo):

Motion:prb Probe To Position

FireStep can probe from the current position to a designated position, stopping when the limit switch on the specified probe pin triggers. The result returned specifies the stepper coordinates at which the limit switch triggered. If the probe never contacts a surface, the command result status s will be STATUS_PROBE_FAILED.

Probes are directional and you can use any motor/axis combination to specify the exact probing movement. For best results, choose a probe destination that is orthogonal to the probed surface.

The prb command is implemented differently for each machine topology (see systo):

See Also