From 6732ed936a5828f11fd71e7e05b3b1e16e92f383 Mon Sep 17 00:00:00 2001
From: Jake <jake.read@cba.mit.edu>
Date: Thu, 1 Nov 2018 15:13:55 -0400
Subject: [PATCH] makes pwm for servos

---
 README.md             |   7 ++-
 programs/mothercnc.js | 126 ++++++++++++++++++++++++++++++++++++++
 server.js             | 138 +++---------------------------------------
 src/hardware/servo.js |  62 +++++++++++++++++++
 4 files changed, 202 insertions(+), 131 deletions(-)
 create mode 100644 programs/mothercnc.js
 create mode 100644 src/hardware/servo.js

diff --git a/README.md b/README.md
index cc436a2..13b8c2f 100644
--- a/README.md
+++ b/README.md
@@ -13,8 +13,13 @@ This project serves the developement environment / api we use to write and repre
 
 ![img moving](doc/images/mothermother.gif)
 
+
 ## Programming Notes
-- wake up planner sequence
+- wake up planner sequence, say hello
+ - load program / don't during startup ?
+ - flow control immediately ? 
+ 
+ - exercise to get in groove: pwm for servos & startup seq. in atkapi 
 - once we can plan gcode sequence, work towards more
  - better hardware abstraction, i.e.
    stepper.port = bridge.port('0,1')
diff --git a/programs/mothercnc.js b/programs/mothercnc.js
new file mode 100644
index 0000000..da711fd
--- /dev/null
+++ b/programs/mothercnc.js
@@ -0,0 +1,126 @@
+
+/*
+// wrap require() up, appending path used to object, and giving ID
+// use the same to load from browser 
+var term = addModule('./src/ui/terminal.js')
+var multiline = addModule('./src/ui/multiline.js')
+var button = addModule('./src/ui/button.js')
+var numOut = addModule('./src/ui/number.js')
+var delay = addModule('./src/util/delay.js')    
+
+var gcode = addModule('./src/parsing/gcode.js')
+var planner = addModule('./src/motion/planner.js')
+
+var xm = addModule('./src/hardware/stepper.js')
+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.evt)
+numOut.outputs.out.attach(multiline.inputs.req)
+button.outputs.whammy.attach(delay.inputs.thru)
+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)
+
+planner.outputs.moveComplete.attach(multiline.inputs.req)
+
+// same motors / bridge 
+xm.state.axis = 'X'
+xm.state.spu = 100
+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 = -100
+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 = -100
+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 = -100
+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()
+
+multiline.load()
+
+// setting data w/r/t the representations they serve 
+
+setUiPos(multiline, 10, 10)
+
+setUiPos(gcode, 450, 10)
+setUiPos(term, 450, 180)
+setUiPos(button, 450, 300)
+setUiPos(numOut, 450, 400)
+setUiPos(delay, 450, 520)
+
+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
+
+setUiPos(xm, hwCol, 10)
+setUiPos(yma, hwCol, 250)
+setUiPos(ymb, hwCol, 490)
+setUiPos(zm, hwCol, 730)
+
+setUiPos(bridge, hwCol, 970)
+
+// setting ui elements / state 
+planner.state.isRunning = 0
\ No newline at end of file
diff --git a/server.js b/server.js
index 4bcf4aa..2932c04 100644
--- a/server.js
+++ b/server.js
@@ -122,141 +122,19 @@ PROGRAM AS API
 
 var modules = new Array()
 
-// wrap require() up, appending path used to object, and giving ID
-// use the same to load from browser 
-var term = addModule('./src/ui/terminal.js')
-var multiline = addModule('./src/ui/multiline.js')
-var button = addModule('./src/ui/button.js')
-var numOut = addModule('./src/ui/number.js')
-var delay = addModule('./src/util/delay.js')    
-
-var gcode = addModule('./src/parsing/gcode.js')
-var planner = addModule('./src/motion/planner.js')
-
-var xm = addModule('./src/hardware/stepper.js')
-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.evt)
-numOut.outputs.out.attach(multiline.inputs.req)
-button.outputs.whammy.attach(delay.inputs.thru)
-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)
-
-planner.outputs.moveComplete.attach(multiline.inputs.req)
-
-// same motors / bridge 
-xm.state.axis = 'X'
-xm.state.spu = 100
-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 = -100
-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 = -100
-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 = -100
-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()
+var test = addModule('./src/hardware/test.js')
+var servo = addModule('./src/hardware/servo.js')
 
-multiline.load()
-
-// setting data w/r/t the representations they serve 
-
-setUiPos(multiline, 10, 10)
-
-setUiPos(gcode, 450, 10)
-setUiPos(term, 450, 180)
-setUiPos(button, 450, 300)
-setUiPos(numOut, 450, 400)
-setUiPos(delay, 450, 520)
-
-var plCol = 900
+test.outputs.packet.attach(bridge.inputs.B)
+bridge.outputs.B.attach(test.inputs.packet)
 
-setUiPos(t1, plCol, 730)
-setUiPos(t2, plCol, 850)
-setUiPos(t3, plCol, 970)
-setUiPos(t4, plCol, 1090)
-setUiPos(t5, plCol, 1210)
-setUiPos(planner, plCol, 10)
+servo.outputs.packet.attach(bridge.inputs.B)
 
-var hwCol = 1350
-
-setUiPos(xm, hwCol, 10)
-setUiPos(yma, hwCol, 250)
-setUiPos(ymb, hwCol, 490)
-setUiPos(zm, hwCol, 730)
-
-setUiPos(bridge, hwCol, 970)
-
-// setting ui elements / state 
-planner.state.isRunning = 0
-/*
-term.state.uiInput = "G1 F100 Z10"
-term.state.uiInput = "G1 Y10"
-term.state.uiInput = "G1 X0"
-term.state.uiInput = "G1 Y0"
-term.state.uiInput = "G1 X10"
-planner.state.isRunning = 1
-*/
-/*
-term.state.uiInput = "G1 X0 Y10"
-term.state.uiInput = "G1 X-1 Y0"
-term.state.uiInput = "G1 X0 Y0"
-*/
+setUiPos(test, 150, 100)
+setUiPos(servo, 150, 300)
+setUiPos(bridge, 750, 150)
 
 function setUiPos(module, left, top){
     if(module.ui == null){
diff --git a/src/hardware/servo.js b/src/hardware/servo.js
new file mode 100644
index 0000000..c20e34f
--- /dev/null
+++ b/src/hardware/servo.js
@@ -0,0 +1,62 @@
+// boilerplate atkapi header
+const InOut = require('../../lib/inout.js')
+let Input = InOut.Input
+let Output = InOut.Output
+let State = InOut.State
+let Button = InOut.Button
+
+const PCKT = require('../../lib/packets.js')
+
+// a constructor, a fn, a javascript mess
+function Servo() {
+
+    var servo = {
+        // descriptions are used in UI
+        description: {
+            name: 'Breadboard Servo Signal Generator',
+            alt: 'servo'
+        }
+    }
+
+    servo.state = State()
+    // alias !
+    var state = servo.state
+
+    state.button = Button('SEND')
+    state.onChange('button', onButtonPress)
+    state.servoVal = 0 // 0->100 does 1 -> 2ms duty on 20ms period
+    state.onChange('servoVal', onButtonPress)
+
+    servo.inputs = {
+        packet: Input('headless packet', onPacketReturn) // makes anything into '1' event
+    }
+
+    servo.outputs = {
+        packet: Output('number')
+    }
+
+    function onButtonPress(evt) {
+        var pwm = state.servoVal
+        if(pwm > 100){
+            pwm = 100
+        } else if (pwm < 0){
+            pwm = 0
+        }
+
+        var microval = Math.round(7.5 * pwm)
+        console.log('pwm on line', microval)
+
+        var pwmpack = PCKT.pack32(microval)
+        pwmpack.unshift(141)
+
+        servo.outputs.packet.emit(pwmpack)
+    }
+
+    function onPacketReturn(evt) {
+    }
+
+    return servo
+}
+
+// exports 
+module.exports = Servo
\ No newline at end of file
-- 
GitLab