diff --git a/README.md b/README.md index ff91c5929796aadc6739e6f4658befb2f50e8b27..9f69cc338d1395e216aa6192ff6a93bd47ef3b67 100644 --- a/README.md +++ b/README.md @@ -139,7 +139,7 @@ Pardon my at-the-moment brief explanation. # Writing New Modules -Whenever a menu is requested, the system searches ```modules/ * ``` for *anything*. include your .js of a new module there. +Whenever a menu is requested, the system searches ```modules/ * ``` for *anything*. When you write a new module, just include your newmodule.js there, and the program should find it. These modules are written with objects inherited from ```lib/jsunit.js``` @@ -217,6 +217,52 @@ module.exports = uiNum Hardware Modules are identical to other modules, but they inherit a class that can be found and examined at ```lib/atkunit.js``` which subsequently calls hardware-interfacing classes from ```lib/atkroute.js``` and often use tools from ```lib/packets.js``` (packets.js is mostly about packing 64-bit information into byte-size units). +# Programatically Connecting and Loading Modules + +We can also write and manipulate modules as software objects. This is sometimes very nice. + +I.E. here is 'main.js' as configured to run the small program described. + +```javascript + +// business +const Reps = require('./reps.js') +const Programs = require('./programs.js') + +// the program object: real simple, just has a description, and a 'modules' +var program = Programs.new('new program') + +/* example program-like-an-api */ +// load some modules +var multiline = Programs.loadModuleFromSource(program, './modules/ui/multiline.js') +var gcode = Programs.loadModuleFromSource(program, './modules/parsing/gcode.js') + +// attaching: always like outputs to inputs +multiline.outputs.lineOut.attach(gcode.inputs.lineIn) + +// we can move things around here as well +multiline.description.position = { + left: 50, + top: 50 +} + +gcode.description.position = { + left: 500, + top: 100 +} + +// if I have a public function in a module, I can also use that +multiline.load('./files/dogbone.gcode') + +// UI +const View = require('./views.js') +View.startHttp() +View.startWs() + +Programs.assignSocket(View.uiSocket) +View.assignProgram(program) +``` + # Development Notes ## For MW diff --git a/main.js b/main.js index 4bf43423ea9d2c16f432bd3a3d4e576c2ec4a7d5..20d41bd1a242e9f4cdc0c3f30332cb0eeca21971 100644 --- a/main.js +++ b/main.js @@ -27,9 +27,31 @@ programs are assemblies of modules const Reps = require('./reps.js') const Programs = require('./programs.js') +// the program object: real simple, just has a description, and a 'modules' var program = Programs.new('new program') -// var step = Programs.loadModuleFromSource(program, './modules/hardware/atkstepper.js') +/* example program-like-an-api +// load some modules +var multiline = Programs.loadModuleFromSource(program, './modules/ui/multiline.js') +var gcode = Programs.loadModuleFromSource(program, './modules/parsing/gcode.js') + +// attaching: always like outputs to inputs +multiline.outputs.lineOut.attach(gcode.inputs.lineIn) + +// we can move things around here as well +multiline.description.position = { + left: 50, + top: 50 +} + +gcode.description.position = { + left: 500, + top: 100 +} + +// if I have a public function in a module, I can also use that +multiline.load('./files/dogbone.gcode') +*/ // UI const View = require('./views.js') diff --git a/modules/hardware/atkmrobot.js b/modules/hardware/atkmrobot.js new file mode 100644 index 0000000000000000000000000000000000000000..de127aed0222dfff2dab61c91444201846b65733 --- /dev/null +++ b/modules/hardware/atkmrobot.js @@ -0,0 +1,83 @@ +// boilerplate atkapi header +const InOut = require('../../lib/jsunit.js') +let Input = InOut.Input +let Output = InOut.Output +let State = InOut.State +let Button = InOut.Button + +const Hardware = require('../../lib/atkunit.js') +const PCKT = require('../../lib/packets.js') + +// a constructor, a fn, a javascript mess +function ATKMathRobot() { + + // we make the module, starting from this base + // '0,1' is the route to our piece of hardware + // 'onPacket' is the function that will be called + // when data arrives from that port + var atkmr = Hardware() + + // change the name ... + atkmr.description.name = 'atk-math-robot-joint' + + // inputs and outputs as usual + atkmr.inputs = { + pc_t: Input('number', onPositionTargetInput) + } + atkmr.outputs = { + ok: Output('nothing-yet') + } + + // and state as well + var state = atkmr.state + + state.message = 'no packet yet' + state.pc_t = 2048 + state.onChange('pc_t', onPositionTargetUserChange) + state.walk = 1024 + state.tickButton = Button('Walk Value', onPositionTickTock) + + // to send things down the well, we can use + // atkmr.route.send(packet) + // where packet is a byte array + + function onPositionTargetInput(evt){ + console.log("INPUTS NOT YET BOUND", evt) + } + + function onPositionTargetUserChange() { + var pc_t = state.pc_t + if (pc_t > 16384) { + pc_t = 16384 + } else if (pc_t < 0) { + pc_t = 0 + } + + var pc_tpack = PCKT.pack32(pc_t) + pc_tpack.unshift(143) + + state.message = 'packet out' + atkmr.route.send(pc_tpack) + } + + function onPositionTickTock(){ + var pc_t = state.pc_t + pc_t += state.walk + pc_t %= 16384 + state.pc_t = pc_t + onPositionTargetUserChange() + } + + // to get replies to certain packets, we can + // subscribe, where 141 (here) is the 'key' + // we're looking for on the network, and the + // msg is byte array we'll get back + atkmr.route.subscribe(143, function(msg){ + state.message = 'packet ok' + }) + + return atkmr +} + +// exports +module.exports = ATKMathRobot \ No newline at end of file diff --git a/modules/hardware/atkseriallink.js b/modules/hardware/atkseriallink.js index 615acb7449fb7418562f04bb4c71ca513ed9fbdc..f97d49311b297e7d0f9393aab0d5527b18bb3b55 100644 --- a/modules/hardware/atkseriallink.js +++ b/modules/hardware/atkseriallink.js @@ -150,7 +150,6 @@ function ATKSerialLink() { // we'll make sure it's what we think it will be // console.log("PORT DATA") var dtArray = new Array() - console.log('sp data', data) if (Buffer.isBuffer(data)) { for (var i = 0; i < data.length; i++) { dtArray[i] = data[i] diff --git a/views.js b/views.js index b9886e006f5db54f0db56a1d3c9828e2fea9f788..32d1138a1c6072d6673738eed3b7d3cea20e223a 100644 --- a/views.js +++ b/views.js @@ -119,7 +119,7 @@ function socketRecv(evt) { } function socketSend(type, data) { - if (sckt.readyState === 1) { + if (sckt != null && sckt.readyState === 1) { var msg = { type: type, data: data @@ -127,7 +127,7 @@ function socketSend(type, data) { //console.log('SEND', msg) sckt.send(JSON.stringify(msg)) } else { - throw 'on socketSend, ws not ready' + console.log('on socketSend, ws not ready') } }