Ignore:
Timestamp:
Apr 30, 2016, 11:29:25 PM (8 years ago)
Author:
ertl-honda
Message:

1.7.10のファイルに更新

Location:
rtos_arduino/trunk/arduino_lib/libraries/Firmata
Files:
45 added
10 edited

Legend:

Unmodified
Added
Removed
  • rtos_arduino/trunk/arduino_lib/libraries/Firmata/examples/AllInputsFirmata/AllInputsFirmata.ino

    r136 r224  
    2323int previousAnalogValues[TOTAL_ANALOG_PINS];
    2424
    25 byte portStatus[TOTAL_PORTS];   // each bit: 1=pin is digital input, 0=other/ignore
     25byte portStatus[TOTAL_PORTS]; // each bit: 1=pin is digital input, 0=other/ignore
    2626byte previousPINs[TOTAL_PORTS];
    2727
     
    4646  byte i, port, status;
    4747
    48   Firmata.setFirmwareVersion(0, 1);
     48  Firmata.setFirmwareVersion(FIRMATA_FIRMWARE_MAJOR_VERSION, FIRMATA_FIRMWARE_MINOR_VERSION);
    4949
    5050  for (pin = 0; pin < TOTAL_PINS; pin++) {
  • rtos_arduino/trunk/arduino_lib/libraries/Firmata/examples/AnalogFirmata/AnalogFirmata.ino

    r136 r224  
    5454{
    5555  if (value == 0) {
    56     analogInputsToReport = analogInputsToReport &~ (1 << pin);
     56    analogInputsToReport = analogInputsToReport & ~ (1 << pin);
    5757  }
    5858  else { // everything but 0 enables reporting of that pin
     
    6767void setup()
    6868{
    69   Firmata.setFirmwareVersion(0, 2);
     69  Firmata.setFirmwareVersion(FIRMATA_FIRMWARE_MAJOR_VERSION, FIRMATA_FIRMWARE_MINOR_VERSION);
    7070  Firmata.attach(ANALOG_MESSAGE, analogWriteCallback);
    7171  Firmata.attach(REPORT_ANALOG, reportAnalogCallback);
  • rtos_arduino/trunk/arduino_lib/libraries/Firmata/examples/EchoString/EchoString.ino

    r136 r224  
    2222
    2323
    24 void sysexCallback(byte command, byte argc, byte*argv)
     24void sysexCallback(byte command, byte argc, byte *argv)
    2525{
    2626  Firmata.sendSysex(command, argc, argv);
     
    2929void setup()
    3030{
    31   Firmata.setFirmwareVersion(0, 1);
     31  Firmata.setFirmwareVersion(FIRMATA_FIRMWARE_MAJOR_VERSION, FIRMATA_FIRMWARE_MINOR_VERSION);
    3232  Firmata.attach(STRING_DATA, stringCallback);
    3333  Firmata.attach(START_SYSEX, sysexCallback);
  • rtos_arduino/trunk/arduino_lib/libraries/Firmata/examples/OldStandardFirmata/OldStandardFirmata.ino

    r136 r224  
    5656void outputPort(byte portNumber, byte portValue)
    5757{
    58   portValue = portValue &~ portStatus[portNumber];
     58  portValue = portValue & ~ portStatus[portNumber];
    5959  if (previousPINs[portNumber] != portValue) {
    6060    Firmata.sendDigitalPort(portNumber, portValue);
     
    7373    if (reportPINs[i]) {
    7474      switch (i) {
    75         case 0: outputPort(0, PIND &~ B00000011); break; // ignore Rx/Tx 0/1
     75        case 0: outputPort(0, PIND & ~ B00000011); break; // ignore Rx/Tx 0/1
    7676        case 1: outputPort(1, PINB); break;
    7777        case 2: outputPort(2, PINC); break;
     
    105105      case INPUT:
    106106        pinMode(pin, INPUT);
    107         portStatus[port] = portStatus[port] &~ (1 << (pin - offset));
     107        portStatus[port] = portStatus[port] & ~ (1 << (pin - offset));
    108108        break;
    109109      case OUTPUT:
     
    113113        portStatus[port] = portStatus[port] | (1 << (pin - offset));
    114114        break;
    115         //case ANALOG: // TODO figure this out
     115      //case ANALOG: // TODO figure this out
    116116      default:
    117117        Firmata.sendString("");
     
    123123void analogWriteCallback(byte pin, int value)
    124124{
    125   setPinModeCallback(pin, PWM);
     125  setPinModeCallback(pin, PIN_MODE_PWM);
    126126  analogWrite(pin, value);
    127127}
     
    132132    case 0: // pins 2-7 (don't change Rx/Tx, pins 0 and 1)
    133133      // 0xFF03 == B1111111100000011    0x03 == B00000011
    134       PORTD = (value &~ 0xFF03) | (PORTD & 0x03);
     134      PORTD = (value & ~ 0xFF03) | (PORTD & 0x03);
    135135      break;
    136136    case 1: // pins 8-13 (14,15 are disabled for the crystal)
     
    151151{
    152152  if (value == 0) {
    153     analogInputsToReport = analogInputsToReport &~ (1 << pin);
     153    analogInputsToReport = analogInputsToReport & ~ (1 << pin);
    154154  }
    155155  else { // everything but 0 enables reporting of that pin
     
    203203   * host computer, since once in the loop(), this firmware will only send
    204204   * digital data on change. */
    205   if (reportPINs[0]) outputPort(0, PIND &~ B00000011); // ignore Rx/Tx 0/1
     205  if (reportPINs[0]) outputPort(0, PIND & ~ B00000011); // ignore Rx/Tx 0/1
    206206  if (reportPINs[1]) outputPort(1, PINB);
    207207  if (reportPINs[2]) outputPort(2, PINC);
  • rtos_arduino/trunk/arduino_lib/libraries/Firmata/examples/ServoFirmata/ServoFirmata.ino

    r136 r224  
    1313 * included in Arduino 0017
    1414 *
    15  * TODO add message to configure minPulse/maxPulse/degrees
    16  *
    1715 * This example code is in the public domain.
    1816 */
     
    2220
    2321Servo servos[MAX_SERVOS];
     22byte servoPinMap[TOTAL_PINS];
     23byte servoCount = 0;
    2424
    2525void analogWriteCallback(byte pin, int value)
    2626{
    27   if (IS_PIN_SERVO(pin)) {
    28     servos[PIN_TO_SERVO(pin)].write(value);
     27  if (IS_PIN_DIGITAL(pin)) {
     28    servos[servoPinMap[pin]].write(value);
    2929  }
     30}
     31
     32void systemResetCallback()
     33{
     34  servoCount = 0;
    3035}
    3136
     
    3439  byte pin;
    3540
    36   Firmata.setFirmwareVersion(0, 2);
     41  Firmata.setFirmwareVersion(FIRMATA_FIRMWARE_MAJOR_VERSION, FIRMATA_FIRMWARE_MINOR_VERSION);
    3742  Firmata.attach(ANALOG_MESSAGE, analogWriteCallback);
     43  Firmata.attach(SYSTEM_RESET, systemResetCallback);
    3844
     45  Firmata.begin(57600);
     46  systemResetCallback();
     47
     48  // attach servos from first digital pin up to max number of
     49  // servos supported for the board
    3950  for (pin = 0; pin < TOTAL_PINS; pin++) {
    40     if (IS_PIN_SERVO(pin)) {
    41       servos[PIN_TO_SERVO(pin)].attach(PIN_TO_DIGITAL(pin));
     51    if (IS_PIN_DIGITAL(pin)) {
     52      if (servoCount < MAX_SERVOS) {
     53        servoPinMap[pin] = servoCount;
     54        servos[servoPinMap[pin]].attach(PIN_TO_DIGITAL(pin));
     55        servoCount++;
     56      }
    4257    }
    4358  }
    44 
    45   Firmata.begin(57600);
    4659}
    4760
     
    5164    Firmata.processInput();
    5265}
    53 
  • rtos_arduino/trunk/arduino_lib/libraries/Firmata/examples/SimpleAnalogFirmata/SimpleAnalogFirmata.ino

    r136 r224  
    2828void setup()
    2929{
    30   Firmata.setFirmwareVersion(0, 1);
     30  Firmata.setFirmwareVersion(FIRMATA_FIRMWARE_MAJOR_VERSION, FIRMATA_FIRMWARE_MINOR_VERSION);
    3131  Firmata.attach(ANALOG_MESSAGE, analogWriteCallback);
    3232  Firmata.begin(57600);
  • rtos_arduino/trunk/arduino_lib/libraries/Firmata/examples/SimpleDigitalFirmata/SimpleDigitalFirmata.ino

    r136 r224  
    5353void setup()
    5454{
    55   Firmata.setFirmwareVersion(0, 1);
     55  Firmata.setFirmwareVersion(FIRMATA_FIRMWARE_MAJOR_VERSION, FIRMATA_FIRMWARE_MINOR_VERSION);
    5656  Firmata.attach(DIGITAL_MESSAGE, digitalWriteCallback);
    5757  Firmata.attach(SET_PIN_MODE, setPinModeCallback);
  • rtos_arduino/trunk/arduino_lib/libraries/Firmata/examples/StandardFirmata/StandardFirmata.ino

    r136 r224  
    11/*
    2  * Firmata is a generic protocol for communicating with microcontrollers
    3  * from software on a host computer. It is intended to work with
    4  * any host computer software package.
    5  *
    6  * To download a host software package, please clink on the following link
    7  * to open the download page in your default browser.
    8  *
    9  * http://firmata.org/wiki/Download
    10  */
    11 
    12 /*
     2  Firmata is a generic protocol for communicating with microcontrollers
     3  from software on a host computer. It is intended to work with
     4  any host computer software package.
     5
     6  To download a host software package, please clink on the following link
     7  to open the list of Firmata client libraries your default browser.
     8
     9  https://github.com/firmata/arduino#firmata-client-libraries
     10
    1311  Copyright (C) 2006-2008 Hans-Christoph Steiner.  All rights reserved.
    1412  Copyright (C) 2010-2011 Paul Stoffregen.  All rights reserved.
    1513  Copyright (C) 2009 Shigeru Kobayashi.  All rights reserved.
    16   Copyright (C) 2009-2011 Jeff Hoefs.  All rights reserved.
     14  Copyright (C) 2009-2016 Jeff Hoefs.  All rights reserved.
    1715
    1816  This library is free software; you can redistribute it and/or
     
    2321  See file LICENSE.txt for further informations on licensing terms.
    2422
    25   formatted using the GNU C formatting and indenting
     23  Last updated by Jeff Hoefs: January 10th, 2016
    2624*/
    27 
    28 /*
    29  * TODO: use Program Control to load stored profiles from EEPROM
    30  */
    3125
    3226#include <Servo.h>
     
    3428#include <Firmata.h>
    3529
    36 // move the following defines to Firmata.h?
    37 #define I2C_WRITE B00000000
    38 #define I2C_READ B00001000
    39 #define I2C_READ_CONTINUOUSLY B00010000
    40 #define I2C_STOP_READING B00011000
    41 #define I2C_READ_WRITE_MODE_MASK B00011000
     30#define I2C_WRITE                   B00000000
     31#define I2C_READ                    B00001000
     32#define I2C_READ_CONTINUOUSLY       B00010000
     33#define I2C_STOP_READING            B00011000
     34#define I2C_READ_WRITE_MODE_MASK    B00011000
    4235#define I2C_10BIT_ADDRESS_MODE_MASK B00100000
    43 
    44 #define MAX_QUERIES 8
    45 #define MINIMUM_SAMPLING_INTERVAL 10
    46 
    47 #define REGISTER_NOT_SPECIFIED -1
     36#define I2C_END_TX_MASK             B01000000
     37#define I2C_STOP_TX                 1
     38#define I2C_RESTART_TX              0
     39#define I2C_MAX_QUERIES             8
     40#define I2C_REGISTER_NOT_SPECIFIED  -1
     41
     42// the minimum interval for sampling analog input
     43#define MINIMUM_SAMPLING_INTERVAL   1
     44
    4845
    4946/*==============================================================================
     
    5148 *============================================================================*/
    5249
     50#ifdef FIRMATA_SERIAL_FEATURE
     51SerialFirmata serialFeature;
     52#endif
     53
    5354/* analog inputs */
    5455int analogInputsToReport = 0; // bitwise array to store pin reporting
     
    5960
    6061/* pins configuration */
    61 byte pinConfig[TOTAL_PINS];         // configuration of every pin
    6262byte portConfigInputs[TOTAL_PORTS]; // each bit: 1 = pin in INPUT, 0 = anything else
    63 int pinState[TOTAL_PINS];           // any value that has been written
    6463
    6564/* timer variables */
    6665unsigned long currentMillis;        // store the current value from millis()
    6766unsigned long previousMillis;       // for comparison with currentMillis
    68 int samplingInterval = 19;          // how often to run the main loop (in ms)
     67unsigned int samplingInterval = 19; // how often to run the main loop (in ms)
    6968
    7069/* i2c data */
    7170struct i2c_device_info {
    7271  byte addr;
    73   byte reg;
     72  int reg;
    7473  byte bytes;
     74  byte stopTX;
    7575};
    7676
    7777/* for i2c read continuous more */
    78 i2c_device_info query[MAX_QUERIES];
    79 
    80 byte i2cRxData[32];
     78i2c_device_info query[I2C_MAX_QUERIES];
     79
     80byte i2cRxData[64];
    8181boolean isI2CEnabled = false;
    8282signed char queryIndex = -1;
    83 unsigned int i2cReadDelayTime = 0;  // default delay time between i2c read request and Wire.requestFrom()
     83// default delay time between i2c read request and Wire.requestFrom()
     84unsigned int i2cReadDelayTime = 0;
    8485
    8586Servo servos[MAX_SERVOS];
     87byte servoPinMap[TOTAL_PINS];
     88byte detachedServos[MAX_SERVOS];
     89byte detachedServoCount = 0;
     90byte servoCount = 0;
     91
     92boolean isResetting = false;
     93
     94
     95/* utility functions */
     96void wireWrite(byte data)
     97{
     98#if ARDUINO >= 100
     99  Wire.write((byte)data);
     100#else
     101  Wire.send(data);
     102#endif
     103}
     104
     105byte wireRead(void)
     106{
     107#if ARDUINO >= 100
     108  return Wire.read();
     109#else
     110  return Wire.receive();
     111#endif
     112}
     113
    86114/*==============================================================================
    87115 * FUNCTIONS
    88116 *============================================================================*/
    89117
    90 void readAndReportData(byte address, int theRegister, byte numBytes) {
     118void attachServo(byte pin, int minPulse, int maxPulse)
     119{
     120  if (servoCount < MAX_SERVOS) {
     121    // reuse indexes of detached servos until all have been reallocated
     122    if (detachedServoCount > 0) {
     123      servoPinMap[pin] = detachedServos[detachedServoCount - 1];
     124      if (detachedServoCount > 0) detachedServoCount--;
     125    } else {
     126      servoPinMap[pin] = servoCount;
     127      servoCount++;
     128    }
     129    if (minPulse > 0 && maxPulse > 0) {
     130      servos[servoPinMap[pin]].attach(PIN_TO_DIGITAL(pin), minPulse, maxPulse);
     131    } else {
     132      servos[servoPinMap[pin]].attach(PIN_TO_DIGITAL(pin));
     133    }
     134  } else {
     135    Firmata.sendString("Max servos attached");
     136  }
     137}
     138
     139void detachServo(byte pin)
     140{
     141  servos[servoPinMap[pin]].detach();
     142  // if we're detaching the last servo, decrement the count
     143  // otherwise store the index of the detached servo
     144  if (servoPinMap[pin] == servoCount && servoCount > 0) {
     145    servoCount--;
     146  } else if (servoCount > 0) {
     147    // keep track of detached servos because we want to reuse their indexes
     148    // before incrementing the count of attached servos
     149    detachedServoCount++;
     150    detachedServos[detachedServoCount - 1] = servoPinMap[pin];
     151  }
     152
     153  servoPinMap[pin] = 255;
     154}
     155
     156void readAndReportData(byte address, int theRegister, byte numBytes, byte stopTX) {
    91157  // allow I2C requests that don't require a register read
    92158  // for example, some devices using an interrupt pin to signify new data available
    93159  // do not always require the register read so upon interrupt you call Wire.requestFrom()
    94   if (theRegister != REGISTER_NOT_SPECIFIED) {
     160  if (theRegister != I2C_REGISTER_NOT_SPECIFIED) {
    95161    Wire.beginTransmission(address);
    96 #if ARDUINO >= 100
    97     Wire.write((byte)theRegister);
    98 #else
    99     Wire.send((byte)theRegister);
    100 #endif
    101     Wire.endTransmission();
     162    wireWrite((byte)theRegister);
     163    Wire.endTransmission(stopTX); // default = true
    102164    // do not set a value of 0
    103165    if (i2cReadDelayTime > 0) {
     
    112174
    113175  // check to be sure correct number of bytes were returned by slave
    114   if (numBytes == Wire.available()) {
    115     i2cRxData[0] = address;
    116     i2cRxData[1] = theRegister;
    117     for (int i = 0; i < numBytes; i++) {
    118 #if ARDUINO >= 100
    119       i2cRxData[2 + i] = Wire.read();
    120 #else
    121       i2cRxData[2 + i] = Wire.receive();
    122 #endif
    123     }
    124   }
    125   else {
    126     if (numBytes > Wire.available()) {
    127       Firmata.sendString("I2C Read Error: Too many bytes received");
    128     } else {
    129       Firmata.sendString("I2C Read Error: Too few bytes received");
    130     }
     176  if (numBytes < Wire.available()) {
     177    Firmata.sendString("I2C: Too many bytes received");
     178  } else if (numBytes > Wire.available()) {
     179    Firmata.sendString("I2C: Too few bytes received");
     180  }
     181
     182  i2cRxData[0] = address;
     183  i2cRxData[1] = theRegister;
     184
     185  for (int i = 0; i < numBytes && Wire.available(); i++) {
     186    i2cRxData[2 + i] = wireRead();
    131187  }
    132188
     
    173229
    174230// -----------------------------------------------------------------------------
     231
     232/* disable the i2c pins so they can be used for other functions */
     233void disableI2CPins() {
     234  isI2CEnabled = false;
     235  // disable read continuous mode for all devices
     236  queryIndex = -1;
     237}
     238
     239/* sets bits in a bit array (int) to toggle the reporting of the analogIns
     240 */
     241//void FirmataClass::setAnalogPinReporting(byte pin, byte state) {
     242//}
     243void reportAnalogCallback(byte analogPin, int value)
     244{
     245  if (analogPin < TOTAL_ANALOG_PINS) {
     246    if (value == 0) {
     247      analogInputsToReport = analogInputsToReport & ~ (1 << analogPin);
     248    } else {
     249      analogInputsToReport = analogInputsToReport | (1 << analogPin);
     250      // prevent during system reset or all analog pin values will be reported
     251      // which may report noise for unconnected analog pins
     252      if (!isResetting) {
     253        // Send pin value immediately. This is helpful when connected via
     254        // ethernet, wi-fi or bluetooth so pin states can be known upon
     255        // reconnecting.
     256        Firmata.sendAnalog(analogPin, analogRead(analogPin));
     257      }
     258    }
     259  }
     260  // TODO: save status to EEPROM here, if changed
     261}
     262
     263// -----------------------------------------------------------------------------
    175264/* sets the pin mode to the correct state and sets the relevant bits in the
    176265 * two bit-arrays that track Digital I/O and PWM status
     
    178267void setPinModeCallback(byte pin, int mode)
    179268{
    180   if (pinConfig[pin] == I2C && isI2CEnabled && mode != I2C) {
     269  if (Firmata.getPinMode(pin) == PIN_MODE_IGNORE)
     270    return;
     271
     272  if (Firmata.getPinMode(pin) == PIN_MODE_I2C && isI2CEnabled && mode != PIN_MODE_I2C) {
    181273    // disable i2c so pins can be used for other functions
    182274    // the following if statements should reconfigure the pins properly
    183275    disableI2CPins();
    184276  }
    185   if (IS_PIN_SERVO(pin) && mode != SERVO && servos[PIN_TO_SERVO(pin)].attached()) {
    186     servos[PIN_TO_SERVO(pin)].detach();
     277  if (IS_PIN_DIGITAL(pin) && mode != PIN_MODE_SERVO) {
     278    if (servoPinMap[pin] < MAX_SERVOS && servos[servoPinMap[pin]].attached()) {
     279      detachServo(pin);
     280    }
    187281  }
    188282  if (IS_PIN_ANALOG(pin)) {
    189     reportAnalogCallback(PIN_TO_ANALOG(pin), mode == ANALOG ? 1 : 0); // turn on/off reporting
     283    reportAnalogCallback(PIN_TO_ANALOG(pin), mode == PIN_MODE_ANALOG ? 1 : 0); // turn on/off reporting
    190284  }
    191285  if (IS_PIN_DIGITAL(pin)) {
    192     if (mode == INPUT) {
     286    if (mode == INPUT || mode == PIN_MODE_PULLUP) {
    193287      portConfigInputs[pin / 8] |= (1 << (pin & 7));
    194288    } else {
     
    196290    }
    197291  }
    198   pinState[pin] = 0;
     292  Firmata.setPinState(pin, 0);
    199293  switch (mode) {
    200     case ANALOG:
     294    case PIN_MODE_ANALOG:
    201295      if (IS_PIN_ANALOG(pin)) {
    202296        if (IS_PIN_DIGITAL(pin)) {
    203           pinMode(PIN_TO_DIGITAL(pin), INPUT); // disable output driver
     297          pinMode(PIN_TO_DIGITAL(pin), INPUT);    // disable output driver
     298#if ARDUINO <= 100
     299          // deprecated since Arduino 1.0.1 - TODO: drop support in Firmata 2.6
    204300          digitalWrite(PIN_TO_DIGITAL(pin), LOW); // disable internal pull-ups
    205         }
    206         pinConfig[pin] = ANALOG;
     301#endif
     302        }
     303        Firmata.setPinMode(pin, PIN_MODE_ANALOG);
    207304      }
    208305      break;
    209306    case INPUT:
    210307      if (IS_PIN_DIGITAL(pin)) {
    211         pinMode(PIN_TO_DIGITAL(pin), INPUT); // disable output driver
     308        pinMode(PIN_TO_DIGITAL(pin), INPUT);    // disable output driver
     309#if ARDUINO <= 100
     310        // deprecated since Arduino 1.0.1 - TODO: drop support in Firmata 2.6
    212311        digitalWrite(PIN_TO_DIGITAL(pin), LOW); // disable internal pull-ups
    213         pinConfig[pin] = INPUT;
     312#endif
     313        Firmata.setPinMode(pin, INPUT);
     314      }
     315      break;
     316    case PIN_MODE_PULLUP:
     317      if (IS_PIN_DIGITAL(pin)) {
     318        pinMode(PIN_TO_DIGITAL(pin), INPUT_PULLUP);
     319        Firmata.setPinMode(pin, PIN_MODE_PULLUP);
     320        Firmata.setPinState(pin, 1);
    214321      }
    215322      break;
     
    218325        digitalWrite(PIN_TO_DIGITAL(pin), LOW); // disable PWM
    219326        pinMode(PIN_TO_DIGITAL(pin), OUTPUT);
    220         pinConfig[pin] = OUTPUT;
    221       }
    222       break;
    223     case PWM:
     327        Firmata.setPinMode(pin, OUTPUT);
     328      }
     329      break;
     330    case PIN_MODE_PWM:
    224331      if (IS_PIN_PWM(pin)) {
    225332        pinMode(PIN_TO_PWM(pin), OUTPUT);
    226333        analogWrite(PIN_TO_PWM(pin), 0);
    227         pinConfig[pin] = PWM;
    228       }
    229       break;
    230     case SERVO:
    231       if (IS_PIN_SERVO(pin)) {
    232         pinConfig[pin] = SERVO;
    233         if (!servos[PIN_TO_SERVO(pin)].attached()) {
    234           servos[PIN_TO_SERVO(pin)].attach(PIN_TO_DIGITAL(pin));
    235         }
    236       }
    237       break;
    238     case I2C:
     334        Firmata.setPinMode(pin, PIN_MODE_PWM);
     335      }
     336      break;
     337    case PIN_MODE_SERVO:
     338      if (IS_PIN_DIGITAL(pin)) {
     339        Firmata.setPinMode(pin, PIN_MODE_SERVO);
     340        if (servoPinMap[pin] == 255 || !servos[servoPinMap[pin]].attached()) {
     341          // pass -1 for min and max pulse values to use default values set
     342          // by Servo library
     343          attachServo(pin, -1, -1);
     344        }
     345      }
     346      break;
     347    case PIN_MODE_I2C:
    239348      if (IS_PIN_I2C(pin)) {
    240349        // mark the pin as i2c
    241350        // the user must call I2C_CONFIG to enable I2C for a device
    242         pinConfig[pin] = I2C;
    243       }
     351        Firmata.setPinMode(pin, PIN_MODE_I2C);
     352      }
     353      break;
     354    case PIN_MODE_SERIAL:
     355#ifdef FIRMATA_SERIAL_FEATURE
     356      serialFeature.handlePinMode(pin, PIN_MODE_SERIAL);
     357#endif
    244358      break;
    245359    default:
     
    249363}
    250364
     365/*
     366 * Sets the value of an individual pin. Useful if you want to set a pin value but
     367 * are not tracking the digital port state.
     368 * Can only be used on pins configured as OUTPUT.
     369 * Cannot be used to enable pull-ups on Digital INPUT pins.
     370 */
     371void setPinValueCallback(byte pin, int value)
     372{
     373  if (pin < TOTAL_PINS && IS_PIN_DIGITAL(pin)) {
     374    if (Firmata.getPinMode(pin) == OUTPUT) {
     375      Firmata.setPinState(pin, value);
     376      digitalWrite(PIN_TO_DIGITAL(pin), value);
     377    }
     378  }
     379}
     380
    251381void analogWriteCallback(byte pin, int value)
    252382{
    253383  if (pin < TOTAL_PINS) {
    254     switch (pinConfig[pin]) {
    255       case SERVO:
    256         if (IS_PIN_SERVO(pin))
    257           servos[PIN_TO_SERVO(pin)].write(value);
    258         pinState[pin] = value;
     384    switch (Firmata.getPinMode(pin)) {
     385      case PIN_MODE_SERVO:
     386        if (IS_PIN_DIGITAL(pin))
     387          servos[servoPinMap[pin]].write(value);
     388        Firmata.setPinState(pin, value);
    259389        break;
    260       case PWM:
     390      case PIN_MODE_PWM:
    261391        if (IS_PIN_PWM(pin))
    262392          analogWrite(PIN_TO_PWM(pin), value);
    263         pinState[pin] = value;
     393        Firmata.setPinState(pin, value);
    264394        break;
    265395    }
     
    269399void digitalWriteCallback(byte port, int value)
    270400{
    271   byte pin, lastPin, mask = 1, pinWriteMask = 0;
     401  byte pin, lastPin, pinValue, mask = 1, pinWriteMask = 0;
    272402
    273403  if (port < TOTAL_PORTS) {
     
    278408      // do not disturb non-digital pins (eg, Rx & Tx)
    279409      if (IS_PIN_DIGITAL(pin)) {
    280         // only write to OUTPUT and INPUT (enables pullup)
    281410        // do not touch pins in PWM, ANALOG, SERVO or other modes
    282         if (pinConfig[pin] == OUTPUT || pinConfig[pin] == INPUT) {
    283           pinWriteMask |= mask;
    284           pinState[pin] = ((byte)value & mask) ? 1 : 0;
     411        if (Firmata.getPinMode(pin) == OUTPUT || Firmata.getPinMode(pin) == INPUT) {
     412          pinValue = ((byte)value & mask) ? 1 : 0;
     413          if (Firmata.getPinMode(pin) == OUTPUT) {
     414            pinWriteMask |= mask;
     415          } else if (Firmata.getPinMode(pin) == INPUT && pinValue == 1 && Firmata.getPinState(pin) != 1) {
     416            // only handle INPUT here for backwards compatibility
     417#if ARDUINO > 100
     418            pinMode(pin, INPUT_PULLUP);
     419#else
     420            // only write to the INPUT pin to enable pullups if Arduino v1.0.0 or earlier
     421            pinWriteMask |= mask;
     422#endif
     423          }
     424          Firmata.setPinState(pin, pinValue);
    285425        }
    286426      }
     
    293433
    294434// -----------------------------------------------------------------------------
    295 /* sets bits in a bit array (int) to toggle the reporting of the analogIns
    296  */
    297 //void FirmataClass::setAnalogPinReporting(byte pin, byte state) {
    298 //}
    299 void reportAnalogCallback(byte analogPin, int value)
    300 {
    301   if (analogPin < TOTAL_ANALOG_PINS) {
    302     if (value == 0) {
    303       analogInputsToReport = analogInputsToReport &~ (1 << analogPin);
    304     } else {
    305       analogInputsToReport = analogInputsToReport | (1 << analogPin);
    306     }
    307   }
    308   // TODO: save status to EEPROM here, if changed
    309 }
    310435
    311436void reportDigitalCallback(byte port, int value)
     
    313438  if (port < TOTAL_PORTS) {
    314439    reportPINs[port] = (byte)value;
     440    // Send port value immediately. This is helpful when connected via
     441    // ethernet, wi-fi or bluetooth so pin states can be known upon
     442    // reconnecting.
     443    if (value) outputPort(port, readPort(port, portConfigInputs[port]), true);
    315444  }
    316445  // do not disable analog reporting on these 8 pins, to allow some
     
    322451}
    323452
     453// -----------------------------------------------------------------------------
     454
     455void enableI2CPins()
     456{
     457  byte i;
     458  // is there a faster way to do this? would probaby require importing
     459  // Arduino.h to get SCL and SDA pins
     460  for (i = 0; i < TOTAL_PINS; i++) {
     461    if (IS_PIN_I2C(i)) {
     462      // mark pins as i2c so they are ignore in non i2c data requests
     463      setPinModeCallback(i, PIN_MODE_I2C);
     464    }
     465  }
     466
     467  isI2CEnabled = true;
     468
     469  Wire.begin();
     470}
     471
    324472/*==============================================================================
    325473 * SYSEX-BASED commands
     
    329477{
    330478  byte mode;
     479  byte stopTX;
    331480  byte slaveAddress;
    332   byte slaveRegister;
    333481  byte data;
     482  int slaveRegister;
    334483  unsigned int delayTime;
    335484
     
    338487      mode = argv[1] & I2C_READ_WRITE_MODE_MASK;
    339488      if (argv[1] & I2C_10BIT_ADDRESS_MODE_MASK) {
    340         Firmata.sendString("10-bit addressing mode is not yet supported");
     489        Firmata.sendString("10-bit addressing not supported");
    341490        return;
    342491      }
    343492      else {
    344493        slaveAddress = argv[0];
     494      }
     495
     496      // need to invert the logic here since 0 will be default for client
     497      // libraries that have not updated to add support for restart tx
     498      if (argv[1] & I2C_END_TX_MASK) {
     499        stopTX = I2C_RESTART_TX;
     500      }
     501      else {
     502        stopTX = I2C_STOP_TX; // default
    345503      }
    346504
     
    350508          for (byte i = 2; i < argc; i += 2) {
    351509            data = argv[i] + (argv[i + 1] << 7);
    352 #if ARDUINO >= 100
    353             Wire.write(data);
    354 #else
    355             Wire.send(data);
    356 #endif
     510            wireWrite(data);
    357511          }
    358512          Wire.endTransmission();
     
    364518            slaveRegister = argv[2] + (argv[3] << 7);
    365519            data = argv[4] + (argv[5] << 7);  // bytes to read
    366             readAndReportData(slaveAddress, (int)slaveRegister, data);
    367520          }
    368521          else {
    369522            // a slave register is NOT specified
     523            slaveRegister = I2C_REGISTER_NOT_SPECIFIED;
    370524            data = argv[2] + (argv[3] << 7);  // bytes to read
    371             readAndReportData(slaveAddress, (int)REGISTER_NOT_SPECIFIED, data);
    372525          }
     526          readAndReportData(slaveAddress, (int)slaveRegister, data, stopTX);
    373527          break;
    374528        case I2C_READ_CONTINUOUSLY:
    375           if ((queryIndex + 1) >= MAX_QUERIES) {
     529          if ((queryIndex + 1) >= I2C_MAX_QUERIES) {
    376530            // too many queries, just ignore
    377531            Firmata.sendString("too many queries");
    378532            break;
    379533          }
     534          if (argc == 6) {
     535            // a slave register is specified
     536            slaveRegister = argv[2] + (argv[3] << 7);
     537            data = argv[4] + (argv[5] << 7);  // bytes to read
     538          }
     539          else {
     540            // a slave register is NOT specified
     541            slaveRegister = (int)I2C_REGISTER_NOT_SPECIFIED;
     542            data = argv[2] + (argv[3] << 7);  // bytes to read
     543          }
    380544          queryIndex++;
    381545          query[queryIndex].addr = slaveAddress;
    382           query[queryIndex].reg = argv[2] + (argv[3] << 7);
    383           query[queryIndex].bytes = argv[4] + (argv[5] << 7);
     546          query[queryIndex].reg = slaveRegister;
     547          query[queryIndex].bytes = data;
     548          query[queryIndex].stopTX = stopTX;
    384549          break;
    385550        case I2C_STOP_READING:
     
    390555            queryIndex = -1;
    391556          } else {
     557            queryIndexToSkip = 0;
    392558            // if read continuous mode is enabled for multiple devices,
    393559            // determine which device to stop reading and remove it's data from
    394560            // the array, shifiting other array data to fill the space
    395561            for (byte i = 0; i < queryIndex + 1; i++) {
    396               if (query[i].addr = slaveAddress) {
     562              if (query[i].addr == slaveAddress) {
    397563                queryIndexToSkip = i;
    398564                break;
     
    401567
    402568            for (byte i = queryIndexToSkip; i < queryIndex + 1; i++) {
    403               if (i < MAX_QUERIES) {
     569              if (i < I2C_MAX_QUERIES) {
    404570                query[i].addr = query[i + 1].addr;
    405                 query[i].reg = query[i + 1].addr;
     571                query[i].reg = query[i + 1].reg;
    406572                query[i].bytes = query[i + 1].bytes;
     573                query[i].stopTX = query[i + 1].stopTX;
    407574              }
    408575            }
     
    433600        int maxPulse = argv[3] + (argv[4] << 7);
    434601
    435         if (IS_PIN_SERVO(pin)) {
    436           if (servos[PIN_TO_SERVO(pin)].attached())
    437             servos[PIN_TO_SERVO(pin)].detach();
    438           servos[PIN_TO_SERVO(pin)].attach(PIN_TO_DIGITAL(pin), minPulse, maxPulse);
    439           setPinModeCallback(pin, SERVO);
     602        if (IS_PIN_DIGITAL(pin)) {
     603          if (servoPinMap[pin] < MAX_SERVOS && servos[servoPinMap[pin]].attached()) {
     604            detachServo(pin);
     605          }
     606          attachServo(pin, minPulse, maxPulse);
     607          setPinModeCallback(pin, PIN_MODE_SERVO);
    440608        }
    441609      }
     
    466634          Firmata.write((byte)INPUT);
    467635          Firmata.write(1);
     636          Firmata.write((byte)PIN_MODE_PULLUP);
     637          Firmata.write(1);
    468638          Firmata.write((byte)OUTPUT);
    469639          Firmata.write(1);
    470640        }
    471641        if (IS_PIN_ANALOG(pin)) {
    472           Firmata.write(ANALOG);
    473           Firmata.write(10);
     642          Firmata.write(PIN_MODE_ANALOG);
     643          Firmata.write(10); // 10 = 10-bit resolution
    474644        }
    475645        if (IS_PIN_PWM(pin)) {
    476           Firmata.write(PWM);
    477           Firmata.write(8);
    478         }
    479         if (IS_PIN_SERVO(pin)) {
    480           Firmata.write(SERVO);
     646          Firmata.write(PIN_MODE_PWM);
     647          Firmata.write(8); // 8 = 8-bit resolution
     648        }
     649        if (IS_PIN_DIGITAL(pin)) {
     650          Firmata.write(PIN_MODE_SERVO);
    481651          Firmata.write(14);
    482652        }
    483653        if (IS_PIN_I2C(pin)) {
    484           Firmata.write(I2C);
    485           Firmata.write(1);  // to do: determine appropriate value
    486         }
     654          Firmata.write(PIN_MODE_I2C);
     655          Firmata.write(1);  // TODO: could assign a number to map to SCL or SDA
     656        }
     657#ifdef FIRMATA_SERIAL_FEATURE
     658        serialFeature.handleCapability(pin);
     659#endif
    487660        Firmata.write(127);
    488661      }
     
    496669        Firmata.write(pin);
    497670        if (pin < TOTAL_PINS) {
    498           Firmata.write((byte)pinConfig[pin]);
    499           Firmata.write((byte)pinState[pin] & 0x7F);
    500           if (pinState[pin] & 0xFF80) Firmata.write((byte)(pinState[pin] >> 7) & 0x7F);
    501           if (pinState[pin] & 0xC000) Firmata.write((byte)(pinState[pin] >> 14) & 0x7F);
     671          Firmata.write(Firmata.getPinMode(pin));
     672          Firmata.write((byte)Firmata.getPinState(pin) & 0x7F);
     673          if (Firmata.getPinState(pin) & 0xFF80) Firmata.write((byte)(Firmata.getPinState(pin) >> 7) & 0x7F);
     674          if (Firmata.getPinState(pin) & 0xC000) Firmata.write((byte)(Firmata.getPinState(pin) >> 14) & 0x7F);
    502675        }
    503676        Firmata.write(END_SYSEX);
     
    512685      Firmata.write(END_SYSEX);
    513686      break;
    514   }
    515 }
    516 
    517 void enableI2CPins()
    518 {
    519   byte i;
    520   // is there a faster way to do this? would probaby require importing
    521   // Arduino.h to get SCL and SDA pins
    522   for (i = 0; i < TOTAL_PINS; i++) {
    523     if (IS_PIN_I2C(i)) {
    524       // mark pins as i2c so they are ignore in non i2c data requests
    525       setPinModeCallback(i, I2C);
    526     }
    527   }
    528 
    529   isI2CEnabled = true;
    530 
    531   // is there enough time before the first I2C request to call this here?
    532   Wire.begin();
    533 }
    534 
    535 /* disable the i2c pins so they can be used for other functions */
    536 void disableI2CPins() {
    537   isI2CEnabled = false;
    538   // disable read continuous mode for all devices
    539   queryIndex = -1;
    540   // uncomment the following if or when the end() method is added to Wire library
    541   // Wire.end();
    542 }
     687
     688    case SERIAL_MESSAGE:
     689#ifdef FIRMATA_SERIAL_FEATURE
     690      serialFeature.handleSysex(command, argc, argv);
     691#endif
     692      break;
     693  }
     694}
     695
    543696
    544697/*==============================================================================
     
    548701void systemResetCallback()
    549702{
     703  isResetting = true;
     704
    550705  // initialize a defalt state
    551706  // TODO: option to load config from EEPROM instead of default
     707
     708#ifdef FIRMATA_SERIAL_FEATURE
     709  serialFeature.reset();
     710#endif
     711
    552712  if (isI2CEnabled) {
    553713    disableI2CPins();
    554714  }
     715
    555716  for (byte i = 0; i < TOTAL_PORTS; i++) {
    556     reportPINs[i] = false;      // by default, reporting off
    557     portConfigInputs[i] = 0;    // until activated
     717    reportPINs[i] = false;    // by default, reporting off
     718    portConfigInputs[i] = 0;  // until activated
    558719    previousPINs[i] = 0;
    559720  }
    560   // pins with analog capability default to analog input
    561   // otherwise, pins default to digital output
     721
    562722  for (byte i = 0; i < TOTAL_PINS; i++) {
     723    // pins with analog capability default to analog input
     724    // otherwise, pins default to digital output
    563725    if (IS_PIN_ANALOG(i)) {
    564726      // turns off pullup, configures everything
    565       setPinModeCallback(i, ANALOG);
    566     } else {
     727      setPinModeCallback(i, PIN_MODE_ANALOG);
     728    } else if (IS_PIN_DIGITAL(i)) {
    567729      // sets the output to 0, configures portConfigInputs
    568730      setPinModeCallback(i, OUTPUT);
    569731    }
     732
     733    servoPinMap[i] = 255;
    570734  }
    571735  // by default, do not report any analog inputs
    572736  analogInputsToReport = 0;
     737
     738  detachedServoCount = 0;
     739  servoCount = 0;
    573740
    574741  /* send digital inputs to set the initial state on the host computer,
     
    581748  }
    582749  */
     750  isResetting = false;
    583751}
    584752
    585753void setup()
    586754{
    587   Firmata.setFirmwareVersion(FIRMATA_MAJOR_VERSION, FIRMATA_MINOR_VERSION);
     755  Firmata.setFirmwareVersion(FIRMATA_FIRMWARE_MAJOR_VERSION, FIRMATA_FIRMWARE_MINOR_VERSION);
    588756
    589757  Firmata.attach(ANALOG_MESSAGE, analogWriteCallback);
     
    592760  Firmata.attach(REPORT_DIGITAL, reportDigitalCallback);
    593761  Firmata.attach(SET_PIN_MODE, setPinModeCallback);
     762  Firmata.attach(SET_DIGITAL_PIN_VALUE, setPinValueCallback);
    594763  Firmata.attach(START_SYSEX, sysexCallback);
    595764  Firmata.attach(SYSTEM_RESET, systemResetCallback);
    596765
     766  // to use a port other than Serial, such as Serial1 on an Arduino Leonardo or Mega,
     767  // Call begin(baud) on the alternate serial port and pass it to Firmata to begin like this:
     768  // Serial1.begin(57600);
     769  // Firmata.begin(Serial1);
     770  // However do not do this if you are using SERIAL_MESSAGE
     771
    597772  Firmata.begin(57600);
     773  while (!Serial) {
     774    ; // wait for serial port to connect. Needed for ATmega32u4-based boards and Arduino 101
     775  }
     776
    598777  systemResetCallback();  // reset to default config
    599778}
     
    610789  checkDigitalInputs();
    611790
    612   /* SERIALREAD - processing incoming messagse as soon as possible, while still
     791  /* STREAMREAD - processing incoming messagse as soon as possible, while still
    613792   * checking digital inputs.  */
    614793  while (Firmata.available())
    615794    Firmata.processInput();
    616795
    617   /* SEND FTDI WRITE BUFFER - make sure that the FTDI buffer doesn't go over
    618    * 60 bytes. use a timer to sending an event character every 4 ms to
    619    * trigger the buffer to dump. */
     796  // TODO - ensure that Stream buffer doesn't go over 60 bytes
    620797
    621798  currentMillis = millis();
     
    624801    /* ANALOGREAD - do all analogReads() at the configured sampling interval */
    625802    for (pin = 0; pin < TOTAL_PINS; pin++) {
    626       if (IS_PIN_ANALOG(pin) && pinConfig[pin] == ANALOG) {
     803      if (IS_PIN_ANALOG(pin) && Firmata.getPinMode(pin) == PIN_MODE_ANALOG) {
    627804        analogPin = PIN_TO_ANALOG(pin);
    628805        if (analogInputsToReport & (1 << analogPin)) {
     
    634811    if (queryIndex > -1) {
    635812      for (byte i = 0; i < queryIndex + 1; i++) {
    636         readAndReportData(query[i].addr, query[i].reg, query[i].bytes);
    637       }
    638     }
    639   }
    640 }
     813        readAndReportData(query[i].addr, query[i].reg, query[i].bytes, query[i].stopTX);
     814      }
     815    }
     816  }
     817
     818#ifdef FIRMATA_SERIAL_FEATURE
     819  serialFeature.update();
     820#endif
     821}
  • rtos_arduino/trunk/arduino_lib/libraries/Firmata/keywords.txt

    r136 r224  
    77#######################################
    88
    9 Firmata KEYWORD1
    10 callbackFunction        KEYWORD1
    11 systemResetCallbackFunction     KEYWORD1
    12 stringCallbackFunction  KEYWORD1
    13 sysexCallbackFunction   KEYWORD1
     9Firmata                         KEYWORD1        Firmata
     10callbackFunction                KEYWORD1        callbackFunction
     11systemResetCallbackFunction     KEYWORD1        systemResetCallbackFunction
     12stringCallbackFunction          KEYWORD1        stringCallbackFunction
     13sysexCallbackFunction           KEYWORD1        sysexCallbackFunction
    1414
    1515#######################################
     
    1717#######################################
    1818
    19 begin   KEYWORD2
    20 begin   KEYWORD2
    21 printVersion    KEYWORD2
    22 blinkVersion    KEYWORD2
    23 printFirmwareVersion    KEYWORD2
    24 setFirmwareVersion      KEYWORD2
     19begin                           KEYWORD2
     20printVersion                    KEYWORD2
     21blinkVersion                    KEYWORD2
     22printFirmwareVersion            KEYWORD2
     23setFirmwareVersion              KEYWORD2
    2524setFirmwareNameAndVersion       KEYWORD2
    26 available       KEYWORD2
    27 processInput    KEYWORD2
    28 sendAnalog      KEYWORD2
    29 sendDigital     KEYWORD2
    30 sendDigitalPortPair     KEYWORD2
    31 sendDigitalPort KEYWORD2
    32 sendString      KEYWORD2
    33 sendString      KEYWORD2
    34 sendSysex       KEYWORD2
    35 attach  KEYWORD2
    36 detach  KEYWORD2
    37 flush   KEYWORD2
     25available                       KEYWORD2
     26processInput                    KEYWORD2
     27isParsingMessage                KEYWORD2
     28parse                           KEYWORD2
     29sendAnalog                      KEYWORD2
     30sendDigital                     KEYWORD2
     31sendDigitalPort                 KEYWORD2
     32sendString                      KEYWORD2
     33sendSysex                       KEYWORD2
     34getPinMode                      KEYWORD2
     35setPinMode                      KEYWORD2
     36getPinState                     KEYWORD2
     37setPinState                     KEYWORD2
     38attach                          KEYWORD2
     39detach                          KEYWORD2
     40write                           KEYWORD2
     41sendValueAsTwo7bitBytes KEYWORD2
     42startSysex                      KEYWORD2
     43endSysex                        KEYWORD2
     44writePort                       KEYWORD2
     45readPort                        KEYWORD2
     46disableBlinkVersion             KEYWORD2
    3847
    3948
     
    4251#######################################
    4352
    44 MAX_DATA_BYTES  LITERAL1
     53FIRMATA_MAJOR_VERSION   LITERAL1
     54FIRMATA_MINOR_VERSION   LITERAL1
     55FIRMATA_BUGFIX_VERSION  LITERAL1
    4556
    46 DIGITAL_MESSAGE LITERAL1
    47 ANALOG_MESSAGE  LITERAL1
    48 REPORT_ANALOG   LITERAL1
    49 REPORT_DIGITAL  LITERAL1
    50 REPORT_VERSION  LITERAL1
    51 SET_PIN_MODE    LITERAL1
    52 SYSTEM_RESET    LITERAL1
     57MAX_DATA_BYTES          LITERAL1
    5358
    54 START_SYSEX     LITERAL1
    55 END_SYSEX       LITERAL1
     59DIGITAL_MESSAGE         LITERAL1
     60ANALOG_MESSAGE          LITERAL1
     61REPORT_ANALOG           LITERAL1
     62REPORT_DIGITAL          LITERAL1
     63REPORT_VERSION          LITERAL1
     64SET_PIN_MODE            LITERAL1
     65SET_DIGITAL_PIN_VALUE   LITERAL1
     66SYSTEM_RESET            LITERAL1
     67START_SYSEX             LITERAL1
     68END_SYSEX               LITERAL1
     69REPORT_FIRMWARE         LITERAL1
     70STRING_DATA             LITERAL1
    5671
    57 PWM     LITERAL1
     72PIN_MODE_ANALOG         LITERAL1
     73PIN_MODE_PWM            LITERAL1
     74PIN_MODE_SERVO          LITERAL1
     75PIN_MODE_SHIFT          LITERAL1
     76PIN_MODE_I2C            LITERAL1
     77PIN_MODE_ONEWIRE        LITERAL1
     78PIN_MODE_STEPPER        LITERAL1
     79PIN_MODE_ENCODER        LITERAL1
     80PIN_MODE_SERIAL         LITERAL1
     81PIN_MODE_PULLUP         LITERAL1
     82PIN_MODE_IGNORE         LITERAL1
    5883
     84TOTAL_PINS              LITERAL1
    5985TOTAL_ANALOG_PINS       LITERAL1
    6086TOTAL_DIGITAL_PINS      LITERAL1
    61 TOTAL_PORTS                     LITERAL1
    62 ANALOG_PORT                     LITERAL1
     87TOTAL_PIN_MODES         LITERAL1
     88TOTAL_PORTS             LITERAL1
     89ANALOG_PORT             LITERAL1
     90MAX_SERVOS              LITERAL1
  • rtos_arduino/trunk/arduino_lib/libraries/Firmata/library.properties

    r136 r224  
    11name=Firmata
    2 version=2.3.6
     2version=2.5.2
    33author=Firmata Developers
    4 maintainer=Firmata Developers <firmata-devel@lists.sourceforge.net>
     4maintainer=https://github.com/firmata/arduino
    55sentence=Enables the communication with computer apps using a standard serial protocol. For all Arduino boards.
    66paragraph=The Firmata library implements the Firmata protocol for communicating with software on the host computer. This allows you to write custom firmware without having to create your own protocol and objects for the programming environment that you are using.
    77category=Device Control
    8 url=http://firmata.org
     8url=https://github.com/firmata/arduino
    99architectures=*
Note: See TracChangeset for help on using the changeset viewer.