IDuino

IDuino is a modified and extended version of Firmata (ve1.0). It is the "software brain" of the AdMoVeo robot loaded in the Arduino board. In case you need to reload it, please follow the steps below:

  1. Make sure you have the Arduino software installed on your PC. see SoftwareEnvironment for details.

  2. Download the IDuino.pde sketch.

  3. Start the Arduino programming environment.
  4. Load the downloaded sketch in the Arduino programming environment by selecting the menu item "File|Sketchbook|Open".
  5. Compile it by either:
    • push the "Verify" button, or
    • Press "Ctrl+R", or
    • select the menu item "Sketch|Verify/Compile".
    Compiling process should be finished with the message "Done compiling" in the message box of the programming environment.
  6. You need to identify the COM port that the Arduino board or the AdMoVeo robot is connected to. it is better if you start the "Device Manager" of your Windows system first. The quickest way to start it is:

    • Press "Win+R";
    • Run "devmgmt.msc" by copy it or type it into the "Open" box then press "OK".

    In "Device Manager", expand "Ports (COM&LPT)", and later watch out what is added when you connect the Arduino board or the AdMoVeo robot.

  7. Connect your Arduino board or the AdMoVeo robot to the PC using a USB cable. Switch the robot on if the robot is used instead of just the Arduino board.

  8. Check the newly added COM port. It should be something like "USB Serial Port (COM5)". It could be a different COM port on your computer. Remember the port number. Close the "Device Manager".
  9. In the Arduino programming environment, set the connection serial port accordingly. You may do it by selecting the menu item "Tools|Serial Port|COMn", n is the port number you find out in the previous step.
  10. Now load the IDuino sketch onto the Arduino board or the AdMoVeo robot, by either:

    • push the button "Upload to I/O Board", or
    • select the menu item "File|Upload to I/O Board".
  11. In the message box of the Arduino programming environment, you should see "Uploading to I/O Board", and if succeed, then "Done compiling".
  12. If you see any red text in the message box, most likely the USB cable was not connected correctly or the COM port was not set correctly. Check the USB cable and the COM port.

   1 /*
   2  * Copyright (C) 2006 Free Software Foundation
   3  *
   4  * This program is free software; you can redistribute it and/or
   5  * modify it under the terms of the GNU General Public License
   6  * as published by the Free Software Foundation; either version 2
   7  * of the License, or (at your option) any later version.
   8  *
   9  * See file LICENSE for further informations on licensing terms.
  10  *
  11  * This program is distributed in the hope that it will be useful,
  12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14  * GNU General Public License for more details.
  15  *
  16  * You should have received a copy of the GNU General Public License
  17  * along with this program; if not, write to the Free Software Foundation,
  18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  19  *
  20  * -----------------------------------------------------------
  21  * Firmata, the general purpose sensorbox firmware for Arduino
  22  * -----------------------------------------------------------
  23  * 
  24  * Firmata turns the Arduino into a Plug-n-Play sensorbox, servo
  25  * controller, and/or PWM motor/lamp controller.
  26  *
  27  * It was originally designed to work with the Pd object [arduino]
  28  * which is included in Pd-extended.  This firmware is intended to
  29  * work with any host computer software package.  It can easily be
  30  * used with other programs like Max/MSP, Processing, or whatever can
  31  * do serial communications.
  32  *
  33  * @author: Hans-Christoph Steiner <hans@at.or.at>
  34  *   help with initial protocol redesign: Jamie Allen <jamie@heavyside.net>
  35  *   much protocol discussion: the Arduino developers mailing list
  36  *   key bugfixes: Georg Holzmann <grh@mur.at>
  37  *                 Gerda Strobl <gerda.strobl@student.tugraz.at>
  38  * @date: 2006-05-19
  39  * @locations: STEIM, Amsterdam, Netherlands
  40  *             IDMI/Polytechnic University, Brookyn, NY, USA
  41  *             Electrolobby Ars Electronica, Linz, Austria
  42  */
  43 
  44 /* 
  45  * TODO: add pulseOut functionality for servos
  46  * TODO: add software PWM for servos, etc (servo.h or pulse.h)
  47  * TODO: add device type reporting (i.e. some firmwares will use the Firmata
  48  *       protocol, but will only support specific devices, like ultrasound 
  49  *       rangefinders or servos)
  50  * TODO: use Program Control to load stored profiles from EEPROM
  51  */
  52 
  53 /* cvs version: $Id: Pd_firmware.pde,v 1.29 2007/03/08 05:37:22 eighthave Exp $ */
  54 /* svn version: 334 */
  55 
  56 /*==============================================================================
  57  * MESSAGE FORMATS
  58  *============================================================================*/
  59 
  60 /* -----------------------------------------------------------------------------
  61  * MAPPING DATA TO MIDI
  62  *
  63  * This protocol uses the MIDI message format, but does not use the whole
  64  * protocol.  Most of the command mappings here will not be directly usable in
  65  * terms of MIDI controllers and synths.  It should co-exist with MIDI without
  66  * trouble and can be parsed by standard MIDI interpreters.  Just some of the
  67  * message data is used differently.
  68  *
  69  * MIDI format: http://www.harmony-central.com/MIDI/Doc/table1.html
  70  * 
  71  *                              MIDI       
  72  * type                command  channel    first byte            second byte 
  73  * -----------------------------------------------------------------------------
  74  * analog I/O            0xE0   pin #      LSB(bits 0-6)         MSB(bits 7-13)
  75  * digital I/O           0x90   port base  LSB(bits 0-6)         MSB(bits 7-13)
  76  * report analog pin     0xC0   pin #      disable/enable(0/1)   - n/a -
  77  * report digital ports  0xD0   port base  disable/enable(0/1)   - n/a -
  78  *
  79  * digital pin mode(I/O) 0xF4   - n/a -    pin # (0-63)          pin state(0=in)
  80  * firmware version      0xF9   - n/a -    minor version         major version
  81  * system reset          0xFF   - n/a -    - n/a -               - n/a -
  82  *
  83  */
  84  
  85 /* nl.tue.id.creapro +>>>>>
  86  * Extensions nl.tue.id.creapro
  87  * configuration        0xFD   - n/a -     0x00                   serial pulling rate (ms)
  88  *                                         0x10                   analog pulling rate (ms)
  89  *                                         0x20                   analog step (1-1023)
  90  * debug                0xFD   - n/a -     0x40                   data received (bytes)
  91  *                                         0x50                   data sent (bytes)
  92  *                                         0x60                   number of commands received
  93  *                                         0x70                   number of commands sent
  94 
  95  * nl.tue.id.creapro +<<<<<
  96 */
  97 
  98 /* proposed extensions using SysEx
  99  *
 100  * type      SysEx start  command  data bytes                         SysEx stop
 101  * -----------------------------------------------------------------------------
 102  * pulse I/O   0xF0        0xA0   five 7-bit chunks, LSB first             0xF7 
 103  * shiftOut    0xF0        0xF5   dataPin; clockPin; 7-bit LSB; 7-bit MSB  0xF7
 104  */
 105 
 106 /* -----------------------------------------------------------------------------
 107  * DATA MESSAGE FORMAT */
 108 
 109 /* two byte digital data format
 110  * ----------------------------
 111  * 0  digital data, 0x90-0x9F, (MIDI NoteOn, but different data usage)
 112  * 1  digital pins 0-6 bitmask
 113  * 2  digital pins 7-13 bitmask 
 114  */
 115 
 116 /* analog 14-bit data format
 117  * -------------------------
 118  * 0  analog pin, 0xE0-0xEF, (MIDI Pitch Wheel)
 119  * 1  analog least significant 7 bits
 120  * 2  analog most significant 7 bits
 121  */
 122 
 123 /* version report format
 124  * Send a single byte 0xF9, Arduino will reply with:
 125  * -------------------------------------------------
 126  * 0  version report header (0xF9) (MIDI Undefined)
 127  * 1  minor version (0-127)
 128  * 2  major version (0-127)
 129  */
 130 
 131 /* pulseIn/Out (uses 32-bit value)
 132  * -------------------------------
 133  * 0  START_SYSEX (0xF0) (MIDI System Exclusive)
 134  * 1  pulseIn/Out (0xA0-0xAF)
 135  * 2  bits 0-6 (least significant byte)
 136  * 3  bits 7-13
 137  * 4  bits 14-20
 138  * 5  bits 21-27
 139  * 6  bits 28-34 (most significant byte)
 140  * 7  END_SYSEX (0xF7) (MIDI End of SysEx - EOX)
 141  */
 142 
 143 /* shiftIn/Out (uses 8-bit value)
 144  * ------------------------------
 145  * 0  START_SYSEX (0xF0)
 146  * 1  shiftOut (0xF5)
 147  * 2  dataPin (0-127)
 148  * 3  clockPin (0-127)
 149  * 4  bits 0-6 (least significant byte)
 150  * 5  bit 7 (most significant bit)
 151  * 6  END_SYSEX (0xF7)
 152  */
 153 
 154 /* -----------------------------------------------------------------------------
 155  * CONTROL MESSAGES */
 156 
 157 /* set digital pin mode
 158  * --------------------
 159  * 1  set digital pin mode (0xF4) (MIDI Undefined)
 160  * 2  pin number (0-127)
 161  * 3  state (INPUT/OUTPUT, 0/1)
 162  */
 163 
 164 /* toggle analogIn reporting by pin
 165  * --------------------------------
 166  * 0  toggle digitalIn reporting (0xC0-0xCF) (MIDI Program Change)
 167  * 1  disable(0)/enable(non-zero) 
 168  */
 169 
 170 /* toggle digitalIn reporting by port pairs
 171  * ----------------------------------------
 172  * 0  toggle digitalIn reporting (0xD0-0xDF) (MIDI Aftertouch)
 173  * 1  disable(0)/enable(non-zero) 
 174  */
 175 
 176 /* request version report
 177  * ----------------------
 178  * 0  request version report (0xF9) (MIDI Undefined)
 179  */
 180 
 181 /*==============================================================================
 182  * MACROS
 183  *============================================================================*/
 184 
 185 /* Version numbers for the protocol.  The protocol is still changing, so these
 186  * version numbers are important.  This number can be queried so that host
 187  * software can test whether it will be compatible with the currently
 188  * installed firmware. */
 189 #define FIRMATA_MAJOR_VERSION   1 // for non-compatible changes
 190 #define FIRMATA_MINOR_VERSION   0 // for backwards compatible changes
 191 
 192 /* total number of pins currently supported */  
 193 #define TOTAL_ANALOG_PINS       6
 194 #define TOTAL_DIGITAL_PINS      14
 195 
 196 // for comparing along with INPUT and OUTPUT
 197 #define PWM                     2
 198 
 199 // for selecting digital inputs
 200 #define PB  2  // digital input, pins 8-13
 201 #define PC  3  // analog input port
 202 #define PD  4  // digital input, pins 0-7
 203 
 204 #define MAX_DATA_BYTES 2 // max number of data bytes in non-SysEx messages
 205 /* message command bytes */
 206 #define DIGITAL_MESSAGE         0x90 // send data for a digital pin
 207 #define ANALOG_MESSAGE          0xE0 // send data for an analog pin (or PWM)
 208 //#define PULSE_MESSAGE           0xA0 // proposed pulseIn/Out message (SysEx)
 209 //#define SHIFTOUT_MESSAGE        0xB0 // proposed shiftOut message (SysEx)
 210 #define REPORT_ANALOG_PIN       0xC0 // enable analog input by pin #
 211 #define REPORT_DIGITAL_PORTS    0xD0 // enable digital input by port pair
 212 #define START_SYSEX             0xF0 // start a MIDI SysEx message
 213 #define SET_DIGITAL_PIN_MODE    0xF4 // set a digital pin to INPUT or OUTPUT 
 214 #define END_SYSEX               0xF7 // end a MIDI SysEx message
 215 #define REPORT_VERSION          0xF9 // report firmware version
 216 #define SYSTEM_RESET            0xFF // reset from MIDI
 217 
 218 
 219 // nl.tue.id.creapro +>>>>>
 220 #define CONFIG                  0xFD
 221 #define SERIAL_PULL_RATE        0x00
 222 #define ANALOG_PULL_RATE        0x10
 223 #define ANALOG_STEP             0x20
 224 
 225 #define DEBUG                   0xFD
 226 #define READ_COUNT              0x40
 227 #define WRITE_COUNT             0x50
 228 #define COMMAND_COUNT           0x60
 229 #define EVENT_COUNT             0x70
 230 
 231 // nl.tue.id.creapro +<<<<<
 232 
 233 
 234 /*==============================================================================
 235  * GLOBAL VARIABLES
 236  *============================================================================*/
 237 
 238 /* input message handling */
 239 byte waitForData = 0; // this flag says the next serial input will be data
 240 byte executeMultiByteCommand = 0; // execute this after getting multi-byte data
 241 byte multiByteChannel = 0; // channel data for multiByteCommands
 242 byte storedInputData[MAX_DATA_BYTES] = {0,0}; // multi-byte data
 243 /* digital pins */
 244 boolean digitalInputsEnabled = false; // output digital inputs or not
 245 int digitalInputs = 0;
 246 int previousDigitalInputs; // previous output to test for change
 247 // nl.tue.id.creapro -+>>>>>
 248 //int digitalPinStatus = 3; // bitwise array to store pin status, ignore RxTx pins
 249 int digitalPinStatus = 0xFFFF; //ignore all pins
 250 // nl.tue.id.creapro -+>>>>>
 251 /* PWM/analog outputs */
 252 int pwmStatus = 0; // bitwise array to store PWM status
 253 /* analog inputs */
 254 int analogPinsToReport = 0; // bitwise array to store pin reporting
 255 int analogPin = 0; // counter for reading analog pins
 256 int analogData; // storage variable for data from analogRead()
 257 /* timer variables */
 258 extern volatile unsigned long timer0_overflow_count; // timer0 from wiring.c
 259 unsigned long nextExecuteTime = 0; // for comparison with timer0_overflow_count
 260 
 261 // nl.tue.id.creapro +>>>>>
 262 int storedAnalogData[TOTAL_ANALOG_PINS];
 263 unsigned long nextAnalogExecuteTime = 0; // for comparison with timer0_overflow_count
 264 
 265 int serialPullRate = 20;
 266 int analogPullRate = 20;
 267 int analogStep = 1;
 268 
 269 int writeCount = 0;
 270 int readCount = 0;
 271 int commandCount = 0;
 272 int eventCount = 0;
 273 // nl.tue.id.creapro +<<<<< 
 274 
 275 
 276 /*==============================================================================
 277  * FUNCTIONS                                                                
 278  *============================================================================*/
 279 // nl.tue.id.creapro +>>>>>
 280 void serialPrint(int byte1, int byte2, int byte3){
 281   Serial.print(byte1, BYTE);
 282   Serial.print(byte2, BYTE);
 283   Serial.print(byte3, BYTE);
 284 }
 285 
 286 void eventSerialPrint(int byte1, int byte2, int byte3){
 287   serialPrint(byte1, byte2, byte3);
 288   writeCount = writeCount + 3;
 289   eventCount++;
 290 }
 291 // nl.tue.id.creapro +<<<<< 
 292  
 293 /* -----------------------------------------------------------------------------
 294  * output the version message to the serial port  */
 295 void printVersion() {
 296   // nl.tue.id.creapro ->>>>>
 297   // Serial.print(REPORT_VERSION, BYTE);
 298   // Serial.print(FIRMATA_MINOR_VERSION, BYTE);
 299   // Serial.print(FIRMATA_MAJOR_VERSION, BYTE);
 300   // nl.tue.id.creatpro -<<<<<
 301   // nl.tue.id.creapro +>>>>>
 302   serialPrint(REPORT_VERSION,FIRMATA_MINOR_VERSION,FIRMATA_MAJOR_VERSION);
 303   // nl.tue.id.creapro +<<<<<  
 304 }
 305 
 306 /* -----------------------------------------------------------------------------
 307  * output digital bytes received from the serial port  */
 308 void outputDigitalBytes(byte pin0_6, byte pin7_13) {
 309   int i;
 310   int mask;
 311   int twoBytesForPorts;
 312     
 313 // this should be converted to use PORTs
 314   twoBytesForPorts = pin0_6 + (pin7_13 << 7);
 315   for(i=2; i<TOTAL_DIGITAL_PINS; ++i) { // ignore Rx,Tx pins (0 and 1)
 316     mask = 1 << i;
 317     if( (digitalPinStatus & mask) && !(pwmStatus & mask) ) {
 318       digitalWrite(i, twoBytesForPorts & mask ? HIGH : LOW);
 319     } 
 320   }
 321 }
 322 
 323 /* -----------------------------------------------------------------------------
 324  * check all the active digital inputs for change of state, then add any events
 325  * to the Serial output queue using Serial.print() */
 326 void checkDigitalInputs(void) {
 327   if(digitalInputsEnabled) {
 328         previousDigitalInputs = digitalInputs;
 329         digitalInputs = PINB << 8;  // get pins 8-13
 330         digitalInputs += PIND;      // get pins 0-7
 331         digitalInputs = digitalInputs & ~digitalPinStatus; // ignore pins set OUTPUT
 332         if(digitalInputs != previousDigitalInputs) {
 333           // TODO: implement more ports as channels for more than 16 digital pins
 334           // nl.tue.id.creapro ->>>>>
 335           // Serial.print(DIGITAL_MESSAGE,BYTE);
 336           // Serial.print(digitalInputs % 128, BYTE); // Tx pins 0-6
 337           // Serial.print(digitalInputs >> 7, BYTE);  // Tx pins 7-13
 338           // nl.tue.id.creatpro -<<<<<
 339           eventSerialPrint(DIGITAL_MESSAGE,
 340                       digitalInputs % 128, // Tx pins 0-6
 341                       digitalInputs >> 7); // Tx pins 7-13
 342         }
 343   }
 344 }
 345 
 346 // -----------------------------------------------------------------------------
 347 /* sets the pin mode to the correct state and sets the relevant bits in the
 348  * two bit-arrays that track Digital I/O and PWM status
 349  */
 350 void setPinMode(byte pin, byte mode) {
 351   if(pin > 1) { // ignore RxTx pins (0,1)
 352         if(mode == INPUT) {
 353           digitalPinStatus = digitalPinStatus &~ (1 << pin);
 354           pwmStatus = pwmStatus &~ (1 << pin);
 355           digitalWrite(pin,LOW); // turn off pin before switching to INPUT
 356           pinMode(pin,INPUT);
 357         }
 358         else if(mode == OUTPUT) {
 359           digitalPinStatus = digitalPinStatus | (1 << pin);
 360           pwmStatus = pwmStatus &~ (1 << pin);
 361           pinMode(pin,OUTPUT);
 362         }
 363         else if( mode == PWM ) {
 364           digitalPinStatus = digitalPinStatus | (1 << pin);
 365           pwmStatus = pwmStatus | (1 << pin);
 366           pinMode(pin,OUTPUT);
 367         }
 368   // TODO: save status to EEPROM here, if changed
 369   }
 370 }
 371 
 372 // -----------------------------------------------------------------------------
 373 /* sets bits in a bit array (int) to toggle the reporting of the analogIns
 374  */
 375 void setAnalogPinReporting(byte pin, byte state) {
 376   if(state == 0) {
 377     analogPinsToReport = analogPinsToReport &~ (1 << pin);
 378   }
 379   else { // everything but 0 enables reporting of that pin
 380     analogPinsToReport = analogPinsToReport | (1 << pin);
 381   }
 382   // TODO: save status to EEPROM here, if changed
 383 }
 384 
 385 /* -----------------------------------------------------------------------------
 386  * processInput() is called whenever a byte is available on the
 387  * Arduino's serial port.  This is where the commands are handled. */
 388 void processInput(int inputData) {
 389   int command;
 390   // nl.tue.id.creapro +>>>>>
 391   readCount ++;
 392   // nl.tue.id.creapro +<<<<<
 393   
 394   // a few commands have byte(s) of data following the command
 395   if( (waitForData > 0) && (inputData < 128) ) {  
 396     waitForData--;
 397     storedInputData[waitForData] = inputData;
 398     if( (waitForData==0) && executeMultiByteCommand ) { // got the whole message
 399       // nl.tue.id.creapro +>>>>>
 400       commandCount++;
 401       // nl.tue.id.creapro +<<<<<
 402       switch(executeMultiByteCommand) {
 403       case ANALOG_MESSAGE:
 404                 setPinMode(multiByteChannel,PWM);
 405                 analogWrite(multiByteChannel, 
 406                 (storedInputData[0] << 7) + storedInputData[1] );
 407         break;
 408       case DIGITAL_MESSAGE:
 409                 outputDigitalBytes(storedInputData[1], storedInputData[0]); //(LSB, MSB)
 410                 break;
 411       case SET_DIGITAL_PIN_MODE:
 412                 setPinMode(storedInputData[1], storedInputData[0]); // (pin#, mode)
 413                 if(storedInputData[0] == INPUT) 
 414                   digitalInputsEnabled = true; // enable reporting of digital inputs
 415         break;
 416       case REPORT_ANALOG_PIN:
 417                 setAnalogPinReporting(multiByteChannel,storedInputData[0]);
 418         break;
 419       case REPORT_DIGITAL_PORTS:
 420                 // TODO: implement MIDI channel as port base for more than 16 digital inputs
 421                 if(storedInputData[0] == 0)
 422                   digitalInputsEnabled = false;
 423                 else
 424                   digitalInputsEnabled = true;
 425         break;
 426       // nl.tue.id.creapro +>>>>>
 427       case CONFIG:
 428       //case DEBUG:
 429             switch(storedInputData[1]&0xF0){
 430               case SERIAL_PULL_RATE:
 431                   serialPullRate = (storedInputData[1]&0x0F)*128 + storedInputData[0];
 432                   break;
 433               case ANALOG_PULL_RATE:
 434                   analogPullRate = (storedInputData[1]&0x0F)*128 + storedInputData[0];
 435                   break;
 436               case ANALOG_STEP:
 437                   analogStep = (storedInputData[1]&0x0F)*128 + storedInputData[0];
 438                   break;
 439               case READ_COUNT:
 440                    switch(storedInputData[0]){
 441                      case 0:
 442                          readCount = 0;
 443                          break;
 444                      case 1:
 445                          readCount -= 2;
 446                          serialPrint(DEBUG, READ_COUNT|((readCount>>7)&0x0F), readCount % 128);
 447                          break;
 448                    }
 449                    break;
 450               case WRITE_COUNT:
 451                    switch(storedInputData[0]){
 452                      case 0:
 453                          writeCount = 0;
 454                          break;
 455                      case 1:
 456                          serialPrint(DEBUG, WRITE_COUNT|((writeCount>>7)&0x0F), writeCount % 128);
 457                          break;
 458                    }
 459                    break;                 
 460               case COMMAND_COUNT:
 461                    switch(storedInputData[0]){
 462                      case 0:
 463                          commandCount = 0;
 464                          break;
 465                      case 1:
 466                          commandCount -= 1;
 467                          serialPrint(DEBUG, COMMAND_COUNT|((commandCount>>7)&0x0F), commandCount % 128);
 468                          break;
 469                    }
 470                    break;    
 471               case EVENT_COUNT:
 472                    switch(storedInputData[0]){
 473                      case 0:
 474                          eventCount = 0;
 475                          break;
 476                      case 1:
 477                          serialPrint(DEBUG, EVENT_COUNT|((eventCount>>7)&0x0F), eventCount % 128);
 478                          break;
 479                    }
 480                    break;               
 481             }
 482             break;
 483       // nl.tue.id.creapro +<<<<<
 484       }
 485       executeMultiByteCommand = 0;
 486     }   
 487   } else {
 488     // remove channel info from command byte if less than 0xF0
 489     if(inputData < 0xF0) {
 490       command = inputData & 0xF0;
 491           multiByteChannel = inputData & 0x0F;
 492     } else {
 493       command = inputData;
 494           // commands in the 0xF* range don't use channel data
 495     }
 496     switch (command) { // TODO: these needs to be switched to command
 497     case ANALOG_MESSAGE:
 498     case DIGITAL_MESSAGE:
 499     case SET_DIGITAL_PIN_MODE:
 500     // nl.tue.id.creapro +>>>>>
 501     case CONFIG:
 502     //case DEBUG:
 503     // nl.tue.id.creapro +<<<<<   
 504       waitForData = 2; // two data bytes needed
 505       executeMultiByteCommand = command;
 506       break;
 507     case REPORT_ANALOG_PIN:
 508     case REPORT_DIGITAL_PORTS:
 509       waitForData = 1; // two data bytes needed
 510       executeMultiByteCommand = command;
 511       break;
 512     case SYSTEM_RESET:
 513       // this doesn't do anything yet
 514       break;
 515     case REPORT_VERSION:
 516           printVersion();
 517       break;
 518     }
 519   }
 520 }
 521 
 522 /* -----------------------------------------------------------------------------
 523  * this function checks to see if there is data waiting on the serial port 
 524  * then processes all of the stored data
 525  */
 526 void checkForSerialReceive() {
 527   while(Serial.available())
 528         processInput(Serial.read());
 529 }
 530 
 531 // =============================================================================
 532 // used for flashing the pin for the version number
 533 void pin13strobe(int count, int onInterval, int offInterval) {
 534   byte i;
 535   pinMode(13, OUTPUT);
 536   for(i=0; i<count; i++) {
 537     delay(offInterval);
 538     digitalWrite(13,1);
 539     delay(onInterval);
 540     digitalWrite(13,0);
 541   }
 542 }
 543 
 544 /*==============================================================================
 545  * SETUP()
 546  *============================================================================*/
 547 void setup() {
 548   byte i;
 549 
 550   Serial.begin(57600); // 9600, 14400, 38400, 57600, 115200
 551 
 552   // flash the pin 13 with the protocol version
 553   pinMode(13,OUTPUT);
 554   pin13strobe(2,1,4); // separator, a quick burst
 555   delay(500);
 556   pin13strobe(FIRMATA_MAJOR_VERSION, 200, 400);
 557   delay(500);
 558   pin13strobe(2,1,4); // separator, a quick burst
 559   delay(500);
 560   pin13strobe(FIRMATA_MINOR_VERSION, 200, 400);
 561   delay(500);
 562   pin13strobe(2,1,4); // separator, a quick burst
 563 
 564 
 565   // nl.tue.id.creapro +>>>>>
 566   for(i=0; i<TOTAL_ANALOG_PINS; ++i) {
 567     storedAnalogData[i] = 0;
 568   // nl.tue.id.creapro +<<<<< 
 569  
 570   }
 571   // TODO: load state from EEPROM here
 572 
 573   printVersion();
 574  
 575  // nl.tue.id.creapro +>>>>>
 576  // make sure we did not miss anything important
 577  checkForSerialReceive();
 578  // nl.tue.id.creapro +<<<<<
 579 
 580   /* TODO: send digital inputs here, if enabled, to set the initial state on the
 581    * host computer, since once in the loop(), the Arduino will only send data on
 582    * change. */
 583 }
 584 
 585 /*==============================================================================
 586  * LOOP()
 587  *============================================================================*/
 588 // nl.tue.id.creapro ->>>>>
 589 //void loop() {
 590 ///* DIGITALREAD - as fast as possible, check for changes and output them to the
 591 // * FTDI buffer using Serial.print()  */
 592 //  checkDigitalInputs();  
 593 //  if(timer0_overflow_count > nextExecuteTime) {  
 594 //      nextExecuteTime = timer0_overflow_count + 19; // run this every 20ms
 595 //      /* SERIALREAD - Serial.read() uses a 128 byte circular buffer, so handle
 596 //       * all serialReads at once, i.e. empty the buffer */
 597 //      checkForSerialReceive();
 598 //      /* SEND FTDI WRITE BUFFER - make sure that the FTDI buffer doesn't go over
 599 //       * 60 bytes. use a timer to sending an event character every 4 ms to
 600 //       * trigger the buffer to dump. */
 601 //      
 602 //      /* ANALOGREAD - right after the event character, do all of the
 603 //       * analogReads().  These only need to be done every 4ms. */
 604 //      for(analogPin=0;analogPin<TOTAL_ANALOG_PINS;analogPin++) {
 605 //        if( analogPinsToReport & (1 << analogPin) ) {
 606 //              analogData = analogRead(analogPin);
 607 //              Serial.print(ANALOG_MESSAGE + analogPin, BYTE);
 608 //              // These two bytes converted back into the 10-bit value on host
 609 //              Serial.print(analogData % 128, BYTE);
 610 //              Serial.print(analogData >> 7, BYTE); 
 611 //        }
 612 //      }
 613 //  }
 614 //}
 615 // nl.tue.id.creapro +>>>>>
 616 void loop() {
 617 /* DIGITALREAD - as fast as possible, check for changes and output them to the
 618  * FTDI buffer using Serial.print()  */
 619   checkDigitalInputs();  
 620   if(timer0_overflow_count > nextExecuteTime) {  
 621         nextExecuteTime = timer0_overflow_count + serialPullRate -1; // run this every 20ms
 622         /* SERIALREAD - Serial.read() uses a 128 byte circular buffer, so handle
 623          * all serialReads at once, i.e. empty the buffer */
 624         checkForSerialReceive();
 625         /* SEND FTDI WRITE BUFFER - make sure that the FTDI buffer doesn't go over
 626          * 60 bytes. use a timer to sending an event character every 4 ms to
 627          * trigger the buffer to dump. */
 628 
 629   }
 630   
 631   if(timer0_overflow_count > nextAnalogExecuteTime) {  
 632         nextAnalogExecuteTime = timer0_overflow_count + analogPullRate -1; // run this every 20ms
 633         /* ANALOGREAD - right after the event character, do all of the
 634          * analogReads().  These only need to be done every 4ms. */
 635         for(analogPin=0;analogPin<TOTAL_ANALOG_PINS;analogPin++) {
 636           if( analogPinsToReport & (1 << analogPin) ) {
 637                 analogData = analogRead(analogPin);
 638 
 639                 if(abs(analogData - storedAnalogData[analogPin])<analogStep) continue;
 640 
 641                 storedAnalogData[analogPin] = analogData;
 642                 eventSerialPrint(ANALOG_MESSAGE + analogPin, 
 643                             analogData % 128,
 644                             analogData >> 7);
 645           }
 646         }
 647   }  
 648 }
 649 // nl.tue.id.creapro +<<<<<
 650