1
0
mirror of https://github.com/arduino/Arduino.git synced 2024-11-29 10:24:12 +01:00

updated Firmata library to version 2.3.5 and moved to the new library format

This commit is contained in:
Fede85 2013-07-04 13:29:15 +02:00
parent 38c3bbbd3c
commit 10a4241ba7
18 changed files with 162 additions and 316 deletions

View File

@ -1,14 +0,0 @@
- make Firmata a subclass of HardwareSerial
- per-pin digital callback, since the per-port callback is a bit complicated
for beginners (maybe Firmata is not for beginners...)
- simplify SimpleDigitalFirmata, take out the code that checks to see if the
data has changed, since it is a bit complicated for this example. Ideally
this example would be based on a call
- turn current SimpleDigitalFirmata into DigitalPortFirmata for a more complex
example using the code which checks for changes before doing anything
- test integration with Wiring

View File

@ -1,228 +0,0 @@
/*
* Firmata is a generic protocol for communicating with microcontrollers
* from software on a host computer. It is intended to work with
* any host computer software package.
*
* To download a host software package, please clink on the following link
* to open the download page in your default browser.
*
* http://firmata.org/wiki/Download
*/
/*
Copyright (C) 2009 Jeff Hoefs. All rights reserved.
Copyright (C) 2009 Shigeru Kobayashi. All rights reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
See file LICENSE.txt for further informations on licensing terms.
*/
#include <Wire.h>
#include <Firmata.h>
#define I2C_WRITE B00000000
#define I2C_READ B00001000
#define I2C_READ_CONTINUOUSLY B00010000
#define I2C_STOP_READING B00011000
#define I2C_READ_WRITE_MODE_MASK B00011000
#define MAX_QUERIES 8
unsigned long currentMillis; // store the current value from millis()
unsigned long previousMillis; // for comparison with currentMillis
unsigned int samplingInterval = 32; // default sampling interval is 33ms
unsigned int i2cReadDelayTime = 0; // default delay time between i2c read request and Wire.requestFrom()
unsigned int powerPinsEnabled = 0; // use as boolean to prevent enablePowerPins from being called more than once
#define MINIMUM_SAMPLING_INTERVAL 10
#define REGISTER_NOT_SPECIFIED -1
struct i2c_device_info {
byte addr;
byte reg;
byte bytes;
};
i2c_device_info query[MAX_QUERIES];
byte i2cRxData[32];
boolean readingContinuously = false;
byte queryIndex = 0;
void readAndReportData(byte address, int theRegister, byte numBytes)
{
if (theRegister != REGISTER_NOT_SPECIFIED) {
Wire.beginTransmission(address);
Wire.write((byte)theRegister);
Wire.endTransmission();
delayMicroseconds(i2cReadDelayTime); // delay is necessary for some devices such as WiiNunchuck
}
else {
theRegister = 0; // fill the register with a dummy value
}
Wire.requestFrom(address, numBytes);
// check to be sure correct number of bytes were returned by slave
if(numBytes == Wire.available()) {
i2cRxData[0] = address;
i2cRxData[1] = theRegister;
for (int i = 0; i < numBytes; i++) {
i2cRxData[2 + i] = Wire.read();
}
// send slave address, register and received bytes
Firmata.sendSysex(I2C_REPLY, numBytes + 2, i2cRxData);
}
else {
if(numBytes > Wire.available()) {
Firmata.sendString("I2C Read Error: Too many bytes received");
} else {
Firmata.sendString("I2C Read Error: Too few bytes received");
}
}
}
void sysexCallback(byte command, byte argc, byte *argv)
{
byte mode;
byte slaveAddress;
byte slaveRegister;
byte data;
int delayTime;
if (command == I2C_REQUEST) {
mode = argv[1] & I2C_READ_WRITE_MODE_MASK;
slaveAddress = argv[0];
switch(mode) {
case I2C_WRITE:
Wire.beginTransmission(slaveAddress);
for (byte i = 2; i < argc; i += 2) {
data = argv[i] + (argv[i + 1] << 7);
Wire.write(data);
}
Wire.endTransmission();
delayMicroseconds(70); // TODO is this needed?
break;
case I2C_READ:
if (argc == 6) {
// a slave register is specified
slaveRegister = argv[2] + (argv[3] << 7);
data = argv[4] + (argv[5] << 7); // bytes to read
readAndReportData(slaveAddress, (int)slaveRegister, data);
}
else {
// a slave register is NOT specified
data = argv[2] + (argv[3] << 7); // bytes to read
readAndReportData(slaveAddress, (int)REGISTER_NOT_SPECIFIED, data);
}
break;
case I2C_READ_CONTINUOUSLY:
if ((queryIndex + 1) >= MAX_QUERIES) {
// too many queries, just ignore
Firmata.sendString("too many queries");
break;
}
query[queryIndex].addr = slaveAddress;
query[queryIndex].reg = argv[2] + (argv[3] << 7);
query[queryIndex].bytes = argv[4] + (argv[5] << 7);
readingContinuously = true;
queryIndex++;
break;
case I2C_STOP_READING:
readingContinuously = false;
queryIndex = 0;
break;
default:
break;
}
}
else if (command == SAMPLING_INTERVAL) {
samplingInterval = argv[0] + (argv[1] << 7);
if (samplingInterval < MINIMUM_SAMPLING_INTERVAL) {
samplingInterval = MINIMUM_SAMPLING_INTERVAL;
}
samplingInterval -= 1;
Firmata.sendString("sampling interval");
}
else if (command == I2C_CONFIG) {
delayTime = (argv[4] + (argv[5] << 7)); // MSB
delayTime = (delayTime << 8) + (argv[2] + (argv[3] << 7)); // add LSB
if((argv[0] + (argv[1] << 7)) > 0) {
enablePowerPins(PORTC3, PORTC2);
}
if(delayTime > 0) {
i2cReadDelayTime = delayTime;
}
if(argc > 6) {
// If you extend I2C_Config, handle your data here
}
}
}
void systemResetCallback()
{
readingContinuously = false;
queryIndex = 0;
}
/* reference: BlinkM_funcs.h by Tod E. Kurt, ThingM, http://thingm.com/ */
// Enables Pins A2 and A3 to be used as GND and Power
// so that I2C devices can be plugged directly
// into Arduino header (pins A2 - A5)
static void enablePowerPins(byte pwrpin, byte gndpin)
{
if(powerPinsEnabled == 0) {
DDRC |= _BV(pwrpin) | _BV(gndpin);
PORTC &=~ _BV(gndpin);
PORTC |= _BV(pwrpin);
powerPinsEnabled = 1;
Firmata.sendString("Power pins enabled");
delay(100);
}
}
void setup()
{
Firmata.setFirmwareVersion(2, 0);
Firmata.attach(START_SYSEX, sysexCallback);
Firmata.attach(SYSTEM_RESET, systemResetCallback);
for (int i = 0; i < TOTAL_PINS; ++i) {
pinMode(i, OUTPUT);
}
Firmata.begin(57600);
Wire.begin();
}
void loop()
{
while (Firmata.available()) {
Firmata.processInput();
}
currentMillis = millis();
if (currentMillis - previousMillis > samplingInterval) {
previousMillis += samplingInterval;
for (byte i = 0; i < queryIndex; i++) {
readAndReportData(query[i].addr, query[i].reg, query[i].bytes);
}
}
}

View File

@ -15,8 +15,6 @@
*/
#include <Firmata.h>
byte analogPin;
void stringCallback(char *myString)
{
Firmata.sendString(myString);

View File

@ -99,7 +99,11 @@ void readAndReportData(byte address, int theRegister, byte numBytes) {
Wire.send((byte)theRegister);
#endif
Wire.endTransmission();
delayMicroseconds(i2cReadDelayTime); // delay is necessary for some devices such as WiiNunchuck
// do not set a value of 0
if (i2cReadDelayTime > 0) {
// delay is necessary for some devices such as WiiNunchuck
delayMicroseconds(i2cReadDelayTime);
}
} else {
theRegister = 0; // fill the register with a dummy value
}
@ -455,57 +459,57 @@ void sysexCallback(byte command, byte argc, byte *argv)
}
break;
case CAPABILITY_QUERY:
Serial.write(START_SYSEX);
Serial.write(CAPABILITY_RESPONSE);
Firmata.write(START_SYSEX);
Firmata.write(CAPABILITY_RESPONSE);
for (byte pin=0; pin < TOTAL_PINS; pin++) {
if (IS_PIN_DIGITAL(pin)) {
Serial.write((byte)INPUT);
Serial.write(1);
Serial.write((byte)OUTPUT);
Serial.write(1);
Firmata.write((byte)INPUT);
Firmata.write(1);
Firmata.write((byte)OUTPUT);
Firmata.write(1);
}
if (IS_PIN_ANALOG(pin)) {
Serial.write(ANALOG);
Serial.write(10);
Firmata.write(ANALOG);
Firmata.write(10);
}
if (IS_PIN_PWM(pin)) {
Serial.write(PWM);
Serial.write(8);
Firmata.write(PWM);
Firmata.write(8);
}
if (IS_PIN_SERVO(pin)) {
Serial.write(SERVO);
Serial.write(14);
Firmata.write(SERVO);
Firmata.write(14);
}
if (IS_PIN_I2C(pin)) {
Serial.write(I2C);
Serial.write(1); // to do: determine appropriate value
Firmata.write(I2C);
Firmata.write(1); // to do: determine appropriate value
}
Serial.write(127);
Firmata.write(127);
}
Serial.write(END_SYSEX);
Firmata.write(END_SYSEX);
break;
case PIN_STATE_QUERY:
if (argc > 0) {
byte pin=argv[0];
Serial.write(START_SYSEX);
Serial.write(PIN_STATE_RESPONSE);
Serial.write(pin);
Firmata.write(START_SYSEX);
Firmata.write(PIN_STATE_RESPONSE);
Firmata.write(pin);
if (pin < TOTAL_PINS) {
Serial.write((byte)pinConfig[pin]);
Serial.write((byte)pinState[pin] & 0x7F);
if (pinState[pin] & 0xFF80) Serial.write((byte)(pinState[pin] >> 7) & 0x7F);
if (pinState[pin] & 0xC000) Serial.write((byte)(pinState[pin] >> 14) & 0x7F);
Firmata.write((byte)pinConfig[pin]);
Firmata.write((byte)pinState[pin] & 0x7F);
if (pinState[pin] & 0xFF80) Firmata.write((byte)(pinState[pin] >> 7) & 0x7F);
if (pinState[pin] & 0xC000) Firmata.write((byte)(pinState[pin] >> 14) & 0x7F);
}
Serial.write(END_SYSEX);
Firmata.write(END_SYSEX);
}
break;
case ANALOG_MAPPING_QUERY:
Serial.write(START_SYSEX);
Serial.write(ANALOG_MAPPING_RESPONSE);
Firmata.write(START_SYSEX);
Firmata.write(ANALOG_MAPPING_RESPONSE);
for (byte pin=0; pin < TOTAL_PINS; pin++) {
Serial.write(IS_PIN_ANALOG(pin) ? PIN_TO_ANALOG(pin) : 127);
Firmata.write(IS_PIN_ANALOG(pin) ? PIN_TO_ANALOG(pin) : 127);
}
Serial.write(END_SYSEX);
Firmata.write(END_SYSEX);
break;
}
}

View File

@ -0,0 +1,10 @@
name=Firmata
author=Hans-Christoph Steiner
email=Hans-Christoph Steiner <hans@at.or.at> (author), Paul Stoffregen <paul@pjrc.com> (maintainer)
sentence=This library implements the Firmata protocol and allows you to control the Arduino board from the an application on the computer.
paragraph=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.
url=http://arduino.cc/en/Reference/Firmata</br>http://firmata.org
architectures=avr, sam
version=1.0
dependencies= SoftwareSerial
core-dependencies=arduino (>=1.5.0)

View File

@ -143,6 +143,7 @@ writePort(port, value, bitmask): Write an 8 bit port.
#define IS_PIN_PWM(p) digitalPinHasPWM(p)
#define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && (p) - 2 < MAX_SERVOS)
#define IS_PIN_I2C(p) ((p) == 18 || (p) == 19)
#define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK)
#define PIN_TO_DIGITAL(p) (p)
#define PIN_TO_ANALOG(p) ((p) - 14)
#define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
@ -158,6 +159,7 @@ writePort(port, value, bitmask): Write an 8 bit port.
#define IS_PIN_PWM(p) digitalPinHasPWM(p)
#define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS)
#define IS_PIN_I2C(p) ((p) == SDA || (p) == SCL)
#define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK)
#define PIN_TO_DIGITAL(p) (p)
#define PIN_TO_ANALOG(p) ((p) - FIRST_ANALOG_PIN)
#define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
@ -191,6 +193,23 @@ writePort(port, value, bitmask): Write an 8 bit port.
#define IS_PIN_PWM(p) digitalPinHasPWM(p)
#define IS_PIN_SERVO(p) ((p) >= 2 && (p) - 2 < MAX_SERVOS)
#define IS_PIN_I2C(p) ((p) == 20 || (p) == 21)
#define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK)
#define PIN_TO_DIGITAL(p) (p)
#define PIN_TO_ANALOG(p) ((p) - 54)
#define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
#define PIN_TO_SERVO(p) ((p) - 2)
// Arduino DUE
#elif defined(__SAM3X8E__)
#define TOTAL_ANALOG_PINS 12
#define TOTAL_PINS 66 // 54 digital + 12 analog
#define VERSION_BLINK_PIN 13
#define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) < TOTAL_PINS)
#define IS_PIN_ANALOG(p) ((p) >= 54 && (p) < TOTAL_PINS)
#define IS_PIN_PWM(p) digitalPinHasPWM(p)
#define IS_PIN_SERVO(p) ((p) >= 2 && (p) - 2 < MAX_SERVOS)
#define IS_PIN_I2C(p) ((p) == 20 || (p) == 21) // 70 71
#define PIN_TO_DIGITAL(p) (p)
#define PIN_TO_ANALOG(p) ((p) - 54)
#define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
@ -207,6 +226,7 @@ writePort(port, value, bitmask): Write an 8 bit port.
#define IS_PIN_PWM(p) digitalPinHasPWM(p)
#define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS)
#define IS_PIN_I2C(p) (0)
#define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK)
#define PIN_TO_DIGITAL(p) (p)
#define PIN_TO_ANALOG(p) (0)
#define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
@ -214,7 +234,7 @@ writePort(port, value, bitmask): Write an 8 bit port.
// Teensy 2.0
#elif defined(__AVR_ATmega32U4__)
#elif defined(__AVR_ATmega32U4__) && defined(CORE_TEENSY)
#define TOTAL_ANALOG_PINS 12
#define TOTAL_PINS 25 // 11 digital + 12 analog
#define VERSION_BLINK_PIN 11
@ -223,12 +243,29 @@ writePort(port, value, bitmask): Write an 8 bit port.
#define IS_PIN_PWM(p) digitalPinHasPWM(p)
#define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS)
#define IS_PIN_I2C(p) ((p) == 5 || (p) == 6)
#define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK)
#define PIN_TO_DIGITAL(p) (p)
#define PIN_TO_ANALOG(p) (((p)<22)?21-(p):11)
#define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
#define PIN_TO_SERVO(p) (p)
// Teensy 3.0
#elif defined(__MK20DX128__)
#define TOTAL_ANALOG_PINS 14
#define TOTAL_PINS 38 // 24 digital + 10 analog-digital + 4 analog
#define VERSION_BLINK_PIN 13
#define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) <= 34)
#define IS_PIN_ANALOG(p) (((p) >= 14 && (p) <= 23) || ((p) >= 34 && (p) <= 38))
#define IS_PIN_PWM(p) digitalPinHasPWM(p)
#define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS)
#define IS_PIN_I2C(p) ((p) == 18 || (p) == 19)
#define PIN_TO_DIGITAL(p) (p)
#define PIN_TO_ANALOG(p) (((p)<=23)?(p)-14:(p)-24)
#define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
#define PIN_TO_SERVO(p) (p)
// Teensy++ 1.0 and 2.0
#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
#define TOTAL_ANALOG_PINS 8
@ -239,12 +276,30 @@ writePort(port, value, bitmask): Write an 8 bit port.
#define IS_PIN_PWM(p) digitalPinHasPWM(p)
#define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS)
#define IS_PIN_I2C(p) ((p) == 0 || (p) == 1)
#define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK)
#define PIN_TO_DIGITAL(p) (p)
#define PIN_TO_ANALOG(p) ((p) - 38)
#define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
#define PIN_TO_SERVO(p) (p)
// Leonardo
#elif defined(__AVR_ATmega32U4__)
#define TOTAL_ANALOG_PINS 12
#define TOTAL_PINS 30 // 14 digital + 12 analog + 4 SPI (D14-D17 on ISP header)
#define VERSION_BLINK_PIN 13
#define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < TOTAL_PINS)
#define IS_PIN_ANALOG(p) ((p) >= 18 && (p) < TOTAL_PINS)
#define IS_PIN_PWM(p) ((p) == 3 || (p) == 5 || (p) == 6 || (p) == 9 || (p) == 10 || (p) == 11 || (p) == 13)
#define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS)
#define IS_PIN_I2C(p) ((p) == 2 || (p) == 3)
#define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK)
#define PIN_TO_DIGITAL(p) (p)
#define PIN_TO_ANALOG(p) (p) - 18
#define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
#define PIN_TO_SERVO(p) (p)
// Sanguino
#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
#define TOTAL_ANALOG_PINS 8
@ -282,6 +337,10 @@ writePort(port, value, bitmask): Write an 8 bit port.
#error "Please edit Boards.h with a hardware abstraction for this board"
#endif
// as long this is not defined for all boards:
#ifndef IS_PIN_SPI(p)
#define IS_PIN_SPI(p) 0
#endif
/*==============================================================================
* readPort() - Read an 8 bit port

View File

@ -28,27 +28,28 @@ extern "C" {
void FirmataClass::sendValueAsTwo7bitBytes(int value)
{
FirmataSerial.write(value & B01111111); // LSB
FirmataSerial.write(value >> 7 & B01111111); // MSB
FirmataSerial->write(value & B01111111); // LSB
FirmataSerial->write(value >> 7 & B01111111); // MSB
}
void FirmataClass::startSysex(void)
{
FirmataSerial.write(START_SYSEX);
FirmataSerial->write(START_SYSEX);
}
void FirmataClass::endSysex(void)
{
FirmataSerial.write(END_SYSEX);
FirmataSerial->write(END_SYSEX);
}
//******************************************************************************
//* Constructors
//******************************************************************************
FirmataClass::FirmataClass(Stream &s) : FirmataSerial(s)
FirmataClass::FirmataClass()
{
firmwareVersionCount = 0;
firmwareVersionVector = 0;
systemReset();
}
@ -56,7 +57,7 @@ FirmataClass::FirmataClass(Stream &s) : FirmataSerial(s)
//* Public Methods
//******************************************************************************
/* begin method for overriding default serial bitrate */
/* begin method with default serial bitrate */
void FirmataClass::begin(void)
{
begin(57600);
@ -66,34 +67,32 @@ void FirmataClass::begin(void)
void FirmataClass::begin(long speed)
{
Serial.begin(speed);
FirmataSerial = Serial;
blinkVersion();
printVersion();
printFirmwareVersion();
begin(Serial);
blinkVersion();
}
/* begin method for overriding default stream */
void FirmataClass::begin(Stream &s)
{
FirmataSerial = s;
systemReset();
FirmataSerial = &s;
printVersion();
printFirmwareVersion();
}
// output the protocol version message to the serial port
void FirmataClass::printVersion(void) {
FirmataSerial.write(REPORT_VERSION);
FirmataSerial.write(FIRMATA_MAJOR_VERSION);
FirmataSerial.write(FIRMATA_MINOR_VERSION);
FirmataSerial->write(REPORT_VERSION);
FirmataSerial->write(FIRMATA_MAJOR_VERSION);
FirmataSerial->write(FIRMATA_MINOR_VERSION);
}
void FirmataClass::blinkVersion(void)
{
// flash the pin with the protocol version
pinMode(VERSION_BLINK_PIN,OUTPUT);
pin13strobe(FIRMATA_MAJOR_VERSION, 40, 210);
strobeBlinkPin(FIRMATA_MAJOR_VERSION, 40, 210);
delay(250);
pin13strobe(FIRMATA_MINOR_VERSION, 40, 210);
strobeBlinkPin(FIRMATA_MINOR_VERSION, 40, 210);
delay(125);
}
@ -103,9 +102,9 @@ void FirmataClass::printFirmwareVersion(void)
if(firmwareVersionCount) { // make sure that the name has been set before reporting
startSysex();
FirmataSerial.write(REPORT_FIRMWARE);
FirmataSerial.write(firmwareVersionVector[0]); // major version number
FirmataSerial.write(firmwareVersionVector[1]); // minor version number
FirmataSerial->write(REPORT_FIRMWARE);
FirmataSerial->write(firmwareVersionVector[0]); // major version number
FirmataSerial->write(firmwareVersionVector[1]); // minor version number
for(i=2; i<firmwareVersionCount; ++i) {
sendValueAsTwo7bitBytes(firmwareVersionVector[i]);
}
@ -128,6 +127,9 @@ void FirmataClass::setFirmwareNameAndVersion(const char *name, byte major, byte
firmwareVersionCount = strlen(name) + 2;
filename = name;
}
free(firmwareVersionVector);
firmwareVersionVector = (byte *) malloc(firmwareVersionCount);
firmwareVersionVector[firmwareVersionCount] = 0;
firmwareVersionVector[0] = major;
@ -138,12 +140,20 @@ void FirmataClass::setFirmwareNameAndVersion(const char *name, byte major, byte
// (char)major, (char)minor, firmwareVersionVector);
}
// this method is only used for unit testing
// void FirmataClass::unsetFirmwareVersion()
// {
// firmwareVersionCount = 0;
// free(firmwareVersionVector);
// firmwareVersionVector = 0;
// }
//------------------------------------------------------------------------------
// Serial Receive Handling
int FirmataClass::available(void)
{
return FirmataSerial.available();
return FirmataSerial->available();
}
@ -177,11 +187,11 @@ void FirmataClass::processSysexMessage(void)
void FirmataClass::processInput(void)
{
int inputData = FirmataSerial.read(); // this is 'int' to handle -1 when no data
int inputData = FirmataSerial->read(); // this is 'int' to handle -1 when no data
int command;
// TODO make sure it handles -1 properly
if (parsingSysex) {
if(inputData == END_SYSEX) {
//stop sysex byte
@ -245,7 +255,7 @@ void FirmataClass::processInput(void)
break;
case REPORT_ANALOG:
case REPORT_DIGITAL:
waitForData = 1; // one data byte needed
waitForData = 1; // two data bytes needed
executeMultiByteCommand = command;
break;
case START_SYSEX:
@ -269,7 +279,7 @@ void FirmataClass::processInput(void)
void FirmataClass::sendAnalog(byte pin, int value)
{
// pin can only be 0-15, so chop higher bits
FirmataSerial.write(ANALOG_MESSAGE | (pin & 0xF));
FirmataSerial->write(ANALOG_MESSAGE | (pin & 0xF));
sendValueAsTwo7bitBytes(value);
}
@ -300,9 +310,9 @@ void FirmataClass::sendDigital(byte pin, int value)
// send an 8-bit port in a single digital message (protocol v2)
void FirmataClass::sendDigitalPort(byte portNumber, int portData)
{
FirmataSerial.write(DIGITAL_MESSAGE | (portNumber & 0xF));
FirmataSerial.write((byte)portData % 128); // Tx bits 0-6
FirmataSerial.write(portData >> 7); // Tx bits 7-13
FirmataSerial->write(DIGITAL_MESSAGE | (portNumber & 0xF));
FirmataSerial->write((byte)portData % 128); // Tx bits 0-6
FirmataSerial->write(portData >> 7); // Tx bits 7-13
}
@ -310,7 +320,7 @@ void FirmataClass::sendSysex(byte command, byte bytec, byte* bytev)
{
byte i;
startSysex();
FirmataSerial.write(command);
FirmataSerial->write(command);
for(i=0; i<bytec; i++) {
sendValueAsTwo7bitBytes(bytev[i]);
}
@ -329,6 +339,12 @@ void FirmataClass::sendString(const char* string)
sendString(STRING_DATA, string);
}
// expose the write method
void FirmataClass::write(byte c)
{
FirmataSerial->write(c);
}
// Internal Actions/////////////////////////////////////////////////////////////
@ -407,7 +423,6 @@ void FirmataClass::systemReset(void)
executeMultiByteCommand = 0; // execute this after getting multi-byte data
multiByteChannel = 0; // channel data for multiByteCommands
for(i=0; i<MAX_DATA_BYTES; i++) {
storedInputData[i] = 0;
}
@ -425,7 +440,7 @@ void FirmataClass::systemReset(void)
// =============================================================================
// used for flashing the pin for the version number
void FirmataClass::pin13strobe(int count, int onInterval, int offInterval)
void FirmataClass::strobeBlinkPin(int count, int onInterval, int offInterval)
{
byte i;
pinMode(VERSION_BLINK_PIN, OUTPUT);
@ -439,6 +454,6 @@ void FirmataClass::pin13strobe(int count, int onInterval, int offInterval)
// make one instance for the user to use
FirmataClass Firmata(Serial);
FirmataClass Firmata;

View File

@ -21,7 +21,7 @@
* installed firmware. */
#define FIRMATA_MAJOR_VERSION 2 // for non-compatible changes
#define FIRMATA_MINOR_VERSION 3 // for backwards compatible changes
#define FIRMATA_BUGFIX_VERSION 1 // for bugfix releases
#define FIRMATA_BUGFIX_VERSION 5 // for bugfix releases
#define MAX_DATA_BYTES 32 // max number of data bytes in non-Sysex messages
@ -87,27 +87,29 @@ extern "C" {
class FirmataClass
{
public:
FirmataClass(Stream &s);
FirmataClass();
/* Arduino constructors */
void begin();
void begin(long);
void begin(Stream &s);
/* querying functions */
void printVersion(void);
void printVersion(void);
void blinkVersion(void);
void printFirmwareVersion(void);
//void setFirmwareVersion(byte major, byte minor); // see macro below
void setFirmwareNameAndVersion(const char *name, byte major, byte minor);
//void unsetFirmwareVersion(); // only used for unit test
/* serial receive handling */
int available(void);
void processInput(void);
/* serial send handling */
void sendAnalog(byte pin, int value);
void sendDigital(byte pin, int value); // TODO implement this
void sendDigitalPort(byte portNumber, int portData);
void sendAnalog(byte pin, int value);
void sendDigital(byte pin, int value); // TODO implement this
void sendDigitalPort(byte portNumber, int portData);
void sendString(const char* string);
void sendString(byte command, const char* string);
void sendSysex(byte command, byte bytec, byte* bytev);
void sendSysex(byte command, byte bytec, byte* bytev);
void write(byte c);
/* attach & detach callback functions to messages */
void attach(byte command, callbackFunction newFunction);
void attach(byte command, systemResetCallbackFunction newFunction);
@ -116,7 +118,7 @@ public:
void detach(byte command);
private:
Stream &FirmataSerial;
Stream *FirmataSerial;
/* firmware name and version */
byte firmwareVersionCount;
byte *firmwareVersionVector;
@ -140,8 +142,8 @@ private:
/* private methods ------------------------------ */
void processSysexMessage(void);
void systemReset(void);
void pin13strobe(int count, int onInterval, int offInterval);
void systemReset(void);
void strobeBlinkPin(int count, int onInterval, int offInterval);
void sendValueAsTwo7bitBytes(int value);
void startSysex(void);
void endSysex(void);