Differences between revisions 1 and 17 (spanning 16 versions)
Revision 1 as of 2008-10-03 22:50:30
Size: 25004
Editor: v215085
Comment:
Revision 17 as of 2008-10-07 13:54:22
Size: 2730
Editor: JunHu
Comment:
Deletions are marked like this. Additions are marked like this.
Line 3: Line 3:
{{{#!cplusplus
/*
 * Copyright (C) 2006 Free Software Foundation
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * See file LICENSE for further informations on licensing terms.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *
 * -----------------------------------------------------------
 * Firmata, the general purpose sensorbox firmware for Arduino
 * -----------------------------------------------------------
 *
 * Firmata turns the Arduino into a Plug-n-Play sensorbox, servo
 * controller, and/or PWM motor/lamp controller.
 *
 * It was originally designed to work with the Pd object [arduino]
 * which is included in Pd-extended. This firmware is intended to
 * work with any host computer software package. It can easily be
 * used with other programs like Max/MSP, Processing, or whatever can
 * do serial communications.
 *
 * @author: Hans-Christoph Steiner <hans@at.or.at>
 * help with initial protocol redesign: Jamie Allen <jamie@heavyside.net>
 * much protocol discussion: the Arduino developers mailing list
 * key bugfixes: Georg Holzmann <grh@mur.at>
 * Gerda Strobl <gerda.strobl@student.tugraz.at>
 * @date: 2006-05-19
 * @locations: STEIM, Amsterdam, Netherlands
 * IDMI/Polytechnic University, Brookyn, NY, USA
 * Electrolobby Ars Electronica, Linz, Austria
 */
IDuino is a modified and extended version of [[http://www.arduino.cc/playground/Interfacing/Firmata|Firmata]] (ve1.0). It is the "software brain" of the AdMoVeo robot loaded in the Arduino board.
Line 47: Line 5:
/*
 * TODO: add pulseOut functionality for servos
 * TODO: add software PWM for servos, etc (servo.h or pulse.h)
 * TODO: add device type reporting (i.e. some firmwares will use the Firmata
 * protocol, but will only support specific devices, like ultrasound
 * rangefinders or servos)
 * TODO: use Program Control to load stored profiles from EEPROM
 */
<<TableOfContents>>
Line 56: Line 7:
/* cvs version: $Id: Pd_firmware.pde,v 1.29 2007/03/08 05:37:22 eighthave Exp $ */
/* svn version: 334 */
== Uploading IDuino to Arduino or to AdmoVeo ==
Line 59: Line 9:
/*==============================================================================
 * MESSAGE FORMATS
 *============================================================================*/
In case you need to reload it, please follow the steps below:
Line 63: Line 11:
/* -----------------------------------------------------------------------------
 * MAPPING DATA TO MIDI
 *
 * This protocol uses the MIDI message format, but does not use the whole
 * protocol. Most of the command mappings here will not be directly usable in
 * terms of MIDI controllers and synths. It should co-exist with MIDI without
 * trouble and can be parsed by standard MIDI interpreters. Just some of the
 * message data is used differently.
 *
 * MIDI format: http://www.harmony-central.com/MIDI/Doc/table1.html
 *
 * MIDI
 * type command channel first byte second byte
 * -----------------------------------------------------------------------------
 * analog I/O 0xE0 pin # LSB(bits 0-6) MSB(bits 7-13)
 * digital I/O 0x90 port base LSB(bits 0-6) MSB(bits 7-13)
 * report analog pin 0xC0 pin # disable/enable(0/1) - n/a -
 * report digital ports 0xD0 port base disable/enable(0/1) - n/a -
 *
 * digital pin mode(I/O) 0xF4 - n/a - pin # (0-63) pin state(0=in)
 * firmware version 0xF9 - n/a - minor version major version
 * system reset 0xFF - n/a - - n/a - - n/a -
 *
 */
 
/* nl.tue.id.creapro +>>>>>
 * Extensions nl.tue.id.creapro
 * configuration 0xFD - n/a - 0x00 serial pulling rate (ms)
 * 0x10 analog pulling rate (ms)
 * 0x20 analog step (1-1023)
 * debug 0xFD - n/a - 0x40 data received (bytes)
 * 0x50 data sent (bytes)
 * 0x60 number of commands received
 * 0x70 number of commands sent
 1. Make sure you have the Arduino software installed on your PC. see SoftwareEnvironment for details.
 1. Download the latest IDuino sketch: [[attachment:IDuino.pde]].
 1. Start the Arduino programming environment.
 1. Load the downloaded sketch in the Arduino programming environment by selecting the menu item "File|Sketchbook|Open".
 1. Compile it by either:
  * push the "Verify" button {{attachment:arduino_compile.gif}}, 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.
 1. 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".
  {{attachment:devmgmt.jpg}} {{attachment:devicemanager.png}}
 In "Device Manager", expand "Ports (COM&LPT)", and later watch out what is added when you connect the Arduino board or the AdMoVeo robot.
 1. 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.
 1. 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".
 {{attachment:devicemanager_com5.png}}
 1. 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.
 1. Now load the IDuino sketch onto the Arduino board or the AdMoVeo robot, by either:
  * push the button "Upload to I/O Board" {{attachment:arduino_upload.gif}}, or
  * select the menu item "File|Upload to I/O Board".
 1. In the message box of the Arduino programming environment, you should see "Uploading to I/O Board", and if succeed, then "Done compiling".
 1. 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.
Line 98: Line 35:
 * nl.tue.id.creapro +<<<<<
*/

/* proposed extensions using SysEx
 *
 * type SysEx start command data bytes SysEx stop
 * -----------------------------------------------------------------------------
 * pulse I/O 0xF0 0xA0 five 7-bit chunks, LSB first 0xF7
 * shiftOut 0xF0 0xF5 dataPin; clockPin; 7-bit LSB; 7-bit MSB 0xF7
 */

/* -----------------------------------------------------------------------------
 * DATA MESSAGE FORMAT */

/* two byte digital data format
 * ----------------------------
 * 0 digital data, 0x90-0x9F, (MIDI NoteOn, but different data usage)
 * 1 digital pins 0-6 bitmask
 * 2 digital pins 7-13 bitmask
 */

/* analog 14-bit data format
 * -------------------------
 * 0 analog pin, 0xE0-0xEF, (MIDI Pitch Wheel)
 * 1 analog least significant 7 bits
 * 2 analog most significant 7 bits
 */

/* version report format
 * Send a single byte 0xF9, Arduino will reply with:
 * -------------------------------------------------
 * 0 version report header (0xF9) (MIDI Undefined)
 * 1 minor version (0-127)
 * 2 major version (0-127)
 */

/* pulseIn/Out (uses 32-bit value)
 * -------------------------------
 * 0 START_SYSEX (0xF0) (MIDI System Exclusive)
 * 1 pulseIn/Out (0xA0-0xAF)
 * 2 bits 0-6 (least significant byte)
 * 3 bits 7-13
 * 4 bits 14-20
 * 5 bits 21-27
 * 6 bits 28-34 (most significant byte)
 * 7 END_SYSEX (0xF7) (MIDI End of SysEx - EOX)
 */

/* shiftIn/Out (uses 8-bit value)
 * ------------------------------
 * 0 START_SYSEX (0xF0)
 * 1 shiftOut (0xF5)
 * 2 dataPin (0-127)
 * 3 clockPin (0-127)
 * 4 bits 0-6 (least significant byte)
 * 5 bit 7 (most significant bit)
 * 6 END_SYSEX (0xF7)
 */

/* -----------------------------------------------------------------------------
 * CONTROL MESSAGES */

/* set digital pin mode
 * --------------------
 * 1 set digital pin mode (0xF4) (MIDI Undefined)
 * 2 pin number (0-127)
 * 3 state (INPUT/OUTPUT, 0/1)
 */

/* toggle analogIn reporting by pin
 * --------------------------------
 * 0 toggle digitalIn reporting (0xC0-0xCF) (MIDI Program Change)
 * 1 disable(0)/enable(non-zero)
 */

/* toggle digitalIn reporting by port pairs
 * ----------------------------------------
 * 0 toggle digitalIn reporting (0xD0-0xDF) (MIDI Aftertouch)
 * 1 disable(0)/enable(non-zero)
 */

/* request version report
 * ----------------------
 * 0 request version report (0xF9) (MIDI Undefined)
 */

/*==============================================================================
 * MACROS
 *============================================================================*/

/* Version numbers for the protocol. The protocol is still changing, so these
 * version numbers are important. This number can be queried so that host
 * software can test whether it will be compatible with the currently
 * installed firmware. */
#define FIRMATA_MAJOR_VERSION 1 // for non-compatible changes
#define FIRMATA_MINOR_VERSION 0 // for backwards compatible changes

/* total number of pins currently supported */
#define TOTAL_ANALOG_PINS 6
#define TOTAL_DIGITAL_PINS 14

// for comparing along with INPUT and OUTPUT
#define PWM 2

// for selecting digital inputs
#define PB 2 // digital input, pins 8-13
#define PC 3 // analog input port
#define PD 4 // digital input, pins 0-7

#define MAX_DATA_BYTES 2 // max number of data bytes in non-SysEx messages
/* message command bytes */
#define DIGITAL_MESSAGE 0x90 // send data for a digital pin
#define ANALOG_MESSAGE 0xE0 // send data for an analog pin (or PWM)
//#define PULSE_MESSAGE 0xA0 // proposed pulseIn/Out message (SysEx)
//#define SHIFTOUT_MESSAGE 0xB0 // proposed shiftOut message (SysEx)
#define REPORT_ANALOG_PIN 0xC0 // enable analog input by pin #
#define REPORT_DIGITAL_PORTS 0xD0 // enable digital input by port pair
#define START_SYSEX 0xF0 // start a MIDI SysEx message
#define SET_DIGITAL_PIN_MODE 0xF4 // set a digital pin to INPUT or OUTPUT
#define END_SYSEX 0xF7 // end a MIDI SysEx message
#define REPORT_VERSION 0xF9 // report firmware version
#define SYSTEM_RESET 0xFF // reset from MIDI


// nl.tue.id.creapro +>>>>>
#define CONFIG 0xFD
#define SERIAL_PULL_RATE 0x00
#define ANALOG_PULL_RATE 0x10
#define ANALOG_STEP 0x20

#define DEBUG 0xFD
#define READ_COUNT 0x40
#define WRITE_COUNT 0x50
#define COMMAND_COUNT 0x60
#define EVENT_COUNT 0x70

// nl.tue.id.creapro +<<<<<


/*==============================================================================
 * GLOBAL VARIABLES
 *============================================================================*/

/* input message handling */
byte waitForData = 0; // this flag says the next serial input will be data
byte executeMultiByteCommand = 0; // execute this after getting multi-byte data
byte multiByteChannel = 0; // channel data for multiByteCommands
byte storedInputData[MAX_DATA_BYTES] = {0,0}; // multi-byte data
/* digital pins */
boolean digitalInputsEnabled = false; // output digital inputs or not
int digitalInputs = 0;
int previousDigitalInputs; // previous output to test for change
// nl.tue.id.creapro -+>>>>>
//int digitalPinStatus = 3; // bitwise array to store pin status, ignore RxTx pins
int digitalPinStatus = 0xFFFF; //ignore all pins
// nl.tue.id.creapro -+>>>>>
/* PWM/analog outputs */
int pwmStatus = 0; // bitwise array to store PWM status
/* analog inputs */
int analogPinsToReport = 0; // bitwise array to store pin reporting
int analogPin = 0; // counter for reading analog pins
int analogData; // storage variable for data from analogRead()
/* timer variables */
extern volatile unsigned long timer0_overflow_count; // timer0 from wiring.c
unsigned long nextExecuteTime = 0; // for comparison with timer0_overflow_count

// nl.tue.id.creapro +>>>>>
int storedAnalogData[TOTAL_ANALOG_PINS];
unsigned long nextAnalogExecuteTime = 0; // for comparison with timer0_overflow_count

int serialPullRate = 20;
int analogPullRate = 20;
int analogStep = 1;

int writeCount = 0;
int readCount = 0;
int commandCount = 0;
int eventCount = 0;
// nl.tue.id.creapro +<<<<<


/*==============================================================================
 * FUNCTIONS
 *============================================================================*/
// nl.tue.id.creapro +>>>>>
void serialPrint(int byte1, int byte2, int byte3){
  Serial.print(byte1, BYTE);
  Serial.print(byte2, BYTE);
  Serial.print(byte3, BYTE);
}

void eventSerialPrint(int byte1, int byte2, int byte3){
  serialPrint(byte1, byte2, byte3);
  writeCount = writeCount + 3;
  eventCount++;
}
// nl.tue.id.creapro +<<<<<
 
/* -----------------------------------------------------------------------------
 * output the version message to the serial port */
void printVersion() {
  // nl.tue.id.creapro ->>>>>
  // Serial.print(REPORT_VERSION, BYTE);
  // Serial.print(FIRMATA_MINOR_VERSION, BYTE);
  // Serial.print(FIRMATA_MAJOR_VERSION, BYTE);
  // nl.tue.id.creatpro -<<<<<
  // nl.tue.id.creapro +>>>>>
  serialPrint(REPORT_VERSION,FIRMATA_MINOR_VERSION,FIRMATA_MAJOR_VERSION);
  // nl.tue.id.creapro +<<<<<
}

/* -----------------------------------------------------------------------------
 * output digital bytes received from the serial port */
void outputDigitalBytes(byte pin0_6, byte pin7_13) {
  int i;
  int mask;
  int twoBytesForPorts;
    
// this should be converted to use PORTs
  twoBytesForPorts = pin0_6 + (pin7_13 << 7);
  for(i=2; i<TOTAL_DIGITAL_PINS; ++i) { // ignore Rx,Tx pins (0 and 1)
    mask = 1 << i;
    if( (digitalPinStatus & mask) && !(pwmStatus & mask) ) {
      digitalWrite(i, twoBytesForPorts & mask ? HIGH : LOW);
    }
  }
}

/* -----------------------------------------------------------------------------
 * check all the active digital inputs for change of state, then add any events
 * to the Serial output queue using Serial.print() */
void checkDigitalInputs(void) {
  if(digitalInputsEnabled) {
 previousDigitalInputs = digitalInputs;
 digitalInputs = PINB << 8; // get pins 8-13
 digitalInputs += PIND; // get pins 0-7
 digitalInputs = digitalInputs & ~digitalPinStatus; // ignore pins set OUTPUT
 if(digitalInputs != previousDigitalInputs) {
   // TODO: implement more ports as channels for more than 16 digital pins
          // nl.tue.id.creapro ->>>>>
   // Serial.print(DIGITAL_MESSAGE,BYTE);
   // Serial.print(digitalInputs % 128, BYTE); // Tx pins 0-6
   // Serial.print(digitalInputs >> 7, BYTE); // Tx pins 7-13
          // nl.tue.id.creatpro -<<<<<
          eventSerialPrint(DIGITAL_MESSAGE,
                      digitalInputs % 128, // Tx pins 0-6
                      digitalInputs >> 7); // Tx pins 7-13
 }
  }
}

// -----------------------------------------------------------------------------
/* sets the pin mode to the correct state and sets the relevant bits in the
 * two bit-arrays that track Digital I/O and PWM status
 */
void setPinMode(byte pin, byte mode) {
  if(pin > 1) { // ignore RxTx pins (0,1)
 if(mode == INPUT) {
   digitalPinStatus = digitalPinStatus &~ (1 << pin);
   pwmStatus = pwmStatus &~ (1 << pin);
   digitalWrite(pin,LOW); // turn off pin before switching to INPUT
   pinMode(pin,INPUT);
 }
 else if(mode == OUTPUT) {
   digitalPinStatus = digitalPinStatus | (1 << pin);
   pwmStatus = pwmStatus &~ (1 << pin);
   pinMode(pin,OUTPUT);
 }
 else if( mode == PWM ) {
   digitalPinStatus = digitalPinStatus | (1 << pin);
   pwmStatus = pwmStatus | (1 << pin);
   pinMode(pin,OUTPUT);
 }
  // TODO: save status to EEPROM here, if changed
  }
}

// -----------------------------------------------------------------------------
/* sets bits in a bit array (int) to toggle the reporting of the analogIns
 */
void setAnalogPinReporting(byte pin, byte state) {
  if(state == 0) {
    analogPinsToReport = analogPinsToReport &~ (1 << pin);
  }
  else { // everything but 0 enables reporting of that pin
    analogPinsToReport = analogPinsToReport | (1 << pin);
  }
  // TODO: save status to EEPROM here, if changed
}

/* -----------------------------------------------------------------------------
 * processInput() is called whenever a byte is available on the
 * Arduino's serial port. This is where the commands are handled. */
void processInput(int inputData) {
  int command;
  // nl.tue.id.creapro +>>>>>
  readCount ++;
  // nl.tue.id.creapro +<<<<<
  
  // a few commands have byte(s) of data following the command
  if( (waitForData > 0) && (inputData < 128) ) {
    waitForData--;
    storedInputData[waitForData] = inputData;
    if( (waitForData==0) && executeMultiByteCommand ) { // got the whole message
      // nl.tue.id.creapro +>>>>>
      commandCount++;
      // nl.tue.id.creapro +<<<<<
      switch(executeMultiByteCommand) {
      case ANALOG_MESSAGE:
  setPinMode(multiByteChannel,PWM);
  analogWrite(multiByteChannel,
  (storedInputData[0] << 7) + storedInputData[1] );
        break;
      case DIGITAL_MESSAGE:
  outputDigitalBytes(storedInputData[1], storedInputData[0]); //(LSB, MSB)
  break;
      case SET_DIGITAL_PIN_MODE:
  setPinMode(storedInputData[1], storedInputData[0]); // (pin#, mode)
  if(storedInputData[0] == INPUT)
    digitalInputsEnabled = true; // enable reporting of digital inputs
        break;
      case REPORT_ANALOG_PIN:
  setAnalogPinReporting(multiByteChannel,storedInputData[0]);
        break;
      case REPORT_DIGITAL_PORTS:
  // TODO: implement MIDI channel as port base for more than 16 digital inputs
  if(storedInputData[0] == 0)
    digitalInputsEnabled = false;
  else
    digitalInputsEnabled = true;
        break;
      // nl.tue.id.creapro +>>>>>
      case CONFIG:
      //case DEBUG:
            switch(storedInputData[1]&0xF0){
              case SERIAL_PULL_RATE:
                  serialPullRate = (storedInputData[1]&0x0F)*128 + storedInputData[0];
                  break;
              case ANALOG_PULL_RATE:
                  analogPullRate = (storedInputData[1]&0x0F)*128 + storedInputData[0];
                  break;
              case ANALOG_STEP:
                  analogStep = (storedInputData[1]&0x0F)*128 + storedInputData[0];
                  break;
              case READ_COUNT:
                   switch(storedInputData[0]){
                     case 0:
                         readCount = 0;
                         break;
                     case 1:
                         readCount -= 2;
                         serialPrint(DEBUG, READ_COUNT|((readCount>>7)&0x0F), readCount % 128);
                         break;
                   }
                   break;
              case WRITE_COUNT:
                   switch(storedInputData[0]){
                     case 0:
                         writeCount = 0;
                         break;
                     case 1:
                         serialPrint(DEBUG, WRITE_COUNT|((writeCount>>7)&0x0F), writeCount % 128);
                         break;
                   }
                   break;
              case COMMAND_COUNT:
                   switch(storedInputData[0]){
                     case 0:
                         commandCount = 0;
                         break;
                     case 1:
                         commandCount -= 1;
                         serialPrint(DEBUG, COMMAND_COUNT|((commandCount>>7)&0x0F), commandCount % 128);
                         break;
                   }
                   break;
              case EVENT_COUNT:
                   switch(storedInputData[0]){
                     case 0:
                         eventCount = 0;
                         break;
                     case 1:
                         serialPrint(DEBUG, EVENT_COUNT|((eventCount>>7)&0x0F), eventCount % 128);
                         break;
                   }
                   break;
            }
            break;
      // nl.tue.id.creapro +<<<<<
      }
      executeMultiByteCommand = 0;
    }
  } else {
    // remove channel info from command byte if less than 0xF0
    if(inputData < 0xF0) {
      command = inputData & 0xF0;
   multiByteChannel = inputData & 0x0F;
    } else {
      command = inputData;
   // commands in the 0xF* range don't use channel data
    }
    switch (command) { // TODO: these needs to be switched to command
    case ANALOG_MESSAGE:
    case DIGITAL_MESSAGE:
    case SET_DIGITAL_PIN_MODE:
    // nl.tue.id.creapro +>>>>>
    case CONFIG:
    //case DEBUG:
    // nl.tue.id.creapro +<<<<<
      waitForData = 2; // two data bytes needed
      executeMultiByteCommand = command;
      break;
    case REPORT_ANALOG_PIN:
    case REPORT_DIGITAL_PORTS:
      waitForData = 1; // two data bytes needed
      executeMultiByteCommand = command;
      break;
    case SYSTEM_RESET:
      // this doesn't do anything yet
      break;
    case REPORT_VERSION:
   printVersion();
      break;
    }
  }
}

/* -----------------------------------------------------------------------------
 * this function checks to see if there is data waiting on the serial port
 * then processes all of the stored data
 */
void checkForSerialReceive() {
  while(Serial.available())
 processInput(Serial.read());
}

// =============================================================================
// used for flashing the pin for the version number
void pin13strobe(int count, int onInterval, int offInterval) {
  byte i;
  pinMode(13, OUTPUT);
  for(i=0; i<count; i++) {
    delay(offInterval);
    digitalWrite(13,1);
    delay(onInterval);
    digitalWrite(13,0);
  }
}

/*==============================================================================
 * SETUP()
 *============================================================================*/
void setup() {
  byte i;

  Serial.begin(57600); // 9600, 14400, 38400, 57600, 115200

  // flash the pin 13 with the protocol version
  pinMode(13,OUTPUT);
  pin13strobe(2,1,4); // separator, a quick burst
  delay(500);
  pin13strobe(FIRMATA_MAJOR_VERSION, 200, 400);
  delay(500);
  pin13strobe(2,1,4); // separator, a quick burst
  delay(500);
  pin13strobe(FIRMATA_MINOR_VERSION, 200, 400);
  delay(500);
  pin13strobe(2,1,4); // separator, a quick burst


  // nl.tue.id.creapro +>>>>>
  for(i=0; i<TOTAL_ANALOG_PINS; ++i) {
    storedAnalogData[i] = 0;
  // nl.tue.id.creapro +<<<<<
 
  }
  // TODO: load state from EEPROM here

  printVersion();
 
 // nl.tue.id.creapro +>>>>>
 // make sure we did not miss anything important
 checkForSerialReceive();
 // nl.tue.id.creapro +<<<<<

  /* TODO: send digital inputs here, if enabled, to set the initial state on the
   * host computer, since once in the loop(), the Arduino will only send data on
   * change. */
}

/*==============================================================================
 * LOOP()
 *============================================================================*/
// nl.tue.id.creapro ->>>>>
//void loop() {
///* DIGITALREAD - as fast as possible, check for changes and output them to the
// * FTDI buffer using Serial.print() */
// checkDigitalInputs();
// if(timer0_overflow_count > nextExecuteTime) {
// nextExecuteTime = timer0_overflow_count + 19; // run this every 20ms
// /* SERIALREAD - Serial.read() uses a 128 byte circular buffer, so handle
// * all serialReads at once, i.e. empty the buffer */
// checkForSerialReceive();
// /* 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. */
//
// /* ANALOGREAD - right after the event character, do all of the
// * analogReads(). These only need to be done every 4ms. */
// for(analogPin=0;analogPin<TOTAL_ANALOG_PINS;analogPin++) {
// if( analogPinsToReport & (1 << analogPin) ) {
// analogData = analogRead(analogPin);
// Serial.print(ANALOG_MESSAGE + analogPin, BYTE);
// // These two bytes converted back into the 10-bit value on host
// Serial.print(analogData % 128, BYTE);
// Serial.print(analogData >> 7, BYTE);
// }
// }
// }
//}
// nl.tue.id.creapro +>>>>>
void loop() {
/* DIGITALREAD - as fast as possible, check for changes and output them to the
 * FTDI buffer using Serial.print() */
  checkDigitalInputs();
  if(timer0_overflow_count > nextExecuteTime) {
 nextExecuteTime = timer0_overflow_count + serialPullRate -1; // run this every 20ms
 /* SERIALREAD - Serial.read() uses a 128 byte circular buffer, so handle
  * all serialReads at once, i.e. empty the buffer */
 checkForSerialReceive();
 /* 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. */

  }
  
  if(timer0_overflow_count > nextAnalogExecuteTime) {
 nextAnalogExecuteTime = timer0_overflow_count + analogPullRate -1; // run this every 20ms
 /* ANALOGREAD - right after the event character, do all of the
  * analogReads(). These only need to be done every 4ms. */
 for(analogPin=0;analogPin<TOTAL_ANALOG_PINS;analogPin++) {
   if( analogPinsToReport & (1 << analogPin) ) {
  analogData = analogRead(analogPin);

                if(abs(analogData - storedAnalogData[analogPin])<analogStep) continue;

                storedAnalogData[analogPin] = analogData;
                eventSerialPrint(ANALOG_MESSAGE + analogPin,
                            analogData % 128,
                            analogData >> 7);
   }
 }
  }
}
// nl.tue.id.creapro +<<<<<
}}}
== Earlier versions ==
 * [[attachment:IDuino.pde|IDuino v1.0]]

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.

Uploading IDuino to Arduino or to AdmoVeo

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 latest IDuino sketch: IDuino.pde.

  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 arduino_compile.gif, 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".

      devicemanager.png

    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".

    devicemanager_com5.png

  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" arduino_upload.gif, 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.

Earlier versions

CreaPro: IDuino (last edited 2013-12-27 22:45:53 by JunHu)