Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(9)

Side by Side Diff: chrome/common/extensions/docs/templates/articles/app_hardware.html

Issue 34603002: Moved app_hardware.html to app_usb.html. Will split out serial port (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Re-upload. Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | chrome/common/extensions/docs/templates/articles/app_usb.html » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 <h1>Accessing Hardware Devices</h1>
2
3 <p>
4 This doc shows you how Chrome Apps can connect to USB devices and read from
5 and write to a user's serial ports. See also the reference docs for the <a
6 href="usb.html">USB API</a> and the <a href="serial.html">Serial API</a>.
7 The <a href="bluetooth.html">Bluetooth API</a> is also available; we've
8 included a link to a Bluetooth sample below.
9 </p>
10
11 <p class="note">
12 <b>API Samples: </b> Want to play with the code? Check out the
13 <a href="https://github.com/GoogleChrome/chrome-app-samples/tree/master/serial ">serial</a>,
14 <a href="https://github.com/GoogleChrome/chrome-app-samples/tree/master/servo" >servo</a>,
15 <a href="https://github.com/GoogleChrome/chrome-app-samples/tree/master/usb">u sb</a>,
16 and
17 <a href="https://github.com/GoogleChrome/chrome-app-samples/tree/master/zephyr _hxm">zephyr_hxm
18 Bluetooth</a> samples.
19 </p>
20
21 <h2 id="usb">Accessing USB devices</h2>
22
23 <p>
24 You can use the <a href="usb.html">USB API</a> to communicate with USB devices
25 using only JavaScript code. Some devices are not accessible through this API
26 &ndash; see <a href="#caveats">Caveats</a> below for details.
27 </p>
28
29 <p>
30 For background information about USB, see the official
31 <a href="http://www.usb.org/home">USB specifications</a>. <br/>
32 <a href="http://www.beyondlogic.org/usbnutshell/usb1.shtml">
33 <i>USB in a NutShell</i></a>
34 is a reasonable crash course that you may find helpful.
35 </p>
36
37 <h3 id="manifest">Manifest requirement</h3>
38
39 <p>The USB API requires the "usb" permission in the manifest file:</p>
40
41 <pre data-filename="manifest.json">
42 "permissions": [
43 "usb"
44 ]
45 </pre>
46
47 <p>In addition, in order to prevent
48 <a href="http://en.wikipedia.org/wiki/Device_fingerprint">finger-printing</a>,
49 you must declare all the device types you want to access in the manifest file.
50 Each type of USB device corresponds to a vendor id/product id (VID/PID) pair.
51 You can use $ref:usb.getDevices to enumerate devices by their VID/PID
52 pair.
53 </p>
54 <p>
55 You must declare the VID/PID pairs for each type of device you want to use
56 under the "usbDevices" permission in your app's manifest file, as shown in the
57 example below:</p>
58
59 <pre data-filename="manifest.json">
60 "permissions": [
61 "usbDevices": [
62 {
63 "vendorId": 123,
64 "productId": 456
65 }
66 ]
67 ]
68 </pre>
69
70 <p class="note">Note that only decimal numbers are allowed in JSON format.
71 You cannot use hexadecimal numbers in these fields.</p>
72
73 <h3 id="finding_device">Finding a device</h3>
74
75 <p>
76 To determine whether one or more specific devices are connected to a user's
77 system, use the $ref:usb.getDevices method:
78 </p>
79
80 <pre>
81 chrome.usb.getDevices(enumerateDevicesOptions, callback);
82 </pre>
83
84 <br/>
85
86 <table class="simple">
87 <tr>
88 <th scope="col">Parameter (type)</th>
89 <th scope="col">Description</th>
90 </tr>
91 <tr>
92 <td>EnumerateDevicesOptions (object)</td>
93 <td>An object specifying both a <code>vendorId</code> (long) and
94 <code>productId</code> (long) used to find the correct type of device on
95 the bus. Your manifest must declare the <code>usbDevices</code> permission
96 section listing all the <code>vendorId</code> and <code>deviceId</code>
97 pairs your app wants to access.
98 </td>
99 </tr>
100 <tr>
101 <td>callback (function)</td>
102 <td>Called when the device enumeration is finished. The callback will be
103 executed with one parameter, an array of <code>Device</code> objects with
104 three properties: <code>device</code>, <code>vendorId</code>,
105 <code>productId</code>. The device property is a stable identifier for a
106 connected device. It will not change until the device is unplugged. The
107 detail of the identifier is opaque and subject to change. Do not rely on
108 its current type. <br/>
109 If no devices are found, the array will be empty.
110 </td>
111 </tr>
112 </table>
113
114 <p>Example:</p>
115
116 <pre>
117 function onDeviceFound(devices) {
118 this.devices=devices;
119 if (devices) {
120 if (devices.length > 0) {
121 console.log("Device(s) found: "+devices.length);
122 } else {
123 console.log("Device could not be found");
124 }
125 } else {
126 console.log("Permission denied.");
127 }
128 }
129
130 chrome.usb.getDevices({"vendorId": vendorId, "productId": productId}, onDeviceFo und);
131 </pre>
132
133 <h3 id="usb_open">Opening a device</h3>
134 <p>
135 Once the <code>Device</code> objects are returned, you can open a device using
136 usb.openDevice to obtain a connection handle. You can only
137 communicate with USB devices using connection handles.
138 </p>
139
140 <table class="simple">
141 <tr>
142 <th scope="col">Property</th>
143 <th scope="col">Description</th>
144 </tr>
145 <tr>
146 <td>device</td>
147 <td>Object received in $ref:usb.getDevices callback.</td>
148 </tr>
149 <tr>
150 <td>data (arraybuffer)</td>
151 <td>Contains the data sent by the device if the transfer was inbound.</td>
152 </tr>
153 </table>
154
155 <p>Example:</p>
156
157 <pre>
158 var usbConnection = null;
159 var onOpenCallback = function(connection) {
160 if (connection) {
161 usbConnection = connection;
162 console.log("Device opened.");
163 } else {
164 console.log("Device failed to open.");
165 }
166 };
167
168 chrome.usb.openDevice(device, onOpenCallback);
169 </pre>
170
171 <p class="note">
172 Not every device can be opened successfully. In general, operating systems
173 lock down many types of USB interfaces (e.g. keyboards and mice, mass storage
174 devices, webcams, etc.) and they cannot be claimed by user applications.
175 On Linux (other than Chrome OS), once an interface of a device is locked down by
176 the OS, the whole device is locked down (because all the interfaces shares the
177 same device file), even if the other interfaces of the device can be used in
178 theory. On Chrome OS, you can request access to unlocked interfaces using the
179 $ref:usb.requestAccess method. If permitted, the permission broker will
180 unlock the device file for you.
181 </p>
182
183 <p>
184 To simplify the opening process, you can use the $ref:usb.findDevices
185 method, which enumerates, requests access, and opens devices in one call:
186 </p>
187
188 <pre>
189 chrome.usb.findDevices({"vendorId": vendorId, "productId": productId, "interface Id": interfaceId}, callback);
190 </pre>
191 <p>which is equivalent to:</p>
192 <pre>
193 chrome.usb.getDevices({"vendorId": vendorId, "productId": productId}, function ( devices) {
194 if (!devices) {
195 console.log("Error enumerating devices.");
196 callback();
197 return;
198 }
199 var connections = [], pendingAccessRequests = devices.length;
200 devices.forEach(function (device) {
201 chrome.usb.requestAccess(interfaceId, function () {
202 // No need to check for errors at this point.
203 // Nothing can be done if an error occurs anyway. You should always try
204 // to open the device.
205 chrome.usb.openDevices(device, function (connection) {
206 if (connection) connections.push(connection);
207 pendingAccessRequests--;
208 if (pendingAccessRequests == 0) {
209 callback(connections);
210 }
211 });
212 });
213 })
214 });
215 </pre>
216
217 <h3 id="usb_transfers">USB transfers and receiving data from a device</h3>
218
219 <p>
220 The USB protocol defines four types of transfers:
221 <a href="#control_transfers">control</a>,
222 <a href="#bulk_transfers">bulk</a>,
223 <a href="#isochronous_transfers">isochronous</a>
224 and <a href="#interrupt_transfers">interrupt</a>.
225 These transfers are described below.
226 </p>
227
228 <p>
229 Transfers can occur in both directions: device-to-host (inbound), and
230 host-to-device (outbound). Due to the nature of the USB protocol,
231 both inbound and outbound messages must be initiated by the host (the
232 computer that runs the Chrome app).
233 For inbound (device-to-host) messages, the host (initiated by your JavaScript
234 code) sends a message flagged as "inbound" to the device.
235 The details of the message depend on the device, but usually will have
236 some identification of what you are requesting from it.
237 The device then responds with the requested data.
238 The device's response is handled by Chrome and delivered asynchronously to the
239 callback you specify in the transfer method.
240 An outbound (host-to-device) message is similar, but the response doesn't
241 contain data returned from the device.
242 </p>
243
244 <p>
245 For each message from the device, the specified callback will receive an event
246 object with the following properties:
247 </p>
248
249 <br>
250
251 <table class="simple">
252 <tr>
253 <th scope="col">Property</th>
254 <th scope="col">Description</th>
255 </tr>
256 <tr>
257 <td>resultCode (integer)</td>
258 <td>0 is success; other values indicate failure. An error string can be<br/>
259 read from <code>chrome.extension.lastError</code> when a failure is<br/>
260 indicated.
261 </td>
262 </tr>
263 <tr>
264 <td>data (arraybuffer)</td>
265 <td>Contains the data sent by the device if the transfer was inbound.</td>
266 </tr>
267 </table>
268
269 <p>Example:</p>
270
271 <pre>
272 var onTransferCallback = function(event) {
273 if (event && event.resultCode === 0 && event.data) {
274 console.log("got " + event.data.byteLength + " bytes");
275 }
276 };
277
278 chrome.usb.bulkTransfer(connectionHandle, transferInfo, onTransferCallback);
279 </pre>
280
281 <h3 id="control_transfers">CONTROL transfers</h3>
282
283 <p>Control transfers are generally used to send or receive configuration or
284 command parameters to a USB device. The controlTransfer method always sends
285 to/reads from endpoint 0, and no claimInterface is required.
286 The method is simple and receives three parameters:</p>
287
288 <pre>
289 chrome.usb.controlTransfer(connectionHandle, transferInfo, transferCallback)
290 </pre>
291
292 <br>
293
294 <table class="simple">
295 <tr>
296 <th scope="col">Parameter (types)</th>
297 <th scope="col">Description</th>
298 </tr>
299 <tr>
300 <td>connectionHandle</td>
301 <td>Object received in $ref:usb.openDevice callback.
302 </td>
303 </tr>
304 <tr>
305 <td>transferInfo</td>
306 <td>Parameter object with values from the table below. Check your USB
307 device protocol specification for details.
308 </td>
309 </tr>
310 <tr>
311 <td>transferCallback()</td>
312 <td>Invoked when the transfer has completed.</td>
313 </tr>
314 </table>
315
316 <p>
317 Values for
318 <code>transferInfo</code>
319 object:
320 </p>
321
322 <table class="simple">
323 <tr>
324 <th scope="col">Value</th>
325 <th scope="col">Description</th>
326 </tr>
327 <tr>
328 <td>requestType (string)</td>
329 <td>"vendor", "standard", "class" or "reserved".</td>
330 </tr>
331 <tr>
332 <td>recipient (string)</td>
333 <td>"device", "interface", "endpoint" or "other".</td>
334 </tr>
335 <tr>
336 <td>direction (string)</td>
337 <td>"in" or "out". The "in" direction is used to notify the device that<br/>
338 it should send information to the host. All communication on a USB<br/>
339 bus is host-initiated, so use an "in" transfer to allow a device to<br/>
340 send information back.
341 </td>
342 </tr>
343 <tr>
344 <td>request (integer)</td>
345 <td>Defined by your device's protocol.</td>
346 </tr>
347 <tr>
348 <td>value (integer)</td>
349 <td>Defined by your device's protocol.</td>
350 </tr>
351 <tr>
352 <td>index (integer)</td>
353 <td>Defined by your device's protocol.</td>
354 </tr>
355 <tr>
356 <td>length (integer)</td>
357 <td>Only used when direction is "in". Notifies the device that this is
358 the amount of data the host is expecting in response.
359 </td>
360 </tr>
361 <tr>
362 <td>data (arraybuffer)</td>
363 <td>Defined by your device's protocol, required when direction is
364 "out".
365 </td>
366 </tr>
367 </table>
368
369 <p>Example:</p>
370
371 <pre>
372 var transferInfo = {
373 "requestType": "vendor",
374 "recipient": "device",
375 "direction": "out",
376 "request": 0x31,
377 "value": 120,
378 "index": 0,
379 // Note that the ArrayBuffer, not the TypedArray itself is used.
380 "data": new Uint8Array([4, 8, 15, 16, 23, 42]).buffer
381 };
382 chrome.usb.controlTransfer(connectionHandle, transferInfo, optionalCallback);
383 </pre>
384
385 <h3 id="isochronous_transfers">ISOCHRONOUS transfers</h3>
386
387 <p>Isochronous transfers are the most complex type of USB transfer. They are
388 commonly used for streams of data, like video and sound. To initiate an
389 isochronous transfer (either inbound or outbound), you must use
390 the $ref:usb.isochronousTransfer method:</p>
391
392 <pre>
393 chrome.usb.isochronousTransfer(connectionHandle, isochronousTransferInfo, transf erCallback)
394 </pre>
395
396 <br/>
397
398 <table class="simple">
399 <tr>
400 <th scope="col">Parameter</th>
401 <th scope="col">Description</th>
402 </tr>
403 <tr>
404 <td>connectionHandle</td>
405 <td>Object received in $ref:usb.openDevice callback.
406 </td>
407 </tr>
408 <tr>
409 <td>isochronousTransferInfo</td>
410 <td>Parameter object with the values in the table below.</td>
411 </tr>
412 <tr>
413 <td>transferCallback()</td>
414 <td>Invoked when the transfer has completed.</td>
415 </tr>
416 </table>
417
418 <p>
419 Values for
420 <code>isochronousTransferInfo</code>
421 object:
422 </p>
423
424 <table class="simple">
425 <tr>
426 <th scope="col">Value</th>
427 <th scope="col">Description</th>
428 </tr>
429 <tr>
430 <td>transferInfo (object)</td>
431 <td>An object with the following attributes:<br/>
432 <b>direction (string): </b>"in" or "out".<br/>
433 <b>endpoint (integer): </b>defined by your device. Usually can be found by
434 looking at an USB instrospection tool, like <code>lsusb -v</code><br/>
435 <b>length (integer): </b>only
436 used when direction is "in". Notifies the device that this is the amount
437 of data the host is expecting in response. <br/>
438
439 Should be AT LEAST <code>packets</code> &times; <code>packetLength</code>.
440 <br/>
441 <b>data (arraybuffer): </b>defined by your device's protocol;
442 only used when direction is "out".
443 </td>
444 </tr>
445 <tr>
446 <td>packets (integer)</td>
447 <td>Total number of packets expected in this transfer.</td>
448 </tr>
449 <tr>
450 <td>packetLength (integer)</td>
451 <td>Expected length of each packet in this transfer.</td>
452 </tr>
453 </table>
454
455 <p>Example:</p>
456
457 <pre>
458 var transferInfo = {
459 "direction": "in",
460 "endpoint": 1,
461 "length": 2560
462 };
463
464 var isoTransferInfo = {
465 "transferInfo": transferInfo,
466 "packets": 20,
467 "packetLength": 128
468 };
469
470 chrome.usb.isochronousTransfer(connectionHandle, isoTransferInfo, optionalCallba ck);
471 </pre>
472
473 <p class="note">
474 <b>Notes:</b> One isochronous transfer will contain
475 <code>isoTransferInfo.packets</code> packets of
476 <code>isoTransferInfo.packetLength</code> bytes.
477 If it is an inbound transfer (your code requested data from the device), the
478 <code>data</code> field in the onUsbEvent will be an ArrayBuffer of size
479 <code>transferInfo.length</code>. It is your duty to walk through this
480 ArrayBuffer and extract the different packets, each starting at a multiple of
481 <code>isoTransferInfo.packetLength</code> bytes. <br/>
482 <br/>
483 If you are expecting a stream of data from the device, remember that
484 you will have to send one "inbound" transfer for each transfer you expect
485 back. USB devices don't send transfers to the USB bus unless the host
486 explicitly requests them through "inbound" transfers.
487 </p>
488
489 <h3 id="bulk_transfers">BULK transfers</h3>
490
491 <p>Bulk transfers are commonly used to transfer a large amount of
492 non-time-sensitive data in a reliable way.
493 $ref:usb.bulkTransfer has three parameters:</p>
494
495 <pre>
496 chrome.usb.bulkTransfer(connectionHandle, transferInfo, transferCallback);
497 </pre>
498
499 <br>
500
501 <table class="simple">
502 <tr>
503 <th scope="col">Parameter</th>
504 <th scope="col">Description</th>
505 </tr>
506 <tr>
507 <td>connectionHandle</td>
508 <td>Object received in $ref:usb.openDevice callback.
509 </td>
510 </tr>
511 <tr>
512 <td>transferInfo</td>
513 <td>Parameter object with the values in the table below.</td>
514 </tr>
515 <tr>
516 <td>transferCallback</td>
517 <td>Invoked when the transfer has completed.</td>
518 </tr>
519 </table>
520
521 <p>
522 Values for
523 <code>transferInfo</code>
524 object:
525 </p>
526
527 <table class="simple">
528 <tr>
529 <th scope="col">Value</th>
530 <th scope="col">Description</th>
531 </tr>
532 <tr>
533 <td>direction (string)</td>
534 <td>"in" or "out".</td>
535 </tr>
536 <tr>
537 <td>endpoint (integer)</td>
538 <td>Defined by your device's protocol.</td>
539 </tr>
540 <tr>
541 <td>length (integer)</td>
542 <td>Only used when direction is "in". Notifies the device that this is
543 the amount of data the host is expecting in response.
544 </td>
545 </tr>
546 <tr>
547 <td>data (ArrayBuffer)</td>
548 <td>Defined by your device's protocol; only used when direction is
549 "out".
550 </td>
551 </tr>
552 </table>
553
554 <p>Example:</p>
555
556 <pre>
557 var transferInfo = {
558 "direction": "out",
559 "endpoint": 1,
560 "data": new Uint8Array([4, 8, 15, 16, 23, 42]).buffer
561 };
562 </pre>
563
564 <h3 id="interrupt_transfers">INTERRUPT transfers</h3>
565
566 <p>Interrupt transfers are used to small amount of time sensitive data.
567 Since all USB communication is initiated by the host, host code usually polls
568 the device periodically, sending interrupt IN transfers that will make the
569 device send data back if there is anything in the interrupt queue (maintained
570 by the device).
571 $ref:usb.interruptTransfer has three parameters:</p>
572
573 <pre>
574 chrome.usb.interruptTransfer(connectionHandle, transferInfo, transferCallback);
575 </pre>
576
577 <br>
578
579 <table class="simple">
580 <tr>
581 <th scope="col">Parameter</th>
582 <th scope="col">Description</th>
583 </tr>
584 <tr>
585 <td>connectionHandle</td>
586 <td>Object received in $ref:usb.openDevice callback.
587 </td>
588 </tr>
589 <tr>
590 <td>transferInfo</td>
591 <td>Parameter object with the values in the table below.</td>
592 </tr>
593 <tr>
594 <td>transferCallback</td>
595 <td>Invoked when the transfer has completed. Notice that this callback
596 doesn't contain the device's response. The purpose of the callback is
597 simply to notify your code that the asynchronous transfer requests has
598 been processed.
599 </td>
600 </tr>
601 </table>
602
603 <p>
604 Values for <code>transferInfo</code> object:
605 </p>
606
607 <table class="simple">
608 <tr>
609 <th scope="col">Value</th>
610 <th scope="col">Description</th>
611 </tr>
612 <tr>
613 <td>direction (string)</td>
614 <td>"in" or "out".</td>
615 </tr>
616 <tr>
617 <td>endpoint (integer)</td>
618 <td>Defined by your device's protocol.</td>
619 </tr>
620 <tr>
621 <td>length (integer)</td>
622 <td>Only used when direction is "in". Notifies the device that this is
623 the amount of data the host is expecting in response.
624 </td>
625 </tr>
626 <tr>
627 <td>data (ArrayBuffer)</td>
628 <td>Defined by your device's protocol; only used when direction is
629 "out".
630 </td>
631 </tr>
632 </table>
633
634 <p>Example:</p>
635
636 <pre>
637 var transferInfo = {
638 "direction": "in",
639 "endpoint": 1,
640 "length": 2
641 };
642 chrome.usb.interruptTransfer(connectionHandle, transferInfo, optionalCallback);
643 </pre>
644
645 <h3 id="caveats">Caveats</h3>
646
647 <p>Not all devices can be accessed through the USB API. In general, devices
648 are not accessible because either the Operating System's kernel or a native
649 driver holds them off from user space code. Some examples are devices with
650 HID profiles on OSX systems, and USB pen drives.</p>
651
652 <p>
653 On most Linux systems, USB devices are mapped with read-only permissions by
654 default. To open a device through this API, your user will need to have
655 write access to it too.
656 A simple solution is to set a udev rule. Create a file
657 <code>/etc/udev/rules.d/50-yourdevicename.rules</code>
658 with the following content:
659 </p>
660
661 <pre>
662 SUBSYSTEM=="usb", ATTR{idVendor}=="[yourdevicevendor]", MODE="0664", GROUP="plug dev"
663 </pre>
664
665 <p>
666 Then, just restart the udev daemon: <code>service udev restart</code>.
667 You can check if device permissions are set correctly by following these
668 steps:
669 </p>
670
671 <ul>
672 <li>Run <code>lsusb</code> to find the bus and device numbers.</li>
673 <li>Run <code>ls -al /dev/bus/usb/[bus]/[device]</code>. This file should be
674 owned by group "plugdev" and have group write permissions.
675 </li>
676 </ul>
677
678 <p>Your app cannot do this automatically since this this procedure requires root
679 access. We recommend that you provide instructions to end-users and link to the
680 <a href="#caveats">Caveats</a> section on this page for an explanation.</p>
681
682 <p>On Chrome OS, simply call $ref:usb.requestAccess. The permission
683 broker does this for you.</p>
684
685 <h2 id="serial">Accessing serial devices</h2>
686
687 <p>
688 You can use the serial API to read
689 and write from a serial device.
690 </p>
691
692 <h3 id="requirement">Manifest requirement</h3>
693
694 <p>
695 You must add the "serial" permission to the manifest file:
696 </p>
697 <pre data-filename="manifest.json">
698 "permissions": [
699 "serial"
700 ]
701 </pre>
702
703 <h3 id="listing">Listing available serial ports</h3>
704
705 <p>
706 To get a list of available serial ports,
707 use the <code>getPorts()</code> method. <b>Note:</b> not all serial ports are av ailable. The API uses a heuristic based on the name of the port to only expose s erial devices that are expected to be safe.
708 </p>
709
710 <pre>
711 var onGetPorts = function(ports) {
712 for (var i=0; i&lt;ports.length; i++) {
713 console.log(ports[i]);
714 }
715 }
716 chrome.serial.getPorts(onGetPorts);
717 </pre>
718
719 <h3 id="opening">Opening a serial device</h3>
720
721 <p>
722 If you know the serial port name, you can open it for read and write using the < code>open</code> method:
723 </p>
724
725 <pre>
726 chrome.serial.open(portName, options, openCallback)
727 </pre>
728
729 <table border="0">
730 <tr>
731 <th scope="col"> Parameter </th>
732 <th scope="col"> Description </th>
733 </tr>
734 <tr>
735 <td>portName&nbsp;(string)</td>
736 <td>If your device's port name is unknown, you can use the <code>getPorts</c ode> method.</td>
737 </tr>
738 <tr>
739 <td>options&nbsp;(object)</td>
740 <td>Parameter object with one single value: <code>bitrate</code>, an integer specifying the desired bitrate used to communicate with the serial port.</td>
741 </tr>
742 <tr>
743 <td>openCallback</td>
744 <td>Invoked when the port has been successfully opened. The callback will be called with one parameter, <code>openInfo</code>, that has one attribute, <code >connectionId</code>. Save this id, because you will need it to actually communi cate with the port.
745 </td>
746 </tr>
747 </table>
748
749 <p>A simple example:</p>
750
751 <pre>
752 var onOpen = function(connectionInfo) {
753 // The serial port has been opened. Save its id to use later.
754 _this.connectionId = connectionInfo.connectionId;
755 // Do whatever you need to do with the opened port.
756 }
757 // Open the serial port /dev/ttyS01
758 chrome.serial.open("/dev/ttyS01", {bitrate: 115200}, onOpen);
759 </pre>
760
761 <h3 id="closing">Closing a serial port</h3>
762
763 <p>
764 Closing a serial port is simple but very important. See the example below:
765 </p>
766
767 <pre>
768 var onClose = function(result) {
769 console.log("Serial port closed");
770 }
771 chrome.serial.close(connectionId, onClose);
772 </pre>
773
774 <h3 id="reading">Reading from a serial port</h3>
775
776 <p>
777 The serial API reads from the serial port and
778 delivers the read bytes as an ArrayBuffer.
779 There is no guarantee that all the requested bytes, even if available in the por t, will be read in one chunk.
780 The following example can accumulate read bytes, at most 128 at a time, until a new line is read,
781 and then call a listener with the <code>ArrayBuffer</code> bytes converted to a String:
782 </p>
783
784 <pre>
785 var dataRead='';
786
787 var onCharRead=function(readInfo) {
788 if (!connectionInfo) {
789 return;
790 }
791 if (readInfo &amp;&amp; readInfo.bytesRead>0 &amp;&amp; readInfo.data) {
792 var str=ab2str(readInfo.data);
793 if (str[readInfo.bytesRead-1]==='\n') {
794 dataRead+=str.substring(0, readInfo.bytesRead-1);
795 onLineRead(dataRead);
796 dataRead="";
797 } else {
798 dataRead+=str;
799 }
800 }
801 chrome.serial.read(connectionId, 128, onCharRead);
802 }
803
804 /* Convert an ArrayBuffer to a String, using UTF-8 as the encoding scheme.
805 This is consistent with how Arduino sends characters by default */
806 var ab2str=function(buf) {
807 return String.fromCharCode.apply(null, new Uint8Array(buf));
808 };
809 </pre>
810
811 <h3 id="writing">Writing to a serial port</h3>
812
813 <p>
814 The writing routine is simpler than reading,
815 since the writing can occur all at once.
816 The only catch is that if your data protocol is String based,
817 you have to convert your output string to an <code>ArrayBuffer</code>.
818 See the code example below:
819 </p>
820
821 <pre>
822 var writeSerial=function(str) {
823 chrome.serial.write(connectionId, str2ab(str), onWrite);
824 }
825 // Convert string to ArrayBuffer
826 var str2ab=function(str) {
827 var buf=new ArrayBuffer(str.length);
828 var bufView=new Uint8Array(buf);
829 for (var i=0; i&lt;str.length; i++) {
830 bufView[i]=str.charCodeAt(i);
831 }
832 return buf;
833 }
834 </pre>
835
836 <h3 id="flushing">Flushing a serial port buffer</h3>
837
838 <p>
839 You can flush your serial port buffer by issuing the flush command:
840 </p>
841
842 <pre>
843 chrome.serial.flush(connectionId, onFlush);
844 </pre>
845
846 <p class="backtotop"><a href="#top">Back to top</a></p>
OLDNEW
« no previous file with comments | « no previous file | chrome/common/extensions/docs/templates/articles/app_usb.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698