1 | var Board = require("./board"),
|
2 | events = require("events"),
|
3 | util = require("util"),
|
4 | within = require("./mixins/within");
|
5 |
|
6 | var priv = new Map();
|
7 | var Devices;
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 | function Sonar(opts) {
|
17 |
|
18 | if (!(this instanceof Sonar)) {
|
19 | return new Sonar(opts);
|
20 | }
|
21 |
|
22 | Board.Component.call(
|
23 | this, opts = Board.Options(opts)
|
24 | );
|
25 |
|
26 | var device, state;
|
27 |
|
28 |
|
29 | this.freq = opts.freq || 100;
|
30 | this.value = null;
|
31 |
|
32 | state = {
|
33 | last: 0,
|
34 | median: 0,
|
35 | samples: []
|
36 | };
|
37 |
|
38 | priv.set(this, state);
|
39 |
|
40 | if (typeof opts.device === "string") {
|
41 | device = Devices[opts.device];
|
42 | } else {
|
43 | device = opts.device;
|
44 | }
|
45 |
|
46 | if (typeof device === "undefined") {
|
47 | device = Devices.DEFAULT;
|
48 | }
|
49 |
|
50 | device.initialize.call(this, opts);
|
51 |
|
52 | if (!device.descriptor.inches) {
|
53 | device.descriptor.inches = {
|
54 | get: function() {
|
55 | return +(this.cm * 0.39).toFixed(2);
|
56 | }
|
57 | };
|
58 | }
|
59 |
|
60 | device.descriptor.in = device.descriptor.inches;
|
61 |
|
62 | Object.defineProperties(this, device.descriptor);
|
63 |
|
64 |
|
65 | setInterval(function() {
|
66 |
|
67 | if (state.samples.length === 0) {
|
68 | return;
|
69 | }
|
70 |
|
71 | state.median = state.samples.sort()[Math.floor(state.samples.length / 2)];
|
72 | this.value = state.median;
|
73 |
|
74 | this.emit("data", state.median);
|
75 |
|
76 |
|
77 |
|
78 |
|
79 | if (state.last && state.median &&
|
80 | (state.median.toFixed(1) !== state.last.toFixed(1))) {
|
81 | this.emit("change", state.median);
|
82 | }
|
83 |
|
84 |
|
85 |
|
86 | state.last = state.median;
|
87 |
|
88 |
|
89 | state.samples.length = 0;
|
90 | }.bind(this), this.freq);
|
91 | }
|
92 |
|
93 | util.inherits(Sonar, events.EventEmitter);
|
94 | Object.assign(Sonar.prototype, within);
|
95 |
|
96 | Devices = {
|
97 | SRF10: {
|
98 | initialize: function(opts) {
|
99 |
|
100 | var samples = priv.get(this).samples;
|
101 | var address = 0x70;
|
102 | var delay = 65;
|
103 |
|
104 |
|
105 | this.io.i2cConfig(opts);
|
106 |
|
107 |
|
108 | this.io.i2cWrite(address, [0x01, 16]);
|
109 | this.io.i2cWrite(address, [0x02, 255]);
|
110 |
|
111 | this.io.setMaxListeners(100);
|
112 |
|
113 | function read() {
|
114 | this.io.i2cWrite(address, [0x02]);
|
115 | this.io.i2cReadOnce(address, 2, function(data) {
|
116 | samples.push((data[0] << 8) | data[1]);
|
117 | }.bind(this));
|
118 |
|
119 | prime.call(this);
|
120 | }
|
121 |
|
122 | function prime() {
|
123 |
|
124 | this.io.i2cWrite(address, [0x00, 0x52]);
|
125 |
|
126 | setTimeout(read.bind(this), delay);
|
127 | }
|
128 |
|
129 | prime.call(this);
|
130 | },
|
131 | descriptor: {
|
132 | cm: {
|
133 | get: function() {
|
134 | var median = priv.get(this).median;
|
135 | return +((((median / 2) * 343.2) / 10) / 1000).toFixed(1);
|
136 | }
|
137 | }
|
138 | }
|
139 | },
|
140 |
|
141 | DEFAULT: {
|
142 | initialize: function() {
|
143 | var samples = priv.get(this).samples;
|
144 |
|
145 |
|
146 | this.mode = this.io.MODES.ANALOG;
|
147 | this.io.pinMode(this.pin, this.mode);
|
148 |
|
149 | this.io.analogRead(this.pin, function(data) {
|
150 | samples.push(data);
|
151 | }.bind(this));
|
152 | },
|
153 | descriptor: {
|
154 | cm: {
|
155 | get: function() {
|
156 | var median = priv.get(this).median;
|
157 | return +((median / 2) * 2.54).toFixed(1);
|
158 | }
|
159 | }
|
160 | }
|
161 | }
|
162 | };
|
163 |
|
164 | Devices.SRF02 = Devices.SRF08 = Devices.SRF10;
|
165 |
|
166 | module.exports = Sonar;
|
167 |
|
168 |
|
169 |
|
170 |
|
171 |
|
172 |
|
173 |
|
174 |
|
175 |
|