The Gcode widget shows you the Gcode loaded into your workspace, lets you send it to the serial port, get back per line status, see an estimated length of time to execute the Gcode, navigate to the XYZ position of a specific line, and much more.
All ChiliPeppr widgets/elements are defined using cpdefine() which is a method that mimics require.js. Each defined object must have a unique ID so it does not conflict with other ChiliPeppr widgets.
Item | Value |
---|---|
ID | com-chilipeppr-widget-gcode |
Name | Widget / Gcode v7 |
Description | The Gcode widget shows you the Gcode loaded into your workspace, lets you send it to the serial port, get back per line status, see an estimated length of time to execute the Gcode, navigate to the XYZ position of a specific line, and much more. |
chilipeppr.load() URL | http://raw.githubusercontent.com/lutorm/widget-gcodelist/master/auto-generated-widget.html |
Edit URL | http://ide.c9.io/lutorm/gcodelist |
Github URL | http://github.com/lutorm/widget-gcodelist |
Test URL | https://preview.c9users.io/lutorm/gcodelist/widget.html |
You can use the code below as a starting point for instantiating this widget inside a workspace or from another widget. The key is that you need to load your widget inlined into a div so the DOM can parse your HTML, CSS, and Javascript. Then you use cprequire() to find your widget's Javascript and get back the instance of it.
// Inject new div to contain widget or use an existing div with an ID
$("body").append('<' + 'div id="myDivWidgetGcode"><' + '/div>');
chilipeppr.load(
"#myDivWidgetGcode",
"http://raw.githubusercontent.com/lutorm/widget-gcodelist/master/auto-generated-widget.html",
function() {
// Callback after widget loaded into #myDivWidgetGcode
// Now use require.js to get reference to instantiated widget
cprequire(
["inline:com-chilipeppr-widget-gcode"], // the id you gave your widget
function(myObjWidgetGcode) {
// Callback that is passed reference to the newly loaded widget
console.log("Widget / Gcode v7 just got loaded.", myObjWidgetGcode);
myObjWidgetGcode.init();
}
);
}
);
This widget/element publishes the following signals. These signals are owned by this widget/element and are published to all objects inside the ChiliPeppr environment that listen to them via the chilipeppr.subscribe(signal, callback) method. To better understand how ChiliPeppr's subscribe() method works see amplify.js's documentation at http://amplifyjs.com/api/pubsub/
Signal | Description |
---|---|
/com-chilipeppr-widget-gcode/onplay | When user hits play button |
/com-chilipeppr-widget-gcode/onpause | When user hits pause button. The payload is a true/false boolean indicating whether it is a pause or an unpause. This event also fires if a pause is triggered for a different reason like from an M6 command. In that case the 2nd paramater of the payload contains a string of "m6". |
/com-chilipeppr-widget-gcode/onstop | When user hits stop button |
/com-chilipeppr-widget-gcode/resize | When we resize in case any other widget wants to listen to that so it can resize itself. |
/com-chilipeppr-widget-gcode/done | When we are done sending all gcode. We send a payload of how many lines sent and time for job. |
/com-chilipeppr-widget-gcode/recvGcode | We publish this signal after you send in a /requestGcode signal. We will send you the Gcode in this widget including metadata. The payload contains { lines: [(your lines as a 0-based array)], metadata: [{isSent: bool, isQueued: bool, isWritten: bool, isComplete: bool}] }. The lines are a 0-based array so if you are trying to line them up with the numbers in the Gcode widget, line 1 corresponds to lines[0] in the array. The metadata is an array that matches the lines array but contains data on the send state of each line. You are being sent an exact reference to that array so if you modify it, you are modifying the actual Gcode and Metadata in this widget. You have been warned. |
/com-chilipeppr-widget-gcode/onChiliPepprPause | This event is published during the play operation when the chilipeppr_pause string is found inside the Gcode. You can place a chilipeppr_pause string anywhere in the Gcode inside a comment and it will tell ChiliPeppr to pause sending when it hits that line. The pause acts much like the M6 tool change pause but it is a pause just for ChiliPeppr to interpret and not the CNC controller. This technique was implemented for synchronizing a secondary microcontroller that could trigger an out-of-band event like a laser solderer, or a solder paste dispenser, or some other control that had to trigger at a specific Gcode line. This specific event is not very helpful to subscribe to because it does not have as much meaning as onChiliPepprPauseOnComplete or onChiliPepprPauseOnExecute. Those two events are triggered when the CNC controller actually gets to the specifically paused line and that is where you would synchronize from. The onChiliPepprPauseOnComplete is triggered by all CNC controllers but is not a very accurate event as most controllers have a planner buffer which means this line is not really what is being executed but will be executed in the very near future at an unknown time. The onChiliPepprPauseOnExecute is a highly accurate event currently only available from TinyG that tells you the CNC controller is exactly executing this line at this moment. A sample macro is available that shows how to use the onChiliPepprPause events. |
/com-chilipeppr-widget-gcode/onChiliPepprPauseOnExecute | This event is published when the line that contained the chilipeppr_pause command inside a comment has actually executed in the CNC controller. This is currently supported by TinyG. Grbl does not support this. The payload of the event includes the line number and the line of gcode that was just executed like { line: 8, gcode: "(chilipeppr_pause solder drop 4)" } |
/com-chilipeppr-widget-gcode/onChiliPepprPauseOnComplete | This event is published when the line that contained the chilipeppr_pause command inside a comment has been actually sent to the CNC controller. If your controller supports onExecute events then it is recommended you use onChiliPepprPauseOnExecute instead because it is much more accurate. To help explain the difference between onChiliPepprPauseOnExecute and onChiliPepprPauseOnComplete, for the onChiliPepprPauseOnComplete event if 1000 lines were buffered to SPJS and this is the 1000th line that this event will only trigger as the 1000th line is dished up to the CNC controller. This gives an event that can be pivoted off of. If the CNC controller has a planner buffer that can hold around 8 moves, you will get this event only when this line of gcode enters the planner buffer. So you are getting the event 8 moves ahead. To make this work in the real world you should likely pause by a length of time to ensure all commands are done or issue a double check command to your CNC controller that sends you back a response where you can ensure the controller is in the correct state. The payload of the event includes the line number and the line of gcode that was just completed like { line: 8, gcode: "(chilipeppr_pause solder drop 4)" } |
This widget/element subscribes to the following signals. These signals are owned by this widget/element. Other objects inside the ChiliPeppr environment can publish to these signals via the chilipeppr.publish(signal, data) method. To better understand how ChiliPeppr's publish() method works see amplify.js's documentation at http://amplifyjs.com/api/pubsub/
Signal | Description |
---|---|
/com-chilipeppr-widget-gcode/requestGcode | Send in this signal and we will publish back out a /recvGcode signal. See /recvGcode for further info. |
/com-chilipeppr-widget-gcode/stop | Send in this signal to stop the gcode playing. Equivalent to hitting the stop button. |
/com-chilipeppr-widget-gcode/play | Send in this signal to play the gcode. Equivalent to hitting the play button. |
/com-chilipeppr-widget-gcode/pause | Send in this signal to pause/unpause the gcode. Equivalent to hitting the pause button. |
/com-chilipeppr-widget-gcode/jumpToLine | Send in an integer of what line to jump to in the Gcode widget. The index you send it should match what visually shows in the Gcode widget, i.e. line 1 should be sent as a 1 (even though the backing array is index 0). |
This widget/element publishes to the following signals that are owned by other objects. To better understand how ChiliPeppr's subscribe() method works see amplify.js's documentation at http://amplifyjs.com/api/pubsub/
Signal | Description |
---|---|
/com-chilipeppr-widget-gcode/com-chilipeppr-widget-3dviewer/gcodeline | When a user clicks a line of gcode. We'll send the gcode and the line number so the subscriber can sync to what we're sending, i.e. a 3D viewer that wants to hilite the line representing this command. The format of the signal data is something like {line: 12, gcode: "G1 F300.0 Z0.0"}. |
/com-chilipeppr-widget-gcode/com-chilipeppr-elem-flashmsg/flashmsg | Send a flash message on certain events. In particular, we send a flash message when a comment line is hit. We also send a flash message when the gcode is done sending. |
This widget/element publishes to the following signals that are owned by other objects. To better understand how ChiliPeppr's publish() method works see amplify.js's documentation at http://amplifyjs.com/api/pubsub/
Signal | Description |
---|---|
/com-chilipeppr-widget-gcode/com-chilipeppr-elem-dragdrop/ondropped | We watch for a drag drop event of the Gcode file. The payload of the signal contains the localStorage object which is just the string representing the entire Gcode file. |
/com-chilipeppr-widget-gcode/com-chilipeppr-interface-cnccontroller/plannerpause | We need to pause when planner tells us. |
/com-chilipeppr-widget-gcode/com-chilipeppr-interface-cnccontroller/plannerresume | We need to resume when planner tells us. |
/com-chilipeppr-widget-gcode/com-chilipeppr-interface-cnccontroller/feedhold | We need to place a manual pause if we see the e-stop hit. That way user can start where they left off. |
/com-chilipeppr-widget-gcode/com-chilipeppr-interface-cnccontroller/onExecute | This signal is sent to us by the CNC controller widget. The payload looks like { line: 234 }. It is ONLY sent if the CNC controller widget is able to determine an executed state. Please refer to your CNC controller's publish documenation to determine if this signal will be published and thus whether this Gcode widget will see these events. |
The table below shows, in order, the methods and properties inside the widget/element.
Method / Property | Type | Description |
---|---|---|
id | string | "com-chilipeppr-widget-gcode" |
url | string | "http://raw.githubusercontent.com/lutorm/widget-gcodelist/master/auto-generated-widget.html" |
fiddleurl | string | "http://ide.c9.io/lutorm/gcodelist" |
githuburl | string | "http://github.com/lutorm/widget-gcodelist" |
testurl | string | "http://gcodelist-lutorm.c9users.io/widget.html" |
name | string | "Widget / Gcode v7" |
desc | string | "The Gcode widget shows you the Gcode loaded into your workspace, lets you send it to the serial port, get back per line status, see an estimated length of time to execute the Gcode, navigate to the XYZ position of a specific line, and much more." |
publish | object | Please see docs above. |
subscribe | object | Please see docs above. |
foreignSubscribe | object | Please see docs above. |
foreignPublish | object | Please see docs above. |
fileLines | object | |
metaLines | object | |
metaObj | object | |
linesComplete | object | |
linesToShow | number | |
linesToShowMax | number | |
delayPerLine | number | |
lineNumbersOnByDefault | boolean | |
isDirtyUnits | boolean | |
init | function | function (settings) |
setupJumpToLine | function | function () |
onJumpToLine | function | function (evt) |
getEstimates | function | function () |
setupStatusSteps | function | function () |
setupPlayPauseStopPubSub | function | function () |
setupSendGcodePubSub | function | function () |
publishGcode | function | function () |
options | object | |
setupOptionsModal | function | function () |
saveOptionsModal | function | function () |
showOptionsModal | function | function () |
hideOptionsModal | function | function () |
setupToolChangeModal | function | function () |
isInToolChangeMode | boolean | |
toolChangeRepositionCmd | object | |
toolChangeCmd | object | |
showToolChangeModal | function | function (linegcode, source) |
hideToolChangeModal | function | function () |
hideToolChangeDiv | function | function (wasPaused) |
showUOMModal | function | function (txt, info, skipLocalStore) |
hideUOMModal | function | function () |
setUOM | function | function (txt, info, skipLocalStore, units) |
getCoordFromControllerRecvCallback | object | |
getCoordFromController | function | function (callback) |
getCoordFromControllerRecv | function | function (coords) |
getMotorConfigCallback | function | function (data) |
getXyzCoordsForLineRecv3dObjCallback | object | |
getXyzCoordsForLineRecv3dObjLine | object | |
obj3d | object | |
getXyzCoordsForLine | function | function (line, callback) |
getXyzCoordsForLineRecv3dObj | function | function (obj3d) |
btnSetup | function | function () |
onFeedhold | function | function () |
pauseBtnIcon | object | |
onPlannerPause | function | function () |
onPlannerResume | function | function () |
isBodyShowing | boolean | |
showBody | function | function (evt) |
hideBody | function | function (evt) |
forkSetup | function | function () |
setupResizeable | function | function () |
setupFeedrateAdjust | function | function () |
feedrateDisable | function | function () |
feedrateEnable | function | function () |
feedrateUp | function | function () |
feedrateDown | function | function () |
feedrateReset | function | function () |
feedrateAdjust | function | function () |
feedrateUpdateDom | function | function () |
onRecv3dObjectPerRowTd | object | |
isShowingCoords | boolean | |
isInsideCoords | boolean | |
onRecv3dObjectPerRow | function | function (obj3d) |
setNewStartPosition | function | function (indx, tr) |
showXyzCoordsForRow | function | function (td) |
setupRowTrigger | function | function () |
timeStart | object | |
timeEnd | object | |
isPlayStep | boolean | |
isPlaying | boolean | |
isPaused | boolean | |
isPausedByPlanner | boolean | |
preUploadRemainder | number | |
currentLine | object | |
onPauseByPlanner | function | function (event) |
onStepBack | function | function (evt) |
onStepFwd | function | function (evt) |
onPause | function | function (event, isFromM6, isFromCpPause) |
resetMetaDataQueueWriteComplete | function | function (indexToStartAfter) |
onStop | function | function (event) |
isResetMetaBeforePlay | boolean | |
isJobDonePubSubSent | boolean | |
onPlay | function | function (event) |
isInMultiLineMode | boolean | |
multiLines | number | |
onPlayMultiLine | function | function () |
onPreUpload | function | function (numToUpload) |
preUploadGang | string | |
preUploadGangArr | object | |
onPreUploadCallback | function | function (data) |
statEls | object | |
isPlayNextLineNoScroll | boolean | |
onPlayNextLine | function | function () |
onChiliPepprPause | function | function (meta) |
onChiliPepprPauseOnComplete | function | function (meta) |
onChiliPepprPauseOnExecute | function | function (meta) |
toHHMMSS | function | function (secs) |
gotoLine | function | function (linenum, isMarkSent) |
fileInfo | object | |
onFileLoaded | function | function (txt, info, skipLocalStore) |
resendGcodeToWorkspace | function | function () |
jumpToTop | function | function () |
jumpToLine | function | function (linenum) |
setupJumpScroll | function | function () |
preSetupInfiniteScroll | function | function (doTopScrollOffset) |
infiniteScrollDestroy | function | function () |
setupInfiniteScroll | function | function (doTopScrollOffset) |
showingStartIndex | number | |
showingEndIndex | number | |
showingStats | function | function () |
setupOnQueueWriteCompletePubSub | function | function () |
jsonOnSend | function | function (data) |
onQueue | function | function (data) |
onWrite | function | function (data) |
displayLine | function | function (index, chilipepprPauseFun) |
onComplete | function | function (data) |
onError | function | function (data) |
isInExecuteScrollToMode | boolean | |
lastLineMarkedExecuted | object | |
onExecute | function | function (data) |
updateRowQueueStats | function | function (linenum) |
updateRowQueueStatsEl | function | function (rowEl) |
prependRows | function | function (endIndx) |
appendRows | function | function (startIndx, skipWaypoint) |
removeAllRows | function | function () |
removeRowsFromStart | function | function () |
removeRowsFromEnd | function | function () |
feedrateEl | object | |
getFeedrateMarkup | function | function (html, isJustGettingRaw) |
getCommentMarkup | function | function (html) |
getTooltipMarkup | function | function (txt) |
lastElemIndex | object | |
cleanupHilites | function | function () |
cleanupDomElem | function | function (elem) |
parseGcodeForDomElem | function | function (elem, doTooltip) |
parseGcode | function | function () |
createGcodeDesc | function | function () |
gcodeIsLoaded | boolean | |
gcodeData | object | |
gcodeLoad | function | function (callback, context) |
obj3dmeta | object | |
userCallbackForGet3dObj | object | |
get3dObj | function | function (callback) |
get3dObjCallback | function | function (data, meta) |
calcEstimatedRemain | function | function (indexOfLineAt) |
ChiliPeppr is a hardware fiddle, meaning it is a website that lets you easily create a workspace to fiddle with your hardware from software. ChiliPeppr provides a Serial Port JSON Server that you run locally on your computer, or remotely on another computer, to connect to the serial port of your hardware like an Arduino or other microcontroller.
You then create a workspace at ChiliPeppr.com that connects to your hardware by starting from scratch or forking somebody else's workspace that is close to what you are after. Then you write widgets in Javascript that interact with your hardware by forking the base template widget or forking another widget that is similar to what you are trying to build.
ChiliPeppr is massively capable such that the workspaces for TinyG and Grbl CNC controllers have become full-fledged CNC machine management software used by tens of thousands.
ChiliPeppr has inspired many people in the hardware/software world to use the browser and Javascript as the foundation for interacting with hardware. The Arduino team in Italy caught wind of ChiliPeppr and now ChiliPeppr's Serial Port JSON Server is the basis for the Arduino's new web IDE. If the Arduino team is excited about building on top of ChiliPeppr, what will you build on top of it?