lede-packages-rs

git clone git://archive.git.mtrnord.blog/MTRNord/lede-packages-rs.git
Log | Files | Refs | README | LICENSE

arduino-firmata.js (10835B)


      1 (function() {
      2   'use strict';
      3   var ArduinoFirmata, SerialPort, debug, events, exports, serialport,
      4     extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
      5     hasProp = {}.hasOwnProperty;
      6 
      7   events = require('eventemitter2');
      8 
      9   SerialPort = (serialport = require('serialport')).SerialPort;
     10 
     11   debug = require('debug')('arduino-firmata');
     12 
     13   exports = module.exports = ArduinoFirmata = (function(superClass) {
     14     extend(ArduinoFirmata, superClass);
     15 
     16     ArduinoFirmata.Status = {
     17       CLOSE: 0,
     18       OPEN: 1
     19     };
     20 
     21     ArduinoFirmata.INPUT = 0;
     22 
     23     ArduinoFirmata.OUTPUT = 1;
     24 
     25     ArduinoFirmata.ANALOG = 2;
     26 
     27     ArduinoFirmata.PWM = 3;
     28 
     29     ArduinoFirmata.SERVO = 4;
     30 
     31     ArduinoFirmata.SHIFT = 5;
     32 
     33     ArduinoFirmata.I2C = 6;
     34 
     35     ArduinoFirmata.LOW = 0;
     36 
     37     ArduinoFirmata.HIGH = 1;
     38 
     39     ArduinoFirmata.MAX_DATA_BYTES = 32;
     40 
     41     ArduinoFirmata.DIGITAL_MESSAGE = 0x90;
     42 
     43     ArduinoFirmata.ANALOG_MESSAGE = 0xE0;
     44 
     45     ArduinoFirmata.REPORT_ANALOG = 0xC0;
     46 
     47     ArduinoFirmata.REPORT_DIGITAL = 0xD0;
     48 
     49     ArduinoFirmata.SET_PIN_MODE = 0xF4;
     50 
     51     ArduinoFirmata.REPORT_VERSION = 0xF9;
     52 
     53     ArduinoFirmata.SYSTEM_RESET = 0xFF;
     54 
     55     ArduinoFirmata.START_SYSEX = 0xF0;
     56 
     57     ArduinoFirmata.END_SYSEX = 0xF7;
     58 
     59     ArduinoFirmata.list = function(callback) {
     60       return serialport.list(function(err, ports) {
     61         var devices, j, len, port;
     62         if (err) {
     63           return callback(err);
     64         }
     65         devices = [];
     66         for (j = 0, len = ports.length; j < len; j++) {
     67           port = ports[j];
     68           if (/usb|acm|com\d+/i.test(port.comName)) {
     69             devices.push(port.comName);
     70           }
     71         }
     72         return callback(null, devices);
     73       });
     74     };
     75 
     76     function ArduinoFirmata() {
     77       this.status = ArduinoFirmata.Status.CLOSE;
     78       this.wait_for_data = 0;
     79       this.execute_multi_byte_command = 0;
     80       this.multi_byte_channel = 0;
     81       this.stored_input_data = [];
     82       this.parsing_sysex = false;
     83       this.sysex_bytes_read = 0;
     84       this.digital_output_data = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
     85       this.digital_input_data = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
     86       this.analog_input_data = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
     87       this.boardVersion = null;
     88     }
     89 
     90     ArduinoFirmata.prototype.isOldArduinoDevice = function() {
     91       return /usbserial|USB/.test(this.serialport_name);
     92     };
     93 
     94     ArduinoFirmata.prototype.connect = function(serialport_name, opts) {
     95       this.serialport_name = serialport_name;
     96       if (opts == null) {
     97         opts = {
     98           baudrate: 57600
     99         };
    100       }
    101       opts.parser = serialport.parsers.raw;
    102       if (!this.serialport_name) {
    103         ArduinoFirmata.list((function(_this) {
    104           return function(err, devices) {
    105             return _this.connect(devices[0], opts);
    106           };
    107         })(this));
    108         return this;
    109       }
    110       this.once('boardReady', function() {
    111         var io_init_wait;
    112         debug('boardReady');
    113         io_init_wait = this.isOldArduinoDevice() ? (debug("old arduino device found " + this.serialport_name), 3000) : (debug("new arduino device found " + this.serialport_name), 100);
    114         debug("wait " + io_init_wait + "(msec)");
    115         return setTimeout((function(_this) {
    116           return function() {
    117             var i, j, k;
    118             for (i = j = 0; j < 6; i = ++j) {
    119               _this.write([ArduinoFirmata.REPORT_ANALOG | i, 1]);
    120             }
    121             for (i = k = 0; k < 2; i = ++k) {
    122               _this.write([ArduinoFirmata.REPORT_DIGITAL | i, 1]);
    123             }
    124             debug('init IO ports');
    125             return _this.emit('connect');
    126           };
    127         })(this), io_init_wait);
    128       });
    129       this.serialport = new SerialPort(this.serialport_name, opts);
    130       this.serialport.once('open', (function(_this) {
    131         return function() {
    132           var cid;
    133           cid = setInterval(function() {
    134             debug('request REPORT_VERSION');
    135             return _this.write([ArduinoFirmata.REPORT_VERSION]);
    136           }, 500);
    137           _this.once('boardVersion', function(version) {
    138             clearInterval(cid);
    139             _this.status = ArduinoFirmata.Status.OPEN;
    140             return _this.emit('boardReady');
    141           });
    142           return _this.serialport.on('data', function(data) {
    143             var byte, j, len, results;
    144             results = [];
    145             for (j = 0, len = data.length; j < len; j++) {
    146               byte = data[j];
    147               results.push(_this.process_input(byte));
    148             }
    149             return results;
    150           });
    151         };
    152       })(this));
    153       return this;
    154     };
    155 
    156     ArduinoFirmata.prototype.isOpen = function() {
    157       return this.status === ArduinoFirmata.Status.OPEN;
    158     };
    159 
    160     ArduinoFirmata.prototype.close = function(callback) {
    161       this.status = ArduinoFirmata.Status.CLOSE;
    162       return this.serialport.close(callback);
    163     };
    164 
    165     ArduinoFirmata.prototype.reset = function(callback) {
    166       return this.write([ArduinoFirmata.SYSTEM_RESET], callback);
    167     };
    168 
    169     ArduinoFirmata.prototype.write = function(bytes, callback) {
    170       return this.serialport.write(bytes, callback);
    171     };
    172 
    173     ArduinoFirmata.prototype.sysex = function(command, data, callback) {
    174       var write_data;
    175       if (data == null) {
    176         data = [];
    177       }
    178       data = data.map(function(i) {
    179         return i & 0x7f;
    180       });
    181       write_data = [ArduinoFirmata.START_SYSEX, command].concat(data, [ArduinoFirmata.END_SYSEX]);
    182       return this.write(write_data, callback);
    183     };
    184 
    185     ArduinoFirmata.prototype.pinMode = function(pin, mode, callback) {
    186       switch (mode) {
    187         case true:
    188           mode = ArduinoFirmata.OUTPUT;
    189           break;
    190         case false:
    191           mode = ArduinoFirmata.INPUT;
    192       }
    193       return this.write([ArduinoFirmata.SET_PIN_MODE, pin, mode], callback);
    194     };
    195 
    196     ArduinoFirmata.prototype.digitalWrite = function(pin, value, callback) {
    197       var port_num;
    198       this.pinMode(pin, ArduinoFirmata.OUTPUT);
    199       port_num = (pin >>> 3) & 0x0F;
    200       if (value === 0 || value === false) {
    201         this.digital_output_data[port_num] &= ~(1 << (pin & 0x07));
    202       } else {
    203         this.digital_output_data[port_num] |= 1 << (pin & 0x07);
    204       }
    205       return this.write([ArduinoFirmata.DIGITAL_MESSAGE | port_num, this.digital_output_data[port_num] & 0x7F, this.digital_output_data[port_num] >>> 7], callback);
    206     };
    207 
    208     ArduinoFirmata.prototype.analogWrite = function(pin, value, callback) {
    209       value = Math.floor(value);
    210       this.pinMode(pin, ArduinoFirmata.PWM);
    211       return this.write([ArduinoFirmata.ANALOG_MESSAGE | (pin & 0x0F), value & 0x7F, value >>> 7], callback);
    212     };
    213 
    214     ArduinoFirmata.prototype.servoWrite = function(pin, angle, callback) {
    215       this.pinMode(pin, ArduinoFirmata.SERVO);
    216       return this.write([ArduinoFirmata.ANALOG_MESSAGE | (pin & 0x0F), angle & 0x7F, angle >>> 7], callback);
    217     };
    218 
    219     ArduinoFirmata.prototype.digitalRead = function(pin) {
    220       return ((this.digital_input_data[pin >>> 3] >>> (pin & 0x07)) & 0x01) > 0;
    221     };
    222 
    223     ArduinoFirmata.prototype.analogRead = function(pin) {
    224       return this.analog_input_data[pin];
    225     };
    226 
    227     ArduinoFirmata.prototype.process_input = function(input_data) {
    228       var analog_value, command, diff, i, j, old_analog_value, results, stat, sysex_command, sysex_data;
    229       if (this.parsing_sysex) {
    230         if (input_data === ArduinoFirmata.END_SYSEX) {
    231           this.parsing_sysex = false;
    232           sysex_command = this.stored_input_data[0];
    233           sysex_data = this.stored_input_data.slice(1, this.sysex_bytes_read);
    234           return this.emit('sysex', {
    235             command: sysex_command,
    236             data: sysex_data
    237           });
    238         } else {
    239           this.stored_input_data[this.sysex_bytes_read] = input_data;
    240           return this.sysex_bytes_read += 1;
    241         }
    242       } else if (this.wait_for_data > 0 && input_data < 128) {
    243         this.wait_for_data -= 1;
    244         this.stored_input_data[this.wait_for_data] = input_data;
    245         if (this.execute_multi_byte_command !== 0 && this.wait_for_data === 0) {
    246           switch (this.execute_multi_byte_command) {
    247             case ArduinoFirmata.DIGITAL_MESSAGE:
    248               input_data = (this.stored_input_data[0] << 7) + this.stored_input_data[1];
    249               diff = this.digital_input_data[this.multi_byte_channel] ^ input_data;
    250               this.digital_input_data[this.multi_byte_channel] = input_data;
    251               if (this.listeners('digitalChange').length > 0) {
    252                 results = [];
    253                 for (i = j = 0; j <= 13; i = ++j) {
    254                   if (((0x01 << i) & diff) > 0) {
    255                     stat = (input_data & diff) > 0;
    256                     results.push(this.emit('digitalChange', {
    257                       pin: i + this.multi_byte_channel * 8,
    258                       value: stat,
    259                       old_value: !stat
    260                     }));
    261                   } else {
    262                     results.push(void 0);
    263                   }
    264                 }
    265                 return results;
    266               }
    267               break;
    268             case ArduinoFirmata.ANALOG_MESSAGE:
    269               analog_value = (this.stored_input_data[0] << 7) + this.stored_input_data[1];
    270               old_analog_value = this.analogRead(this.multi_byte_channel);
    271               this.analog_input_data[this.multi_byte_channel] = analog_value;
    272               if (old_analog_value !== analog_value) {
    273                 return this.emit('analogChange', {
    274                   pin: this.multi_byte_channel,
    275                   value: analog_value,
    276                   old_value: old_analog_value
    277                 });
    278               }
    279               break;
    280             case ArduinoFirmata.REPORT_VERSION:
    281               this.boardVersion = this.stored_input_data[1] + "." + this.stored_input_data[0];
    282               return this.emit('boardVersion', this.boardVersion);
    283           }
    284         }
    285       } else {
    286         if (input_data < 0xF0) {
    287           command = input_data & 0xF0;
    288           this.multi_byte_channel = input_data & 0x0F;
    289         } else {
    290           command = input_data;
    291         }
    292         if (command === ArduinoFirmata.START_SYSEX) {
    293           this.parsing_sysex = true;
    294           return this.sysex_bytes_read = 0;
    295         } else if (command === ArduinoFirmata.DIGITAL_MESSAGE || command === ArduinoFirmata.ANALOG_MESSAGE || command === ArduinoFirmata.REPORT_VERSION) {
    296           this.wait_for_data = 2;
    297           return this.execute_multi_byte_command = command;
    298         }
    299       }
    300     };
    301 
    302     return ArduinoFirmata;
    303 
    304   })(events.EventEmitter2);
    305 
    306 }).call(this);