Commit fd635a0e authored by Jake Read's avatar Jake Read
Browse files

failsafe commit, things work with 7 lines gcode

parent 7a19653c
......@@ -4,7 +4,11 @@ aka project consistent-sandbox
## oy
- num primatives, wrap to sys
- wait return -> planner
- port flushing ?
- want a test / reset set
- really, should be built into bridge (or hardware default objs)
- read file ? default lines ? run it
- then you have this multiline gcode / start / stop sequencing issue
......
//----------------------------------------- mkterminal
/*
small program for sending apa packets along a serial line
*/
// check that we have portname
if (process.argv.length < 3) {
logAdvice()
process.exit(-1)
}
if (process.argv[2] == '-h' || process.argv[2] == 'help') {
logAdvice()
process.exit(-1)
}
var SerialPort = require('serialport');
var ByteLengthParser = SerialPort.parsers.ByteLength;
var port = new SerialPort(process.argv[2], {
baudRate: 250000,
/* dataBits: 8,
parity: 'none',
flowControl: false,
*/
});
//----------------------------------------- readline
/*
key input from terminal
*/
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
rl.on('line', parseLineIn);
function parseLineIn(data) {
/*
packet like "packet port,port,etc,ptr,byte,byte,byte..."
does like "len,int,int,int,254?,byte,byte,byte,etc"
next do key:type:values
apa_end_addr_delimiter 255
apa_addr_pointer 254
apa_addr_flood 253
key_position_float 127
key_speed_float 128
key_position_steps 129
key_speed_steps 130
*/
if (data.includes('packet')) {
var argstring = data.split(' ')[1]; // everything following 'packet '
var args = argstring.split(',');
var packet = new Array();
var i = 0; // args
var u = 0; // packet
while (i < args.length) {
switch (args[i]) {
case 'ptr':
packet[u] = 254;
i++;
u++;
break;
case 'end':
packet[u] = 255;
i++;
u++;
break;
case 'test':
packet[u] = 127;
i++;
u++;
break;
case 'reset':
packet[u] = 128;
i++;
u++;
break;
case 'setPos':
packet[u] = 129
var newPos = parseInt(args[i + 1])
packet[u + 1] = (newPos >> 8) & 255
packet[u + 2] = newPos & 255
i += 2
u += 3
break
case 'getPos':
packet[u] = 130
i ++
u++
break
case 'block':
packet[u] = 131;
// a linked acceleration planned segment
// we'll be going betwee float-space for steps in the higher levels, so
var steps = parseInt(args[i + 1])
packet = packet.concat(pack32(steps))
// but accel and speeds need to be in floats
var entry = parseInt(args[i + 2])
packet = packet.concat(pack32(entry))
// pack 64 bit float to 32 bit?
var accel = parseInt(args[i + 3])
packet = packet.concat(pack32(accel))
var accelLength = parseInt(args[i + 4])
packet = packet.concat(pack32(accelLength))
var deccelLength = parseInt(args[i + 5])
packet = packet.concat(pack32(deccelLength))
i += 6
u += 21
break;
case 'wait':
packet[u] = 132;
// a linked acceleration planned segment
// this one flagged as a wait period via the delimiter
// we'll be going betwee float-space for steps in the higher levels, so
var steps = parseInt(args[i + 1])
packet = packet.concat(pack32(steps))
// but accel and speeds need to be in floats
var entry = parseInt(args[i + 2])
packet = packet.concat(pack32(entry))
// pack 64 bit float to 32 bit?
var accel = parseInt(args[i + 3])
packet = packet.concat(pack32(accel))
var accelLength = parseInt(args[i + 4])
packet = packet.concat(pack32(accelLength))
var deccelLength = parseInt(args[i + 5])
packet = packet.concat(pack32(deccelLength))
i += 6
u += 21
break;
case 'speed':
packet[u] = 141;
var speed = parseInt(args[i +1])
packet = packet.concat(pack32(speed))
var duty = parseInt(args[i + 2])
packet = packet.concat(pack32(duty))
i += 3;
u += 9;
break;
default:
packet[u] = parseInt(args[i]);
u++;
i++;
break;
}
}
packet.unshift(packet.length + 1); // push the length into header
data_out(packet);
// now through bytes
} else if (data.includes('dummy packet')) {
var packet = Buffer.from([12, 3, 1, 254, 4, 255, 1, 2, 3, 4, 5, 6]);
data_out(packet);
} else if (data.includes('help')) {
logAdvice();
} else if (data.includes('exit')) {
process.exit(0);
} else {
data_out(data);
}
}
function pack32(val) {
var pack = new Array();
pack[0] = (val >> 24) & 255;
pack[1] = (val >> 16) & 255;
pack[2] = (val >> 8) & 255;
pack[3] = val & 255;
return pack;
}
function packFloat(val) {
var pack; // the array of bytes
// as a view into a typed array
var view = new DataView(new ArrayBuffer(4));
view.setFloat32(0, val);
pack = Array.apply(null, { length: 4 }).map((_, i) => view.getUint8(i))
console.log('packed', val, 'as', pack)
return pack
}
function logAdvice() {
console.log('use serialport-list to find ports')
console.log("command line: node serialterminal portname");
console.log('route,ptr,end,command,args')
console.log('test: sends byte 128 to network test')
console.log('steps: {steps uint32_t, speed steps/s float, dir uint8_t}')
console.log('block: steps, entry, accel, accelLength, deccelLength')
}
//----------------------------------------- parsing
/*
does the business
*/
var parser = port.pipe(new ByteLengthParser({ length: 1 }));
parser.on('data', data_in);
function data_in(data) {
console.log(data[0]);
}
function data_out(data) {
console.log('sent: ', data);
port.write(data, function(err) {
if (err) {
return console.log('port error on write: ', err.message);
}
});
}
port.on('open', function(err) {
console.log('port open');
});
port.on('error', function(err) {
console.log('port error: ', err.message);
});
\ No newline at end of file
......@@ -84,7 +84,7 @@ function addRep(rep) {
var domElem = document.createElement('div')
// dif. color for hardwares ?
domElem.className = 'block'
if(rep.description.isHardware){
if (rep.description.isHardware) {
domElem.classList.add('hardware')
}
domElem.style.left = lastPos.X + 'px'
......@@ -119,8 +119,8 @@ function addRep(rep) {
stateElem.className = 'state'
rep.ui.state = {}
for (st in rep.state) {
var li = writeStateRep(stateElem, rep, st)
rep.ui.state[st] = li
var inputItem = writeStateRep(stateElem, rep, st)
rep.ui.state[st] = inputItem
}
// WRITE INPUTS
......@@ -182,18 +182,18 @@ function addRep(rep) {
putUi(rep)
}
function redrawLinks(){
while(svg.firstChild){
function redrawLinks() {
while (svg.firstChild) {
svg.removeChild(svg.firstChild)
}
// rm old links then redraw everything
//console.log('now drawing links')
for(var i = 0; i < reps.length; i ++){
for (var i = 0; i < reps.length; i++) {
var rep = reps[i]
for(key in rep.outputs){
for (key in rep.outputs) {
var output = rep.outputs[key]
var outputUi = rep.ui.outputs[key]
for(input in output.calls){
for (input in output.calls) {
var toId = output.calls[input].parentId
var toKey = output.calls[input].key
var inputUi = reps[toId].ui.inputs[toKey]
......@@ -207,12 +207,12 @@ function redrawLinks(){
}
}
function changeRep(data){
function changeRep(data) {
console.log('CHANGE REP', data)
var rep = reps[data.id]
for (var key in data){
if (key == 'outputs'){
for (var key in data) {
if (key == 'outputs') {
rep.outputs = data.outputs
}
}
......@@ -224,9 +224,17 @@ function changeRep(data){
function changeState(data) {
var rep = reps[data.id]
for (var key in data.state) {
rep.state[key] = data.state[key]
if (rep.ui.state[key] != null) {
rep.ui.state[key].value = rep.state[key]
if (data.state[key].isButton) {
console.log('BUTTON UPDATE')
} else if (data.state[key].isMultiLine) {
//console.log("rep", rep.ui.state[key].value, 'data', data.state[key].value)
rep.ui.state[key].value = data.state[key].value
} else {
// two ?
rep.state[key] = data.state[key]
if (rep.ui.state[key] != null) {
rep.ui.state[key].value = rep.state[key]
}
}
}
}
......@@ -249,7 +257,7 @@ function putState(rep) {
}
// save ui position to server for reload
function putUi(rep){
function putUi(rep) {
var data = {
id: rep.id,
ui: {
......
......@@ -17,6 +17,22 @@ function writeStateRep(container, rep, key) {
})
container.appendChild(li)
return li
} else if (variable.isMultiLine) {
console.log('MULTILINE!')
var li = document.createElement('li')
li.appendChild(document.createTextNode(variable.label))
li.appendChild(document.createElement('br'))
var txtArea = document.createElement('textarea')
txtArea.rows = variable.rows
txtArea.cols = 27
txtArea.value = variable.value
txtArea.addEventListener('change', function(){
rep.state[key].value = txtArea.value
putState(rep)
})
li.appendChild(txtArea)
container.appendChild(li)
return txtArea
} else {
if (typeof variable == 'string') {
var li = document.createElement('li')
......@@ -56,7 +72,7 @@ function writeStateRep(container, rep, key) {
input.value = variable.toString()
input.addEventListener('change', function() {
var arr = input.value.split(',')
arr.forEach(function(element, index, array){
arr.forEach(function(element, index, array) {
array[index] = parseFloat(element)
})
rep.state[key] = arr
......
......@@ -38,6 +38,10 @@ body {
color: #eee;
}
textarea {
resize: none;
}
/*
.state li:hover {
background-color: #303030;
......
......@@ -43,7 +43,7 @@ function Output(type){
console.log('no inputs bound to this output')
} else {
for(index in this.calls){
this.calls[index].fn(data)
this.calls[index].fn(JSON.parse(JSON.stringify(data)))
}
}
}
......@@ -83,11 +83,24 @@ function Button(label){
return button
}
// now we're definitely writing a UI class
function MultiLine(label, rows){
var ml = {
isMultiLine: true,
label: label,
rows: rows,
value: ' - '
}
return ml
}
module.exports = {
Input: Input,
Output: Output,
State: State,
Button: Button
Button: Button,
MultiLine: MultiLine
}
/*
......
......@@ -61,7 +61,7 @@ function socketSend(type, data) {
type: type,
data: data
}
console.log('SEND', msg)
//console.log('SEND', msg)
sckt.send(JSON.stringify(msg))
}
}
......@@ -70,7 +70,7 @@ function socketRecv(evt) {
var recv = JSON.parse(evt)
var type = recv.type
var data = recv.data
console.log('RECV', recv)
//console.log('RECV', recv)
// bang thru
switch (type) {
case 'console':
......@@ -126,13 +126,20 @@ var yma = addModule('./src/hardware/stepper.js')
var ymb = addModule('./src/hardware/stepper.js')
var zm = addModule('./src/hardware/stepper.js')
var t1 = addModule('./src/hardware/test.js')
var t2 = addModule('./src/hardware/test.js')
var t3 = addModule('./src/hardware/test.js')
var t4 = addModule('./src/hardware/test.js')
var t5 = addModule('./src/hardware/test.js')
var bridge = addModule('./src/hardware/bridge.js')
// attaching an output to an input
term.outputs.lineOut.attach(gcode.inputs.lineIn)
multiline.outputs.lineOut.attach(gcode.inputs.lineIn)
gcode.outputs.instructionOut.attach(planner.inputs.instruction)
button.outputs.whammy.attach(numOut.inputs.thru)
button.outputs.whammy.attach(numOut.inputs.evt)
numOut.outputs.out.attach(multiline.inputs.req)
button.outputs.whammy.attach(delay.inputs.thru)
delay.outputs.out.attach(planner.inputs.run)
......@@ -140,10 +147,13 @@ delay.outputs.out.attach(planner.inputs.run)
// bi-directional hook planner / motor
planner.outputs.moves.attach(xm.inputs.move)
xm.outputs.ack.attach(planner.inputs.acks)
planner.outputs.moves.attach(yma.inputs.move)
yma.outputs.ack.attach(planner.inputs.acks)
planner.outputs.moves.attach(ymb.inputs.move)
//ymb.outputs.ack.attach(planner.inputs.acks)
planner.outputs.moves.attach(zm.inputs.move)
zm.outputs.ack.attach(planner.inputs.acks)
......@@ -151,16 +161,39 @@ zm.outputs.ack.attach(planner.inputs.acks)
xm.state.axis = 'X'
xm.outputs.packet.attach(bridge.inputs.A)
bridge.outputs.A.attach(xm.inputs.packet)
bridge.state.rA = '0,3'
t1.outputs.packet.attach(bridge.inputs.A)
bridge.outputs.A.attach(t1.inputs.packet)
yma.state.axis = 'Y'
yma.state.spu = -200
yma.outputs.packet.attach(bridge.inputs.B)
bridge.outputs.B.attach(yma.inputs.packet)
bridge.state.rB = '0,0'
t2.outputs.packet.attach(bridge.inputs.B)
bridge.outputs.B.attach(t2.inputs.packet)
ymb.state.axis = 'Y'
// should have to reverse this but did it with wires :|
ymb.state.spu = -200
ymb.outputs.packet.attach(bridge.inputs.C)
bridge.outputs.C.attach(ymb.inputs.packet)
bridge.state.rC = '0,5'
t3.outputs.packet.attach(bridge.inputs.C)
bridge.outputs.C.attach(t3.inputs.packet)
zm.state.axis = 'Z'
zm.state.spu = -200
zm.outputs.packet.attach(bridge.inputs.D)
bridge.outputs.D.attach(zm.inputs.packet)
bridge.state.rD = '0,1'
t4.outputs.packet.attach(bridge.inputs.D)
bridge.outputs.D.attach(t4.inputs.packet)
t5.outputs.packet.attach(bridge.inputs.E)
bridge.outputs.E.attach(t5.inputs.packet)
bridge.state.rE = '0'
bridge.init()
......@@ -174,7 +207,14 @@ setUiPos(button, 450, 300)
setUiPos(numOut, 450, 400)
setUiPos(delay, 450, 520)
setUiPos(planner, 900, 10)
var plCol = 900
setUiPos(t1, plCol, 730)
setUiPos(t2, plCol, 850)
setUiPos(t3, plCol, 970)
setUiPos(t4, plCol, 1090)
setUiPos(t5, plCol, 1210)
setUiPos(planner, plCol, 10)
var hwCol = 1350
......@@ -332,13 +372,19 @@ function changeState(data) {
if (isStateKey(key)) {
if (oldState[key].isButton) {
if (oldState[key].isPressed != newState[key].isPressed) {
console.log('CHANGE STATE', key, 'to', newState[key], 'in', data.id)
console.log('CHANGE BUTTON STATE', key, 'to', newState[key], 'in', data.id)
// this will trigger some 'onChange' f'ns
// that might change some state
oldState[key] = newState[key]
// to prevent quickly changing it back, we'll exit now (one state change from UI per trx)
return true
}
} else if (oldState[key].isMultiLine) {
if (oldState[key].value != newState[key].value){
console.log('CHANGE MULTILINE STATE', key, 'to', newState[key].value, 'in', data.id)
oldState[key].value = newState[key].value
return true
}
} else if (oldState[key] !== newState[key]) {
console.log('CHANGE STATE', key, 'to', newState[key], 'in', data.id)
oldState[key] = newState[key]
......
......@@ -17,8 +17,8 @@ function ATKBridge() {
}
}
bridge.state = State()
var state = bridge.state
var state = State()
bridge.state = state
state.rA = '0,0'
state.rB = '0,1'
......@@ -64,7 +64,7 @@ function ATKBridge() {
} else {
if (port == null) {
port = new serialport(state.portName, {
baudRate: 750000
baudRate: 250000
})
port.on('open', function() {
state.portStatus = 'open'
......@@ -177,6 +177,18 @@ function ATKBridge() {
B: {
route: state.rB,
output: bridge.outputs.B
},
C: {
route: state.rC,
output: bridge.outputs.C
},
D: {
route: state.rD,
output: bridge.outputs.D
},
E: {
route: state.rE,
output: bridge.outputs.E
}
}
......@@ -184,6 +196,7 @@ function ATKBridge() {
function onPortData(data) {
// we'll make sure it's what we think it will be
console.log("PORT DATA")
var dtArray = new Array()
if (Buffer.isBuffer(data)) {
for (var i = 0; i < data.length; i++) {
......@@ -217,8 +230,8 @@ function ATKBridge() {
function onPacket(pckt) {
var debug = false
console.log('PCKT IN <<', pckt.toString())
shiftPacketPointer(pckt)
console.log('PCKT IN <<', pckt.toString(), '-----------------------')
var incomingRoute = pckt.slice(2, pckt.indexOf(255))
// flip to match outgoing
var returnRoute = new Array()
......@@ -226,13 +239,27 @@ function ATKBridge() {
returnRoute[i] = incomingRoute[incomingRoute.length - 1 - i]
}
var match = null
for (key in bridge.pairs) {
if (returnRoute.toString() === bridge.pairs[key].route.toString()) {
if (debug) console.log("PCKT FOUND", key)