-
Notifications
You must be signed in to change notification settings - Fork 0
/
arm.js
129 lines (105 loc) · 3.32 KB
/
arm.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
let inherits = require('util').inherits
let EventEmitter = require('events').EventEmitter
let five = require('johnny-five')
let TAU = Math.PI * 2
class Arm {
constructor(opts) {
this.label = opts.label
this.position = {x0: opts.x0, y0: opts.y0, x1: null, y1: null, step: null}
this.homeDirection = opts.homeDirection
this.stepsPerRev = 3200
this.theta_home = opts.theta_home
this.theta_max = opts.theta_max
this.r0 = opts.r0
this.r1 = opts.r1
this.motor = new five.Stepper({
type: five.Stepper.TYPE.DRIVER,
stepsPerRev: this.stepsPerRev,
pins: {
step: opts.stepPin,
dir: opts.dirPin
}
})
this.limitSwitch = new five.Button({
pin: opts.limitPin,
invert: true
})
this.limitSwitch.label = opts.label
this.limitSwitch.on('press', function() {
console.log( this.label + ' closed' )
})
this.limitSwitch.on('release', function() {
console.log( this.label + ' open' )
})
EventEmitter.call(this)
this.setMaxListeners(100)
}
get angle() {
if (this.label == "A") {
return Math.round((this.theta_home - (this.position.step / this.stepsPerRev * 360)) * 100) / 100
} else {
return Math.round((this.theta_home + (this.position.step / this.stepsPerRev * 360)) * 100) / 100
}
}
set angle(theta) {
if (this.position.step == null) { return }
if (this.label == "A") {
if ((theta > this.theta_home) || (theta < this.theta_max)) { return }
} else {
if ((theta < this.theta_home) || (theta > this.theta_max)) { return }
}
let steps = Math.round( this.stepsPerRev / 360 * (theta - this.angle) )
if (steps > 0) {
this.ccw(steps)
} else {
steps = Math.abs(steps)
this.cw(steps)
}
}
updatePosition() {
this.position.x1 = this.position.x0 + Math.round((Math.cos(TAU * this.angle / 360) * this.r0) * 100) / 100
this.position.y1 = Math.round((Math.sin(TAU * this.angle / 360) * this.r0) * 100) / 100
// Notify listeners
this.emit('position', this.position)
}
cw(numSteps = 100, rpm = 15) {
// Check if valid
if (this.position.step == null) { return }
if (typeof(numSteps) !== 'number') { return }
if (numSteps <= 0) { return }
if (this.homeDirection == 1) {
this.position.step += numSteps
} else {
if (this.position.step - numSteps < 0) { return }
this.position.step -= numSteps
}
this.motor.step({steps: numSteps, direction:0, rpm:rpm}, ()=>{})
this.updatePosition()
}
ccw(numSteps = 100, rpm = 15) {
// Check if valid
if (this.position.step == null) { return }
if (typeof(numSteps) !== 'number') { return }
if (numSteps <= 0) { return }
if (this.homeDirection == 1) {
if (this.position.step - numSteps < 0) { return }
this.position.step -= numSteps
} else {
this.position.step += numSteps
}
this.motor.step({steps: numSteps, direction:1, rpm:rpm}, ()=>{})
this.updatePosition()
}
home(interval = 4){
if (this.limitSwitch.value == 1) {
this.position.step = 0
this.updatePosition()
return
} else {
this.motor.step({steps: 1, direction: this.homeDirection, rpm:15}, ()=>{})
setTimeout(this.home.bind(this), interval, interval)
}
}
}
inherits(Arm, EventEmitter)
module.exports = Arm