forked from espruino/EspruinoDocs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPixy.js
124 lines (106 loc) · 2.87 KB
/
Pixy.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
/* Copyright (c) 2014 Gordon Williams, Pur3 Ltd. See the file LICENSE for copying permission. */
/*
Module for CMUcam5 'Pixy' camera
```
SPI2.setup({sck : B13, miso : B14, mosi : B15, baud : 1000000});
var pixy = exports.connect(SPI2);
console.log(pixy.getBlocks());
```
*/
var C = {
PIXY_START_WORD : 0xaa55,
PIXY_START_WORDX : 0x55aa,
PIXY_MAXIMUM_ARRAYSIZE : 130,
PIXY_SYNC_BYTE : 0x5a,
PIXY_SYNC_BYTE_DATA : 0x5b,
PIXY_OUTBUF_SIZE : 6
};
function Pixy(spi) {
this.spi = spi;
this.skipStart = false;
this.outIndex = 0;
this.outBuf = undefined;
}
/** For internal use - get a work and send out any queued up data */
Pixy.prototype.getWord = function() {
// ordering is different because Pixy is sending 16 bits through SPI
// instead of 2 bytes in a 16-bit word as with I2C
var w, cout = 0;
if (outBuf)
{
w = this.spi.send(C.PIXY_SYNC_BYTE_DATA);
cout = outBuf[outIndex++];
if (outIndex==outLen)
outBuf = undefined;
}
else
w = this.spi.send(C.PIXY_SYNC_BYTE);
return (w<<8) | this.spi.send(cout);
};
/** For internal use - get a single byte */
Pixy.prototype.getByte = function() {
return this.spi.send(0x00);
};
/** For internal use - queue the given data to be sent */
Pixy.prototype.send = function(data) {
if (outBuf) return -1;
outBuf = data;
outIndex = 0;
return len;
};
/** For internal use - get the start of a frame */
Pixy.prototype.getStart = function() {
var lastw = 0xffff;
while(true) {
var w = this.getWord();
if (w===0 && lastw===0) {
// delayMicroseconds(10);
return false;
} else if (w==C.PIXY_START_WORD && lastw==C.PIXY_START_WORD)
return true;
else if (w==C.PIXY_START_WORDX) {
console.log("reorder");
this.getByte(); // resync
}
lastw = w;
}
};
/** Get an array of tracked blocks in the form:
{ id: number, x: number, y: number, width: number, height: number }
*/
Pixy.prototype.getBlocks = function() {
var blocks = [];
if (!this.skipStart) {
if (!this.getStart())
return [];
} else
this.skipStart = false;
while (blocks.length < C.PIXY_MAXIMUM_ARRAYSIZE) {
var checksum = this.getWord();
if (checksum==C.PIXY_START_WORD) {
// we've reached the beginning of the next frame
this.skipStart = true;
return blocks;
}
else if (checksum===0)
return blocks;
var block = {
id : this.getWord(),
x : this.getWord(),
y : this.getWord(),
width : this.getWord(),
height : this.getWord()
};
if (checksum==block.id+block.x+block.y+block.width+block.height)
blocks.push(block);
else
console.log("cs error");
if (this.getWord()!=C.PIXY_START_WORD)
return blocks;
}
return blocks;
};
/** Return a new Pixy object that's connected to the given SPI port */
exports.connect = function(spi) {
return new Pixy(spi);
};