-
Notifications
You must be signed in to change notification settings - Fork 0
/
frdmHID.js
188 lines (156 loc) · 6.74 KB
/
frdmHID.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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
// frdmHID.js - Communication with the FRDM board, USBHID
// Based on Dream Cheeky Big Red Button by Dj Walker-Morgan
var HID = require('node-hid');
var _ = require("underscore"); //Does not work in console
var FRDM_vendorId = 4660;
var FRDM_productId = 6;
// File variable to access the frmd
var frdmHIDdev;
// Protol specifications
// [b0-b2] - CmdType
var FRDM_cmdType_bit = 0;
var FRDM_cmdType_mask = 0x07;
var FRDM_cmdType_status = 0x00; // Get status
var FRDM_cmdType_set = 0x01; // Command describes an inmediate action
var FRDM_cmdType_store = 0x02; // Command describes an action to store
// b3 - _OFF(0)/ON(1). Motor Motor number (Not contained in command)
var FRDM_state_bit = 4;
var FRDM_state_mask = 0x01;
// b4 - SPEED. 0: Speed control disabled (Not contained in command)
var FRDM_speed_bit = 5;
var FRDM_speed_mask = 0x01;
// b5 - POSITION. 0: Position control disabled (Not contained in command)
var FRDM_position_bit = 6;
var FRDM_position_mask = 0x01;
// b6 - TIME, only for store commands. 0: time information not sent.
var FRDM_time_bit = 7;
var FRDM_time_mask = 0x01;
// b7 - UNDEFINDED
var INT16_MAX = 0x7FFF;
// Sends a desired motor state
function setMotorState(motorNo, state){
// Call the create command with only the state and motor no
sendCommand(createCommand(FRDM_cmdType_set, state, motorNo));
}
// Sends the desired motor speed
function setMotorSpeed(motorNo, state, speed){
// Convert speed from float to singed 16b
speed = speed*INT16_MAX | 0;
console.log(speed);
// Call the create command with only the state and motor no
sendCommand(createCommand(FRDM_cmdType_set, state, motorNo, speed));
}
// Sends the desire motor position. speed optional.
function setMotorPosition(motorNo, state, position, speed){
// Call the create command with only the state and motor no
sendCommand(createCommand(FRDM_cmdType_set, state, motorNo));
}
// Sends a store command. Speed and position are optional values.
function storeCommand(motorNo, state, time, speed, position){
// Call the create command with only the state and motor no
// Type is different from the others
sendCommand(createCommand(FRDM_cmdType_store, state, motorNo));
}
// Adds the CMD type header and payload length
// Data: list of bytes to send
function createCommand(cmdType, state, motorNo, speed, position, time){
if ( (cmdType === 'undefined') ||
( (cmdType != FRDM_cmdType_status) &&
( (state === 'undefined') || (motorNo === 'undefined') ) ||
( (cmdType != FRDM_cmdType_store) && (time === 'undefined') ) ) )
throw new Error('Required protocol arguments not fulfilled');
var cmd_buffer = new Buffer(100); // Much larger than required, then cropped
cmd_buffer.fill(0);
var lengthUsed = 0;
var cmd_enable = 0x00;
cmd_enable = cmd_enable | (cmdType & FRDM_cmdType_mask);
// Only if argument exists (is included)
if (state !== undefined){
cmd_enable = cmd_enable | (FRDM_state_mask << FRDM_state_bit);
}
if (motorNo !== undefined){
// Does not have enable bit
// Add motorNo byte
//cmd_buffer.writeUIntBE(0xAB, 0, 2);
cmd_buffer.writeUIntBE(motorNo, lengthUsed, 1);
lengthUsed++;
//cmd_buffer = Buffer.concat([cmd_buffer, (new Buffer([motorNo]))], cmd_buffer.length+1);
}
if (speed !== undefined){
// Update enable bit to reflect this information
cmd_enable = cmd_enable | (FRDM_speed_mask << FRDM_speed_bit);
cmd_buffer.writeIntBE(speed, lengthUsed, 2);
lengthUsed = lengthUsed + 2;
//cmd_buffer = Buffer.concat([cmd_buffer, (new Buffer([speed]))], cmd_buffer.length+2);
}
if (position !== undefined) {
cmd_enable = cmd_enable | (FRDM_position_mask << FRDM_position_bit);
cmd_buffer.writeUIntBE(position, lengthUsed, 1);
lengthUsed++;
//cmd_buffer = Buffer.concat([cmd_buffer, (new Buffer([position]))], cmd_buffer.length+1);
}
if (time !== undefined){
cmd_enable = cmd_enable | (FRDM_time_mask << FRDM_time_bit);
// TODO: check time lenght
// DONE: FIX second byte.
cmd_buffer.writeUIntBE(time, lengthUsed, 1);
lengthUsed++;
//cmd_buffer = Buffer.concat([cmd_buffer, (new Buffer([time]))], cmd_buffer.length+2);
}
var cmd_buffer_header = new Buffer(2);
// Add lenght
cmd_buffer_header.writeUIntBE(lengthUsed, 1, 1);
//cmd_buffer = Buffer.concat([(new Buffer([cmd_buffer.length])), cmd_buffer], cmd_buffer.length+1)
// Add enable bit first
cmd_buffer_header.writeUIntBE(cmd_enable, 0, 1);
//cmd_buffer = Buffer.concat([(new Buffer([cmd_enable])), cmd_buffer], cmd_buffer.length+1);
// Crop cmd_buffer to lenghtUsed and append header
cmd_buffer = Buffer.concat( [ cmd_buffer_header, (cmd_buffer.slice(0, lengthUsed)) ], cmd_buffer_header.length+lengthUsed );
// Note that if you want to disable auto-acknowlegment, you must also set a
// payload size — for some reason these are linked in the nRF24 feature set.
if (cmd_buffer.length > 32){
throw new Error('Command payload too long, NRF24 only supports 32 byte payload!');
}
return cmd_buffer;
}
function sendCommand(cmd){
console.log('Sending command: ', cmd);
frdmHIDdev.write(cmd);
}
function openHIDDevice(){
//console.log('\r\nHID devices', HID.devices());
// Same as HID.devices(FRDM_vendorId, FRMD_productId);
var frdmHID = _.where( HID.devices(), {vendorId: FRDM_vendorId,
productId: FRDM_productId});
if (!frdmHID.length){
throw new Error('No FRDM HID board detected');
}
//console.log('\r\nFRMD HID boards:', frdmHID);
if (frdmHID.length > 1){
console.log('More than one FRDM HID boards detected, using first one');
frdmHID = frdmHID[0];
}
else {
console.log('FRMD HID board found, serial no:', frdmHID[0].serialNumber);
}
// Open comunication
frdmHIDdev = new HID.HID(frdmHID[0].path);
console.log('HID dev channel open');
// Hook funcition to read from device
//frdmHIDdev.read(onRead);
frdmHIDdev.on('data', function (data) {
console.log("Incoming data: ", data);
});
// TODO: Implement error HID handler
frdmHIDdev.on("error", function(err) {
console.log('Error in HID procolol: ', err);
});
}
function closeHIDDevice(){
frdmHIDdev.close();
console.log('HID dev channel closed');
}
module.exports.openHIDDevice = openHIDDevice;
module.exports.closeHIDDevice = closeHIDDevice;
module.exports.setMotorState = setMotorState;
module.exports.setMotorSpeed = setMotorSpeed;