Skip to content

Commit e2cede3

Browse files
brought StandardFirmataYun up to date with StandardFirmata and added explanation of sketch purpose
1 parent 407971b commit e2cede3

File tree

2 files changed

+82
-80
lines changed

2 files changed

+82
-80
lines changed

examples/StandardFirmata/StandardFirmata.ino

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
#include <Wire.h>
2828
#include <Firmata.h>
2929

30-
// move the following defines to Firmata.h?
3130
#define I2C_WRITE B00000000
3231
#define I2C_READ B00001000
3332
#define I2C_READ_CONTINUOUSLY B00010000

examples/StandardFirmataYun/StandardFirmataYun.ino

Lines changed: 82 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
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-
*/
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+
https://github.com/firmata/arduino#firmata-client-libraries
1110
12-
/*
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.
@@ -23,29 +21,36 @@
2321
2422
See file LICENSE.txt for further informations on licensing terms.
2523
26-
formatted using the GNU C formatting and indenting
24+
Last updated by Jeff Hoefs: April 11, 2015
2725
*/
2826

2927
/*
30-
* TODO: use Program Control to load stored profiles from EEPROM
31-
*/
28+
README
29+
30+
The Arduino Yun has both an Arduino (Atmega32u4) environment and a
31+
Linux (Linino) environment.
32+
33+
StandardFirmataYun enables Firmata running on the Arduino environment
34+
to communicate with a Firmata client application running on the Linux
35+
environment.
36+
*/
3237

3338
#include <Servo.h>
3439
#include <Wire.h>
3540
#include <Firmata.h>
3641

37-
// move the following defines to Firmata.h?
38-
#define I2C_WRITE B00000000
39-
#define I2C_READ B00001000
40-
#define I2C_READ_CONTINUOUSLY B00010000
41-
#define I2C_STOP_READING B00011000
42-
#define I2C_READ_WRITE_MODE_MASK B00011000
42+
#define I2C_WRITE B00000000
43+
#define I2C_READ B00001000
44+
#define I2C_READ_CONTINUOUSLY B00010000
45+
#define I2C_STOP_READING B00011000
46+
#define I2C_READ_WRITE_MODE_MASK B00011000
4347
#define I2C_10BIT_ADDRESS_MODE_MASK B00100000
48+
#define MAX_QUERIES 8
49+
#define REGISTER_NOT_SPECIFIED -1
4450

45-
#define MAX_QUERIES 8
51+
// the minimum interval for sampling analog input
4652
#define MINIMUM_SAMPLING_INTERVAL 10
4753

48-
#define REGISTER_NOT_SPECIFIED -1
4954

5055
/*==============================================================================
5156
* GLOBAL VARIABLES
@@ -66,7 +71,7 @@ int pinState[TOTAL_PINS]; // any value that has been written
6671
/* timer variables */
6772
unsigned long currentMillis; // store the current value from millis()
6873
unsigned long previousMillis; // for comparison with currentMillis
69-
unsigned int samplingInterval = 19; // how often to run the main loop (in ms)
74+
unsigned int samplingInterval = 19; // how often to run the main loop (in ms)
7075

7176
/* i2c data */
7277
struct i2c_device_info {
@@ -78,19 +83,38 @@ struct i2c_device_info {
7883
/* for i2c read continuous more */
7984
i2c_device_info query[MAX_QUERIES];
8085

81-
boolean isResetting = false;
82-
8386
byte i2cRxData[32];
8487
boolean isI2CEnabled = false;
8588
signed char queryIndex = -1;
86-
unsigned int i2cReadDelayTime = 0; // default delay time between i2c read request and Wire.requestFrom()
89+
// default delay time between i2c read request and Wire.requestFrom()
90+
unsigned int i2cReadDelayTime = 0;
8791

8892
Servo servos[MAX_SERVOS];
8993
byte servoPinMap[TOTAL_PINS];
9094
byte detachedServos[MAX_SERVOS];
9195
byte detachedServoCount = 0;
9296
byte servoCount = 0;
9397

98+
boolean isResetting = false;
99+
100+
/* utility functions */
101+
void wireWrite(byte data)
102+
{
103+
#if ARDUINO >= 100
104+
Wire.write((byte)data);
105+
#else
106+
Wire.send(data);
107+
#endif
108+
}
109+
110+
byte wireRead(void)
111+
{
112+
#if ARDUINO >= 100
113+
return Wire.read();
114+
#else
115+
return Wire.receive();
116+
#endif
117+
}
94118

95119
/*==============================================================================
96120
* FUNCTIONS
@@ -103,19 +127,16 @@ void attachServo(byte pin, int minPulse, int maxPulse)
103127
if (detachedServoCount > 0) {
104128
servoPinMap[pin] = detachedServos[detachedServoCount - 1];
105129
if (detachedServoCount > 0) detachedServoCount--;
106-
}
107-
else {
130+
} else {
108131
servoPinMap[pin] = servoCount;
109132
servoCount++;
110133
}
111134
if (minPulse > 0 && maxPulse > 0) {
112135
servos[servoPinMap[pin]].attach(PIN_TO_DIGITAL(pin), minPulse, maxPulse);
113-
}
114-
else {
136+
} else {
115137
servos[servoPinMap[pin]].attach(PIN_TO_DIGITAL(pin));
116138
}
117-
}
118-
else {
139+
} else {
119140
Firmata.sendString("Max servos attached");
120141
}
121142
}
@@ -127,8 +148,7 @@ void detachServo(byte pin)
127148
// otherwise store the index of the detached servo
128149
if (servoPinMap[pin] == servoCount && servoCount > 0) {
129150
servoCount--;
130-
}
131-
else if (servoCount > 0) {
151+
} else if (servoCount > 0) {
132152
// keep track of detached servos because we want to reuse their indexes
133153
// before incrementing the count of attached servos
134154
detachedServoCount++;
@@ -144,41 +164,31 @@ void readAndReportData(byte address, int theRegister, byte numBytes) {
144164
// do not always require the register read so upon interrupt you call Wire.requestFrom()
145165
if (theRegister != REGISTER_NOT_SPECIFIED) {
146166
Wire.beginTransmission(address);
147-
#if ARDUINO >= 100
148-
Wire.write((byte)theRegister);
149-
#else
150-
Wire.send((byte)theRegister);
151-
#endif
167+
wireWrite((byte)theRegister);
152168
Wire.endTransmission();
153169
// do not set a value of 0
154170
if (i2cReadDelayTime > 0) {
155171
// delay is necessary for some devices such as WiiNunchuck
156172
delayMicroseconds(i2cReadDelayTime);
157173
}
158-
}
159-
else {
174+
} else {
160175
theRegister = 0; // fill the register with a dummy value
161176
}
162177

163178
Wire.requestFrom(address, numBytes); // all bytes are returned in requestFrom
164179

165180
// check to be sure correct number of bytes were returned by slave
166181
if (numBytes < Wire.available()) {
167-
Firmata.sendString("I2C Read Error: Too many bytes received");
168-
}
169-
else if (numBytes > Wire.available()) {
170-
Firmata.sendString("I2C Read Error: Too few bytes received");
182+
Firmata.sendString("I2C: Too many bytes received");
183+
} else if (numBytes > Wire.available()) {
184+
Firmata.sendString("I2C: Too few bytes received");
171185
}
172186

173187
i2cRxData[0] = address;
174188
i2cRxData[1] = theRegister;
175189

176190
for (int i = 0; i < numBytes && Wire.available(); i++) {
177-
#if ARDUINO >= 100
178-
i2cRxData[2 + i] = Wire.read();
179-
#else
180-
i2cRxData[2 + i] = Wire.receive();
181-
#endif
191+
i2cRxData[2 + i] = wireRead();
182192
}
183193

184194
// send slave address, register and received bytes
@@ -228,6 +238,9 @@ void checkDigitalInputs(void)
228238
*/
229239
void setPinModeCallback(byte pin, int mode)
230240
{
241+
if (pinConfig[pin] == IGNORE)
242+
return;
243+
231244
if (pinConfig[pin] == I2C && isI2CEnabled && mode != I2C) {
232245
// disable i2c so pins can be used for other functions
233246
// the following if statements should reconfigure the pins properly
@@ -244,8 +257,7 @@ void setPinModeCallback(byte pin, int mode)
244257
if (IS_PIN_DIGITAL(pin)) {
245258
if (mode == INPUT) {
246259
portConfigInputs[pin / 8] |= (1 << (pin & 7));
247-
}
248-
else {
260+
} else {
249261
portConfigInputs[pin / 8] &= ~(1 << (pin & 7));
250262
}
251263
}
@@ -254,15 +266,15 @@ void setPinModeCallback(byte pin, int mode)
254266
case ANALOG:
255267
if (IS_PIN_ANALOG(pin)) {
256268
if (IS_PIN_DIGITAL(pin)) {
257-
pinMode(PIN_TO_DIGITAL(pin), INPUT); // disable output driver
269+
pinMode(PIN_TO_DIGITAL(pin), INPUT); // disable output driver
258270
digitalWrite(PIN_TO_DIGITAL(pin), LOW); // disable internal pull-ups
259271
}
260272
pinConfig[pin] = ANALOG;
261273
}
262274
break;
263275
case INPUT:
264276
if (IS_PIN_DIGITAL(pin)) {
265-
pinMode(PIN_TO_DIGITAL(pin), INPUT); // disable output driver
277+
pinMode(PIN_TO_DIGITAL(pin), INPUT); // disable output driver
266278
digitalWrite(PIN_TO_DIGITAL(pin), LOW); // disable internal pull-ups
267279
pinConfig[pin] = INPUT;
268280
}
@@ -417,11 +429,7 @@ void sysexCallback(byte command, byte argc, byte *argv)
417429
Wire.beginTransmission(slaveAddress);
418430
for (byte i = 2; i < argc; i += 2) {
419431
data = argv[i] + (argv[i + 1] << 7);
420-
#if ARDUINO >= 100
421-
Wire.write(data);
422-
#else
423-
Wire.send(data);
424-
#endif
432+
wireWrite(data);
425433
}
426434
Wire.endTransmission();
427435
delayMicroseconds(70);
@@ -466,8 +474,7 @@ void sysexCallback(byte command, byte argc, byte *argv)
466474
// read continuous reporting for that device
467475
if (queryIndex <= 0) {
468476
queryIndex = -1;
469-
}
470-
else {
477+
} else {
471478
// if read continuous mode is enabled for multiple devices,
472479
// determine which device to stop reading and remove it's data from
473480
// the array, shifiting other array data to fill the space
@@ -526,8 +533,7 @@ void sysexCallback(byte command, byte argc, byte *argv)
526533
if (samplingInterval < MINIMUM_SAMPLING_INTERVAL) {
527534
samplingInterval = MINIMUM_SAMPLING_INTERVAL;
528535
}
529-
}
530-
else {
536+
} else {
531537
//Firmata.sendString("Not enough data");
532538
}
533539
break;
@@ -551,19 +557,19 @@ void sysexCallback(byte command, byte argc, byte *argv)
551557
}
552558
if (IS_PIN_ANALOG(pin)) {
553559
Firmata.write(ANALOG);
554-
Firmata.write(10);
560+
Firmata.write(10); // 10 = 10-bit resolution
555561
}
556562
if (IS_PIN_PWM(pin)) {
557563
Firmata.write(PWM);
558-
Firmata.write(8);
564+
Firmata.write(8); // 8 = 8-bit resolution
559565
}
560566
if (IS_PIN_DIGITAL(pin)) {
561567
Firmata.write(SERVO);
562568
Firmata.write(14);
563569
}
564570
if (IS_PIN_I2C(pin)) {
565571
Firmata.write(I2C);
566-
Firmata.write(1); // to do: determine appropriate value
572+
Firmata.write(1); // TODO: could assign a number to map to SCL or SDA
567573
}
568574
Firmata.write(127);
569575
}
@@ -609,7 +615,6 @@ void enableI2CPins()
609615

610616
isI2CEnabled = true;
611617

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

@@ -627,14 +632,16 @@ void disableI2CPins() {
627632
void systemResetCallback()
628633
{
629634
isResetting = true;
635+
630636
// initialize a defalt state
631637
// TODO: option to load config from EEPROM instead of default
638+
632639
if (isI2CEnabled) {
633640
disableI2CPins();
634641
}
635642

636643
for (byte i = 0; i < TOTAL_PORTS; i++) {
637-
reportPINs[i] = false; // by default, reporting off
644+
reportPINs[i] = false; // by default, reporting off
638645
portConfigInputs[i] = 0; // until activated
639646
previousPINs[i] = 0;
640647
}
@@ -645,8 +652,7 @@ void systemResetCallback()
645652
if (IS_PIN_ANALOG(i)) {
646653
// turns off pullup, configures everything
647654
setPinModeCallback(i, ANALOG);
648-
}
649-
else {
655+
} else {
650656
// sets the output to 0, configures portConfigInputs
651657
setPinModeCallback(i, OUTPUT);
652658
}
@@ -663,11 +669,11 @@ void systemResetCallback()
663669
* since once in the loop(), this firmware will only send on change */
664670
/*
665671
TODO: this can never execute, since no pins default to digital input
666-
but it will be needed when/if we support EEPROM stored config
667-
for (byte i=0; i < TOTAL_PORTS; i++) {
668-
outputPort(i, readPort(i, portConfigInputs[i]), true);
669-
}
670-
*/
672+
but it will be needed when/if we support EEPROM stored config
673+
for (byte i=0; i < TOTAL_PORTS; i++) {
674+
outputPort(i, readPort(i, portConfigInputs[i]), true);
675+
}
676+
*/
671677
isResetting = false;
672678
}
673679

@@ -710,14 +716,12 @@ void loop()
710716
* FTDI buffer using Serial.print() */
711717
checkDigitalInputs();
712718

713-
/* SERIALREAD - processing incoming messagse as soon as possible, while still
719+
/* STREAMREAD - processing incoming messagse as soon as possible, while still
714720
* checking digital inputs. */
715721
while (Firmata.available())
716722
Firmata.processInput();
717723

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

722726
currentMillis = millis();
723727
if (currentMillis - previousMillis > samplingInterval) {
@@ -739,4 +743,3 @@ void loop()
739743
}
740744
}
741745
}
742-

0 commit comments

Comments
 (0)