Conditional G Code - RJ TextEd Syntax file.



  • I am in the process of creating a syntax file for RJ TextEd which will highlight the text and also allow for code folding and auto completion.
    It's still a work in progress and I need to ensure that I have the hierarchical structure correct in a couple of places.

    @dc42 , if you can contact me by DM I can email or send the files for you to check over.

    Here are a couple of screen shots.

    Auto completion of conditional G Code object model
    screenshot2.png

    Auto completion of G & M Codes (only about half way through these)
    You can see that it will place the G Code with options and a hyperlink to the relevant section of the dozuki.
    screenshot1.png


  • administrators

    Looks good! I don't use or know RJ TextEd, so I'll decline your offer of files to look over. Perhaps someone else can help you?

    I use Notepad++ for editing GCode files, so I'd be interested in a configuration for syntax highlighting, folding etc. for that program with GCode files.

    Perhaps we should create a new github repository to host this sort of thing?



  • @dc42
    RJ TextEd is a free text editor similar to Notepad ++
    The main thing I want to clarify is that I have the hierarchical structure correct as when I run M409 I naturally only get the values for my priinter.
    i.e. One extruder, no tool changer, heated chamber etc etc.

    You should be able to see how I've interpreted the output here.
    Objects with square brackets [] assume an extruder, heater number etc will be inserted.
    classes.png

    classes2.png


  • administrators

    If you are getting the editor to recognise each part of the object model, that will change as I add more of it.
    Here's a response from M409 in my current firmware build, on a delta printer:

    {"key":"","flags":"","result":{"boards":[{"firmwareFileName":"Duet2CombinedFirmware.bin","firmwareVersion":"3.01-beta2","iapFileNameSD":"Duet2CombinedIAP.bin","mcuTemp":{"current":22.2,"max":23.2,"min":9.7},"name":"Duet 2 WiFi","shortName":"2WiFi","vIn":{"current":24.4,"max":24.8,"min":24.3}}],"fans":[{"actualValue":0,"blip":0.10,"max":1.00,"min":0.10,"name":"","requestedValue":0,"rpm":-1,"thermostatic":{"control":false}},{"actualValue":0,"blip":0.10,"max":1.00,"min":0.10,"name":"","requestedValue":1.00,"rpm":-1,"thermostatic":{"control":true,"heaters":[1],"highTemperature":45.0,"lowTemperature":45.0}},{"actualValue":0,"blip":0.10,"max":1.00,"min":0.30,"name":"","requestedValue":1.00,"rpm":-1,"thermostatic":{"control":true,"heaters":[10,11],"highTemperature":55.0,"lowTemperature":45.0}}],"heat":{"coldExtrudeTemperature":160.0,"coldRetractTemperature":90.0,"heaters":[{"current":21.2,"max":125.0,"min":-273.1,"sensor":0,"state":"off"},{"current":21.5,"max":290.0,"min":-273.1,"sensor":1,"state":"off"}],"sensors":[{"lastReading":21.2,"name":"","type":"Thermistor"},{"lastReading":21.5,"name":"","type":"PT100 (MAX31865)"},null,null,null,null,null,null,null,null,{"lastReading":22.1,"name":"Mcu","type":"Microcontroller embedded temperature sensor"},{"lastReading":0,"name":"Drivers","type":"Stepper driver temperature warnings"}]},"job":{"file":{"filament":[],"firstLayerHeight":0,"height":0,"layerHeight":0,"numLayers":0,"size":0},"layer":0,"timesLeft":null},"move":{"axes":[{"acceleration":3000.0,"drivers":["0"],"homed":false,"jerk":600.0,"letter":"X","machinePosition":0,"max":150.0,"min":-150.0,"speed":15000.0,"userPosition":0,"visible":true,"workplaceOffsets":[0,0,0,0,0,0,0,0,0]},{"acceleration":3000.0,"drivers":["1"],"homed":false,"jerk":600.0,"letter":"Y","machinePosition":0,"max":150.0,"min":-150.0,"speed":15000.0,"userPosition":0,"visible":true,"workplaceOffsets":[0,0,0,0,0,0,0,0,0]},{"acceleration":3000.0,"drivers":["2"],"homed":false,"jerk":600.0,"letter":"Z","machinePosition":470.070,"max":470.1,"min":0,"speed":15000.0,"userPosition":470.070,"visible":true,"workplaceOffsets":[0,0,0,0,0,0,0,0,0]}],"calibrationDeviation":{"deviation":0,"mean":0},"currentMove":{"acceleration":0,"deceleration":0,"requestedSpeed":0,"topSpeed":0},"daa":{"enabled":false,"minimumAcceleration":10.0,"period":0.0},"extruders":[{"driver":"3","factor":100.0,"nonlinear":{"a":0.015,"b":0.001,"upperLimit":0.20},"pressureAdvance":0.20},{"driver":"4","factor":100.0,"nonlinear":{"a":0,"b":0,"upperLimit":0.20},"pressureAdvance":0}],"idle":{"factor":0.3,"timeout":30.0},"initialDeviation":{"deviation":0,"mean":0},"kinematics":{"deltaRadius":180.679,"homedHeight":470.070,"name":"Linear delta","printRadius":150.0,"towers":[null,null,null],"xTilt":0.001,"yTilt":-0.001},"meshDeviation":{"deviation":0,"mean":0},"printingAcceleration":10000.0,"speedFactor":100.0,"travelAcceleration":10000.0,"workspaceNumber":1},"network":{"interfaces":[{"actualIP":"192.168.1.126","gateway":"0.0.0.0","subnet":"0.255.255.255","type":"wifi"}]},"sensors":{"endstops":[{"triggered":false,"type":"inputPin"},{"triggered":false,"type":"inputPin"},{"triggered":false,"type":"inputPin"}],"probes":[{"calibrationTemperature":25.0,"disablesHeaters":false,"diveHeight":6.0,"maxProbeCount":5,"offsets":[0,0],"recoveryTime":0.2,"speed":16.7,"temperatureCoefficient":0,"threshold":100,"tolerance":0.020,"travelSpeed":200.0,"triggerHeight":-0.100,"type":8,"value":[0]}]},"state":{"currentTool":-1,"machineMode":"FFF","status":"Idle","upTime":637},"tools":[{"active":[0],"axes":[[0],[1]],"extruders":[0],"fans":[0],"heaters":[1],"mix":[1.00],"name":"","offsets":[0,0,0],"standby":[0],"state":"off"},{"active":[0],"axes":[[0],[1]],"extruders":[1],"fans":[0],"heaters":[2],"mix":[1.00],"name":"","offsets":[0,0,0],"standby":[0],"state":"off"}]}}
    

    Paste it into https://codebeautify.org/jsonviewer to make sense of it.


  • administrators

    ... and here's one from a Cartesian machine with additional axes:

    {"key":"","flags":"","result":{"boards":[{"firmwareFileName":"Duet3Firmware_MB6HC.bin","firmwareVersion":"3.01-beta2","iapFileNameSBC":"Duet3_SBCiap_MB6HC.bin","iapFileNameSD":"Duet3_SDiap_MB6HC.bin","mcuTemp":{"current":30.7,"max":30.9,"min":14.3},"name":"Duet 3 MB6HC","shortName":"MB6HC","v12":{"current":12.1,"max":12.2,"min":12.1},"vIn":{"current":24.1,"max":24.2,"min":24.0}}],"fans":[{"actualValue":0,"blip":0.10,"max":1.00,"min":0.10,"name":"Print Fan","requestedValue":0,"rpm":-1,"thermostatic":{"control":false}},{"actualValue":0,"blip":0.10,"max":1.00,"min":0.49,"name":"Hot End Fan","requestedValue":1.00,"rpm":-1,"thermostatic":{"control":true,"heaters":[1],"highTemperature":60.0,"lowTemperature":60.0}}],"heat":{"coldExtrudeTemperature":160.0,"coldRetractTemperature":90.0,"heaters":[{"current":22.3,"max":100.0,"min":-273.1,"sensor":0,"state":"off"},{"current":22.3,"max":280.0,"min":-273.1,"sensor":1,"state":"active"}],"sensors":[{"lastReading":22.3,"name":"Bed Temp","type":"remote"},{"lastReading":22.3,"name":"Hot End Temp","type":"remote"}]},"job":{"file":{"filament":[],"firstLayerHeight":0,"height":0,"layerHeight":0,"numLayers":0,"size":0},"layer":0,"timesLeft":null},"move":{"axes":[{"acceleration":1000.0,"drivers":["3.2","0.0","0.2"],"homed":false,"jerk":900.0,"letter":"X","machinePosition":0,"max":344.0,"min":0,"speed":50000.0,"userPosition":0,"visible":true,"workplaceOffsets":[0,0,0,0,0,0,0,0,0]},{"acceleration":1000.0,"drivers":["3.1","0.1","0.3"],"homed":false,"jerk":900.0,"letter":"Y","machinePosition":0,"max":364.0,"min":0,"speed":35000.0,"userPosition":0,"visible":true,"workplaceOffsets":[0,0,0,0,0,0,0,0,0]},{"acceleration":100.0,"drivers":["3.0"],"homed":false,"jerk":100.0,"letter":"Z","machinePosition":0,"max":760.0,"min":0,"speed":450.0,"userPosition":0,"visible":true,"workplaceOffsets":[0,0,0,0,0,0,0,0,0]},{"acceleration":1000.0,"drivers":["0.0"],"homed":false,"jerk":900.0,"letter":"U","machinePosition":0,"max":344.0,"min":0,"speed":50000.0,"userPosition":0,"visible":true,"workplaceOffsets":[0,0,0,0,0,0,0,0,0]},{"acceleration":1000.0,"drivers":["0.1"],"homed":false,"jerk":900.0,"letter":"V","machinePosition":0,"max":364.0,"min":0,"speed":35000.0,"userPosition":0,"visible":true,"workplaceOffsets":[0,0,0,0,0,0,0,0,0]},{"acceleration":1000.0,"drivers":["0.2"],"homed":false,"jerk":900.0,"letter":"A","machinePosition":0,"max":344.0,"min":0,"speed":50000.0,"userPosition":0,"visible":true,"workplaceOffsets":[0,0,0,0,0,0,0,0,0]},{"acceleration":1000.0,"drivers":["0.3"],"homed":false,"jerk":900.0,"letter":"B","machinePosition":0,"max":364.0,"min":0,"speed":35000.0,"userPosition":0,"visible":true,"workplaceOffsets":[0,0,0,0,0,0,0,0,0]}],"calibrationDeviation":{"deviation":0,"mean":0},"currentMove":{"acceleration":0,"deceleration":0,"requestedSpeed":0,"topSpeed":0},"daa":{"enabled":false,"minimumAcceleration":10.0,"period":0.0},"extruders":[{"driver":"1.0","factor":100.0,"nonlinear":{"a":0,"b":0,"upperLimit":0.20},"pressureAdvance":0.40},{"driver":"1.1","factor":100.0,"nonlinear":{"a":0,"b":0,"upperLimit":0.20},"pressureAdvance":0.40},{"driver":"1.2","factor":100.0,"nonlinear":{"a":0,"b":0,"upperLimit":0.20},"pressureAdvance":0.40},{"driver":"2.0","factor":100.0,"nonlinear":{"a":0,"b":0,"upperLimit":0.20},"pressureAdvance":0},{"driver":"2.1","factor":100.0,"nonlinear":{"a":0,"b":0,"upperLimit":0.20},"pressureAdvance":0.40},{"driver":"2.2","factor":100.0,"nonlinear":{"a":0,"b":0,"upperLimit":0.20},"pressureAdvance":0.40}],"idle":{"factor":0.2,"timeout":30.0},"initialDeviation":{"deviation":0,"mean":0},"kinematics":{"forwardMatrix":[[0.500,0.500,0,0,0,0,0],[0.500,-0.500,0,0,0,0,0],[0,0,1.000,0,0,0,0],[0,0,0,0.500,0.500,0,0],[0,0,0,0.500,-0.500,0,0],[0,0,0,0,0,0.500,0.500],[0,0,0,0,0,0.500,-0.500]],"inverseMatrix":[[0.500,0.500,0,0,0,0,0],[0.500,-0.500,0,0,0,0,0],[0,0,1.000,0,0,0,0],[0,0,0,0.500,0.500,0,0],[0,0,0,0.500,-0.500,0,0],[0,0,0,0,0,0.500,0.500],[0,0,0,0,0,0.500,-0.500]],"name":"CoreXYUV"},"meshDeviation":{"deviation":0,"mean":0},"printingAcceleration":10000.0,"speedFactor":100.0,"travelAcceleration":10000.0,"workspaceNumber":1},"network":{"interfaces":[{"actualIP":"192.168.1.83","gateway":"192.168.1.254","subnet":"255.255.255.0","type":"ethernet"}]},"sensors":{"endstops":[{"triggered":true,"type":"inputPin"},{"triggered":true,"type":"inputPin"},{"triggered":true,"type":"inputPin"},{"triggered":true,"type":"inputPin"},{"triggered":true,"type":"inputPin"},{"triggered":true,"type":"inputPin"},{"triggered":true,"type":"inputPin"}],"probes":[]},"state":{"currentTool":0,"machineMode":"FFF","status":"Idle","upTime":780},"tools":[{"active":[0],"axes":[[0],[1]],"extruders":[0,1,2,4,5],"fans":[0],"heaters":[1],"mix":[1.00,0,0,0,0],"name":"Black","offsets":[0,0,0,0,0,0,0],"standby":[0],"state":"active"},{"active":[0],"axes":[[0],[1]],"extruders":[0,1,2,4,5],"fans":[0],"heaters":[1],"mix":[0,1.00,0,0,0],"name":"Red","offsets":[0,0,0,0,0,0,0],"standby":[0],"state":"off"},{"active":[0],"axes":[[0],[1]],"extruders":[0,1,2,4,5],"fans":[0],"heaters":[1],"mix":[0,0,1.00,0,0],"name":"Yellow","offsets":[0,0,0,0,0,0,0],"standby":[0],"state":"off"},{"active":[0],"axes":[[0],[1]],"extruders":[0,1,2,4,5],"fans":[0],"heaters":[1],"mix":[0,0,0,1.00,0],"name":"Blue","offsets":[0,0,0,0,0,0,0],"standby":[0],"state":"off"},{"active":[0],"axes":[[0],[1]],"extruders":[0,1,2,4,5],"fans":[0],"heaters":[1],"mix":[0,0,0,0,1.00],"name":"White","offsets":[0,0,0,0,0,0,0],"standby":[0],"state":"off"},{"active":[0],"axes":[[0],[1]],"extruders":[0,1,2,4,5],"fans":[0],"heaters":[1],"mix":[0,0.50,0.50,0,0],"name":"Orange","offsets":[0,0,0,0,0,0,0],"standby":[0],"state":"off"},{"active":[0],"axes":[[0],[1]],"extruders":[0,1,2,4,5],"fans":[0],"heaters":[1],"mix":[0,0.50,0,0.50,0],"name":"Purple","offsets":[0,0,0,0,0,0,0],"standby":[0],"state":"off"},{"active":[0],"axes":[[0],[1]],"extruders":[0,1,2,4,5],"fans":[0],"heaters":[1],"mix":[0,0,0.50,0.50,0],"name":"Green","offsets":[0,0,0,0,0,0,0],"standby":[0],"state":"off"},{"active":[0],"axes":[[0],[1]],"extruders":[0,1,2,4,5],"fans":[0],"heaters":[1],"mix":[0,0.50,0,0,0.50],"name":"Pink","offsets":[0,0,0,0,0,0,0],"standby":[0],"state":"off"}]}}
    


  • @dc42
    Thanks, those have quite a bit more in them which I've added.
    Some of the properties which are accessed by an array aren't entirely clear to me how they are intended to be read, or if there are new properties going to be added.
    For example,

    • Is there actually an array of extruders? (as there are in offsets)
    • Is extruders[0] returning a boolean value , or will there be further parameters/classes added?
    • Is there the possibility for "extruders[0]

    Likewise for "mix", "offsets" etc?

    list.JPG

    I don't want to burn up too much of the time you could be spending coding the object model, but if I'm clear on how it will progress I think this will help people utilise it more easily.


  • administrators

    Yes, move.extruders is an array, as in this example (generated using the RRF 3.01beta 2 that I released yesterday):

    {"key":"","flags":"99","result":{"boards":[{"firmwareFileName":"Duet2CombinedFirmware.bin","firmwareVersion":"3.01-beta2","iapFileNameSD":"Duet2CombinedIAP.bin","mcuTemp":{"current":14.1,"max":14.4,"min":9.2},"name":"Duet 2 WiFi","shortName":"2WiFi","vIn":{"current":24.5,"max":24.7,"min":24.4}}],"fans":[{"actualValue":0,"blip":0.10,"max":1.00,"min":0.10,"name":"","requestedValue":0,"rpm":-1,"thermostatic":{"control":false}},{"actualValue":0,"blip":0.10,"max":1.00,"min":0.10,"name":"","requestedValue":1.00,"rpm":-1,"thermostatic":{"control":true,"heaters":[1],"highTemperature":45.0,"lowTemperature":45.0}},{"actualValue":0,"blip":0.10,"max":1.00,"min":0.30,"name":"","requestedValue":1.00,"rpm":-1,"thermostatic":{"control":true,"heaters":[10,11],"highTemperature":55.0,"lowTemperature":45.0}}],"heat":{"coldExtrudeTemperature":160.0,"coldRetractTemperature":90.0,"heaters":[{"current":20.1,"max":125.0,"min":-273.1,"sensor":0,"state":"off"},{"current":20.5,"max":290.0,"min":-273.1,"sensor":1,"state":"off"}],"sensors":[{"lastReading":20.1,"name":"","type":"Thermistor"},{"lastReading":20.5,"name":"","type":"PT100 (MAX31865)"},null,null,null,null,null,null,null,null,{"lastReading":14.1,"name":"Mcu","type":"Microcontroller embedded temperature sensor"},{"lastReading":0,"name":"Drivers","type":"Stepper driver temperature warnings"}]},"job":{"file":{"filament":[],"firstLayerHeight":0,"height":0,"layerHeight":0,"numLayers":0,"size":0},"layer":0,"timesLeft":null},"move":{"axes":[{"acceleration":3000.0,"drivers":["0"],"homed":false,"jerk":600.0,"letter":"X","machinePosition":0,"max":150.0,"min":-150.0,"speed":15000.0,"userPosition":0,"visible":true,"workplaceOffsets":[0,0,0,0,0,0,0,0,0]},{"acceleration":3000.0,"drivers":["1"],"homed":false,"jerk":600.0,"letter":"Y","machinePosition":0,"max":150.0,"min":-150.0,"speed":15000.0,"userPosition":0,"visible":true,"workplaceOffsets":[0,0,0,0,0,0,0,0,0]},{"acceleration":3000.0,"drivers":["2"],"homed":false,"jerk":600.0,"letter":"Z","machinePosition":470.070,"max":470.1,"min":0,"speed":15000.0,"userPosition":470.070,"visible":true,"workplaceOffsets":[0,0,0,0,0,0,0,0,0]}],"calibrationDeviation":{"deviation":0,"mean":0},"currentMove":{"acceleration":0,"deceleration":0,"requestedSpeed":0,"topSpeed":0},"daa":{"enabled":false,"minimumAcceleration":10.0,"period":0.0},"extruders":[{"driver":"3","factor":100.0,"nonlinear":{"a":0.015,"b":0.001,"upperLimit":0.20},"pressureAdvance":0.20},{"driver":"4","factor":100.0,"nonlinear":{"a":0,"b":0,"upperLimit":0.20},"pressureAdvance":0}],"idle":{"factor":0.3,"timeout":30.0},"initialDeviation":{"deviation":0,"mean":0},"kinematics":{"deltaRadius":180.679,"homedHeight":470.070,"name":"Linear delta","printRadius":150.0,"towers":[null,null,null],"xTilt":0.001,"yTilt":-0.001},"meshDeviation":{"deviation":0,"mean":0},"printingAcceleration":10000.0,"speedFactor":100.0,"travelAcceleration":10000.0,"workspaceNumber":1},"network":{"interfaces":[{"actualIP":"192.168.1.126","gateway":"0.0.0.0","subnet":"0.255.255.255","type":"wifi"}]},"sensors":{"endstops":[{"triggered":false,"type":"inputPin"},{"triggered":false,"type":"inputPin"},{"triggered":false,"type":"inputPin"}],"probes":[{"calibrationTemperature":25.0,"disablesHeaters":false,"diveHeight":6.0,"maxProbeCount":5,"offsets":[0,0],"recoveryTime":0.2,"speed":16.7,"temperatureCoefficient":0,"threshold":100,"tolerance":0.020,"travelSpeed":200.0,"triggerHeight":-0.100,"type":8,"value":[0]}]},"state":{"currentTool":-1,"machineMode":"FFF","status":"Idle","upTime":47},"tools":[{"active":[0],"axes":[[0],[1]],"extruders":[0],"fans":[0],"heaters":[1],"mix":[1.00],"name":"","offsets":[0,0,0],"standby":[0],"state":"off"},{"active":[0],"axes":[[0],[1]],"extruders":[1],"fans":[0],"heaters":[2],"mix":[1.00],"name":"","offsets":[0,0,0],"standby":[0],"state":"off"}]}}
    

    You can also see the individual members of each extruder in this example.

    'mix' is an array. Its length will be the number of extruders in the M563 definition of the tool.

    In conditional GCode you can index any array. Currently, if you use an array then you must index it or use the # operator to take its length, because conditional GCode doesn't yet support doing anything else to array values.

    HTH David



  • I had to put this on hold a little as I discovered a bug in RJ Texted which was causing autocomplete to fail where an array was involved.
    e.g. move.axes would work, but would stop working when you got to move.axes[0].

    The author has responded with a fix in the latest beta available here
    https://www.rj-texted.se/Forum/viewtopic.php?f=10&t=4807

    I'm pretty sure I have most/all of the object model documented in the language files here.
    https://www.dropbox.com/s/75re836p55tvmk3/reprap.zip?dl=0

    They need to be placed in the correct folder, usually
    C:\Users*your user name* \AppData\Roaming\RJ TextEd\Syntax\User defined

    You then need to activate them in RJ Texted.
    Go to ENVIRONMENT > ADDONS - then select HIGHLIGHTERS on the left.
    Scroll down the list and check "Reprap"
    selection.jpg

    You can then create a new file and select "reprap" as the syntax format.
    Or you can open a file and reformat.

    You also need to activate html link following if you want to be able to use the links to the dozuki added after G or M codes when they are added from the dropdown or auto completion list.
    URL.jpg

    { } etc so that when you type the leading brace, it adds the trailing brace automatically.

    braces.jpg

    Once the object model is stable we can submit the syntax file for inclusion in the standard distribution.
    Until then we can work on it among ourselves to improve it.
    I could probably do an installation setup that automatically put the files in the right spot and adjusted all the settings, but again until the model is stable (and there's an indication this is being used) it will have to be manually done.

    An example

    screenshot.jpg



  • Curious: Is anyone working a syntax highlight definition for either Sublime or Atom?



  • @Danal
    I looked into doing one for notepad ++ but found their method of creating syntax highlighting files quite clunky so I gave up.
    I do have atom, but haven’t looked into it.
    If it’s easy to carry over what I’ve already done in RJ TextEd I’ll have a look, otherwise you’re on your own 😉



  • @OwenD said in Conditional G Code - RJ TextEd Syntax file.:

    otherwise you’re on your own

    That's really where I was going... I wanted to be sure there wasn't something underway. Personally, I'd lean much more toward Sublime (even though I asked about both).

    Of course, editors are a very personal choice...

    Thanks!



  • @Danal
    Both Atom and Sublime have syntax for matters for GCode available.
    Perhaps you can use these as the basis and add autocomplete etc.

    https://packagecontrol.io/packages/G-code Syntax Highlighting

    https://atom.io/packages/language-gcode-fff

    I’m afraid some life stuff has just come up that will prevent me putting any more time into this for a while.


Log in to reply