mirror of
https://github.com/arduino/Arduino.git
synced 2025-01-18 07:52:14 +01:00
Updating to Firmata-2.1beta1 (rev 23).
This commit is contained in:
parent
e5dc169cc7
commit
3b78ba0d8c
@ -60,7 +60,7 @@ FirmataClass::FirmataClass(void)
|
|||||||
/* begin method for overriding default serial bitrate */
|
/* begin method for overriding default serial bitrate */
|
||||||
void FirmataClass::begin(void)
|
void FirmataClass::begin(void)
|
||||||
{
|
{
|
||||||
Serial.begin(115200);
|
Serial.begin(57600);
|
||||||
blinkVersion();
|
blinkVersion();
|
||||||
delay(300);
|
delay(300);
|
||||||
printVersion();
|
printVersion();
|
||||||
@ -154,7 +154,7 @@ void FirmataClass::processSysexMessage(void)
|
|||||||
case REPORT_FIRMWARE:
|
case REPORT_FIRMWARE:
|
||||||
printFirmwareVersion();
|
printFirmwareVersion();
|
||||||
break;
|
break;
|
||||||
case FIRMATA_STRING:
|
case STRING_DATA:
|
||||||
if(currentStringCallback) {
|
if(currentStringCallback) {
|
||||||
byte bufferLength = (sysexBytesRead - 1) / 2;
|
byte bufferLength = (sysexBytesRead - 1) / 2;
|
||||||
char *buffer = (char*)malloc(bufferLength * sizeof(char));
|
char *buffer = (char*)malloc(bufferLength * sizeof(char));
|
||||||
@ -327,7 +327,7 @@ void FirmataClass::sendString(byte command, const char* string)
|
|||||||
// send a string as the protocol string type
|
// send a string as the protocol string type
|
||||||
void FirmataClass::sendString(const char* string)
|
void FirmataClass::sendString(const char* string)
|
||||||
{
|
{
|
||||||
sendString(FIRMATA_STRING, string);
|
sendString(STRING_DATA, string);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -355,7 +355,7 @@ void FirmataClass::attach(byte command, systemResetCallbackFunction newFunction)
|
|||||||
void FirmataClass::attach(byte command, stringCallbackFunction newFunction)
|
void FirmataClass::attach(byte command, stringCallbackFunction newFunction)
|
||||||
{
|
{
|
||||||
switch(command) {
|
switch(command) {
|
||||||
case FIRMATA_STRING: currentStringCallback = newFunction; break;
|
case STRING_DATA: currentStringCallback = newFunction; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -368,7 +368,7 @@ void FirmataClass::detach(byte command)
|
|||||||
{
|
{
|
||||||
switch(command) {
|
switch(command) {
|
||||||
case SYSTEM_RESET: currentSystemResetCallback = NULL; break;
|
case SYSTEM_RESET: currentSystemResetCallback = NULL; break;
|
||||||
case FIRMATA_STRING: currentStringCallback = NULL; break;
|
case STRING_DATA: currentStringCallback = NULL; break;
|
||||||
case START_SYSEX: currentSysexCallback = NULL; break;
|
case START_SYSEX: currentSysexCallback = NULL; break;
|
||||||
default:
|
default:
|
||||||
attach(command, (callbackFunction)NULL);
|
attach(command, (callbackFunction)NULL);
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
* software can test whether it will be compatible with the currently
|
* software can test whether it will be compatible with the currently
|
||||||
* installed firmware. */
|
* installed firmware. */
|
||||||
#define FIRMATA_MAJOR_VERSION 2 // for non-compatible changes
|
#define FIRMATA_MAJOR_VERSION 2 // for non-compatible changes
|
||||||
#define FIRMATA_MINOR_VERSION 0 // for backwards compatible changes
|
#define FIRMATA_MINOR_VERSION 1 // for backwards compatible changes
|
||||||
#define VERSION_BLINK_PIN 13 // digital pin to blink version on
|
#define VERSION_BLINK_PIN 13 // digital pin to blink version on
|
||||||
|
|
||||||
#define MAX_DATA_BYTES 32 // max number of data bytes in non-Sysex messages
|
#define MAX_DATA_BYTES 32 // max number of data bytes in non-Sysex messages
|
||||||
@ -42,12 +42,22 @@
|
|||||||
#define END_SYSEX 0xF7 // end a MIDI Sysex message
|
#define END_SYSEX 0xF7 // end a MIDI Sysex message
|
||||||
|
|
||||||
// extended command set using sysex (0-127/0x00-0x7F)
|
// extended command set using sysex (0-127/0x00-0x7F)
|
||||||
/* 0x00-0x0F reserved for custom commands */
|
/* 0x00-0x0F reserved for user-defined commands */
|
||||||
#define SERVO_CONFIG 0x70 // set max angle, minPulse, maxPulse, freq
|
#define SERVO_CONFIG 0x70 // set max angle, minPulse, maxPulse, freq
|
||||||
#define FIRMATA_STRING 0x71 // a string message with 14-bits per char
|
#define STRING_DATA 0x71 // a string message with 14-bits per char
|
||||||
|
#define SHIFT_DATA 0x75 // a bitstream to/from a shift register
|
||||||
|
#define I2C_REQUEST 0x76 // send an I2C read/write request
|
||||||
|
#define I2C_REPLY 0x77 // a reply to an I2C read request
|
||||||
|
#define I2C_CONFIG 0x78 // config I2C settings such as delay times and power pins
|
||||||
#define REPORT_FIRMWARE 0x79 // report name and version of the firmware
|
#define REPORT_FIRMWARE 0x79 // report name and version of the firmware
|
||||||
|
#define SAMPLING_INTERVAL 0x7A // set the poll rate of the main loop
|
||||||
#define SYSEX_NON_REALTIME 0x7E // MIDI Reserved for non-realtime messages
|
#define SYSEX_NON_REALTIME 0x7E // MIDI Reserved for non-realtime messages
|
||||||
#define SYSEX_REALTIME 0x7F // MIDI Reserved for realtime messages
|
#define SYSEX_REALTIME 0x7F // MIDI Reserved for realtime messages
|
||||||
|
// these are DEPRECATED to make the naming more consistent
|
||||||
|
#define FIRMATA_STRING 0x71 // same as STRING_DATA
|
||||||
|
#define SYSEX_I2C_REQUEST 0x76 // same as I2C_REQUEST
|
||||||
|
#define SYSEX_I2C_REPLY 0x77 // same as I2C_REPLY
|
||||||
|
#define SYSEX_SAMPLING_INTERVAL 0x7A // same as SAMPLING_INTERVAL
|
||||||
|
|
||||||
// pin modes
|
// pin modes
|
||||||
//#define INPUT 0x00 // defined in wiring.h
|
//#define INPUT 0x00 // defined in wiring.h
|
||||||
@ -55,7 +65,8 @@
|
|||||||
#define ANALOG 0x02 // analog pin in analogInput mode
|
#define ANALOG 0x02 // analog pin in analogInput mode
|
||||||
#define PWM 0x03 // digital pin in PWM output mode
|
#define PWM 0x03 // digital pin in PWM output mode
|
||||||
#define SERVO 0x04 // digital pin in Servo output mode
|
#define SERVO 0x04 // digital pin in Servo output mode
|
||||||
|
#define SHIFT 0x05 // shiftIn/shiftOut mode
|
||||||
|
#define I2C 0x06 // pin included in I2C setup
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
// callback function types
|
// callback function types
|
||||||
@ -151,6 +162,11 @@ extern FirmataClass Firmata;
|
|||||||
#define TOTAL_DIGITAL_PINS 20 // 14 digital + 6 analog
|
#define TOTAL_DIGITAL_PINS 20 // 14 digital + 6 analog
|
||||||
#define TOTAL_PORTS 3 // total number of ports for the board
|
#define TOTAL_PORTS 3 // total number of ports for the board
|
||||||
#define ANALOG_PORT 2 // port# of analog used as digital
|
#define ANALOG_PORT 2 // port# of analog used as digital
|
||||||
|
#elif defined(__AVR_ATmega1280__)// Arduino Mega
|
||||||
|
#define TOTAL_ANALOG_PINS 16
|
||||||
|
#define TOTAL_DIGITAL_PINS 54
|
||||||
|
#define TOTAL_PORTS 8 // total number of ports for the board
|
||||||
|
#define ANALOG_PORT 2 // port# of analog used as digital
|
||||||
#elif defined(__AVR_ATmega128__)// Wiring
|
#elif defined(__AVR_ATmega128__)// Wiring
|
||||||
#define TOTAL_ANALOG_PINS 8
|
#define TOTAL_ANALOG_PINS 8
|
||||||
#define TOTAL_DIGITAL_PINS 51
|
#define TOTAL_DIGITAL_PINS 51
|
||||||
|
@ -61,7 +61,7 @@ void setup()
|
|||||||
|
|
||||||
servo9.attach(9);
|
servo9.attach(9);
|
||||||
servo10.attach(10);
|
servo10.attach(10);
|
||||||
Firmata.begin();
|
Firmata.begin(57600);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*==============================================================================
|
/*==============================================================================
|
||||||
|
@ -25,9 +25,9 @@ void sysexCallback(byte command, byte argc, byte*argv)
|
|||||||
void setup()
|
void setup()
|
||||||
{
|
{
|
||||||
Firmata.setFirmwareVersion(0, 1);
|
Firmata.setFirmwareVersion(0, 1);
|
||||||
Firmata.attach(FIRMATA_STRING, stringCallback);
|
Firmata.attach(STRING_DATA, stringCallback);
|
||||||
Firmata.attach(START_SYSEX, sysexCallback);
|
Firmata.attach(START_SYSEX, sysexCallback);
|
||||||
Firmata.begin();
|
Firmata.begin(57600);
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop()
|
void loop()
|
||||||
|
220
hardware/libraries/Firmata/examples/I2CFirmata/I2CFirmata.pde
Normal file
220
hardware/libraries/Firmata/examples/I2CFirmata/I2CFirmata.pde
Normal file
@ -0,0 +1,220 @@
|
|||||||
|
/*
|
||||||
|
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 nextExecuteMillis; // 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.send((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.receive();
|
||||||
|
}
|
||||||
|
// 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.send(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(PC3, PC2);
|
||||||
|
}
|
||||||
|
|
||||||
|
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_DIGITAL_PINS; ++i) {
|
||||||
|
pinMode(i, OUTPUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* I2C data is not reliable at higher baud rates, you'll need to change the
|
||||||
|
baud rate on the host computer as well. To get a firmware running with
|
||||||
|
minimal effort, you can try using the default baud rate (115200) */
|
||||||
|
Firmata.begin(38400);
|
||||||
|
Wire.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
while (Firmata.available()) {
|
||||||
|
Firmata.processInput();
|
||||||
|
}
|
||||||
|
|
||||||
|
currentMillis = millis();
|
||||||
|
if (currentMillis > nextExecuteMillis) {
|
||||||
|
nextExecuteMillis = currentMillis + samplingInterval;
|
||||||
|
|
||||||
|
for (byte i = 0; i < queryIndex; i++) {
|
||||||
|
readAndReportData(query[i].addr, query[i].reg, query[i].bytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -28,7 +28,7 @@ void setup()
|
|||||||
servo9.attach(9);
|
servo9.attach(9);
|
||||||
servo10.attach(10);
|
servo10.attach(10);
|
||||||
|
|
||||||
Firmata.begin();
|
Firmata.begin(57600);
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop()
|
void loop()
|
||||||
|
@ -16,7 +16,7 @@ void setup()
|
|||||||
{
|
{
|
||||||
Firmata.setFirmwareVersion(0, 1);
|
Firmata.setFirmwareVersion(0, 1);
|
||||||
Firmata.attach(ANALOG_MESSAGE, analogWriteCallback);
|
Firmata.attach(ANALOG_MESSAGE, analogWriteCallback);
|
||||||
Firmata.begin();
|
Firmata.begin(57600);
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop()
|
void loop()
|
||||||
|
@ -45,7 +45,7 @@ void setup()
|
|||||||
Firmata.setFirmwareVersion(0, 1);
|
Firmata.setFirmwareVersion(0, 1);
|
||||||
Firmata.attach(DIGITAL_MESSAGE, digitalWriteCallback);
|
Firmata.attach(DIGITAL_MESSAGE, digitalWriteCallback);
|
||||||
Firmata.attach(SET_PIN_MODE, setPinModeCallback);
|
Firmata.attach(SET_PIN_MODE, setPinModeCallback);
|
||||||
Firmata.begin();
|
Firmata.begin(57600);
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop()
|
void loop()
|
||||||
|
@ -50,14 +50,20 @@ TARGET := $(shell pwd | sed 's|.*/\(.*\)|\1|')
|
|||||||
ARDUINO = /Applications/arduino
|
ARDUINO = /Applications/arduino
|
||||||
ARDUINO_SRC = $(ARDUINO)/hardware/cores/arduino
|
ARDUINO_SRC = $(ARDUINO)/hardware/cores/arduino
|
||||||
ARDUINO_LIB_SRC = $(ARDUINO)/hardware/libraries
|
ARDUINO_LIB_SRC = $(ARDUINO)/hardware/libraries
|
||||||
|
ARDUINO_TOOLS = $(ARDUINO)/hardware/tools
|
||||||
INCLUDE = -I$(ARDUINO_SRC) -I$(ARDUINO)/hardware/tools/avr/avr/include \
|
INCLUDE = -I$(ARDUINO_SRC) -I$(ARDUINO)/hardware/tools/avr/avr/include \
|
||||||
-I$(ARDUINO_LIB_SRC)/EEPROM \
|
-I$(ARDUINO_LIB_SRC)/EEPROM \
|
||||||
-I$(ARDUINO_LIB_SRC)/Firmata \
|
-I$(ARDUINO_LIB_SRC)/Firmata \
|
||||||
|
-I$(ARDUINO_LIB_SRC)/Matrix \
|
||||||
|
-I$(ARDUINO_LIB_SRC)/Servo \
|
||||||
|
-I$(ARDUINO_LIB_SRC)/Wire \
|
||||||
-I$(ARDUINO_LIB_SRC)
|
-I$(ARDUINO_LIB_SRC)
|
||||||
SRC = $(wildcard $(ARDUINO_SRC)/*.c)
|
SRC = $(wildcard $(ARDUINO_SRC)/*.c)
|
||||||
CXXSRC = applet/$(TARGET).cpp $(ARDUINO_SRC)/HardwareSerial.cpp \
|
CXXSRC = applet/$(TARGET).cpp $(ARDUINO_SRC)/HardwareSerial.cpp \
|
||||||
$(ARDUINO_LIB_SRC)/EEPROM/EEPROM.cpp \
|
$(ARDUINO_LIB_SRC)/EEPROM/EEPROM.cpp \
|
||||||
$(ARDUINO_LIB_SRC)/Firmata/Firmata.cpp \
|
$(ARDUINO_LIB_SRC)/Firmata/Firmata.cpp \
|
||||||
|
$(ARDUINO_LIB_SRC)/Servo/Servo.cpp \
|
||||||
|
$(ARDUINO_SRC)/Print.cpp \
|
||||||
$(ARDUINO_SRC)/WMath.cpp
|
$(ARDUINO_SRC)/WMath.cpp
|
||||||
HEADERS = $(wildcard $(ARDUINO_SRC)/*.h) $(wildcard $(ARDUINO_LIB_SRC)/*/*.h)
|
HEADERS = $(wildcard $(ARDUINO_SRC)/*.h) $(wildcard $(ARDUINO_LIB_SRC)/*/*.h)
|
||||||
|
|
||||||
@ -106,12 +112,14 @@ AVRDUDE_FLAGS = -F -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) \
|
|||||||
-b $(UPLOAD_RATE) -q -V
|
-b $(UPLOAD_RATE) -q -V
|
||||||
|
|
||||||
# Program settings
|
# Program settings
|
||||||
CC = avr-gcc
|
ARDUINO_AVR_BIN = $(ARDUINO_TOOLS)/avr/bin
|
||||||
CXX = avr-g++
|
CC = $(ARDUINO_AVR_BIN)/avr-gcc
|
||||||
OBJCOPY = avr-objcopy
|
CXX = $(ARDUINO_AVR_BIN)/avr-g++
|
||||||
OBJDUMP = avr-objdump
|
OBJCOPY = $(ARDUINO_AVR_BIN)/avr-objcopy
|
||||||
SIZE = avr-size
|
OBJDUMP = $(ARDUINO_AVR_BIN)/avr-objdump
|
||||||
NM = avr-nm
|
SIZE = $(ARDUINO_AVR_BIN)/avr-size
|
||||||
|
NM = $(ARDUINO_AVR_BIN)/avr-nm
|
||||||
|
#AVRDUDE = $(ARDUINO_AVR_BIN)/avrdude
|
||||||
AVRDUDE = avrdude
|
AVRDUDE = avrdude
|
||||||
REMOVE = rm -f
|
REMOVE = rm -f
|
||||||
MV = mv -f
|
MV = mv -f
|
||||||
@ -204,7 +212,8 @@ applet/$(TARGET).cpp: $(TARGET).pde
|
|||||||
|
|
||||||
# Link: create ELF output file from object files.
|
# Link: create ELF output file from object files.
|
||||||
applet/$(TARGET).elf: applet/$(TARGET).cpp $(OBJ)
|
applet/$(TARGET).elf: applet/$(TARGET).cpp $(OBJ)
|
||||||
$(CC) $(ALL_CFLAGS) $(OBJ) --output $@ $(LDFLAGS)
|
$(CC) $(ALL_CFLAGS) $(OBJ) -lm --output $@ $(LDFLAGS)
|
||||||
|
# $(CC) $(ALL_CFLAGS) $(OBJ) $(ARDUINO_TOOLS)/avr/avr/lib/avr5/crtm168.o --output $@ $(LDFLAGS)
|
||||||
|
|
||||||
pd_close_serial:
|
pd_close_serial:
|
||||||
echo 'close;' | /Applications/Pd-extended.app/Contents/Resources/bin/pdsend 34567 || true
|
echo 'close;' | /Applications/Pd-extended.app/Contents/Resources/bin/pdsend 34567 || true
|
||||||
@ -258,4 +267,7 @@ etags_MINGW:
|
|||||||
# etags -a /usr/include/*.h /usr/include/sys/*.h
|
# etags -a /usr/include/*.h /usr/include/sys/*.h
|
||||||
|
|
||||||
|
|
||||||
|
path:
|
||||||
|
echo $(PATH)
|
||||||
|
echo $$PATH
|
||||||
|
|
||||||
|
@ -7,15 +7,18 @@
|
|||||||
version 2.1 of the License, or (at your option) any later version.
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
See file LICENSE.txt for further informations on licensing terms.
|
See file LICENSE.txt for further informations on licensing terms.
|
||||||
|
|
||||||
|
formatted using the GNU C formatting and indenting
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TODO: add Servo support using setPinMode(pin, SERVO);
|
* TODO: add Servo support using setPinModeCallback(pin, SERVO);
|
||||||
* TODO: use Program Control to load stored profiles from EEPROM
|
* TODO: use Program Control to load stored profiles from EEPROM
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <EEPROM.h>
|
|
||||||
#include <Firmata.h>
|
#include <Firmata.h>
|
||||||
|
#include <Servo.h>
|
||||||
|
|
||||||
/*==============================================================================
|
/*==============================================================================
|
||||||
* GLOBAL VARIABLES
|
* GLOBAL VARIABLES
|
||||||
@ -34,7 +37,9 @@ byte portStatus[TOTAL_PORTS];
|
|||||||
/* timer variables */
|
/* timer variables */
|
||||||
unsigned long currentMillis; // store the current value from millis()
|
unsigned long currentMillis; // store the current value from millis()
|
||||||
unsigned long nextExecuteMillis; // for comparison with currentMillis
|
unsigned long nextExecuteMillis; // for comparison with currentMillis
|
||||||
|
int samplingInterval = 19; // how often to run the main loop (in ms)
|
||||||
|
|
||||||
|
Servo servos[2]; // the servo library can control servos on pins 9 and 10 only
|
||||||
|
|
||||||
/*==============================================================================
|
/*==============================================================================
|
||||||
* FUNCTIONS
|
* FUNCTIONS
|
||||||
@ -59,9 +64,15 @@ void checkDigitalInputs(void)
|
|||||||
for(i=0; i < TOTAL_PORTS; i++) {
|
for(i=0; i < TOTAL_PORTS; i++) {
|
||||||
if(reportPINs[i]) {
|
if(reportPINs[i]) {
|
||||||
switch(i) {
|
switch(i) {
|
||||||
case 0: outputPort(0, PIND &~ B00000011); break; // ignore Rx/Tx 0/1
|
case 0:
|
||||||
case 1: outputPort(1, PINB); break;
|
outputPort(0, PIND &~ B00000011); // ignore Rx/Tx 0/1
|
||||||
case ANALOG_PORT: outputPort(ANALOG_PORT, PINC); break;
|
break;
|
||||||
|
case 1:
|
||||||
|
outputPort(1, PINB);
|
||||||
|
break;
|
||||||
|
case ANALOG_PORT:
|
||||||
|
outputPort(ANALOG_PORT, PINC);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -75,6 +86,7 @@ void setPinModeCallback(byte pin, int mode) {
|
|||||||
byte port = 0;
|
byte port = 0;
|
||||||
byte offset = 0;
|
byte offset = 0;
|
||||||
|
|
||||||
|
// TODO: abstract for different boards
|
||||||
if (pin < 8) {
|
if (pin < 8) {
|
||||||
port = 0;
|
port = 0;
|
||||||
offset = 0;
|
offset = 0;
|
||||||
@ -87,21 +99,34 @@ void setPinModeCallback(byte pin, int mode) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(pin > 1) { // ignore RxTx (pins 0 and 1)
|
if(pin > 1) { // ignore RxTx (pins 0 and 1)
|
||||||
pinStatus[pin] = mode;
|
reportAnalogCallback(pin - 14, mode == ANALOG ? 1 : 0); // turn on/off reporting
|
||||||
switch(mode) {
|
switch(mode) {
|
||||||
|
case ANALOG:
|
||||||
|
digitalWrite(pin, LOW); // disable internal pull-ups and fall thru to 'case INPUT:'
|
||||||
case INPUT:
|
case INPUT:
|
||||||
|
pinStatus[pin] = mode;
|
||||||
pinMode(pin, INPUT);
|
pinMode(pin, INPUT);
|
||||||
portStatus[port] = portStatus[port] &~ (1 << (pin - offset));
|
portStatus[port] = portStatus[port] &~ (1 << (pin - offset));
|
||||||
break;
|
break;
|
||||||
case OUTPUT:
|
case OUTPUT:
|
||||||
digitalWrite(pin, LOW); // disable PWM
|
digitalWrite(pin, LOW); // disable PWM and fall thru to 'case PWM:'
|
||||||
case PWM:
|
case PWM:
|
||||||
|
pinStatus[pin] = mode;
|
||||||
pinMode(pin, OUTPUT);
|
pinMode(pin, OUTPUT);
|
||||||
portStatus[port] = portStatus[port] | (1 << (pin - offset));
|
portStatus[port] = portStatus[port] | (1 << (pin - offset));
|
||||||
break;
|
break;
|
||||||
//case ANALOG: // TODO figure this out
|
case SERVO:
|
||||||
|
if((pin == 9 || pin == 10))
|
||||||
|
pinStatus[pin] = mode;
|
||||||
|
else
|
||||||
|
Firmata.sendString("Servo only on pins 9 and 10");
|
||||||
|
break;
|
||||||
|
case I2C:
|
||||||
|
pinStatus[pin] = mode;
|
||||||
|
Firmata.sendString("I2C mode not yet supported");
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
Firmata.sendString("");
|
Firmata.sendString("Unknown pin mode"); // TODO: put error msgs in EEPROM
|
||||||
}
|
}
|
||||||
// TODO: save status to EEPROM here, if changed
|
// TODO: save status to EEPROM here, if changed
|
||||||
}
|
}
|
||||||
@ -109,8 +134,15 @@ void setPinModeCallback(byte pin, int mode) {
|
|||||||
|
|
||||||
void analogWriteCallback(byte pin, int value)
|
void analogWriteCallback(byte pin, int value)
|
||||||
{
|
{
|
||||||
setPinModeCallback(pin,PWM);
|
switch(pinStatus[pin]) {
|
||||||
|
case SERVO:
|
||||||
|
if(pin == 9) servos[0].write(value);
|
||||||
|
if(pin == 10) servos[1].write(value);
|
||||||
|
break;
|
||||||
|
case PWM:
|
||||||
analogWrite(pin, value);
|
analogWrite(pin, value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void digitalWriteCallback(byte port, int value)
|
void digitalWriteCallback(byte port, int value)
|
||||||
@ -124,7 +156,12 @@ void digitalWriteCallback(byte port, int value)
|
|||||||
PORTB = (byte)value;
|
PORTB = (byte)value;
|
||||||
break;
|
break;
|
||||||
case 2: // analog pins used as digital
|
case 2: // analog pins used as digital
|
||||||
PORTC = (byte)value;
|
byte pin;
|
||||||
|
byte pinModeMask;
|
||||||
|
for(pin=0; pin<8; pin++)
|
||||||
|
if(pinStatus[pin] == OUTPUT)
|
||||||
|
pinModeMask += 1 << pin;
|
||||||
|
PORTC = (byte)value & pinModeMask;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -141,6 +178,7 @@ void reportAnalogCallback(byte pin, int value)
|
|||||||
}
|
}
|
||||||
else { // everything but 0 enables reporting of that pin
|
else { // everything but 0 enables reporting of that pin
|
||||||
analogInputsToReport = analogInputsToReport | (1 << pin);
|
analogInputsToReport = analogInputsToReport | (1 << pin);
|
||||||
|
setPinModeCallback(pin, ANALOG);
|
||||||
}
|
}
|
||||||
// TODO: save status to EEPROM here, if changed
|
// TODO: save status to EEPROM here, if changed
|
||||||
}
|
}
|
||||||
@ -152,6 +190,34 @@ void reportDigitalCallback(byte port, int value)
|
|||||||
analogInputsToReport = 0;
|
analogInputsToReport = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*==============================================================================
|
||||||
|
* SYSEX-BASED commands
|
||||||
|
*============================================================================*/
|
||||||
|
|
||||||
|
void sysexCallback(byte command, byte argc, byte *argv)
|
||||||
|
{
|
||||||
|
switch(command) {
|
||||||
|
case SERVO_CONFIG:
|
||||||
|
if(argc > 4) {
|
||||||
|
// these vars are here for clarity, they'll optimized away by the compiler
|
||||||
|
byte pin = argv[0] - 9; // servos are pins 9 and 10, so offset for array
|
||||||
|
int minPulse = argv[1] + (argv[2] << 7);
|
||||||
|
int maxPulse = argv[3] + (argv[4] << 7);
|
||||||
|
servos[pin].attach(argv[0], minPulse, maxPulse);
|
||||||
|
// TODO does the Servo have to be detach()ed before reconfiguring?
|
||||||
|
setPinModeCallback(pin, SERVO);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SAMPLING_INTERVAL:
|
||||||
|
if (argc > 1)
|
||||||
|
samplingInterval = argv[0] + (argv[1] << 7);
|
||||||
|
else
|
||||||
|
Firmata.sendString("Not enough data");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*==============================================================================
|
/*==============================================================================
|
||||||
* SETUP()
|
* SETUP()
|
||||||
*============================================================================*/
|
*============================================================================*/
|
||||||
@ -159,20 +225,20 @@ void setup()
|
|||||||
{
|
{
|
||||||
byte i;
|
byte i;
|
||||||
|
|
||||||
Firmata.setFirmwareVersion(2, 0);
|
Firmata.setFirmwareVersion(2, 1);
|
||||||
|
|
||||||
Firmata.attach(ANALOG_MESSAGE, analogWriteCallback);
|
Firmata.attach(ANALOG_MESSAGE, analogWriteCallback);
|
||||||
Firmata.attach(DIGITAL_MESSAGE, digitalWriteCallback);
|
Firmata.attach(DIGITAL_MESSAGE, digitalWriteCallback);
|
||||||
Firmata.attach(REPORT_ANALOG, reportAnalogCallback);
|
Firmata.attach(REPORT_ANALOG, reportAnalogCallback);
|
||||||
Firmata.attach(REPORT_DIGITAL, reportDigitalCallback);
|
Firmata.attach(REPORT_DIGITAL, reportDigitalCallback);
|
||||||
Firmata.attach(SET_PIN_MODE, setPinModeCallback);
|
Firmata.attach(SET_PIN_MODE, setPinModeCallback);
|
||||||
|
Firmata.attach(START_SYSEX, sysexCallback);
|
||||||
|
|
||||||
portStatus[0] = B00000011; // ignore Tx/RX pins
|
portStatus[0] = B00000011; // ignore Tx/RX pins
|
||||||
portStatus[1] = B11000000; // ignore 14/15 pins
|
portStatus[1] = B11000000; // ignore 14/15 pins
|
||||||
portStatus[2] = B00000000;
|
portStatus[2] = B00000000;
|
||||||
|
|
||||||
// for(i=0; i<TOTAL_DIGITAL_PINS; ++i) { // TODO make this work with analogs
|
for(i=0; i<TOTAL_DIGITAL_PINS; ++i) { // TODO make this work with analogs
|
||||||
for(i=0; i<14; ++i) {
|
|
||||||
setPinModeCallback(i,OUTPUT);
|
setPinModeCallback(i,OUTPUT);
|
||||||
}
|
}
|
||||||
// set all outputs to 0 to make sure internal pull-up resistors are off
|
// set all outputs to 0 to make sure internal pull-up resistors are off
|
||||||
@ -193,7 +259,7 @@ void setup()
|
|||||||
if(reportPINs[1]) outputPort(1, PINB);
|
if(reportPINs[1]) outputPort(1, PINB);
|
||||||
if(reportPINs[ANALOG_PORT]) outputPort(ANALOG_PORT, PINC);
|
if(reportPINs[ANALOG_PORT]) outputPort(ANALOG_PORT, PINC);
|
||||||
|
|
||||||
Firmata.begin();
|
Firmata.begin(57600);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*==============================================================================
|
/*==============================================================================
|
||||||
@ -206,7 +272,7 @@ void loop()
|
|||||||
checkDigitalInputs();
|
checkDigitalInputs();
|
||||||
currentMillis = millis();
|
currentMillis = millis();
|
||||||
if(currentMillis > nextExecuteMillis) {
|
if(currentMillis > nextExecuteMillis) {
|
||||||
nextExecuteMillis = currentMillis + 19; // run this every 20ms
|
nextExecuteMillis = currentMillis + samplingInterval;
|
||||||
/* SERIALREAD - Serial.read() uses a 128 byte circular buffer, so handle
|
/* SERIALREAD - Serial.read() uses a 128 byte circular buffer, so handle
|
||||||
* all serialReads at once, i.e. empty the buffer */
|
* all serialReads at once, i.e. empty the buffer */
|
||||||
while(Firmata.available())
|
while(Firmata.available())
|
||||||
|
Loading…
x
Reference in New Issue
Block a user