Skip to content

Add StandardFirmataEthernet example #191

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Apr 12, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Firmata.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Firmata.cpp - Firmata library v2.4.2 - 2015-3-16
Firmata.cpp - Firmata library v2.4.3 - 2015-4-11
Copyright (C) 2006-2008 Hans-Christoph Steiner. All rights reserved.

This library is free software; you can redistribute it and/or
Expand Down
4 changes: 2 additions & 2 deletions Firmata.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Firmata.h - Firmata library v2.4.2 - 2015-3-16
Firmata.h - Firmata library v2.4.3 - 2015-4-11
Copyright (C) 2006-2008 Hans-Christoph Steiner. All rights reserved.
This library is free software; you can redistribute it and/or
Expand All @@ -21,7 +21,7 @@
* installed firmware. */
#define FIRMATA_MAJOR_VERSION 2 // for non-compatible changes
#define FIRMATA_MINOR_VERSION 4 // for backwards compatible changes
#define FIRMATA_BUGFIX_VERSION 2 // for bugfix releases
#define FIRMATA_BUGFIX_VERSION 3 // for bugfix releases

#define MAX_DATA_BYTES 64 // max number of data bytes in incoming messages

Expand Down
115 changes: 59 additions & 56 deletions examples/StandardFirmata/StandardFirmata.ino
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
/*
* 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
*/
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.
https://github.com/firmata/arduino#firmata-client-libraries
/*
Copyright (C) 2006-2008 Hans-Christoph Steiner. All rights reserved.
Copyright (C) 2010-2011 Paul Stoffregen. All rights reserved.
Copyright (C) 2009 Shigeru Kobayashi. All rights reserved.
Copyright (C) 2009-2014 Jeff Hoefs. All rights reserved.
Copyright (C) 2009-2015 Jeff Hoefs. 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
Expand All @@ -22,29 +20,25 @@
See file LICENSE.txt for further informations on licensing terms.
formatted using the GNU C formatting and indenting
Last updated by Jeff Hoefs: April 11, 2015
*/

/*
* TODO: use Program Control to load stored profiles from EEPROM
*/

#include <Servo.h>
#include <Wire.h>
#include <Firmata.h>

// move the following defines to 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 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 I2C_10BIT_ADDRESS_MODE_MASK B00100000
#define MAX_QUERIES 8
#define REGISTER_NOT_SPECIFIED -1

#define MAX_QUERIES 8
// the minimum interval for sampling analog input
#define MINIMUM_SAMPLING_INTERVAL 10

#define REGISTER_NOT_SPECIFIED -1

/*==============================================================================
* GLOBAL VARIABLES
Expand All @@ -65,7 +59,7 @@ int pinState[TOTAL_PINS]; // any value that has been written
/* timer variables */
unsigned long currentMillis; // store the current value from millis()
unsigned long previousMillis; // for comparison with currentMillis
unsigned int samplingInterval = 19; // how often to run the main loop (in ms)
unsigned int samplingInterval = 19; // how often to run the main loop (in ms)

/* i2c data */
struct i2c_device_info {
Expand All @@ -77,19 +71,38 @@ struct i2c_device_info {
/* for i2c read continuous more */
i2c_device_info query[MAX_QUERIES];

boolean isResetting = false;

byte i2cRxData[32];
boolean isI2CEnabled = false;
signed char queryIndex = -1;
unsigned int i2cReadDelayTime = 0; // default delay time between i2c read request and Wire.requestFrom()
// default delay time between i2c read request and Wire.requestFrom()
unsigned int i2cReadDelayTime = 0;

Servo servos[MAX_SERVOS];
byte servoPinMap[TOTAL_PINS];
byte detachedServos[MAX_SERVOS];
byte detachedServoCount = 0;
byte servoCount = 0;

boolean isResetting = false;

/* utility functions */
void wireWrite(byte data)
{
#if ARDUINO >= 100
Wire.write((byte)data);
#else
Wire.send(data);
#endif
}

byte wireRead(void)
{
#if ARDUINO >= 100
return Wire.read();
#else
return Wire.receive();
#endif
}

/*==============================================================================
* FUNCTIONS
Expand Down Expand Up @@ -139,11 +152,7 @@ void readAndReportData(byte address, int theRegister, byte numBytes) {
// do not always require the register read so upon interrupt you call Wire.requestFrom()
if (theRegister != REGISTER_NOT_SPECIFIED) {
Wire.beginTransmission(address);
#if ARDUINO >= 100
Wire.write((byte)theRegister);
#else
Wire.send((byte)theRegister);
#endif
wireWrite((byte)theRegister);
Wire.endTransmission();
// do not set a value of 0
if (i2cReadDelayTime > 0) {
Expand All @@ -158,20 +167,16 @@ void readAndReportData(byte address, int theRegister, byte numBytes) {

// check to be sure correct number of bytes were returned by slave
if (numBytes < Wire.available()) {
Firmata.sendString("I2C Read Error: Too many bytes received");
Firmata.sendString("I2C: Too many bytes received");
} else if (numBytes > Wire.available()) {
Firmata.sendString("I2C Read Error: Too few bytes received");
Firmata.sendString("I2C: Too few bytes received");
}

i2cRxData[0] = address;
i2cRxData[1] = theRegister;

for (int i = 0; i < numBytes && Wire.available(); i++) {
#if ARDUINO >= 100
i2cRxData[2 + i] = Wire.read();
#else
i2cRxData[2 + i] = Wire.receive();
#endif
i2cRxData[2 + i] = wireRead();
}

// send slave address, register and received bytes
Expand Down Expand Up @@ -221,6 +226,9 @@ void checkDigitalInputs(void)
*/
void setPinModeCallback(byte pin, int mode)
{
if (pinConfig[pin] == IGNORE)
return;

if (pinConfig[pin] == I2C && isI2CEnabled && mode != I2C) {
// disable i2c so pins can be used for other functions
// the following if statements should reconfigure the pins properly
Expand All @@ -246,15 +254,15 @@ void setPinModeCallback(byte pin, int mode)
case ANALOG:
if (IS_PIN_ANALOG(pin)) {
if (IS_PIN_DIGITAL(pin)) {
pinMode(PIN_TO_DIGITAL(pin), INPUT); // disable output driver
pinMode(PIN_TO_DIGITAL(pin), INPUT); // disable output driver
digitalWrite(PIN_TO_DIGITAL(pin), LOW); // disable internal pull-ups
}
pinConfig[pin] = ANALOG;
}
break;
case INPUT:
if (IS_PIN_DIGITAL(pin)) {
pinMode(PIN_TO_DIGITAL(pin), INPUT); // disable output driver
pinMode(PIN_TO_DIGITAL(pin), INPUT); // disable output driver
digitalWrite(PIN_TO_DIGITAL(pin), LOW); // disable internal pull-ups
pinConfig[pin] = INPUT;
}
Expand Down Expand Up @@ -409,11 +417,7 @@ void sysexCallback(byte command, byte argc, byte *argv)
Wire.beginTransmission(slaveAddress);
for (byte i = 2; i < argc; i += 2) {
data = argv[i] + (argv[i + 1] << 7);
#if ARDUINO >= 100
Wire.write(data);
#else
Wire.send(data);
#endif
wireWrite(data);
}
Wire.endTransmission();
delayMicroseconds(70);
Expand Down Expand Up @@ -541,19 +545,19 @@ void sysexCallback(byte command, byte argc, byte *argv)
}
if (IS_PIN_ANALOG(pin)) {
Firmata.write(ANALOG);
Firmata.write(10);
Firmata.write(10); // 10 = 10-bit resolution
}
if (IS_PIN_PWM(pin)) {
Firmata.write(PWM);
Firmata.write(8);
Firmata.write(8); // 8 = 8-bit resolution
}
if (IS_PIN_DIGITAL(pin)) {
Firmata.write(SERVO);
Firmata.write(14);
}
if (IS_PIN_I2C(pin)) {
Firmata.write(I2C);
Firmata.write(1); // to do: determine appropriate value
Firmata.write(1); // TODO: could assign a number to map to SCL or SDA
}
Firmata.write(127);
}
Expand Down Expand Up @@ -599,7 +603,6 @@ void enableI2CPins()

isI2CEnabled = true;

// is there enough time before the first I2C request to call this here?
Wire.begin();
}

Expand All @@ -617,14 +620,16 @@ void disableI2CPins() {
void systemResetCallback()
{
isResetting = true;

// initialize a defalt state
// TODO: option to load config from EEPROM instead of default

if (isI2CEnabled) {
disableI2CPins();
}

for (byte i = 0; i < TOTAL_PORTS; i++) {
reportPINs[i] = false; // by default, reporting off
reportPINs[i] = false; // by default, reporting off
portConfigInputs[i] = 0; // until activated
previousPINs[i] = 0;
}
Expand Down Expand Up @@ -687,14 +692,12 @@ void loop()
* FTDI buffer using Serial.print() */
checkDigitalInputs();

/* SERIALREAD - processing incoming messagse as soon as possible, while still
/* STREAMREAD - processing incoming messagse as soon as possible, while still
* checking digital inputs. */
while (Firmata.available())
Firmata.processInput();

/* SEND FTDI WRITE BUFFER - make sure that the FTDI buffer doesn't go over
* 60 bytes. use a timer to sending an event character every 4 ms to
* trigger the buffer to dump. */
// TODO - ensure that Stream buffer doesn't go over 60 bytes

currentMillis = millis();
if (currentMillis - previousMillis > samplingInterval) {
Expand Down
Loading