00001 /* 00002 * Copyright 2007-2008 (c) Erik Sjodin, eriksjodin.net 00003 * 00004 * Devloped at: The Interactive Institutet / Art and Technology, 00005 * OF Lab / Ars Electronica 00006 * 00007 * Permission is hereby granted, free of charge, to any person 00008 * obtaining a copy of this software and associated documentation 00009 * files (the "Software"), to deal in the Software without 00010 * restriction, including without limitation the rights to use, 00011 * copy, modify, merge, publish, distribute, sublicense, and/or sell 00012 * copies of the Software, and to permit persons to whom the 00013 * Software is furnished to do so, subject to the following 00014 * conditions: 00015 * 00016 * The above copyright notice and this permission notice shall be 00017 * included in all copies or substantial portions of the Software. 00018 * 00019 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 00020 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 00021 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 00022 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 00023 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 00024 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 00025 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 00026 * OTHER DEALINGS IN THE SOFTWARE. 00027 */ 00028 00029 #ifndef OF_STANDARD_FIRMATA_H 00030 #define OF_STANDARD_FIRMATA_H 00031 00032 00033 #include <list> 00034 #include <vector> 00035 #include <string> 00036 #include <iostream> 00037 00038 #include "ofEvents.h" 00039 #include "ofSerial.h" 00040 00041 using namespace std; 00042 00043 /* 00044 * Version numbers for the protocol. The protocol is still changing, so these 00045 * version numbers are important. This number can be queried so that host 00046 * software can test whether it will be compatible with the currently installed firmware. 00047 */ 00048 00049 #define FIRMATA_MAJOR_VERSION 2 // for non-compatible changes 00050 #define FIRMATA_MINOR_VERSION 0 // for backwards compatible changes 00051 #define FIRMATA_MAX_DATA_BYTES 32 // max number of data bytes in non-Sysex messages 00052 // message command bytes (128-255/0x80-0xFF) 00053 #define FIRMATA_DIGITAL_MESSAGE 0x90 // send data for a digital pin 00054 #define FIRMATA_ANALOG_MESSAGE 0xE0 // send data for an analog pin (or PWM) 00055 #define FIRMATA_REPORT_ANALOG 0xC0 // enable analog input by pin # 00056 #define FIRMATA_REPORT_DIGITAL 0xD0 // enable digital input by port pair 00057 // 00058 #define FIRMATA_SET_PIN_MODE 0xF4 // set a pin to INPUT/OUTPUT/PWM/etc 00059 // 00060 #define FIRMATA_REPORT_VERSION 0xF9 // report protocol version 00061 #define FIRMATA_SYSTEM_RESET 0xFF // reset from MIDI 00062 // 00063 #define FIRMATA_START_SYSEX 0xF0 // start a MIDI Sysex message 00064 #define FIRMATA_END_SYSEX 0xF7 // end a MIDI Sysex message 00065 // pin modes 00066 #define FIRMATA_INPUT 0x00 00067 #define FIRMATA_OUTPUT 0x01 00068 #define FIRMATA_ANALOG 0x02 // analog pin in analogInput mode 00069 #define FIRMATA_PWM 0x03 // digital pin in PWM output mode 00070 #define FIRMATA_SERVO 0x04 // digital pin in Servo output mode 00071 // extended command set using SysEx (0-127/0x00-0x7F) 00072 /* 0x00-0x0F reserved for custom commands */ 00073 #define FIRMATA_SYSEX_SERVO_CONFIG 0x70 00074 #define FIRMATA_SYSEX_FIRMATA_STRING 0x71 // a string message with 14-bits per char 00075 #define FIRMATA_SYSEX_REPORT_FIRMWARE 0x79 // report name and version of the firmware 00076 #define FIRMATA_SYSEX_NON_REALTIME 0x7E // MIDI Reserved for non-realtime messages 00077 #define FIRMATA_SYSEX_REALTIME 0x7F // MIDI Reserved for realtime messages 00078 //#define FIRMATA_SYSEX_SHIFTOUT_MESSAGE 0xB0 // proposed shiftOut message (SysEx) 00079 00080 // ---- arduino constants (for Arduino NG and Diecimila) 00081 00082 // board settings 00083 #define ARD_TOTAL_DIGITAL_PINS 22 // total number of pins currently supported 00084 #define ARD_TOTAL_ANALOG_PINS 8 00085 #define ARD_TOTAL_PORTS 3 // total number of ports for the board 00086 // pin modes 00087 #define ARD_INPUT 0x00 00088 #define ARD_OUTPUT 0x01 00089 #define ARD_ANALOG 0x02 // analog pin in analogInput mode 00090 #define ARD_PWM 0x03 // digital pin in PWM output mode 00091 #define ARD_SERVO 0x04 // digital pin in Servo output mode 00092 #define ARD_HIGH 1 00093 #define ARD_LOW 0 00094 #define ARD_ON 1 00095 #define ARD_OFF 0 00096 00097 /* 00098 #if defined(__AVR_ATmega168__) // Arduino NG and Diecimila 00099 #define ARD_TOTAL_ANALOG_PINS 8 00100 #define ARD_TOTAL_DIGITAL_PINS 22 // 14 digital + 8 analog 00101 #define ARD_TOTAL_PORTS 3 // total number of ports for the board 00102 #define ARD_ANALOG_PORT 2 // port# of analog used as digital 00103 #elif defined(__AVR_ATmega8__) // old Arduinos 00104 #define ARD_TOTAL_ANALOG_PINS 6 00105 #define ARD_TOTAL_DIGITAL_PINS 20 // 14 digital + 6 analog 00106 #define ARD_TOTAL_PORTS 3 // total number of ports for the board 00107 #define ARD_ANALOG_PORT 2 // port# of analog used as digital 00108 #elif defined(__AVR_ATmega128__)// Wiring 00109 #define ARD_TOTAL_ANALOG_PINS 8 00110 #define ARD_TOTAL_DIGITAL_PINS 43 00111 #define ARD_TOTAL_PORTS 5 // total number of ports for the board 00112 #define ARD_ANALOG_PORT 2 // port# of analog used as digital 00113 #else // anything else 00114 #define ARD_TOTAL_ANALOG_PINS 6 00115 #define ARD_TOTAL_DIGITAL_PINS 14 00116 #define ARD_TOTAL_PORTS 3 // total number of ports for the board 00117 #define ARD_ANALOG_PORT 2 // port# of analog used as digital 00118 #endif 00119 */ 00120 00135 class ofStandardFirmata{ 00136 00137 public: 00138 ofStandardFirmata(); 00139 00140 virtual ~ofStandardFirmata(); 00141 00142 // --- setup functions 00143 int connect(string device, int baud = 115200); 00144 // opens a serial port connection to the arduino 00145 00146 void disconnect(); 00147 // closes the serial port connection 00148 00149 void update(); 00150 // polls data from the serial port, this has to be called periodically 00151 00152 bool isInitialized(); 00153 // returns true if a succesfull connection has been established and the Arduino has reported a firmware 00154 00155 void setDigitalHistoryLength(int length); 00156 void setAnalogHistoryLength(int length); 00157 void setStringHistoryLength(int length); 00158 void setSysExHistoryLength(int nSysEx); 00159 00160 // --- senders 00161 00162 void sendDigitalPinMode(int pin, int mode); 00163 // pin: 2-13 00164 // mode: ARD_INPUT, ARD_OUTPUT, ARD_PWM 00165 // setting a pins mode to ARD_INPUT turns on reporting for the port the pin is on 00166 // Note: analog pins 0-5 can be used as digitial pins 16-21 but if the mode of _one_ of these pins is set to ARD_INPUT then _all_ analog pin reporting will be turned off 00167 00168 void sendAnalogPinReporting(int pin, int mode); 00169 // pin: 0-5 00170 // mode: ARD_ON or ARD_OFF 00171 // Note: analog pins 0-5 can be used as digitial pins 16-21 but if reporting for _one_ analog pin is enabled then reporting for _all_ of digital pin 16-21 will be turned off 00172 00173 void sendDigital(int pin, int value, bool force = false); 00174 // pin: 2-13 00175 // value: ARD_LOW or ARD_HIGH 00176 // the pins mode has to be set to ARD_OUTPUT or ARD_INPUT (in the latter mode pull-up resistors are enabled/disabled) 00177 // Note: pin 16-21 can also be used if analog inputs 0-5 are used as digital pins 00178 00179 void sendPwm(int pin, int value, bool force = false); 00180 // pin: 3, 5, 6, 9, 10 and 11 00181 // value: 0 (always off) to 255 (always on). 00182 // the pins mode has to be set to ARD_PWM 00183 // TODO check if the PWM bug still is there causing frequent digital port reporting... 00184 00185 void sendSysEx(int command, vector<unsigned char> data); 00186 00187 void sendString(string str); 00188 // firmata can not handle strings longer than 12 characters. 00189 00190 void sendProtocolVersionRequest(); 00191 00192 void sendFirmwareVersionRequest(); 00193 00194 void sendReset(); 00195 00196 // --- senders for SysEx communication 00197 00198 void sendSysExBegin(); 00199 // sends the FIRMATA_START_SYSEX command 00200 00201 void sendSysExEnd(); 00202 // sends the FIRMATA_END_SYSEX command 00203 00204 void sendByte(unsigned char byte); 00205 // sends a byte without wrapping it in a firmata message, data has to be in the 0-127 range, 00206 // values > 127 will be interpreted as commands. 00207 00208 void sendValueAsTwo7bitBytes(int value); 00209 // sends a value as two 7-bit bytes without wrapping it in a firmata message 00210 // values in the range 0 - 16384 will be sent as two bytes within the 0-127 data range. 00211 00212 // --- getters 00213 00214 int getPwm(int pin); 00215 // pin: 3, 5, 6, 9, 10 and 11 00216 // returns the last set PWM value (0-255) for the given pin 00217 // the pins mode has to be ARD_PWM 00218 // Note: pin 16-21 can also be used if analog inputs 0-5 are used as digital pins 00219 00220 int getDigital(int pin); 00221 // pin: 2-13 00222 // returns the last received value (if the pin mode is ARD_INPUT) or the last set value (if the pin mode is ARD_OUTPUT) for the given pin 00223 // Note: pin 16-21 can also be used if analog inputs 0-5 are used as digital pins 00224 00225 int getAnalog(int pin); 00226 // pin: 0-5 00227 // returns the last received analog value (0-1023) for the given pin 00228 00229 vector<unsigned char> getSysEx(); 00230 // returns the last received SysEx message 00231 00232 string getString(); 00233 // returns the last received string 00234 00235 int getMajorProtocolVersion(); 00236 // returns the major firmware version 00237 00238 int getMinorProtocolVersion(); 00239 // returns the minor firmware version 00240 00241 int getMajorFirmwareVersion(); 00242 // returns the major firmware version 00243 00244 int getMinorFirmwareVersion(); 00245 // returns the minor firmware version 00246 00247 string getFirmwareName(); 00248 // returns the name of the firmware 00249 00250 list<int>* getDigitalHistory(int pin); 00251 // pin: 2-13 00252 // returns a pointer to the digital data history list for the given pin 00253 // Note: pin 16-21 can also be used if analog inputs 0-5 are used as digital pins 00254 00255 list<int>* getAnalogHistory(int pin); 00256 // pin: 0-5 00257 // returns a pointer to the analog data history list for the given pin 00258 00259 list<vector<unsigned char> >* getSysExHistory(); 00260 // returns a pointer to the SysEx history 00261 00262 list<string>* getStringHistory(); 00263 // returns a pointer to the string history 00264 00265 int getDigitalPinMode(int pin); 00266 // returns ARD_INPUT, ARD_OUTPUT, ARD_PWM, ARD_SERVO, ARD_ANALOG 00267 00268 int getAnalogPinReporting(int pin); 00269 // returns ARD_ON, ARD_OFF 00270 00271 int getValueFromTwo7bitBytes(unsigned char lsb, unsigned char msb); 00272 // useful for parsing SysEx messages 00273 00274 // --- events 00275 00276 ofEvent<const int> EDigitalPinChanged; 00277 // triggered when a digital pin changes value, the pin that changed is passed as an argument 00278 00279 ofEvent<const int> EAnalogPinChanged; 00280 // triggered when an analog pin changes value, the pin that changed is passed as an argument 00281 00282 ofEvent<const vector<unsigned char> > ESysExReceived; 00283 // triggered when a SysEx message that isn't in the extended command set is received, the SysEx message is passed as an argument 00284 00285 ofEvent<const int> EProtocolVersionReceived; 00286 // triggered when a protocol version is received, the major version is passed as an argument 00287 00288 ofEvent<const int> EFirmwareVersionReceived; 00289 // triggered when a firmware version is received, the major version is passed as an argument 00290 00291 ofEvent<const int> EInitialized; 00292 // triggered when the firmware version is received upon connect, the major firmware version is passed as an argument 00293 // from this point it's safe to send to the Arduino. 00294 00295 ofEvent<const string> EStringReceived; 00296 // triggered when a string is received, the string is passed as an argument 00297 00298 protected: 00299 00300 bool _initialized; 00301 00302 void sendDigitalPinReporting(int pin, int mode); 00303 // sets pin reporting to ARD_ON or ARD_OFF 00304 // enables / disables reporting for the pins port 00305 00306 void sendDigitalPortReporting(int port, int mode); 00307 // sets port reporting to ARD_ON or ARD_OFF 00308 // enables / disables reporting for ports 0-2 00309 // port 0: pins 2-7 (0,1 are serial RX/TX) 00310 // port 1: pins 8-13 (14,15 are disabled for the crystal) 00311 // port 2: pins 16-21 analog pins used as digital, all analog reporting will be turned off if this is set to ARD_ON 00312 00313 void processData(unsigned char inputData); 00314 void processDigitalPort(int port, unsigned char value); 00315 virtual void processSysExData(vector<unsigned char> data); 00316 00317 ofSerial _port; 00318 int _portStatus; 00319 00320 // --- history variables 00321 int _analogHistoryLength; 00322 int _digitalHistoryLength; 00323 int _stringHistoryLength; 00324 int _sysExHistoryLength; 00325 00326 // --- data processing variables 00327 int _waitForData; 00328 int _executeMultiByteCommand; 00329 int _multiByteChannel; // indicates which pin data came from 00330 00331 // --- data holders 00332 unsigned char _storedInputData[FIRMATA_MAX_DATA_BYTES]; 00333 vector<unsigned char> _sysExData; 00334 int _majorProtocolVersion; 00335 int _minorProtocolVersion; 00336 int _majorFirmwareVersion; 00337 int _minorFirmwareVersion; 00338 string _firmwareName; 00339 00340 list<vector<unsigned char> > _sysExHistory; 00341 // maintains a history of received sysEx messages (excluding SysEx messages in the extended command set) 00342 00343 list<string> _stringHistory; 00344 // maintains a history of received strings 00345 00346 list<int> _analogHistory[ARD_TOTAL_ANALOG_PINS]; 00347 // a history of received data for each analog pin 00348 00349 list<int> _digitalHistory[ARD_TOTAL_DIGITAL_PINS]; 00350 // a history of received data for each digital pin 00351 00352 int _digitalPinMode[ARD_TOTAL_DIGITAL_PINS]; 00353 // the modes for all digital pins 00354 00355 int _digitalPinValue[ARD_TOTAL_DIGITAL_PINS]; 00356 // the last set values (DIGITAL/PWM) on all digital pins 00357 00358 int _digitalPortValue[ARD_TOTAL_PORTS]; 00359 // the last set values on all ports 00360 00361 int _digitalPortReporting[ARD_TOTAL_PORTS]; 00362 // whether pin reporting is enabled / disabled 00363 00364 int _digitalPinReporting[ARD_TOTAL_DIGITAL_PINS]; 00365 // whether pin reporting is enabled / disabled 00366 00367 int _analogPinReporting[ARD_TOTAL_ANALOG_PINS]; 00368 // whether pin reporting is enabled / disabled 00369 00370 }; 00371 00372 #endif