Merge branch 'new-extension' of https://github.com/arduino/Arduino into new-extension

This commit is contained in:
Zach Eveland 2011-09-16 10:27:11 -04:00
commit ab8fc5aab7
22 changed files with 493 additions and 223 deletions

View File

@ -2048,87 +2048,38 @@ public class Editor extends JFrame implements RunnerListener {
* modifications (if any) to the previous sketch need to be saved. * modifications (if any) to the previous sketch need to be saved.
*/ */
protected boolean handleOpenInternal(String path) { protected boolean handleOpenInternal(String path) {
// rename .pde files to .ino
File[] oldFiles = (new File(path)).getParentFile().listFiles(new FilenameFilter() {
public boolean accept(File dir, String name) {
return (name.toLowerCase().endsWith(".pde"));
}
});
if (oldFiles != null && oldFiles.length > 0) {
if (!Preferences.getBoolean("editor.update_extension")) {
Object[] options = { "OK", "Cancel" };
String prompt =
"In Arduino 1.0, the file extension for sketches changed\n" +
"from \".pde\" to \".ino\". This version of the software only\n" +
"supports the new extension. Rename the files in this sketch\n" +
"(and future sketches) and continue?";
int result = JOptionPane.showOptionDialog(this,
prompt,
"New extension",
JOptionPane.YES_NO_OPTION,
JOptionPane.QUESTION_MESSAGE,
null,
options,
options[0]);
if (result != JOptionPane.YES_OPTION) {
return false;
}
Preferences.setBoolean("editor.update_extension", true);
}
for (int i = 0; i < oldFiles.length; i++) {
String oldPath = oldFiles[i].getPath();
File newFile = new File(oldPath.substring(0, oldPath.length() - 4) + ".ino");
try {
Base.copyFile(oldFiles[i], newFile);
} catch (IOException e) {
Base.showWarning("Error", "Could not copy to a proper location.", e);
return false;
}
// remove the original file, so user doesn't get confused
oldFiles[i].delete();
// update with the new path
if (oldFiles[i].compareTo(new File(path)) == 0) {
path = newFile.getAbsolutePath();
}
}
}
// check to make sure that this .pde file is // check to make sure that this .pde file is
// in a folder of the same name // in a folder of the same name
File file = new File(path); File file = new File(path);
File parentFile = new File(file.getParent()); String fileName = file.getName();
String parentName = parentFile.getName(); File parent = file.getParentFile();
String pdeName = parentName + ".ino"; String parentName = parent.getName();
File altFile = new File(file.getParent(), pdeName); String pdeName = parentName + ".pde";
File altPdeFile = new File(parent, pdeName);
String inoName = parentName + ".ino";
File altInoFile = new File(parent, pdeName);
if (pdeName.equals(file.getName())) { if (pdeName.equals(fileName) || inoName.equals(fileName)) {
// no beef with this guy // no beef with this guy
} else if (altFile.exists()) { } else if (altPdeFile.exists()) {
// user selected a .java from the same sketch, // user selected a .java from the same sketch, but open the .pde instead
// but open the .pde instead path = altPdeFile.getAbsolutePath();
path = altFile.getAbsolutePath(); } else if (altInoFile.exists()) {
//System.out.println("found alt file in same folder"); path = altInoFile.getAbsolutePath();
} else if (!path.endsWith(".ino") && !path.endsWith(".pde")) {
} else if (!path.endsWith(".ino")) {
Base.showWarning("Bad file selected", Base.showWarning("Bad file selected",
"Processing can only open its own sketches\n" + "Processing can only open its own sketches\n" +
"and other files ending in .ino", null); "and other files ending in .ino or .pde", null);
return false; return false;
} else { } else {
String properParent = String properParent =
file.getName().substring(0, file.getName().length() - 4); fileName.substring(0, fileName.length() - 4);
Object[] options = { "OK", "Cancel" }; Object[] options = { "OK", "Cancel" };
String prompt = String prompt =
"The file \"" + file.getName() + "\" needs to be inside\n" + "The file \"" + fileName + "\" needs to be inside\n" +
"a sketch folder named \"" + properParent + "\".\n" + "a sketch folder named \"" + properParent + "\".\n" +
"Create this folder, move the file, and continue?"; "Create this folder, move the file, and continue?";
@ -2223,7 +2174,7 @@ public class Editor extends JFrame implements RunnerListener {
// need to get the name, user might also cancel here // need to get the name, user might also cancel here
} else if (immediately) { } else if (immediately) {
handleSave2(); return handleSave2();
} else { } else {
SwingUtilities.invokeLater(new Runnable() { SwingUtilities.invokeLater(new Runnable() {
@ -2236,15 +2187,16 @@ public class Editor extends JFrame implements RunnerListener {
} }
protected void handleSave2() { protected boolean handleSave2() {
toolbar.activate(EditorToolbar.SAVE); toolbar.activate(EditorToolbar.SAVE);
statusNotice("Saving..."); statusNotice("Saving...");
boolean saved = false;
try { try {
if (sketch.save()) { saved = sketch.save();
if (saved)
statusNotice("Done Saving."); statusNotice("Done Saving.");
} else { else
statusEmpty(); statusEmpty();
}
// rebuild sketch menu in case a save-as was forced // rebuild sketch menu in case a save-as was forced
// Disabling this for 0125, instead rebuild the menu inside // Disabling this for 0125, instead rebuild the menu inside
// the Save As method of the Sketch object, since that's the // the Save As method of the Sketch object, since that's the
@ -2263,6 +2215,7 @@ public class Editor extends JFrame implements RunnerListener {
} }
//toolbar.clear(); //toolbar.clear();
toolbar.deactivate(EditorToolbar.SAVE); toolbar.deactivate(EditorToolbar.SAVE);
return saved;
} }

View File

@ -36,6 +36,7 @@ import java.awt.event.*;
import java.beans.*; import java.beans.*;
import java.io.*; import java.io.*;
import java.util.*; import java.util.*;
import java.util.List;
import java.util.zip.*; import java.util.zip.*;
import javax.swing.*; import javax.swing.*;
@ -261,7 +262,6 @@ public class Sketch {
} }
} }
boolean renamingCode; boolean renamingCode;
/** /**
@ -709,13 +709,42 @@ public class Sketch {
if (!saveAs()) return false; if (!saveAs()) return false;
} }
// rename .pde files to .ino
File mainFile = new File(getMainFilePath());
File mainFolder = mainFile.getParentFile();
File[] pdeFiles = mainFolder.listFiles(new FilenameFilter() {
public boolean accept(File dir, String name) {
return name.toLowerCase().endsWith(".pde");
}
});
if (pdeFiles != null && pdeFiles.length > 0) {
// Do rename of all .pde files to new .ino extension
for (File pdeFile : pdeFiles)
renameCodeToInoExtension(pdeFile);
}
for (int i = 0; i < codeCount; i++) { for (int i = 0; i < codeCount; i++) {
if (code[i].isModified()) code[i].save(); if (code[i].isModified())
code[i].save();
} }
calcModified(); calcModified();
return true; return true;
} }
protected boolean renameCodeToInoExtension(File pdeFile) {
for (SketchCode c : code) {
if (!c.getFile().equals(pdeFile))
continue;
String pdeName = pdeFile.getPath();
pdeName = pdeName.substring(0, pdeName.length() - 4) + ".ino";
return c.renameTo(new File(pdeName), "ino");
}
return false;
}
/** /**
* Handles 'Save As' for a sketch. * Handles 'Save As' for a sketch.
@ -1261,7 +1290,7 @@ public class Sketch {
StringBuffer bigCode = new StringBuffer(); StringBuffer bigCode = new StringBuffer();
int bigCount = 0; int bigCount = 0;
for (SketchCode sc : code) { for (SketchCode sc : code) {
if (sc.isExtension("ino")) { if (sc.isExtension("ino") || sc.isExtension("pde")) {
sc.setPreprocOffset(bigCount); sc.setPreprocOffset(bigCount);
bigCode.append(sc.getProgram()); bigCode.append(sc.getProgram());
bigCode.append('\n'); bigCode.append('\n');
@ -1357,7 +1386,7 @@ public class Sketch {
} }
// sc.setPreprocName(filename); // sc.setPreprocName(filename);
} else if (sc.isExtension("ino")) { } else if (sc.isExtension("ino") || sc.isExtension("pde")) {
// The compiler and runner will need this to have a proper offset // The compiler and runner will need this to have a proper offset
sc.addPreprocOffset(headerOffset); sc.addPreprocOffset(headerOffset);
} }
@ -1762,7 +1791,7 @@ public class Sketch {
* For Processing, this is true for .pde files. (Broken out for subclasses.) * For Processing, this is true for .pde files. (Broken out for subclasses.)
*/ */
public boolean hideExtension(String what) { public boolean hideExtension(String what) {
return what.equals(getDefaultExtension()); return getHiddenExtensions().contains(what);
} }
@ -1802,12 +1831,17 @@ public class Sketch {
return "ino"; return "ino";
} }
static private List<String> hiddenExtensions = Arrays.asList("ino", "pde");
public List<String> getHiddenExtensions() {
return hiddenExtensions;
}
/** /**
* Returns a String[] array of proper extensions. * Returns a String[] array of proper extensions.
*/ */
public String[] getExtensions() { public String[] getExtensions() {
return new String[] { "ino", "c", "cpp", "h" }; return new String[] { "ino", "pde", "c", "cpp", "h" };
} }

View File

@ -113,8 +113,8 @@ public class SketchCode {
protected boolean renameTo(File what, String ext) { protected boolean renameTo(File what, String ext) {
boolean success = file.renameTo(what); boolean success = file.renameTo(what);
if (success) { if (success) {
this.file = what; // necessary? file = what;
this.extension = ext; extension = ext;
makePrettyName(); makePrettyName();
} }
return success; return success;

Binary file not shown.

View File

@ -7,11 +7,11 @@
<!-- all these need to change for new releases --> <!-- all these need to change for new releases -->
<key>CFBundleGetInfoString</key> <key>CFBundleGetInfoString</key>
<string>1.0-beta3</string> <string>1.0-beta4</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>0100</string> <string>0100</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>1.0-beta3</string> <string>1.0-beta4</string>
<!-- now stop changing things and get outta here --> <!-- now stop changing things and get outta here -->
<key>CFBundleAllowMixedLocalizations</key> <key>CFBundleAllowMixedLocalizations</key>

View File

@ -29,30 +29,39 @@
// private method to read stream with timeout // private method to read stream with timeout
int Stream::timedRead() int Stream::timedRead()
{ {
//Serial.println(_timeout); int c;
this->_startMillis = millis(); _startMillis = millis();
while(millis() - this->_startMillis < this->_timeout) do {
{ c = read();
if (this->available() > 0) { if (c >= 0) return c;
return this->read(); } while(millis() - _startMillis < _timeout);
}
}
return -1; // -1 indicates timeout return -1; // -1 indicates timeout
} }
// returns the next digit in the stream or -1 if timeout // private method to peek stream with timeout
// discards non-numeric characters int Stream::timedPeek()
int Stream::getNextDigit()
{ {
int c; int c;
do{ _startMillis = millis();
c = timedRead(); do {
if( c < 0) c = peek();
return c; // timeout if (c >= 0) return c;
} } while(millis() - _startMillis < _timeout);
while( c != '-' && (c < '0' || c > '9') ) ; return -1; // -1 indicates timeout
}
return c; // returns peek of the next digit in the stream or -1 if timeout
// discards non-numeric characters
int Stream::peekNextDigit()
{
int c;
while (1) {
c = timedPeek();
if (c < 0) return c; // timeout
if (c == '-') return c;
if (c >= '0' && c <= '9') return c;
read(); // discard non-numeric
}
} }
// Public Methods // Public Methods
@ -130,7 +139,7 @@ long Stream::parseInt(char skipChar)
long value = 0; long value = 0;
int c; int c;
c = getNextDigit(); c = peekNextDigit();
// ignore non numeric leading characters // ignore non numeric leading characters
if(c < 0) if(c < 0)
return 0; // zero returned if timeout return 0; // zero returned if timeout
@ -142,9 +151,10 @@ long Stream::parseInt(char skipChar)
isNegative = true; isNegative = true;
else if(c >= '0' && c <= '9') // is c a digit? else if(c >= '0' && c <= '9') // is c a digit?
value = value * 10 + c - '0'; value = value * 10 + c - '0';
c = timedRead(); read(); // consume the character we got with peek
c = timedPeek();
} }
while( (c >= '0' && c <= '9') || c == skipChar ); while( (c >= '0' && c <= '9') || c == skipChar );
if(isNegative) if(isNegative)
value = -value; value = -value;
@ -168,7 +178,7 @@ float Stream::parseFloat(char skipChar){
char c; char c;
float fraction = 1.0; float fraction = 1.0;
c = getNextDigit(); c = peekNextDigit();
// ignore non numeric leading characters // ignore non numeric leading characters
if(c < 0) if(c < 0)
return 0; // zero returned if timeout return 0; // zero returned if timeout
@ -185,7 +195,8 @@ float Stream::parseFloat(char skipChar){
if(isFraction) if(isFraction)
fraction *= 0.1; fraction *= 0.1;
} }
c = timedRead(); read(); // consume the character we got with peek
c = timedPeek();
} }
while( (c >= '0' && c <= '9') || c == '.' || c == skipChar ); while( (c >= '0' && c <= '9') || c == '.' || c == skipChar );

View File

@ -41,7 +41,8 @@ class Stream : public Print
long _timeout; // number of milliseconds to wait for the next char before aborting timed read long _timeout; // number of milliseconds to wait for the next char before aborting timed read
long _startMillis; // used for timeout measurement long _startMillis; // used for timeout measurement
int timedRead(); // private method to read stream with timeout int timedRead(); // private method to read stream with timeout
int getNextDigit(); // returns the next numeric digit in the stream or -1 if timeout int timedPeek(); // private method to peek stream with timeout
int peekNextDigit(); // returns the next numeric digit in the stream or -1 if timeout
public: public:
virtual int available() = 0; virtual int available() = 0;

View File

@ -124,6 +124,10 @@ writePort(port, value, bitmask): Write an 8 bit port.
* Board Specific Configuration * Board Specific Configuration
*============================================================================*/ *============================================================================*/
#ifndef digitalPinHasPWM
#define digitalPinHasPWM(p) IS_PIN_DIGITAL(p)
#endif
// Arduino Duemilanove, Diecimila, and NG // Arduino Duemilanove, Diecimila, and NG
#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) #if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__)
#if defined(NUM_ANALOG_INPUTS) && NUM_ANALOG_INPUTS == 6 #if defined(NUM_ANALOG_INPUTS) && NUM_ANALOG_INPUTS == 6
@ -136,7 +140,7 @@ writePort(port, value, bitmask): Write an 8 bit port.
#define VERSION_BLINK_PIN 13 #define VERSION_BLINK_PIN 13
#define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) <= 19) #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) <= 19)
#define IS_PIN_ANALOG(p) ((p) >= 14 && (p) < 14 + TOTAL_ANALOG_PINS) #define IS_PIN_ANALOG(p) ((p) >= 14 && (p) < 14 + TOTAL_ANALOG_PINS)
#define IS_PIN_PWM(p) IS_PIN_DIGITAL(p) #define IS_PIN_PWM(p) digitalPinHasPWM(p)
#define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && (p) - 2 < MAX_SERVOS) #define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && (p) - 2 < MAX_SERVOS)
#define IS_PIN_I2C(p) ((p) == 18 || (p) == 19) #define IS_PIN_I2C(p) ((p) == 18 || (p) == 19)
#define PIN_TO_DIGITAL(p) (p) #define PIN_TO_DIGITAL(p) (p)
@ -151,7 +155,7 @@ writePort(port, value, bitmask): Write an 8 bit port.
#define VERSION_BLINK_PIN WLED #define VERSION_BLINK_PIN WLED
#define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < TOTAL_PINS) #define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < TOTAL_PINS)
#define IS_PIN_ANALOG(p) ((p) >= FIRST_ANALOG_PIN && (p) < (FIRST_ANALOG_PIN+TOTAL_ANALOG_PINS)) #define IS_PIN_ANALOG(p) ((p) >= FIRST_ANALOG_PIN && (p) < (FIRST_ANALOG_PIN+TOTAL_ANALOG_PINS))
#define IS_PIN_PWM(p) IS_PIN_DIGITAL(p) #define IS_PIN_PWM(p) digitalPinHasPWM(p)
#define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS) #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS)
#define IS_PIN_I2C(p) ((p) == SDA || (p) == SCL) #define IS_PIN_I2C(p) ((p) == SDA || (p) == SCL)
#define PIN_TO_DIGITAL(p) (p) #define PIN_TO_DIGITAL(p) (p)
@ -167,7 +171,7 @@ writePort(port, value, bitmask): Write an 8 bit port.
#define VERSION_BLINK_PIN 13 #define VERSION_BLINK_PIN 13
#define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) <= 19) #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) <= 19)
#define IS_PIN_ANALOG(p) ((p) >= 14 && (p) <= 19) #define IS_PIN_ANALOG(p) ((p) >= 14 && (p) <= 19)
#define IS_PIN_PWM(p) IS_PIN_DIGITAL(p) #define IS_PIN_PWM(p) digitalPinHasPWM(p)
#define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && (p) - 2 < MAX_SERVOS) #define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && (p) - 2 < MAX_SERVOS)
#define IS_PIN_I2C(p) ((p) == 18 || (p) == 19) #define IS_PIN_I2C(p) ((p) == 18 || (p) == 19)
#define PIN_TO_DIGITAL(p) (p) #define PIN_TO_DIGITAL(p) (p)
@ -178,13 +182,13 @@ writePort(port, value, bitmask): Write an 8 bit port.
// Arduino Mega // Arduino Mega
#elif defined(__AVR_ATmega1280__) #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
#define TOTAL_ANALOG_PINS 16 #define TOTAL_ANALOG_PINS 16
#define TOTAL_PINS 70 // 54 digital + 16 analog #define TOTAL_PINS 70 // 54 digital + 16 analog
#define VERSION_BLINK_PIN 13 #define VERSION_BLINK_PIN 13
#define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) < TOTAL_PINS) #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) < TOTAL_PINS)
#define IS_PIN_ANALOG(p) ((p) >= 54 && (p) < TOTAL_PINS) #define IS_PIN_ANALOG(p) ((p) >= 54 && (p) < TOTAL_PINS)
#define IS_PIN_PWM(p) IS_PIN_DIGITAL(p) #define IS_PIN_PWM(p) digitalPinHasPWM(p)
#define IS_PIN_SERVO(p) ((p) >= 2 && (p) - 2 < MAX_SERVOS) #define IS_PIN_SERVO(p) ((p) >= 2 && (p) - 2 < MAX_SERVOS)
#define IS_PIN_I2C(p) ((p) == 20 || (p) == 21) #define IS_PIN_I2C(p) ((p) == 20 || (p) == 21)
#define PIN_TO_DIGITAL(p) (p) #define PIN_TO_DIGITAL(p) (p)
@ -200,7 +204,7 @@ writePort(port, value, bitmask): Write an 8 bit port.
#define VERSION_BLINK_PIN 6 #define VERSION_BLINK_PIN 6
#define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < TOTAL_PINS) #define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < TOTAL_PINS)
#define IS_PIN_ANALOG(p) (0) #define IS_PIN_ANALOG(p) (0)
#define IS_PIN_PWM(p) IS_PIN_DIGITAL(p) #define IS_PIN_PWM(p) digitalPinHasPWM(p)
#define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS) #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS)
#define IS_PIN_I2C(p) (0) #define IS_PIN_I2C(p) (0)
#define PIN_TO_DIGITAL(p) (p) #define PIN_TO_DIGITAL(p) (p)
@ -216,7 +220,7 @@ writePort(port, value, bitmask): Write an 8 bit port.
#define VERSION_BLINK_PIN 11 #define VERSION_BLINK_PIN 11
#define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < TOTAL_PINS) #define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < TOTAL_PINS)
#define IS_PIN_ANALOG(p) ((p) >= 11 && (p) <= 22) #define IS_PIN_ANALOG(p) ((p) >= 11 && (p) <= 22)
#define IS_PIN_PWM(p) IS_PIN_DIGITAL(p) #define IS_PIN_PWM(p) digitalPinHasPWM(p)
#define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS) #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS)
#define IS_PIN_I2C(p) ((p) == 5 || (p) == 6) #define IS_PIN_I2C(p) ((p) == 5 || (p) == 6)
#define PIN_TO_DIGITAL(p) (p) #define PIN_TO_DIGITAL(p) (p)
@ -232,7 +236,7 @@ writePort(port, value, bitmask): Write an 8 bit port.
#define VERSION_BLINK_PIN 6 #define VERSION_BLINK_PIN 6
#define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < TOTAL_PINS) #define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < TOTAL_PINS)
#define IS_PIN_ANALOG(p) ((p) >= 38 && (p) < TOTAL_PINS) #define IS_PIN_ANALOG(p) ((p) >= 38 && (p) < TOTAL_PINS)
#define IS_PIN_PWM(p) IS_PIN_DIGITAL(p) #define IS_PIN_PWM(p) digitalPinHasPWM(p)
#define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS) #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS)
#define IS_PIN_I2C(p) ((p) == 0 || (p) == 1) #define IS_PIN_I2C(p) ((p) == 0 || (p) == 1)
#define PIN_TO_DIGITAL(p) (p) #define PIN_TO_DIGITAL(p) (p)
@ -248,7 +252,7 @@ writePort(port, value, bitmask): Write an 8 bit port.
#define VERSION_BLINK_PIN 0 #define VERSION_BLINK_PIN 0
#define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) < TOTAL_PINS) #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) < TOTAL_PINS)
#define IS_PIN_ANALOG(p) ((p) >= 24 && (p) < TOTAL_PINS) #define IS_PIN_ANALOG(p) ((p) >= 24 && (p) < TOTAL_PINS)
#define IS_PIN_PWM(p) IS_PIN_DIGITAL(p) #define IS_PIN_PWM(p) digitalPinHasPWM(p)
#define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS) #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS)
#define IS_PIN_I2C(p) ((p) == 16 || (p) == 17) #define IS_PIN_I2C(p) ((p) == 16 || (p) == 17)
#define PIN_TO_DIGITAL(p) (p) #define PIN_TO_DIGITAL(p) (p)
@ -264,7 +268,7 @@ writePort(port, value, bitmask): Write an 8 bit port.
#define VERSION_BLINK_PIN 13 #define VERSION_BLINK_PIN 13
#define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) < TOTAL_PINS) #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) < TOTAL_PINS)
#define IS_PIN_ANALOG(p) ((p) >= 36 && (p) < TOTAL_PINS) #define IS_PIN_ANALOG(p) ((p) >= 36 && (p) < TOTAL_PINS)
#define IS_PIN_PWM(p) IS_PIN_DIGITAL(p) #define IS_PIN_PWM(p) digitalPinHasPWM(p)
#define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS) #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS)
#define IS_PIN_I2C(p) ((p) == 4 || (p) == 5) #define IS_PIN_I2C(p) ((p) == 4 || (p) == 5)
#define PIN_TO_DIGITAL(p) (p) #define PIN_TO_DIGITAL(p) (p)

View File

@ -68,7 +68,6 @@ void FirmataClass::begin(long speed)
Serial.begin(speed); Serial.begin(speed);
FirmataSerial = Serial; FirmataSerial = Serial;
blinkVersion(); blinkVersion();
delay(300);
printVersion(); printVersion();
printFirmwareVersion(); printFirmwareVersion();
} }
@ -92,11 +91,10 @@ void FirmataClass::blinkVersion(void)
{ {
// flash the pin with the protocol version // flash the pin with the protocol version
pinMode(VERSION_BLINK_PIN,OUTPUT); pinMode(VERSION_BLINK_PIN,OUTPUT);
pin13strobe(FIRMATA_MAJOR_VERSION, 200, 400); pin13strobe(FIRMATA_MAJOR_VERSION, 40, 210);
delay(300); delay(250);
pin13strobe(2,1,4); // separator, a quick burst pin13strobe(FIRMATA_MINOR_VERSION, 40, 210);
delay(300); delay(125);
pin13strobe(FIRMATA_MINOR_VERSION, 200, 400);
} }
void FirmataClass::printFirmwareVersion(void) void FirmataClass::printFirmwareVersion(void)

View File

@ -1,3 +1,14 @@
/*
* Firmata is a generic protocol for communicating with microcontrollers
* from software on a host computer. It is intended to work with
* any host computer software package.
*
* To download a host software package, please clink on the following link
* to open the download page in your default browser.
*
* http://firmata.org/wiki/Download
*/
/* /*
* This firmware reads all inputs and sends them as fast as it can. It was * This firmware reads all inputs and sends them as fast as it can. It was
* inspired by the ease-of-use of the Arduino2Max program. * inspired by the ease-of-use of the Arduino2Max program.

View File

@ -1,3 +1,14 @@
/*
* Firmata is a generic protocol for communicating with microcontrollers
* from software on a host computer. It is intended to work with
* any host computer software package.
*
* To download a host software package, please clink on the following link
* to open the download page in your default browser.
*
* http://firmata.org/wiki/Download
*/
/* This firmware supports as many analog ports as possible, all analog inputs, /* This firmware supports as many analog ports as possible, all analog inputs,
* four PWM outputs, and two with servo support. * four PWM outputs, and two with servo support.
* *

View File

@ -1,3 +1,14 @@
/*
* Firmata is a generic protocol for communicating with microcontrollers
* from software on a host computer. It is intended to work with
* any host computer software package.
*
* To download a host software package, please clink on the following link
* to open the download page in your default browser.
*
* http://firmata.org/wiki/Download
*/
/* This sketch accepts strings and raw sysex messages and echos them back. /* This sketch accepts strings and raw sysex messages and echos them back.
* *
* This example code is in the public domain. * This example code is in the public domain.

View File

@ -1,3 +1,14 @@
/*
* Firmata is a generic protocol for communicating with microcontrollers
* from software on a host computer. It is intended to work with
* any host computer software package.
*
* To download a host software package, please clink on the following link
* to open the download page in your default browser.
*
* http://firmata.org/wiki/Download
*/
/* /*
Copyright (C) 2009 Jeff Hoefs. All rights reserved. Copyright (C) 2009 Jeff Hoefs. All rights reserved.
Copyright (C) 2009 Shigeru Kobayashi. All rights reserved. Copyright (C) 2009 Shigeru Kobayashi. All rights reserved.

View File

@ -1,3 +1,14 @@
/*
* Firmata is a generic protocol for communicating with microcontrollers
* from software on a host computer. It is intended to work with
* any host computer software package.
*
* To download a host software package, please clink on the following link
* to open the download page in your default browser.
*
* http://firmata.org/wiki/Download
*/
/* /*
Copyright (C) 2006-2008 Hans-Christoph Steiner. All rights reserved. Copyright (C) 2006-2008 Hans-Christoph Steiner. All rights reserved.

View File

@ -1,3 +1,14 @@
/*
* Firmata is a generic protocol for communicating with microcontrollers
* from software on a host computer. It is intended to work with
* any host computer software package.
*
* To download a host software package, please clink on the following link
* to open the download page in your default browser.
*
* http://firmata.org/wiki/Download
*/
/* This firmware supports as many servos as possible using the Servo library /* This firmware supports as many servos as possible using the Servo library
* included in Arduino 0017 * included in Arduino 0017
* *

View File

@ -1,3 +1,14 @@
/*
* Firmata is a generic protocol for communicating with microcontrollers
* from software on a host computer. It is intended to work with
* any host computer software package.
*
* To download a host software package, please clink on the following link
* to open the download page in your default browser.
*
* http://firmata.org/wiki/Download
*/
/* Supports as many analog inputs and analog PWM outputs as possible. /* Supports as many analog inputs and analog PWM outputs as possible.
* *
* This example code is in the public domain. * This example code is in the public domain.

View File

@ -1,3 +1,14 @@
/*
* Firmata is a generic protocol for communicating with microcontrollers
* from software on a host computer. It is intended to work with
* any host computer software package.
*
* To download a host software package, please clink on the following link
* to open the download page in your default browser.
*
* http://firmata.org/wiki/Download
*/
/* Supports as many digital inputs and outputs as possible. /* Supports as many digital inputs and outputs as possible.
* *
* This example code is in the public domain. * This example code is in the public domain.

View File

@ -1,5 +1,19 @@
/*
* Firmata is a generic protocol for communicating with microcontrollers
* from software on a host computer. It is intended to work with
* any host computer software package.
*
* To download a host software package, please clink on the following link
* to open the download page in your default browser.
*
* http://firmata.org/wiki/Download
*/
/* /*
Copyright (C) 2006-2008 Hans-Christoph Steiner. All rights reserved. Copyright (C) 2006-2008 Hans-Christoph Steiner. All rights reserved.
Copyright (C) 2010-2011 Paul Stoffregen. All rights reserved.
Copyright (C) 2009 Shigeru Kobayashi. All rights reserved.
Copyright (C) 2009-2011 Jeff Hoefs. All rights reserved.
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
@ -16,8 +30,22 @@
*/ */
#include <Servo.h> #include <Servo.h>
#include <Wire.h>
#include <Firmata.h> #include <Firmata.h>
// move the following defines to 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 I2C_10BIT_ADDRESS_MODE_MASK B00100000
#define MAX_QUERIES 8
#define MINIMUM_SAMPLING_INTERVAL 10
#define REGISTER_NOT_SPECIFIED -1
/*============================================================================== /*==============================================================================
* GLOBAL VARIABLES * GLOBAL VARIABLES
*============================================================================*/ *============================================================================*/
@ -39,12 +67,69 @@ unsigned long currentMillis; // store the current value from millis()
unsigned long previousMillis; // for comparison with currentMillis unsigned long previousMillis; // for comparison with currentMillis
int samplingInterval = 19; // how often to run the main loop (in ms) int samplingInterval = 19; // how often to run the main loop (in ms)
Servo servos[MAX_SERVOS]; /* i2c data */
struct i2c_device_info {
byte addr;
byte reg;
byte bytes;
};
/* for i2c read continuous more */
i2c_device_info query[MAX_QUERIES];
byte i2cRxData[32];
boolean isI2CEnabled = false;
signed char queryIndex = -1;
unsigned int i2cReadDelayTime = 0; // default delay time between i2c read request and Wire.requestFrom()
Servo servos[MAX_SERVOS];
/*============================================================================== /*==============================================================================
* FUNCTIONS * FUNCTIONS
*============================================================================*/ *============================================================================*/
void readAndReportData(byte address, int theRegister, byte numBytes) {
// allow I2C requests that don't require a register read
// for example, some devices using an interrupt pin to signify new data available
// do not always require the register read so upon interrupt you call Wire.requestFrom()
if (theRegister != REGISTER_NOT_SPECIFIED) {
Wire.beginTransmission(address);
#if ARDUINO >= 100
Wire.write((byte)theRegister);
#else
Wire.send((byte)theRegister);
#endif
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); // all bytes are returned in requestFrom
// 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++) {
#if ARDUINO >= 100
i2cRxData[2 + i] = Wire.read();
#else
i2cRxData[2 + i] = Wire.receive();
#endif
}
}
else {
if(numBytes > Wire.available()) {
Firmata.sendString("I2C Read Error: Too many bytes received");
} else {
Firmata.sendString("I2C Read Error: Too few bytes received");
}
}
// send slave address, register and received bytes
Firmata.sendSysex(SYSEX_I2C_REPLY, numBytes + 2, i2cRxData);
}
void outputPort(byte portNumber, byte portValue, byte forceSend) void outputPort(byte portNumber, byte portValue, byte forceSend)
{ {
// pins not configured as INPUT are cleared to zeros // pins not configured as INPUT are cleared to zeros
@ -88,6 +173,11 @@ void checkDigitalInputs(void)
*/ */
void setPinModeCallback(byte pin, int mode) void setPinModeCallback(byte pin, int mode)
{ {
if (pinConfig[pin] == I2C && isI2CEnabled && mode != I2C) {
// disable i2c so pins can be used for other functions
// the following if statements should reconfigure the pins properly
disableI2CPins();
}
if (IS_PIN_SERVO(pin) && mode != SERVO && servos[PIN_TO_SERVO(pin)].attached()) { if (IS_PIN_SERVO(pin) && mode != SERVO && servos[PIN_TO_SERVO(pin)].attached()) {
servos[PIN_TO_SERVO(pin)].detach(); servos[PIN_TO_SERVO(pin)].detach();
} }
@ -138,14 +228,15 @@ void setPinModeCallback(byte pin, int mode)
pinConfig[pin] = SERVO; pinConfig[pin] = SERVO;
if (!servos[PIN_TO_SERVO(pin)].attached()) { if (!servos[PIN_TO_SERVO(pin)].attached()) {
servos[PIN_TO_SERVO(pin)].attach(PIN_TO_DIGITAL(pin)); servos[PIN_TO_SERVO(pin)].attach(PIN_TO_DIGITAL(pin));
} else {
Firmata.sendString("Servo only on pins from 2 to 13");
} }
} }
break; break;
case I2C: case I2C:
pinConfig[pin] = mode; if (IS_PIN_I2C(pin)) {
Firmata.sendString("I2C mode not yet supported"); // mark the pin as i2c
// the user must call I2C_CONFIG to enable I2C for a device
pinConfig[pin] = I2C;
}
break; break;
default: default:
Firmata.sendString("Unknown pin mode"); // TODO: put error msgs in EEPROM Firmata.sendString("Unknown pin mode"); // TODO: put error msgs in EEPROM
@ -232,7 +323,104 @@ void reportDigitalCallback(byte port, int value)
void sysexCallback(byte command, byte argc, byte *argv) void sysexCallback(byte command, byte argc, byte *argv)
{ {
byte mode;
byte slaveAddress;
byte slaveRegister;
byte data;
unsigned int delayTime;
switch(command) { switch(command) {
case I2C_REQUEST:
mode = argv[1] & I2C_READ_WRITE_MODE_MASK;
if (argv[1] & I2C_10BIT_ADDRESS_MODE_MASK) {
Firmata.sendString("10-bit addressing mode is not yet supported");
return;
}
else {
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);
#if ARDUINO >= 100
Wire.write(data);
#else
Wire.send(data);
#endif
}
Wire.endTransmission();
delayMicroseconds(70);
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;
}
queryIndex++;
query[queryIndex].addr = slaveAddress;
query[queryIndex].reg = argv[2] + (argv[3] << 7);
query[queryIndex].bytes = argv[4] + (argv[5] << 7);
break;
case I2C_STOP_READING:
byte queryIndexToSkip;
// if read continuous mode is enabled for only 1 i2c device, disable
// read continuous reporting for that device
if (queryIndex <= 0) {
queryIndex = -1;
} else {
// if read continuous mode is enabled for multiple devices,
// determine which device to stop reading and remove it's data from
// the array, shifiting other array data to fill the space
for (byte i = 0; i < queryIndex + 1; i++) {
if (query[i].addr = slaveAddress) {
queryIndexToSkip = i;
break;
}
}
for (byte i = queryIndexToSkip; i<queryIndex + 1; i++) {
if (i < MAX_QUERIES) {
query[i].addr = query[i+1].addr;
query[i].reg = query[i+1].addr;
query[i].bytes = query[i+1].bytes;
}
}
queryIndex--;
}
break;
default:
break;
}
break;
case I2C_CONFIG:
delayTime = (argv[0] + (argv[1] << 7));
if(delayTime > 0) {
i2cReadDelayTime = delayTime;
}
if (!isI2CEnabled) {
enableI2CPins();
}
break;
case SERVO_CONFIG: case SERVO_CONFIG:
if(argc > 4) { if(argc > 4) {
// these vars are here for clarity, they'll optimized away by the compiler // these vars are here for clarity, they'll optimized away by the compiler
@ -241,7 +429,6 @@ void sysexCallback(byte command, byte argc, byte *argv)
int maxPulse = argv[3] + (argv[4] << 7); int maxPulse = argv[3] + (argv[4] << 7);
if (IS_PIN_SERVO(pin)) { if (IS_PIN_SERVO(pin)) {
// servos are pins from 2 to 13, so offset for array
if (servos[PIN_TO_SERVO(pin)].attached()) if (servos[PIN_TO_SERVO(pin)].attached())
servos[PIN_TO_SERVO(pin)].detach(); servos[PIN_TO_SERVO(pin)].detach();
servos[PIN_TO_SERVO(pin)].attach(PIN_TO_DIGITAL(pin), minPulse, maxPulse); servos[PIN_TO_SERVO(pin)].attach(PIN_TO_DIGITAL(pin), minPulse, maxPulse);
@ -250,10 +437,14 @@ void sysexCallback(byte command, byte argc, byte *argv)
} }
break; break;
case SAMPLING_INTERVAL: case SAMPLING_INTERVAL:
if (argc > 1) if (argc > 1) {
samplingInterval = argv[0] + (argv[1] << 7); samplingInterval = argv[0] + (argv[1] << 7);
else if (samplingInterval < MINIMUM_SAMPLING_INTERVAL) {
Firmata.sendString("Not enough data"); samplingInterval = MINIMUM_SAMPLING_INTERVAL;
}
} else {
//Firmata.sendString("Not enough data");
}
break; break;
case EXTENDED_ANALOG: case EXTENDED_ANALOG:
if (argc > 1) { if (argc > 1) {
@ -285,6 +476,10 @@ void sysexCallback(byte command, byte argc, byte *argv)
Serial.write(SERVO); Serial.write(SERVO);
Serial.write(14); Serial.write(14);
} }
if (IS_PIN_I2C(pin)) {
Serial.write(I2C);
Serial.write(1); // to do: determine appropriate value
}
Serial.write(127); Serial.write(127);
} }
Serial.write(END_SYSEX); Serial.write(END_SYSEX);
@ -315,33 +510,52 @@ void sysexCallback(byte command, byte argc, byte *argv)
} }
} }
void enableI2CPins()
{
byte i;
// is there a faster way to do this? would probaby require importing
// Arduino.h to get SCL and SDA pins
for (i=0; i < TOTAL_PINS; i++) {
if(IS_PIN_I2C(i)) {
// mark pins as i2c so they are ignore in non i2c data requests
setPinModeCallback(i, I2C);
}
}
isI2CEnabled = true;
// is there enough time before the first I2C request to call this here?
Wire.begin();
}
/* disable the i2c pins so they can be used for other functions */
void disableI2CPins() {
isI2CEnabled = false;
// disable read continuous mode for all devices
queryIndex = -1;
// uncomment the following if or when the end() method is added to Wire library
// Wire.end();
}
/*============================================================================== /*==============================================================================
* SETUP() * SETUP()
*============================================================================*/ *============================================================================*/
void setup()
void systemResetCallback()
{ {
byte i; // initialize a defalt state
// TODO: option to load config from EEPROM instead of default
Firmata.setFirmwareVersion(FIRMATA_MAJOR_VERSION, FIRMATA_MINOR_VERSION); if (isI2CEnabled) {
disableI2CPins();
Firmata.attach(ANALOG_MESSAGE, analogWriteCallback); }
Firmata.attach(DIGITAL_MESSAGE, digitalWriteCallback); for (byte i=0; i < TOTAL_PORTS; i++) {
Firmata.attach(REPORT_ANALOG, reportAnalogCallback); reportPINs[i] = false; // by default, reporting off
Firmata.attach(REPORT_DIGITAL, reportDigitalCallback); portConfigInputs[i] = 0; // until activated
Firmata.attach(SET_PIN_MODE, setPinModeCallback);
Firmata.attach(START_SYSEX, sysexCallback);
// TODO: load state from EEPROM here
/* these are initialized to zero by the compiler startup code
for (i=0; i < TOTAL_PORTS; i++) {
reportPINs[i] = false;
portConfigInputs[i] = 0;
previousPINs[i] = 0; previousPINs[i] = 0;
} }
*/ // pins with analog capability default to analog input
for (i=0; i < TOTAL_PINS; i++) { // otherwise, pins default to digital output
for (byte i=0; i < TOTAL_PINS; i++) {
if (IS_PIN_ANALOG(i)) { if (IS_PIN_ANALOG(i)) {
// turns off pullup, configures everything // turns off pullup, configures everything
setPinModeCallback(i, ANALOG); setPinModeCallback(i, ANALOG);
@ -350,16 +564,34 @@ void setup()
setPinModeCallback(i, OUTPUT); setPinModeCallback(i, OUTPUT);
} }
} }
// by defult, do not report any analog inputs // by default, do not report any analog inputs
analogInputsToReport = 0; analogInputsToReport = 0;
Firmata.begin(57600);
/* send digital inputs to set the initial state on the host computer, /* send digital inputs to set the initial state on the host computer,
* since once in the loop(), this firmware will only send on change */ * since once in the loop(), this firmware will only send on change */
for (i=0; i < TOTAL_PORTS; i++) { /*
TODO: this can never execute, since no pins default to digital input
but it will be needed when/if we support EEPROM stored config
for (byte i=0; i < TOTAL_PORTS; i++) {
outputPort(i, readPort(i, portConfigInputs[i]), true); outputPort(i, readPort(i, portConfigInputs[i]), true);
} }
*/
}
void setup()
{
Firmata.setFirmwareVersion(FIRMATA_MAJOR_VERSION, FIRMATA_MINOR_VERSION);
Firmata.attach(ANALOG_MESSAGE, analogWriteCallback);
Firmata.attach(DIGITAL_MESSAGE, digitalWriteCallback);
Firmata.attach(REPORT_ANALOG, reportAnalogCallback);
Firmata.attach(REPORT_DIGITAL, reportDigitalCallback);
Firmata.attach(SET_PIN_MODE, setPinModeCallback);
Firmata.attach(START_SYSEX, sysexCallback);
Firmata.attach(SYSTEM_RESET, systemResetCallback);
Firmata.begin(57600);
systemResetCallback(); // reset to default config
} }
/*============================================================================== /*==============================================================================
@ -394,5 +626,11 @@ void loop()
} }
} }
} }
// report i2c data for all device with read continuous mode enabled
if (queryIndex > -1) {
for (byte i = 0; i < queryIndex + 1; i++) {
readAndReportData(query[i].addr, query[i].reg, query[i].bytes);
}
}
} }
} }

View File

@ -101,7 +101,10 @@ int File::read(void *buf, uint16_t nbyte) {
int File::available() { int File::available() {
if (! _file) return 0; if (! _file) return 0;
return size() - position();
uint32_t n = size() - position();
return n > 0X7FFF ? 0X7FFF : n;
} }
void File::flush() { void File::flush() {

View File

@ -80,7 +80,7 @@ void setup()
// print the type and size of the first FAT-type volume // print the type and size of the first FAT-type volume
long volumesize; uint32_t volumesize;
Serial.print("\nVolume type is FAT"); Serial.print("\nVolume type is FAT");
Serial.println(volume.fatType(), DEC); Serial.println(volume.fatType(), DEC);
Serial.println(); Serial.println();

View File

@ -1,50 +0,0 @@
#include <SoftwareSerial.h>
SoftwareSerial ss(2, 3);
SoftwareSerial ss2(4, 5);
/* This sample shows how to correctly process received data
on two different "soft" serial ports. Here we listen on
the first port (ss) until we receive a '?' character. Then
we begin listening on the other soft port.
*/
void setup()
{
// Start the HW serial port
Serial.begin(57600);
// Start each soft serial port
ss.begin(4800);
ss2.begin(4800);
// By default, the most recently "begun" port is listening.
// We want to listen on ss, so let's explicitly select it.
ss.listen();
// Simply wait for a ? character to come down the pipe
Serial.println("Data from the first port: ");
char c = 0;
do
if (ss.available())
{
c = (char)ss.read();
Serial.print(c);
}
while (c != '?');
// Now listen on the second port
ss2.listen();
Serial.println("Data from the second port: ");
}
void loop()
{
if (ss2.available())
{
char c = (char)ss2.read();
Serial.print(c);
}
}

View File

@ -6,28 +6,19 @@ The boards can be assembled by hand or purchased preassembled; the open-source
IDE can be downloaded for free. IDE can be downloaded for free.
For more information, see the website at: http://www.arduino.cc/ For more information, see the website at: http://www.arduino.cc/
or the forums at: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl or the forums at: http://arduino.cc/forum/
To report a bug or a make a suggestions, go to: To report a bug in the software, go to:
[hardware] http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?board=hwbugs http://code.google.com/p/arduino/issues/list
[software] http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?board=swbugs
For other suggestions, use the forum:
http://arduino.cc/forum/index.php/board,21.0.html
INSTALLATION INSTALLATION
Detailed instructions are in reference/Guide_Windows.html and Detailed instructions are in reference/Guide_Windows.html and
reference/Guide_MacOSX.html. For Linux, see the Arduino playground: reference/Guide_MacOSX.html. For Linux, see the Arduino playground:
http://www.arduino.cc/playground/Learning/Linux http://www.arduino.cc/playground/Learning/Linux
If you are using a USB Arduino, you will need to install the drivers for the
FTDI chip on the board. These can be found in the drivers/ directory.
* On Windows, plug in the Arduino board and point the Windows Add Hardware
wizard to the drivers/FTDI USB Drivers sub-directory of the Arduino
application directory.
* On the Mac, install the FTDIUSBSerialDriver_10_4_10_5_10_6.mpkg package.
* On Linux, drivers are included in kernel versions 2.4.20 or greater.
CREDITS CREDITS
Arduino is an open source project, supported by many. Arduino is an open source project, supported by many.
@ -37,6 +28,5 @@ Gianluca Martino, and David A. Mellis.
Arduino uses the GNU avr-gcc toolchain, avrdude, avr-libc, and code from Arduino uses the GNU avr-gcc toolchain, avrdude, avr-libc, and code from
Processing and Wiring. Processing and Wiring.
Icon designed by ToDo: http://www.todo.to.it/ Icon and about image designed by ToDo: http://www.todo.to.it/
"About" image created by Thomas Glaser (envis precisely).