//----------------------------------------- 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); });