mirror of https://github.com/noisymime/Arduino.git
Pre-merge upstream Arduino
This commit is contained in:
commit
b276a75d13
|
@ -0,0 +1,8 @@
|
|||
app/bin/
|
||||
app/pde.jar
|
||||
build/macosx/work/
|
||||
core/bin/
|
||||
core/core.jar
|
||||
build/macosx/arduino.xcworkspace/contents.xcworkspacedata
|
||||
|
||||
build/macosx/arduino.xcworkspace/xcuserdata/mellis.xcuserdatad/UserInterfaceState.xcuserstate
|
|
@ -46,9 +46,9 @@ import static processing.app.I18n._;
|
|||
* files and images, etc) that comes from that.
|
||||
*/
|
||||
public class Base {
|
||||
public static final int REVISION = 100;
|
||||
public static final int REVISION = 101;
|
||||
/** This might be replaced by main() if there's a lib/version.txt file. */
|
||||
static String VERSION_NAME = "0100";
|
||||
static String VERSION_NAME = "0101";
|
||||
/** Set true if this a proper release rather than a numbered revision. */
|
||||
static public boolean RELEASE = false;
|
||||
|
||||
|
@ -171,6 +171,9 @@ public class Base {
|
|||
// run static initialization that grabs all the prefs
|
||||
Preferences.init(null);
|
||||
|
||||
// load the I18n module for internationalization
|
||||
I18n.init(Preferences.get("editor.languages.current"));
|
||||
|
||||
// setup the theme coloring fun
|
||||
Theme.init();
|
||||
|
||||
|
@ -1535,12 +1538,12 @@ public class Base {
|
|||
|
||||
|
||||
static public String getAvrBasePath() {
|
||||
if(Base.isLinux()) {
|
||||
return ""; // avr tools are installed system-wide and in the path
|
||||
} else {
|
||||
return getHardwarePath() + File.separator + "tools" +
|
||||
File.separator + "avr" + File.separator + "bin" + File.separator;
|
||||
}
|
||||
String path = getHardwarePath() + File.separator + "tools" +
|
||||
File.separator + "avr" + File.separator + "bin" + File.separator;
|
||||
if (Base.isLinux() && !(new File(path)).exists()) {
|
||||
return ""; // use distribution provided avr tools if bundled tools missing
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -264,7 +264,9 @@ public class Editor extends JFrame implements RunnerListener {
|
|||
splitPane.setDividerSize(dividerSize);
|
||||
}
|
||||
|
||||
splitPane.setMinimumSize(new Dimension(600, 400));
|
||||
// the following changed from 600, 400 for netbooks
|
||||
// http://code.google.com/p/arduino/issues/detail?id=52
|
||||
splitPane.setMinimumSize(new Dimension(600, 100));
|
||||
box.add(splitPane);
|
||||
|
||||
// hopefully these are no longer needed w/ swing
|
||||
|
@ -288,19 +290,9 @@ public class Editor extends JFrame implements RunnerListener {
|
|||
setPlacement(location);
|
||||
|
||||
|
||||
// If the window is resized too small this will resize it again to the
|
||||
// minimums. Adapted by Chris Lonnen from comments here:
|
||||
// http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4320050
|
||||
// as a fix for http://dev.processing.org/bugs/show_bug.cgi?id=25
|
||||
final int minW = Preferences.getInteger("editor.window.width.min");
|
||||
final int minH = Preferences.getInteger("editor.window.height.min");
|
||||
addComponentListener(new java.awt.event.ComponentAdapter() {
|
||||
public void componentResized(ComponentEvent event) {
|
||||
setSize((getWidth() < minW) ? minW : getWidth(),
|
||||
(getHeight() < minH) ? minH : getHeight());
|
||||
}
|
||||
});
|
||||
|
||||
// Set the minimum size for the editor window
|
||||
setMinimumSize(new Dimension(Preferences.getInteger("editor.window.width.min"),
|
||||
Preferences.getInteger("editor.window.height.min")));
|
||||
// System.out.println("t3");
|
||||
|
||||
// Bring back the general options for the editor
|
||||
|
@ -1135,7 +1127,11 @@ public class Editor extends JFrame implements RunnerListener {
|
|||
undoItem.addActionListener(undoAction = new UndoAction());
|
||||
menu.add(undoItem);
|
||||
|
||||
redoItem = newJMenuItem(_("Redo"), 'Y');
|
||||
if (!Base.isMacOS()) {
|
||||
redoItem = newJMenuItem(_("Redo"), 'Y');
|
||||
} else {
|
||||
redoItem = newJMenuItemShift(_("Redo"), 'Z');
|
||||
}
|
||||
redoItem.addActionListener(redoAction = new RedoAction());
|
||||
menu.add(redoItem);
|
||||
|
||||
|
@ -1247,14 +1243,33 @@ public class Editor extends JFrame implements RunnerListener {
|
|||
item.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (find != null) {
|
||||
//find.find(true);
|
||||
//FindReplace find = new FindReplace(Editor.this); //.show();
|
||||
find.find(true);
|
||||
find.findNext();
|
||||
}
|
||||
}
|
||||
});
|
||||
menu.add(item);
|
||||
|
||||
item = newJMenuItemShift(_("Find Previous"), 'G');
|
||||
item.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (find != null) {
|
||||
find.findPrevious();
|
||||
}
|
||||
}
|
||||
});
|
||||
menu.add(item);
|
||||
|
||||
item = newJMenuItem(_("Use Selection For Find"), 'E');
|
||||
item.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (find == null) {
|
||||
find = new FindReplace(Editor.this);
|
||||
}
|
||||
find.setFindText( getSelectedText() );
|
||||
}
|
||||
});
|
||||
menu.add(item);
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
|
|
|
@ -122,6 +122,14 @@ public class EditorListener {
|
|||
}
|
||||
}
|
||||
|
||||
if ((event.getModifiers() & KeyEvent.CTRL_MASK) != 0) {
|
||||
// Consume ctrl-m(carriage return) keypresses
|
||||
if (code == KeyEvent.VK_M) {
|
||||
event.consume(); // does nothing
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if ((event.getModifiers() & KeyEvent.META_MASK) != 0) {
|
||||
//event.consume(); // does nothing
|
||||
return false;
|
||||
|
|
|
@ -46,8 +46,9 @@ import javax.swing.*;
|
|||
*/
|
||||
public class FindReplace extends JFrame implements ActionListener {
|
||||
|
||||
static final int BIG = 13;
|
||||
static final int EDGE = Base.isMacOS() ? 20 : 13;
|
||||
static final int SMALL = 6;
|
||||
static final int BUTTONGAP = 12; // 12 is correct for Mac, other numbers may be required for other platofrms
|
||||
|
||||
Editor editor;
|
||||
|
||||
|
@ -59,14 +60,14 @@ public class FindReplace extends JFrame implements ActionListener {
|
|||
JButton replaceButton;
|
||||
JButton replaceAllButton;
|
||||
JButton replaceFindButton;
|
||||
JButton previousButton;
|
||||
JButton findButton;
|
||||
|
||||
JCheckBox ignoreCaseBox;
|
||||
static boolean ignoreCase = true;
|
||||
|
||||
/// true when there's something selected in the editor
|
||||
boolean found;
|
||||
|
||||
JCheckBox wrapAroundBox;
|
||||
static boolean wrapAround = true;
|
||||
|
||||
public FindReplace(Editor editor) {
|
||||
super("Find");
|
||||
|
@ -77,23 +78,66 @@ public class FindReplace extends JFrame implements ActionListener {
|
|||
pain.setLayout(null);
|
||||
|
||||
JLabel findLabel = new JLabel(_("Find:"));
|
||||
Dimension d0 = findLabel.getPreferredSize();
|
||||
JLabel replaceLabel = new JLabel(_("Replace with:"));
|
||||
Dimension d1 = replaceLabel.getPreferredSize();
|
||||
Dimension labelDimension = replaceLabel.getPreferredSize();
|
||||
|
||||
pain.add(findLabel);
|
||||
pain.add(replaceLabel);
|
||||
|
||||
pain.add(findField = new JTextField(20));
|
||||
pain.add(replaceField = new JTextField(20));
|
||||
Dimension d2 = findField.getPreferredSize();
|
||||
int fieldHeight = findField.getPreferredSize().height;
|
||||
|
||||
if (findString != null) findField.setText(findString);
|
||||
if (replaceString != null) replaceField.setText(replaceString);
|
||||
//System.out.println("setting find str to " + findString);
|
||||
//findField.requestFocusInWindow();
|
||||
|
||||
//pain.setDefault
|
||||
ignoreCaseBox = new JCheckBox(_("Ignore Case"));
|
||||
ignoreCaseBox.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
ignoreCase = ignoreCaseBox.isSelected();
|
||||
}
|
||||
});
|
||||
ignoreCaseBox.setSelected(ignoreCase);
|
||||
pain.add(ignoreCaseBox);
|
||||
|
||||
wrapAroundBox = new JCheckBox(_("Wrap Around"));
|
||||
wrapAroundBox.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
wrapAround = wrapAroundBox.isSelected();
|
||||
}
|
||||
});
|
||||
wrapAroundBox.setSelected(wrapAround);
|
||||
pain.add(wrapAroundBox);
|
||||
|
||||
JPanel buttons = new JPanel();
|
||||
|
||||
buttons.setLayout(new FlowLayout(FlowLayout.CENTER,BUTTONGAP,0));
|
||||
|
||||
// ordering is different on mac versus pc
|
||||
if (Base.isMacOS()) {
|
||||
buttons.add(replaceAllButton = new JButton(_("Replace All")));
|
||||
buttons.add(replaceButton = new JButton(_("Replace")));
|
||||
buttons.add(replaceFindButton = new JButton(_("Replace & Find")));
|
||||
buttons.add(previousButton = new JButton(_("Previous")));
|
||||
buttons.add(findButton = new JButton(_("Find")));
|
||||
|
||||
} else {
|
||||
buttons.add(findButton = new JButton(_("Find")));
|
||||
buttons.add(previousButton = new JButton(_("Previous"))); // is this the right position for non-Mac?
|
||||
buttons.add(replaceFindButton = new JButton(_("Replace & Find")));
|
||||
buttons.add(replaceButton = new JButton(_("Replace")));
|
||||
buttons.add(replaceAllButton = new JButton(_("Replace All")));
|
||||
}
|
||||
pain.add(buttons);
|
||||
|
||||
// to fix ugliness.. normally macosx java 1.3 puts an
|
||||
// ugly white border around this object, so turn it off.
|
||||
if (Base.isMacOS()) {
|
||||
buttons.setBorder(null);
|
||||
}
|
||||
|
||||
/*
|
||||
findField.addFocusListener(new FocusListener() {
|
||||
public void focusGained(FocusEvent e) {
|
||||
|
@ -109,92 +153,74 @@ public class FindReplace extends JFrame implements ActionListener {
|
|||
});
|
||||
*/
|
||||
|
||||
// +1 since it's better to tend downwards
|
||||
int yoff = (1 + d2.height - d1.height) / 2;
|
||||
Dimension buttonsDimension = buttons.getPreferredSize();
|
||||
int visibleButtonWidth = buttonsDimension.width - 2 * BUTTONGAP;
|
||||
int fieldWidth = visibleButtonWidth - (labelDimension.width + SMALL);
|
||||
|
||||
findLabel.setBounds(BIG + (d1.width-d0.width) + yoff, BIG,
|
||||
d1.width, d1.height);
|
||||
replaceLabel.setBounds(BIG, BIG + d2.height + SMALL + yoff,
|
||||
d1.width, d1.height);
|
||||
// +1 since it's better to tend downwards
|
||||
int yoff = (1 + fieldHeight - labelDimension.height) / 2;
|
||||
|
||||
//ignoreCase = true;
|
||||
ignoreCaseBox = new JCheckBox(_("Ignore Case"));
|
||||
ignoreCaseBox.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
ignoreCase = ignoreCaseBox.isSelected();
|
||||
}
|
||||
});
|
||||
ignoreCaseBox.setSelected(ignoreCase);
|
||||
pain.add(ignoreCaseBox);
|
||||
int ypos = EDGE;
|
||||
|
||||
int labelWidth = findLabel.getPreferredSize().width;
|
||||
findLabel.setBounds(EDGE + (labelDimension.width-labelWidth), ypos + yoff, // + yoff was added to the wrong field
|
||||
labelWidth, labelDimension.height);
|
||||
findField.setBounds(EDGE + labelDimension.width + SMALL, ypos,
|
||||
fieldWidth, fieldHeight);
|
||||
|
||||
ypos += fieldHeight + SMALL;
|
||||
|
||||
labelWidth = replaceLabel.getPreferredSize().width;
|
||||
replaceLabel.setBounds(EDGE + (labelDimension.width-labelWidth), ypos + yoff,
|
||||
labelWidth, labelDimension.height);
|
||||
replaceField.setBounds(EDGE + labelDimension.width + SMALL, ypos,
|
||||
fieldWidth, fieldHeight);
|
||||
|
||||
//
|
||||
ypos += fieldHeight + SMALL;
|
||||
|
||||
JPanel buttons = new JPanel();
|
||||
buttons.setLayout(new FlowLayout());
|
||||
ignoreCaseBox.setBounds(EDGE + labelDimension.width + SMALL,
|
||||
ypos,
|
||||
(fieldWidth-SMALL)/2, fieldHeight);
|
||||
|
||||
// ordering is different on mac versus pc
|
||||
if (Base.isMacOS()) {
|
||||
buttons.add(replaceAllButton = new JButton(_("Replace All")));
|
||||
buttons.add(replaceButton = new JButton(_("Replace")));
|
||||
buttons.add(replaceFindButton = new JButton(_("Replace & Find")));
|
||||
buttons.add(findButton = new JButton(_("Find")));
|
||||
wrapAroundBox.setBounds(EDGE + labelDimension.width + SMALL + (fieldWidth-SMALL)/2 + SMALL,
|
||||
ypos,
|
||||
(fieldWidth-SMALL)/2, fieldHeight);
|
||||
|
||||
} else {
|
||||
buttons.add(findButton = new JButton(_("Find")));
|
||||
buttons.add(replaceFindButton = new JButton(_("Replace & Find")));
|
||||
buttons.add(replaceButton = new JButton(_("Replace")));
|
||||
buttons.add(replaceAllButton = new JButton(_("Replace All")));
|
||||
}
|
||||
pain.add(buttons);
|
||||
ypos += fieldHeight + SMALL;
|
||||
|
||||
// to fix ugliness.. normally macosx java 1.3 puts an
|
||||
// ugly white border around this object, so turn it off.
|
||||
if (Base.isMacOS()) {
|
||||
buttons.setBorder(null);
|
||||
}
|
||||
buttons.setBounds(EDGE-BUTTONGAP, ypos,
|
||||
buttonsDimension.width, buttonsDimension.height);
|
||||
|
||||
Dimension d3 = buttons.getPreferredSize();
|
||||
//buttons.setBounds(BIG, BIG + d2.height*2 + SMALL + BIG,
|
||||
buttons.setBounds(BIG, BIG + d2.height*3 + SMALL*2 + BIG,
|
||||
d3.width, d3.height);
|
||||
ypos += buttonsDimension.height + EDGE;
|
||||
|
||||
//
|
||||
// Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
|
||||
|
||||
findField.setBounds(BIG + d1.width + SMALL, BIG,
|
||||
d3.width - (d1.width + SMALL), d2.height);
|
||||
replaceField.setBounds(BIG + d1.width + SMALL, BIG + d2.height + SMALL,
|
||||
d3.width - (d1.width + SMALL), d2.height);
|
||||
int wide = visibleButtonWidth + EDGE*2;
|
||||
int high = ypos; // butt.y + butt.height + EDGE*2 + SMALL;
|
||||
|
||||
ignoreCaseBox.setBounds(BIG + d1.width + SMALL,
|
||||
BIG + d2.height*2 + SMALL*2,
|
||||
d3.width, d2.height);
|
||||
pack();
|
||||
Insets insets = getInsets();
|
||||
//System.out.println("Insets = " + insets);
|
||||
setSize(wide + insets.left + insets.right,high + insets.top + insets.bottom);
|
||||
|
||||
//
|
||||
setLocationRelativeTo( null ); // center
|
||||
// setBounds((screen.width - wide) / 2, (screen.height - high) / 2, wide, high);
|
||||
|
||||
replaceButton.addActionListener(this);
|
||||
replaceAllButton.addActionListener(this);
|
||||
replaceFindButton.addActionListener(this);
|
||||
findButton.addActionListener(this);
|
||||
previousButton.addActionListener(this);
|
||||
|
||||
// you mustn't replace what you haven't found, my son
|
||||
replaceButton.setEnabled(false);
|
||||
replaceFindButton.setEnabled(false);
|
||||
|
||||
// so that typing will go straight to this field
|
||||
//findField.requestFocus();
|
||||
// semantics of replace are "replace the current selection with the replace field"
|
||||
// so whether we have found before or not is irrelevent
|
||||
// replaceButton.setEnabled(false);
|
||||
// replaceFindButton.setEnabled(false);
|
||||
|
||||
// make the find button the blinky default
|
||||
getRootPane().setDefaultButton(findButton);
|
||||
|
||||
Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
|
||||
|
||||
int wide = d3.width + BIG*2;
|
||||
Rectangle butt = buttons.getBounds(); // how big is your butt?
|
||||
int high = butt.y + butt.height + BIG*2 + SMALL;
|
||||
|
||||
setBounds((screen.width - wide) / 2,
|
||||
(screen.height - high) / 2, wide, high);
|
||||
|
||||
setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
|
||||
addWindowListener(new WindowAdapter() {
|
||||
public void windowClosing(WindowEvent e) {
|
||||
|
@ -245,11 +271,13 @@ public class FindReplace extends JFrame implements ActionListener {
|
|||
Object source = e.getSource();
|
||||
|
||||
if (source == findButton) {
|
||||
find(true);
|
||||
findNext();
|
||||
|
||||
} else if (source == previousButton) {
|
||||
findPrevious();
|
||||
|
||||
} else if (source == replaceFindButton) {
|
||||
replace();
|
||||
find(true);
|
||||
replaceAndFindNext();
|
||||
|
||||
} else if (source == replaceButton) {
|
||||
replace();
|
||||
|
@ -260,50 +288,54 @@ public class FindReplace extends JFrame implements ActionListener {
|
|||
}
|
||||
|
||||
|
||||
// look for the next instance of the find string
|
||||
// to be found later than the current caret selection
|
||||
|
||||
// look for the next instance of the find string to be found
|
||||
// once found, select it (and go to that line)
|
||||
|
||||
public void find(boolean wrap) {
|
||||
// in case search len is zero,
|
||||
// otherwise replace all will go into an infinite loop
|
||||
found = false;
|
||||
private boolean find(boolean wrap,boolean backwards ) {
|
||||
|
||||
String search = findField.getText();
|
||||
//System.out.println("finding for " + search + " " + findString);
|
||||
// this will catch "find next" being called when no search yet
|
||||
if (search.length() == 0) return;
|
||||
if (search.length() == 0) return false;
|
||||
|
||||
String text = editor.getText();
|
||||
|
||||
if (ignoreCase) {
|
||||
search = search.toLowerCase();
|
||||
search = search.toLowerCase();
|
||||
text = text.toLowerCase();
|
||||
}
|
||||
|
||||
//int selectionStart = editor.textarea.getSelectionStart();
|
||||
int selectionEnd = editor.getSelectionStop();
|
||||
int nextIndex;
|
||||
if (!backwards) {
|
||||
//int selectionStart = editor.textarea.getSelectionStart();
|
||||
int selectionEnd = editor.getSelectionStop();
|
||||
|
||||
int nextIndex = text.indexOf(search, selectionEnd);
|
||||
if (nextIndex == -1) {
|
||||
if (wrap) {
|
||||
nextIndex = text.indexOf(search, selectionEnd);
|
||||
if (wrap && nextIndex == -1) {
|
||||
// if wrapping, a second chance is ok, start from beginning
|
||||
nextIndex = text.indexOf(search, 0);
|
||||
}
|
||||
} else {
|
||||
//int selectionStart = editor.textarea.getSelectionStart();
|
||||
int selectionStart = editor.getSelectionStart()-1;
|
||||
|
||||
if (nextIndex == -1) {
|
||||
found = false;
|
||||
replaceButton.setEnabled(false);
|
||||
replaceFindButton.setEnabled(false);
|
||||
//Toolkit.getDefaultToolkit().beep();
|
||||
return;
|
||||
if ( selectionStart >= 0 ) {
|
||||
nextIndex = text.lastIndexOf(search, selectionStart);
|
||||
} else {
|
||||
nextIndex = -1;
|
||||
}
|
||||
if (wrap && nextIndex == -1) {
|
||||
// if wrapping, a second chance is ok, start from the end
|
||||
nextIndex = text.lastIndexOf(search);
|
||||
}
|
||||
}
|
||||
found = true;
|
||||
replaceButton.setEnabled(true);
|
||||
replaceFindButton.setEnabled(true);
|
||||
editor.setSelection(nextIndex, nextIndex + search.length());
|
||||
|
||||
if (nextIndex != -1) {
|
||||
editor.setSelection(nextIndex, nextIndex + search.length());
|
||||
} else {
|
||||
//Toolkit.getDefaultToolkit().beep();
|
||||
}
|
||||
return nextIndex != -1;
|
||||
}
|
||||
|
||||
|
||||
|
@ -312,28 +344,18 @@ public class FindReplace extends JFrame implements ActionListener {
|
|||
* replacement text field.
|
||||
*/
|
||||
public void replace() {
|
||||
if (!found) return; // don't replace if nothing found
|
||||
|
||||
// check to see if the document has wrapped around
|
||||
// otherwise this will cause an infinite loop
|
||||
String sel = editor.getSelectedText();
|
||||
if (sel.equals(replaceField.getText())) {
|
||||
found = false;
|
||||
replaceButton.setEnabled(false);
|
||||
replaceFindButton.setEnabled(false);
|
||||
return;
|
||||
}
|
||||
|
||||
editor.setSelectedText(replaceField.getText());
|
||||
//editor.setSketchModified(true);
|
||||
//editor.sketch.setCurrentModified(true);
|
||||
editor.getSketch().setModified(true); // TODO is this necessary?
|
||||
|
||||
// don't allow a double replace
|
||||
replaceButton.setEnabled(false);
|
||||
replaceFindButton.setEnabled(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace the current selection with whatever's in the
|
||||
* replacement text field, and then find the next match
|
||||
*/
|
||||
public void replaceAndFindNext() {
|
||||
replace();
|
||||
findNext();
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace everything that matches by doing find and replace
|
||||
|
@ -343,9 +365,35 @@ public class FindReplace extends JFrame implements ActionListener {
|
|||
// move to the beginning
|
||||
editor.setSelection(0, 0);
|
||||
|
||||
do {
|
||||
find(false);
|
||||
replace();
|
||||
} while (found);
|
||||
boolean foundAtLeastOne = false;
|
||||
while ( true ) {
|
||||
if ( find(false,false) ) {
|
||||
foundAtLeastOne = true;
|
||||
replace();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( !foundAtLeastOne ) {
|
||||
Toolkit.getDefaultToolkit().beep();
|
||||
}
|
||||
}
|
||||
|
||||
public void setFindText( String t ) {
|
||||
findField.setText( t );
|
||||
findString = t;
|
||||
}
|
||||
|
||||
public void findNext() {
|
||||
if ( !find( wrapAround, false ) ) {
|
||||
Toolkit.getDefaultToolkit().beep();
|
||||
}
|
||||
}
|
||||
|
||||
public void findPrevious() {
|
||||
if ( !find( wrapAround, true ) ) {
|
||||
Toolkit.getDefaultToolkit().beep();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -12,11 +12,25 @@
|
|||
*/
|
||||
|
||||
package processing.app;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Locale.*;
|
||||
import java.text.MessageFormat;
|
||||
|
||||
public class I18n {
|
||||
// start using current locale but still allow using the dropdown list later
|
||||
private static ResourceBundle i18n = ResourceBundle.getBundle("processing.app.Resources");
|
||||
public static Locale locale;
|
||||
|
||||
static protected void init (String language) {
|
||||
// there might be a null pointer exception ... most likely will never happen but the jvm gets mad
|
||||
try {
|
||||
if (language == null || language.trim().length() == 0) locale = Locale.getDefault();
|
||||
else locale = new Locale(language);
|
||||
i18n = ResourceBundle.getBundle("processing.app.Resources", locale);
|
||||
} catch (java.lang.NullPointerException e) {
|
||||
}
|
||||
}
|
||||
|
||||
public static String _(String s) {
|
||||
try {
|
||||
|
|
|
@ -80,6 +80,51 @@ public class Preferences {
|
|||
static final String PROMPT_OK = _("OK");
|
||||
static final String PROMPT_BROWSE = _("Browse");
|
||||
|
||||
String[] languages = {
|
||||
_("System Default"),
|
||||
"Català" + " (" + _("Catalan") + ")",
|
||||
"简体中文" + " (" + _("Chinese Simplified") + ")",
|
||||
"繁體中文" + " (" + _("Chinese Traditional") + ")",
|
||||
"Dansk" + " (" + _("Danish") + ")",
|
||||
"Nederlands" + " (" + _("Dutch") + ")",
|
||||
"English" + " (" + _("English") + ")",
|
||||
"Français" + " (" + _("French") + ")",
|
||||
"Pilipino" + " (" + _("Filipino") + ")",
|
||||
"Galego" + " (" + _("Galician") + ")",
|
||||
"Deutsch" + " (" + _("German") + ")",
|
||||
"ελληνικά" + " (" + _("Greek") + ")",
|
||||
"Magyar" + " (" + _("Hungarian") + ")",
|
||||
"Italiano" + " (" + _("Italian") + ")",
|
||||
"日本語" + " (" + _("Japanese") + ")",
|
||||
"Latviešu" + " (" + _("Latvian") + ")",
|
||||
"فارسی" + " (" + _("Persian") + ")",
|
||||
"Português" + " (" + _("Portuguese") + ")",
|
||||
"Română" + " (" + _("Romanian") + ")",
|
||||
"Русский" + " (" + _("Russian") + ")",
|
||||
"Español" + " (" + _("Spanish") + ")"};
|
||||
String[] languagesISO = {
|
||||
"",
|
||||
"ca",
|
||||
"zh_cn",
|
||||
"zh_tw",
|
||||
"da",
|
||||
"nl",
|
||||
"en",
|
||||
"fr",
|
||||
"tl",
|
||||
"gl",
|
||||
"de",
|
||||
"el",
|
||||
"hu",
|
||||
"it",
|
||||
"ja",
|
||||
"lv",
|
||||
"fa",
|
||||
"pt_br",
|
||||
"ro",
|
||||
"ru",
|
||||
"es"};
|
||||
|
||||
/**
|
||||
* Standardized width for buttons. Mac OS X 10.3 wants 70 as its default,
|
||||
* Windows XP needs 66, and my Ubuntu machine needs 80+, so 80 seems proper.
|
||||
|
@ -117,6 +162,7 @@ public class Preferences {
|
|||
JCheckBox exportSeparateBox;
|
||||
JCheckBox verboseCompilationBox;
|
||||
JCheckBox verboseUploadBox;
|
||||
JCheckBox verifyUploadBox;
|
||||
JCheckBox externalEditorBox;
|
||||
JCheckBox memoryOverrideBox;
|
||||
JTextField memoryField;
|
||||
|
@ -124,6 +170,7 @@ public class Preferences {
|
|||
JTextField fontSizeField;
|
||||
JCheckBox updateExtensionBox;
|
||||
JCheckBox autoAssociateBox;
|
||||
JComboBox comboLanguage;
|
||||
|
||||
|
||||
// the calling editor, so updates can be applied
|
||||
|
@ -278,9 +325,25 @@ public class Preferences {
|
|||
top += vmax + GUI_BETWEEN;
|
||||
|
||||
|
||||
// Preferred language: [ ] (requires restart of Arduino)
|
||||
Container box = Box.createHorizontalBox();
|
||||
label = new JLabel(_("Editor language: "));
|
||||
box.add(label);
|
||||
comboLanguage = new JComboBox(languages);
|
||||
comboLanguage.setSelectedIndex((Arrays.asList(languagesISO)).indexOf(Preferences.get("editor.languages.current")));
|
||||
box.add(comboLanguage);
|
||||
label = new JLabel(_(" (requires restart of Arduino)"));
|
||||
box.add(label);
|
||||
pain.add(box);
|
||||
d = box.getPreferredSize();
|
||||
box.setForeground(Color.gray);
|
||||
box.setBounds(left, top, d.width, d.height);
|
||||
right = Math.max(right, left + d.width);
|
||||
top += d.height + GUI_BETWEEN;
|
||||
|
||||
// Editor font size [ ]
|
||||
|
||||
Container box = Box.createHorizontalBox();
|
||||
box = Box.createHorizontalBox();
|
||||
label = new JLabel(_("Editor font size: "));
|
||||
box.add(label);
|
||||
fontSizeField = new JTextField(4);
|
||||
|
@ -308,8 +371,16 @@ public class Preferences {
|
|||
d = box.getPreferredSize();
|
||||
box.setBounds(left, top, d.width, d.height);
|
||||
top += d.height + GUI_BETWEEN;
|
||||
|
||||
|
||||
// [ ] Verify code after upload
|
||||
|
||||
verifyUploadBox = new JCheckBox(_("Verify code after upload"));
|
||||
pain.add(verifyUploadBox);
|
||||
d = verifyUploadBox.getPreferredSize();
|
||||
verifyUploadBox.setBounds(left, top, d.width + 10, d.height);
|
||||
right = Math.max(right, left + d.width);
|
||||
top += d.height + GUI_BETWEEN;
|
||||
|
||||
// [ ] Use external editor
|
||||
|
||||
externalEditorBox = new JCheckBox(_("Use external editor"));
|
||||
|
@ -350,7 +421,6 @@ public class Preferences {
|
|||
top += d.height + GUI_BETWEEN;
|
||||
}
|
||||
|
||||
|
||||
// More preferences are in the ...
|
||||
|
||||
label = new JLabel(_("More preferences can be edited directly in the file"));
|
||||
|
@ -491,7 +561,8 @@ public class Preferences {
|
|||
// put each of the settings into the table
|
||||
setBoolean("build.verbose", verboseCompilationBox.isSelected());
|
||||
setBoolean("upload.verbose", verboseUploadBox.isSelected());
|
||||
|
||||
setBoolean("upload.verify", verifyUploadBox.isSelected());
|
||||
|
||||
// setBoolean("sketchbook.closing_last_window_quits",
|
||||
// closingLastQuitsBox.isSelected());
|
||||
//setBoolean("sketchbook.prompt", sketchPromptBox.isSelected());
|
||||
|
@ -538,6 +609,11 @@ public class Preferences {
|
|||
|
||||
setBoolean("editor.update_extension", updateExtensionBox.isSelected());
|
||||
|
||||
// adds the selected language to the preferences file
|
||||
Object newItem = comboLanguage.getSelectedItem();
|
||||
int pos = (Arrays.asList(languages)).indexOf(newItem.toString()); // position in the languages array
|
||||
set("editor.languages.current",(Arrays.asList(languagesISO)).get(pos));
|
||||
|
||||
editor.applyPreferences();
|
||||
}
|
||||
|
||||
|
@ -548,6 +624,7 @@ public class Preferences {
|
|||
// set all settings entry boxes to their actual status
|
||||
verboseCompilationBox.setSelected(getBoolean("build.verbose"));
|
||||
verboseUploadBox.setSelected(getBoolean("upload.verbose"));
|
||||
verifyUploadBox.setSelected(getBoolean("upload.verify"));
|
||||
|
||||
//closingLastQuitsBox.
|
||||
// setSelected(getBoolean("sketchbook.closing_last_window_quits"));
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -834,6 +834,17 @@ public class JEditTextArea extends JComponent
|
|||
return lineElement.getEndOffset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the end offset of the specified line, but not past the end of the text
|
||||
* @param line The line
|
||||
* @return The end offset of the specified line, safe to use for a selection, or -1 if the line is
|
||||
* invalid.
|
||||
*/
|
||||
public int getSafeLineStopOffset(int line)
|
||||
{
|
||||
return Math.min(getLineStopOffset(line),getDocumentLength());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the length of the specified line.
|
||||
* @param line The line
|
||||
|
@ -1144,7 +1155,7 @@ public class JEditTextArea extends JComponent
|
|||
{
|
||||
throw new IllegalArgumentException("Bounds out of"
|
||||
+ " range: " + newStart + "," +
|
||||
newEnd);
|
||||
newEnd + " [" + getDocumentLength() + "]");
|
||||
}
|
||||
|
||||
// If the new position is the same as the old, we don't
|
||||
|
@ -1201,6 +1212,86 @@ public class JEditTextArea extends JComponent
|
|||
// getLineOfOffset(end));
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isWordCharacter( char ch, String noWordSep )
|
||||
{
|
||||
return Character.isLetterOrDigit(ch) || ch=='_' || noWordSep.indexOf(ch) != -1;
|
||||
}
|
||||
|
||||
protected void setNewSelectionWord( int line, int offset )
|
||||
{
|
||||
if (getLineLength(line) == 0) {
|
||||
newSelectionStart = getLineStartOffset(line);
|
||||
newSelectionEnd = newSelectionStart;
|
||||
return;
|
||||
}
|
||||
|
||||
String noWordSep = (String)document.getProperty("noWordSep");
|
||||
if(noWordSep == null)
|
||||
noWordSep = "";
|
||||
|
||||
String lineText = getLineText(line);
|
||||
|
||||
int wordStart = 0;
|
||||
int wordEnd = lineText.length();
|
||||
|
||||
char ch = lineText.charAt(Math.max(0,offset - 1));
|
||||
|
||||
// special case for whitespace (fry 0122, bug #348)
|
||||
// this is really nasty.. turns out that double-clicking any non-letter
|
||||
// or digit char gets lumped together.. sooo, this quickly gets messy,
|
||||
// because really it needs to check whether the chars are of the same
|
||||
// type.. so a double space or double - might be grouped together,
|
||||
// but what about a +=1? do + and - get grouped but not the 1? blech,
|
||||
// coming back to this later. it's not a difficult fix, just a
|
||||
// time-consuming one to track down all the proper cases.
|
||||
/*
|
||||
if (ch == ' ') {
|
||||
//System.out.println("yeehaa");
|
||||
|
||||
for(int i = offset - 1; i >= 0; i--) {
|
||||
if (lineText.charAt(i) == ' ') {
|
||||
wordStart = i;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
for(int i = offset; i < lineText.length(); i++) {
|
||||
if (lineText.charAt(i) == ' ') {
|
||||
wordEnd = i + 1;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
*/
|
||||
|
||||
// If the user clicked on a non-letter char,
|
||||
// we select the surrounding non-letters
|
||||
boolean selectNoLetter = !isWordCharacter(ch,noWordSep);
|
||||
|
||||
for(int i = offset - 1; i >= 0; i--) {
|
||||
ch = lineText.charAt(i);
|
||||
if (selectNoLetter ^ !isWordCharacter(ch,noWordSep)) {
|
||||
wordStart = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for(int i = offset; i < lineText.length(); i++) {
|
||||
ch = lineText.charAt(i);
|
||||
if(selectNoLetter ^ !isWordCharacter(ch,noWordSep)) {
|
||||
wordEnd = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
//}
|
||||
int lineStart = getLineStartOffset(line);
|
||||
|
||||
newSelectionStart = lineStart + wordStart;
|
||||
newSelectionEnd = lineStart + wordEnd;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
@ -1684,6 +1775,14 @@ public class JEditTextArea extends JComponent
|
|||
protected int selectionEnd;
|
||||
protected int selectionEndLine;
|
||||
protected boolean biasLeft;
|
||||
|
||||
protected int newSelectionStart; // hack to get around lack of multiple returns in Java
|
||||
protected int newSelectionEnd;
|
||||
|
||||
protected boolean selectWord;
|
||||
protected boolean selectLine;
|
||||
protected int selectionAncorStart;
|
||||
protected int selectionAncorEnd;
|
||||
|
||||
protected int bracketPosition;
|
||||
protected int bracketLine;
|
||||
|
@ -2021,9 +2120,26 @@ public class JEditTextArea extends JComponent
|
|||
{
|
||||
if (popup != null && popup.isVisible()) return;
|
||||
|
||||
setSelectionRectangular((evt.getModifiers()
|
||||
& InputEvent.CTRL_MASK) != 0);
|
||||
select(getMarkPosition(),xyToOffset(evt.getX(),evt.getY()));
|
||||
if ( !selectWord && !selectLine ) {
|
||||
setSelectionRectangular((evt.getModifiers()
|
||||
& InputEvent.CTRL_MASK) != 0);
|
||||
select(getMarkPosition(),xyToOffset(evt.getX(),evt.getY()));
|
||||
} else {
|
||||
int line = yToLine(evt.getY());
|
||||
if ( selectWord ) {
|
||||
setNewSelectionWord( line, xToOffset(line,evt.getX()) );
|
||||
} else {
|
||||
newSelectionStart = getLineStartOffset(line);
|
||||
newSelectionEnd = getSafeLineStopOffset(line);
|
||||
}
|
||||
if ( newSelectionStart < selectionAncorStart ) {
|
||||
select(newSelectionStart,selectionAncorEnd);
|
||||
} else if ( newSelectionEnd > selectionAncorEnd ) {
|
||||
select(selectionAncorStart,newSelectionEnd);
|
||||
} else {
|
||||
select(newSelectionStart,newSelectionEnd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final Cursor normalCursor = new Cursor(Cursor.DEFAULT_CURSOR);
|
||||
|
@ -2094,6 +2210,9 @@ public class JEditTextArea extends JComponent
|
|||
int offset = xToOffset(line,evt.getX());
|
||||
int dot = getLineStartOffset(line) + offset;
|
||||
|
||||
selectLine = false;
|
||||
selectWord = false;
|
||||
|
||||
switch(evt.getClickCount()) {
|
||||
|
||||
case 1:
|
||||
|
@ -2159,74 +2278,11 @@ public class JEditTextArea extends JComponent
|
|||
bl.printStackTrace();
|
||||
}
|
||||
|
||||
String noWordSep = (String)document.getProperty("noWordSep");
|
||||
if(noWordSep == null)
|
||||
noWordSep = "";
|
||||
|
||||
// Ok, it's not a bracket... select the word
|
||||
String lineText = getLineText(line);
|
||||
|
||||
int wordStart = 0;
|
||||
int wordEnd = lineText.length();
|
||||
|
||||
char ch = lineText.charAt(Math.max(0,offset - 1));
|
||||
|
||||
// special case for whitespace (fry 0122, bug #348)
|
||||
// this is really nasty.. turns out that double-clicking any non-letter
|
||||
// or digit char gets lumped together.. sooo, this quickly gets messy,
|
||||
// because really it needs to check whether the chars are of the same
|
||||
// type.. so a double space or double - might be grouped together,
|
||||
// but what about a +=1? do + and - get grouped but not the 1? blech,
|
||||
// coming back to this later. it's not a difficult fix, just a
|
||||
// time-consuming one to track down all the proper cases.
|
||||
/*
|
||||
if (ch == ' ') {
|
||||
//System.out.println("yeehaa");
|
||||
|
||||
for(int i = offset - 1; i >= 0; i--) {
|
||||
if (lineText.charAt(i) == ' ') {
|
||||
wordStart = i;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
for(int i = offset; i < lineText.length(); i++) {
|
||||
if (lineText.charAt(i) == ' ') {
|
||||
wordEnd = i + 1;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
*/
|
||||
|
||||
// If the user clicked on a non-letter char,
|
||||
// we select the surrounding non-letters
|
||||
boolean selectNoLetter = (!Character.isLetterOrDigit(ch)
|
||||
&& noWordSep.indexOf(ch) == -1);
|
||||
|
||||
for(int i = offset - 1; i >= 0; i--) {
|
||||
ch = lineText.charAt(i);
|
||||
if (selectNoLetter ^ (!Character.isLetterOrDigit(ch) &&
|
||||
noWordSep.indexOf(ch) == -1)) {
|
||||
wordStart = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for(int i = offset; i < lineText.length(); i++) {
|
||||
ch = lineText.charAt(i);
|
||||
if(selectNoLetter ^ (!Character.isLetterOrDigit(ch) &&
|
||||
noWordSep.indexOf(ch) == -1)) {
|
||||
wordEnd = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
//}
|
||||
|
||||
int lineStart = getLineStartOffset(line);
|
||||
select(lineStart + wordStart,lineStart + wordEnd);
|
||||
setNewSelectionWord( line, offset );
|
||||
select(newSelectionStart,newSelectionEnd);
|
||||
selectWord = true;
|
||||
selectionAncorStart = selectionStart;
|
||||
selectionAncorEnd = selectionEnd;
|
||||
|
||||
/*
|
||||
String lineText = getLineText(line);
|
||||
|
@ -2242,7 +2298,10 @@ public class JEditTextArea extends JComponent
|
|||
private void doTripleClick(MouseEvent evt, int line,
|
||||
int offset, int dot)
|
||||
{
|
||||
select(getLineStartOffset(line),getLineStopOffset(line)-1);
|
||||
selectLine = true;
|
||||
select(getLineStartOffset(line),getSafeLineStopOffset(line));
|
||||
selectionAncorStart = selectionStart;
|
||||
selectionAncorEnd = selectionEnd;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -515,7 +515,10 @@ implements TabExpander, Printable
|
|||
*/
|
||||
public Dimension getMinimumSize()
|
||||
{
|
||||
return getPreferredSize();
|
||||
Dimension dim = new Dimension();
|
||||
dim.width = fm.charWidth('w') * 10;
|
||||
dim.height = fm.getHeight() * 4;
|
||||
return dim;
|
||||
}
|
||||
|
||||
// package-private members
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
<condition property="macosx"><os family="mac" /></condition>
|
||||
<condition property="windows"><os family="windows" /></condition>
|
||||
<condition property="linux"><os family="unix" /></condition>
|
||||
<condition property="linux32"><os family="unix" arch="i386" /></condition>
|
||||
<condition property="linux64"><os family="unix" arch="amd64" /></condition>
|
||||
|
||||
<condition property="platform"
|
||||
|
@ -15,7 +16,7 @@
|
|||
<condition property="platform"
|
||||
value="windows"><os family="windows" /></condition>
|
||||
<condition property="platform"
|
||||
value="linux"><os family="unix" arch="i386" /></condition>
|
||||
value="linux32"><os family="unix" arch="i386" /></condition>
|
||||
<condition property="platform"
|
||||
value="linux64"><os family="unix" arch="amd64" /></condition>
|
||||
|
||||
|
@ -388,6 +389,9 @@
|
|||
<param name="target.path" value="linux/work" />
|
||||
</antcall>
|
||||
|
||||
<copy todir="linux/work" file="linux/dist/arduino" />
|
||||
<chmod perm="755" file="linux/work/arduino" />
|
||||
|
||||
<copy todir="linux/work/hardware">
|
||||
<fileset dir="linux/dist" includes="tools/**" />
|
||||
</copy>
|
||||
|
@ -402,12 +406,28 @@
|
|||
<antcall target="linux-unzip-arm-toolchain" />
|
||||
</target>
|
||||
|
||||
<target name="linux32-build" depends="linux-build" description="Build linux (32-bit) version">
|
||||
<!-- Unzip AVR tools -->
|
||||
<exec executable="tar" dir="linux/work/hardware">
|
||||
<arg value="-xjf"/>
|
||||
<arg value="../../avr_tools_linux32.tar.bz2"/>
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
<target name="linux64-build" depends="linux-build" description="Build linux (64-bit) version">
|
||||
<copy tofile="linux/work/hardware/tools/avrdude" file="linux/dist/tools/avrdude64" overwrite="true" />
|
||||
<copy tofile="linux/work/lib/librxtxSerial.so" file="linux/dist/lib/librxtxSerial64.so" overwrite="true" />
|
||||
|
||||
<chmod perm="755" file="linux/work/hardware/tools/avrdude" />
|
||||
|
||||
<!-- Unzip AVR tools -->
|
||||
<exec executable="tar" dir="linux/work/hardware">
|
||||
<arg value="-xjf"/>
|
||||
<arg value="../../avr_tools_linux64.tar.bz2"/>
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
<target name="linux-run" depends="linux-build"
|
||||
<target name="linux32-run" depends="linux32-build"
|
||||
description="Run Linux (32-bit) version">
|
||||
<exec executable="./linux/work/arduino" spawn="false"/>
|
||||
</target>
|
||||
|
@ -475,7 +495,7 @@
|
|||
<!--
|
||||
<tar compression="gzip" basedir="linux/work"
|
||||
destfile="linux/arduino-${version}.tgz" />
|
||||
-->
|
||||
|
||||
<tar compression="gzip" destfile="linux/arduino-${version}-linux.tgz">
|
||||
<tarfileset dir="linux/work"
|
||||
prefix="arduino-${version}"
|
||||
|
@ -487,6 +507,18 @@
|
|||
<tarfileset file="linux/work/hardware/tools/avrdude" filemode="755"
|
||||
prefix="arduino-${version}/hardware/tools" />
|
||||
</tar>
|
||||
-->
|
||||
<move file="linux/work" tofile="linux/arduino-${version}" />
|
||||
|
||||
<exec executable="tar" dir="linux">
|
||||
<arg value="-z"/>
|
||||
<arg value="-c"/>
|
||||
<arg value="-f"/>
|
||||
<arg value="arduino-${version}-linux.tgz"/>
|
||||
<arg value="arduino-${version}"/>
|
||||
</exec>
|
||||
|
||||
<move file="linux/arduino-${version}" tofile="linux/work" />
|
||||
|
||||
<echo>
|
||||
=======================================================
|
||||
|
@ -497,6 +529,8 @@
|
|||
</echo>
|
||||
</target>
|
||||
|
||||
<target name="linux32-dist" depends="linux-dist"
|
||||
description="Build .tar.gz of linux version" />
|
||||
|
||||
<target name="linux64-dist" depends="linux-dist"
|
||||
description="Build .tar.gz of linux version" />
|
||||
|
@ -683,6 +717,7 @@
|
|||
<tarfileset dir="../"
|
||||
prefix="arduino-${version}"
|
||||
excludes="**/*.tgz,
|
||||
**/*.bz2,
|
||||
**/macosx/,
|
||||
**/windows/,
|
||||
**/work/,
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -1,15 +1,21 @@
|
|||
/*
|
||||
AnalogReadSerial
|
||||
Reads an analog input on pin 0, prints the result to the serial monitor
|
||||
Reads an analog input on pin 0, prints the result to the serial monitor.
|
||||
Attach the center pin of a potentiometer to pin A0, and the outside pins to +5V and ground.
|
||||
|
||||
This example code is in the public domain.
|
||||
*/
|
||||
|
||||
// the setup routine runs once when you press reset:
|
||||
void setup() {
|
||||
// initialize serial communication at 9600 bits per second:
|
||||
Serial.begin(9600);
|
||||
}
|
||||
|
||||
// the loop routine runs over and over again forever:
|
||||
void loop() {
|
||||
// read the input on analog pin 0:
|
||||
int sensorValue = analogRead(A0);
|
||||
// print out the value you read:
|
||||
Serial.println(sensorValue);
|
||||
}
|
||||
|
|
|
@ -4,16 +4,21 @@
|
|||
|
||||
This example code is in the public domain.
|
||||
*/
|
||||
|
||||
// Pin 13 has an LED connected on most Arduino boards.
|
||||
// give it a name:
|
||||
int led = 13;
|
||||
|
||||
// the setup routine runs once when you press reset:
|
||||
void setup() {
|
||||
// initialize the digital pin as an output.
|
||||
// Pin 13 has an LED connected on most Arduino boards:
|
||||
pinMode(13, OUTPUT);
|
||||
pinMode(led, OUTPUT);
|
||||
}
|
||||
|
||||
// the loop routine runs over and over again forever:
|
||||
void loop() {
|
||||
digitalWrite(13, HIGH); // set the LED on
|
||||
delay(1000); // wait for a second
|
||||
digitalWrite(13, LOW); // set the LED off
|
||||
delay(1000); // wait for a second
|
||||
digitalWrite(led, HIGH); // turn the LED on (HIGH is the voltage level)
|
||||
delay(1000); // wait for a second
|
||||
digitalWrite(led, LOW); // turn the LED off by making the voltage LOW
|
||||
delay(1000); // wait for a second
|
||||
}
|
||||
|
|
|
@ -5,14 +5,23 @@
|
|||
This example code is in the public domain.
|
||||
*/
|
||||
|
||||
// digital pin 2 has a pushbutton attached to it. Give it a name:
|
||||
int pushButton = 2;
|
||||
|
||||
// the setup routine runs once when you press reset:
|
||||
void setup() {
|
||||
// initialize serial communication at 9600 bits per second:
|
||||
Serial.begin(9600);
|
||||
pinMode(2, INPUT);
|
||||
// make the pushbutton's pin an input:
|
||||
pinMode(pushButton, INPUT);
|
||||
}
|
||||
|
||||
// the loop routine runs over and over again forever:
|
||||
void loop() {
|
||||
int sensorValue = digitalRead(2);
|
||||
Serial.println(sensorValue);
|
||||
// read the input pin:
|
||||
int buttonState = digitalRead(pushButton);
|
||||
// print out the state of the button:
|
||||
Serial.println(buttonState);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -5,19 +5,22 @@
|
|||
using the analogWrite() function.
|
||||
|
||||
This example code is in the public domain.
|
||||
|
||||
*/
|
||||
|
||||
int led = 9; // the pin that the LED is attached to
|
||||
int brightness = 0; // how bright the LED is
|
||||
int fadeAmount = 5; // how many points to fade the LED by
|
||||
|
||||
// the setup routine runs once when you press reset:
|
||||
void setup() {
|
||||
// declare pin 9 to be an output:
|
||||
pinMode(9, OUTPUT);
|
||||
pinMode(led, OUTPUT);
|
||||
}
|
||||
|
||||
// the loop routine runs over and over again forever:
|
||||
void loop() {
|
||||
// set the brightness of pin 9:
|
||||
analogWrite(9, brightness);
|
||||
analogWrite(led, brightness);
|
||||
|
||||
// change the brightness for next time through the loop:
|
||||
brightness = brightness + fadeAmount;
|
||||
|
@ -29,3 +32,4 @@ void loop() {
|
|||
// wait for 30 milliseconds to see the dimming effect
|
||||
delay(30);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
ReadAnalogVoltage
|
||||
Reads an analog input on pin 0, converts it to voltage, and prints the result to the serial monitor.
|
||||
Attach the center pin of a potentiometer to pin A0, and the outside pins to +5V and ground.
|
||||
|
||||
This example code is in the public domain.
|
||||
*/
|
||||
|
||||
// the setup routine runs once when you press reset:
|
||||
void setup() {
|
||||
// initialize serial communication at 9600 bits per second:
|
||||
Serial.begin(9600);
|
||||
}
|
||||
|
||||
// the loop routine runs over and over again forever:
|
||||
void loop() {
|
||||
// read the input on analog pin 0:
|
||||
int sensorValue = analogRead(A0);
|
||||
// Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V):
|
||||
float voltage = sensorValue * (5.0 / 1023.0);
|
||||
// print out the value you read:
|
||||
Serial.println(voltage);
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
Input Pullup Serial
|
||||
|
||||
This example demonstrates the use of pinMode(INPUT_PULLUP). It reads a
|
||||
digital input on pin 2 and prints the results to the serial monitor.
|
||||
|
||||
The circuit:
|
||||
* Momentary switch attached from pin 2 to ground
|
||||
* Built-in LED on pin 13
|
||||
|
||||
Unlike pinMode(INPUT), there is no pull-down resistor necessary. An internal
|
||||
20K-ohm resistor is pulled to 5V. This configuration causes the input to
|
||||
read HIGH when the switch is open, and LOW when it is closed.
|
||||
|
||||
created 14 March 2012
|
||||
by Scott Fitzgerald
|
||||
|
||||
http://www.arduino.cc/en/Tutorial/InputPullupSerial
|
||||
|
||||
This example code is in the public domain
|
||||
|
||||
*/
|
||||
|
||||
void setup(){
|
||||
//start serial connection
|
||||
Serial.begin(9600);
|
||||
//configure pin2 as an input and enable the internal pull-up resistor
|
||||
pinMode(2, INPUT_PULLUP);
|
||||
pinMode(13, OUTPUT);
|
||||
|
||||
}
|
||||
|
||||
void loop(){
|
||||
//read the pushbutton value into a variable
|
||||
int sensorVal = digitalRead(2);
|
||||
//print out the value of the pushbutton
|
||||
Serial.println(sensorVal);
|
||||
|
||||
// Keep in mind the pullup means the pushbutton's
|
||||
// logic is inverted. It goes HIGH when it's open,
|
||||
// and LOW when it's pressed. Turn on pin 13 when the
|
||||
// button's pressed, and off when it's not:
|
||||
if (sensorVal == HIGH) {
|
||||
digitalWrite(13, LOW);
|
||||
}
|
||||
else {
|
||||
digitalWrite(13, HIGH);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
Created 26 Sept. 2005
|
||||
by Tom Igoe
|
||||
modified 30 Aug 2011
|
||||
modified 24 April 2012
|
||||
by Tom Igoe and Scott Fitzgerald
|
||||
|
||||
This example code is in the public domain.
|
||||
|
@ -147,65 +147,95 @@ void serialEvent(Serial myPort) {
|
|||
Max/MSP version 5 patch to run with this example:
|
||||
|
||||
----------begin_max5_patcher----------
|
||||
2569.3oc2as0jiZqD9YO+Jzw09PRc75BIAX671TaUop8gy4gLoNmG1YqsjAY
|
||||
rxhAGPLW1T4+dZIAd.aCFeiEuYqXFABQqu9qa0Rp0ec2fgyiegmND8KnOgFL
|
||||
3utav.8sT2XPd4ACWwdwKjkpq1vU7zTV.e3Hyyj7Wj5665Tbq3LYHWJecM2z
|
||||
tCGh9b9iVyjdKEQAeIg6IMOkRmM1ZDx10UcgRF6LBgmN1Zy6H70se77+38yJ
|
||||
9DKhijQrU5Ovv6SDrvhmDksRDAedsvRJU8Tw2zUGSfuyl5ZjUckwpa922cm5
|
||||
mQsDLh3OCx0NXQJODgqENlyhBFNpkvBchFVzfCwZ+vh60DVHm.r3EuZEORtC
|
||||
t7.WISnOvBCe+uwSWGGkxQnGidL5AdjeJhgl+pjifuNRtjiRMUecbhbDhE4i
|
||||
R3LnVTcsRQhnwHzCfXhVDmvChyfZ3EGFmLB8x53Tyq7J7Wn3EPS6IR7B4nrT
|
||||
.n0M+SrvLnYR3xrjHtOZQR7ps+tiMh2+MVx+EzuuTjhz5JDzSy.KAn5Lir5y
|
||||
eR3AhdjtTL7SBB5SpO8VMIBZjfXsPDC2GpCCojIP1L89EFIC45f9o6e3Ce7i
|
||||
n6+YUCmJYIxr0iA4.ZvuxUxwyLgo+ajDUCLR8AizsLfnQn7l.8LbW9SfXIjv
|
||||
qAZdzJ.1P9LIartS5AvqDvArM590I.ayZ1iQyeE8fWrTh9Ug7aA7DVnuFW+c
|
||||
.q9XP7F+.ghHtGnBzJZLtdhsskshK6PLV85BXmZL3cNRlM9XX1VWPlsLQD.n
|
||||
C5m.Mwmje9mUpDOE4RDrT99P9BIPMidBdUAP5AV08ggFdSB6YEWPgoqShg2Q
|
||||
yOeV.OeIa8ZPSNmq32n+C6Efq9m.kETcfimb96Xz+WotkJtYgTrPjvA9Onn2
|
||||
gE.bNV5WQ2m3mIhh0LmRs0d0lz5UlDiWJGKGs1jXtTixz8lQalvEQBIHVvGM
|
||||
UqlBXJONOqQZi2BvfjosuWrWPiTOngmXo8oatfoZPiZWCnYeq.ZdK4desvWD
|
||||
GXYdBQtmLvk1iCu+wgJ12bdfHBLF.QNyioLGTVCKjJGSFPW8vUYQBySUtKWw
|
||||
70t0f+bdXr2WQoKy.i.+3miNZJqsqA8czvNgRajxR6aneMQbrF.XkqDMzaFo
|
||||
6wgmV.YDrNjCWaC.4psvwypAfH6Ef9e7DeVDauPDcePjUcAkUVN4I4.SNx.s
|
||||
gHTMjVJvSJU6ACeq23nGfYlsoKYYT1khiBv6.Ekhq6SVE2zmu3XZiXvO8a0W
|
||||
WiJ+Tslhn0f+YvFRSv296xxBkeY+fS0muf4wq8kqQULXXPhvONRIFUdW0sK9
|
||||
f.Gvn6cJK45ZDwVumWVFGGNmk7jHULOjWQS.rYVjXE39TJLRDDWQwCEqVmHL
|
||||
VratGOhAswxTuj3vvJMk4IOsmmXB95YgubotsdCupL8lRLmJ1YUteiS2opQ2
|
||||
hjf4.H4T7+kqT81b0Fw+DGSrPZRyro5Bk7Kssom8jxeuZ8OUa3+6ZDhG6LyA
|
||||
OcR0Wb6oHMnvok4OFcs.VK0+NOHkjCoF5ryrCBot2zPZkwF1cFoJVZy.ZwLS
|
||||
2YFp0xYsLwvXtXlBOA2..6TK.ukep5FYsgQW2C5R6FzcMChIw5RvXMF+4DV7
|
||||
TqCBnzSFPsOE.sinq+afR0HPpG03PV+UHm1GFKImLVR9QGKycj1ZnDe6BkMM
|
||||
vDDVMKYDZMCvrXXtMn2gQuifdGE8N6KhgewExAGpx5ldnJs7b1rRmIpUKNmN
|
||||
taHqauXRSqETZfYU5IEy7U0fC6cfAlT137vnwrenQCp0QgFtV8Tzv74FdfQ5
|
||||
HSGSg+y1dj9uaWWF2pXs1ZIKNht7aScTs1L0LKLcuQ878iEowYIdE58h.dPU
|
||||
6S97ToHZybo+zaNH2phKE99Um4pFtE9qiAJUt.h9bqzdGsb6zV41s+I231H2
|
||||
S5WxMts3shPQ5OxM4XjaZuQtUCt1d415FTtw8K4d1wf23aP4lzqvaWq1J2N8
|
||||
K+fsUtc6W768LL3sgbO46gbmeSnCX1tjT1Sb+u.eFHDwuvjxDw7LoIDrxaex
|
||||
4uaBM9vCsYFAgwyYg4asylVoRauiTscac2aHwkYmzrpcWyJOsi8NkCb995N8
|
||||
sLYptT1wYxMRpL8udeCYxzAQjolDBf51BDw4FAQToB.LfJ9DS2MCjju8ylcV
|
||||
rVHwtuAIx3ffP9YyGLoKhY8JpsySabC1u1pWqSS8hM6RrcqTuV2PoyXCo2Y6
|
||||
xmwbduYKMroMAL1S6aIzXnmesc+PQpT08KtpLBF0xbrXV9pz3t4x9vC5rivT
|
||||
v9xo2kpTPLrQq8Qsydvwjze1js23fJcSmiNWRveuxj0mXga7OsuEl1jTWtlt
|
||||
sIGdqqaiut85SJIixVMmmbHEu1tuIkus6jRnfiaiJ+aJcOoAcusILPWyfbGP
|
||||
2Os+o7anaianaSlRZc2lX8CKmmZWFFZlySH8OR+EBFJFfKGFbZDF5g190LhX
|
||||
Vzao5wgvnRWZAR4XxF37zsrVnZ10EpnWNn5agnfj3r0HZ8QR2xnGrMAMNA23
|
||||
.HG+3njuSrHHdZnKBbnCeFgZWr0XSbU4YgEooXqoVWyLZldIym7PAXpsjmvU
|
||||
oMtWXbJe6iRSCCGQMo4MYlgzX03Anh3dyjj8U.EUh3dLXxz7T51oMXxj9FlT
|
||||
2IOTSMNwUiI2xwvRn6jfnU.Dbea550AH5SYF6TONl1k3H13lPDbu67XVmYyG
|
||||
pX1DvA3Aolut5joTx1Isov5yWzJCIgXMoQim9lsyYtvcDhwzHOPNRwu6kUf+
|
||||
9rvc+4JtLI9sjcrlAUaQ2rXfTmlTwXxMi6.8Yr3z7FjuBlFRuYY7q0a.8lY4
|
||||
L0F7LzLWKqyZ0sx4KTrloLswU6EeUOHeWx02323L+Buhhn0YRz7rEKTmm4m3
|
||||
IuBFXnUhPv6I2KNxO8nO8iTy4IKeo.sZ5vOhuYNwnlAXTGna0gztokIwrj.X
|
||||
WCLfabXDbmECl9qWMO8Lvw16+cNnry9dWIsNpYKuUl.kpzNa2892p6czPsUj
|
||||
bnsPlbONQhByHUkxwTr5B0d5lRmov51BYcVmBeTbKDIpS2JSUxFwZjIxrtWl
|
||||
tzTehEUwrbLqlH1rP5UKkmgyDplCpKctFLSZQOYKqpCawfmYRR+7oXYuoz4h
|
||||
6VsQZmzstbZCWvw9z74XN+h1NlSrdkRTmxnqtTW37zoas9IsxgNoakIRakIb
|
||||
24QpshDoyDI21.Szt0w8V1g0jNmS6TYBa2VGHGAcpXHByvG1jYaJ0INIrNM2
|
||||
cj7kmjtozYJsaoJuLCuctHXaFDaqHw5GbPqN0klNltCF3WG65uMy4gP6dYhb
|
||||
H9T2RmZ07HNRmD4tzv4KbOAuozkHpxCQzvc7LLZiSBR25jffuBy5IWORw5KE
|
||||
CagO+YWiuFKOA0VOzDY5zRRqtz4Jszqgz5ZjVWqxRqpTWXei6VWyXx0d4nfB
|
||||
+8c+C81VE7B
|
||||
3908.3oc6ckziiaiE9b0+J3XjCIXpp.WzZNMURv.jCInQ5fYNjNngrDssRKK
|
||||
4nkp6JA4+973hrkrsjncKu0SRiXasQ83G+dKj7QV+4qtaxzrOxKlf9Zzuft6
|
||||
t+7U2cm7ThSbm936lrL3igIAExaaRJ+CYS+sI2qtTI+ikxSuBMKNojm+N3D4
|
||||
Aua5KkPwpuoUAkgKhSm+tbdXo5cQXVOhuGwrohuHD4WT7iXzupen3HY4BuqG
|
||||
rH0kzrrzxzfkb4kdJONHo9JoUKiSS3kRgjt4jYUk0mkznPJh+CYgHewpSqty
|
||||
xWVwUh3jIqkEYEfmqQEMr.ETbB+YddQbVZix+tIAqV03z203QDX4ukIKHm6W
|
||||
ep3T0ovqOUN+435m2Rcx+5U0E+FTzVBh9xOsHXIh5YuADg1x4IYgumG0r3mj
|
||||
shmFmtJmWvSKCJ0um0WNhOKnJo7c6GmZe8YAg7Ne381Rc2j44wQYoBgn0SJN
|
||||
c8qCHH1RhQqJi7NRCVsmGt.pGUESCxE31zDdCV.PRyxRZeo0MU.WOHMdYPIu
|
||||
LVIrT75BMd4p73zxVuHdZ.TFKJByyRRZUTpq77dtRDzZFx+PbT4BYY0DJgaO
|
||||
dUcSvj0XTT7bdQY6yUFLun8YZo71jl0TIt042RYNLa4RfCTWfsznKWDWfJpl
|
||||
tJHrbgV6t.AZInfzWP.4INpJHA8za91u+6QN1nk7hh.PpQwonxEbTAWzpilV
|
||||
MimilkmsDtPbo3TPiUdY0pGa9ZShS4gYUJz1pwE1iwCpxbAgJI9DGGwWNzFT
|
||||
ksLf3z7M0MybG6Hj1WngsD7VEXS8j5q7Wu5U0+39ir8QJJS5GMHdtRimL4m1
|
||||
0e1EVX0YsE2YssINriYRoFRyWVMoRRUGQvnkmms3pnXDYHbBKMPpIOL5i1s8
|
||||
3rMPwFcRCsGRyPH780.8HBnpWz.vlEQBWJ+0CSunehJSmJxiIZRtNGhhDYrU
|
||||
jt3ZQyA2fHJhZDifXIQHUHH8oGYgOREI5nqHIzhFWUndPyBdB3VzHJGwUhkV
|
||||
rgvRl2UCVNMHcd234lf1DN16HFEIdHt99A5hrp7v5WWMSBQZgMP.Tkwoqig8
|
||||
W1.Sn1f3h3nn1wLpBypPDzlJ7XinEGkLiMPloWOhrgR7dpZWJQV1faDy35Qj
|
||||
MThMFkWFGsJChQPqrQp8iorV6Q28HBVF4nMVDJj7f1xyYACFScisg.ruLHOW
|
||||
uMUS4Am4pI4PTnHi.6bi02HNzSYnDBe4cgAgKzRk1jc8PJLoH3Ydz6.Q.7K8
|
||||
tfxx73oUkJq1MGuCy5TpAi.POWZ3AenidLOOIaZPhdjZVW3sdk6LXEGzHb7p
|
||||
Mfr7SEy3SXHyBSxJ3J2ncNNYVJsXG6Me10nj4cfCRFdTFjLo7q3SiCpjjEDM
|
||||
.nvra.GN39.E2CDTHWXPo8.xzfqrHCHKnf5QUYUVdoZPUjCSC7LU8.XtTUXl
|
||||
X8vr51GjwFGLC2AlMdLkU4RiaRrnmJuiudnDk0ZW+9p6TuKBe433JUCzp6fU
|
||||
iOF0SUk2UQYUPNTEkiZubvKa1tsmgL5SCTXGHnnG0CceLpkpR9Rs28IUESWl
|
||||
EwWNKfHlg.zj6Ee7S+nE8A+m9F7Cu40u9gMm+aRp3kYYkKd3GDOz5y+c7b96
|
||||
K9gfvuIK68uNO6g2vUUL80WxihCVFD9vlB30e2SOrmxUb527RZ3nZNrljGrR
|
||||
70vs1J9suWuZ3zaHVdG3RIJLgGj2Gfn6TcGcstEfvtH.hpFLlnBndjOLGQAI
|
||||
z98BXc6yQxghmOn6gZqj0ShPOXhynLOjzCESt+XwE8TxrCvrdXo16rqnLgvb
|
||||
HaFmbh29QD+K0DyNdjDwvzQL.NXpoMvoOBxkger0HwMRQbpbCh91fjjG9Idw
|
||||
prTH9SzaSea5a.GQEPnnh43WNefMlsOgx18n.vgUNO.tKl7tDyI3iHzafJHZ
|
||||
VVNedVEbGgYIY42i93prB0i7B7KT1LnnCiyAiinpBnsPV7OG.tYKfBsrJOkG
|
||||
UG5aq26iJw6GyJ4eM5mEgEKaNQPMEBUp.t8.krplOVTlZdJAW27bjvGK7p2p
|
||||
HQPgLOSJDYv4E9gQBYBjMUselRxDy+4WplIzm9JQAWOEmfb.E364B43CAwp5
|
||||
uRRDEv8hWXprjADMUOYpOg9.bVQpEfhKgGCnAnk.rghBJCdTVICA3sDvAhE5
|
||||
oU4hf67ea5zWPuILqrD8uiK+i477fjHIt9y.V88yy3uMsZUj7wnxGKNAdPx5
|
||||
fAZMErDZOcJU4M01WFQokix.pKa+JE1WacmnKFeYd7b.0PeIzB8Kk+5WIZpB
|
||||
Ejt34KJeHgOCh4HK8Y3QiAkAfs8TRhhOkG7AAGQf0qxyfmQxa+PLb8Ex.2PS
|
||||
4BdO5GB9Hvg+cfJCMofAIMu9Qz+UPCjckqVJlEmyA8Bf.rC6.3hAEuG8TdTU
|
||||
bZljQ0nr1ayIqmTwQYfyRGafZhur5vfuyMSqYNWmtAPwWHalDSuUgT0Bosh.
|
||||
JpAR89Y6Ez5QEfPTQO4J0DHLInIliz8BZV2JfV3Bd36qsQwAVVXbr1BGXp6s
|
||||
Sd5sSDruo74wofx.HxUgxQwTnMLqTXvRmiGh2PUZr5pBynKChjl6feNUjSRn
|
||||
hEUfRPT1GfG9Ik4TQBm.hEZZ.bc38HjAMKGzDRijEm1ifx1dbgzQyKh6FZc3
|
||||
wOCkRJH+KUh0daWs6wzltWx1puXxlWW6NZWY2JiTBzzILRIANku02NourySM
|
||||
VI1VJTvQZff32AJr+dS9e34QAoA6EGXlGFH9yk7yyQAlVd3SR94g+TxOu1sU
|
||||
Flgd6ICI96LzazyPu1cgqsZ8r74SgF.65+efbMf4pGHT7lgHh30Sha3N5Ia.
|
||||
oqjMf7nsuMwycf7iYDybiAAVr3eC.oTMjpzEr8GDRc9bFRGHYXDrzg.Tlx+q
|
||||
NW8TY1IkzCfZ2IftkQstbB08HUezoDS+oFyI.cWIhWBaDiUo7qIrDO7f.L6n
|
||||
AXqCmyNT9act.z+Iv.GR0uES0ZXfjdz.IczAxQOUR+zvRsUTigRxmyPYeNlj
|
||||
yXv8Peef2ZFzuLzWPPeAE8ELzWXYlhe8WzAcUg+b1UkIoCLzIH60zwASGXau
|
||||
a1Dq2nUY.sox4vng+m0nACePngC9lEMLZMBPodOxf+yx5d4uMCTHm3kJvIIG
|
||||
jcLMedEQldkjpoBkQyjY1Hk.hmSY95Iwos8NDb9VSlIWOIntqgxryUjL6bCJ
|
||||
y1lli5tWWxrQ7YmqGYlc6shK1iY2dr0wtNjYxgHyzaq0OznY235awCr8zSz6
|
||||
EGd1QNUKf.74dADTBbTbeotjpW95IolY0WpKYONY8M83Rx2MChx3fL+iG5Mm
|
||||
tXpdmvXj8uTvaAL1WjbbarQD4Z6kXBpnm6a69oKV2PY9WY174IbC3CaRQ9iK
|
||||
Q4sYGQpwdtZ5wFrc7n569.M83OOR5ydSB1ZcAWCxdbKuavz9LILxfD.wWO.W
|
||||
Nq+Zu4Es+AP6s5p9jDWH8ET+c85+XbW0.N1nDCTD7U4DGc6ohnU019fS7kQ0
|
||||
o43luuOGjv5agHp0DT.CysOfgLR3xXlXTUKm16RivRsn3z0O6cl3YScAvtrb
|
||||
hwekGB7BZuqESUzBJWmCvK7t9HF8Ts6cUAPoFWso3aP8ApWyJ3wqOPo2pJDC
|
||||
BQ0NI0Pj8QCQ2r1L5vKaU5lDRYX7yRur1UYYZmJQ9iDHwN9dndB5n5ejflmm
|
||||
UsBwLHnDkKXWRuAkb3NeuzqRstiQGP.fCQFdHNzaE.8u58Nz9svFE9SGIE1X
|
||||
kv9Iwfl1BdNWjA7xcThsWCS847loyFD8pZq2E2F04lYULzBTDYhrFSDDJdjo
|
||||
fisN2NUN26e4xRu51zD5ZseJ4HC63WyIX6jRqsp0jangBnK.Qlo58PCpWevt
|
||||
ahzqK7fbKsdX6R64aao8LmWhBPh9jKVAPMzb5a2cV6opdWHneMmqMEmAGsPh
|
||||
ieigIjV+4gF1GgbMNXg+NH44YaRYyd..S1ThHzKhFwwGRaWVITqyj9FvPqMT
|
||||
d0pDuSqDrOGF.Uogf.juCFi9WAUkYR+rFPanDcPG8SbrtjyG03ZQ8m3AqC5H
|
||||
NcUUoXSwVrqXKVcZu.5ZnkwIfIVdXVZTwAuTTUiYuxwjZDK6ZgnRtYV8tJmP
|
||||
hEcuXgz2Goxyaiw35UkaWbpqtfzD02oUkkYqi.YQbZqIIWrIljFolsdmMKFR
|
||||
wCJ2+DTn.9QlkOld+d9Qy9IJdpLfy05Ik2b8GsG9h8rdm1ZFx1FrmmlA2snw
|
||||
qI9Mcdi2nr6q3Gc87nLawurbw1dda+tMyGJ9HaQmlkGwy6davisMgrkM65oz
|
||||
eulfYCzG46am8tSDK144xV4cEvVMTRXq9CIX8+ALNWb6sttKNkiZetnbz+lx
|
||||
cQnb1Nds2C0tvLNe14hwQtxYbxhqc17qHfamUcZZ3NYSWqjJuiDoizZ+ud2j
|
||||
naRK4k3346IIVdR1kKiQjM39adMamvc6n+Xp36Yf3SIGh3uKbquqs1JksTII
|
||||
kuJ7RrZSFb2Cn9j5a6DT8cMo0iczU+lsYaU8YNVh5k5uzJLU26ZcfuJE6XLY
|
||||
0mcRp9NTCp+L+Ap+in7Xf3b9jFQBLtIY06PbrGhcrU6N00Qlaf9N0+QPo9nS
|
||||
P6qsI7aYNLSNOHpsAxis0ggnZLjYqyyFkdSqinVsPaqSDZaYBZ6c93uLCjGm
|
||||
iCroJVLzU45iNE.pIUfs3TWb.0FejHp9uANr0GcJPTroFDNOHpkIweLnI1QT
|
||||
dHl3P7LhOF3Ahd9rnvLwAMy5JSdNezGlsIsW9mW44r26js+alhxjlkdhN0YE
|
||||
YqiH5MTeWo6D4Qm.ieLS7OynmuVGSbmbFUlnWWhiQlhOeN+Yl35bq.tGo9JR
|
||||
cj8AVqdz7nSgVB9zNj.FTOU68o5d9KO5TUOGxVMw+jTO8T6wqD0hEiHsOJO5
|
||||
TTOMoS.zlqN0SpZjz6GcH05ylVM0jwuidlkmAif374ih5M5QPfccr8Hqifff
|
||||
otN8pt3hUcaWu8nosBhwmD0Epw5KmoF.poxy4YHbnjqfPJqcM3Y2vun7nS.i
|
||||
f3eETiqcRX2LR.4QmhZrkoCSGwzZrqKHrVR8caari+55d2caPqmq5n.ywe8Q
|
||||
WrZL9fpwVXeaogMByE6y1SMdjk+gbavbN7fYvVtt1C2XwHJSzpk+tidUO25H
|
||||
UB9onw9mlFQ10fhpZBaDatcMTTEGcJpwzqg92qqiVtM6Cu0IRQ0ndEdfCAqV
|
||||
l0qYAUmPrctbxO4XCuPMa1asYzKDks1D52ZCne6Mednz9qW8+.vfqkDA
|
||||
-----------end_max5_patcher-----------
|
||||
|
||||
|
||||
|
||||
*/
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
Created 26 Sept. 2005
|
||||
by Tom Igoe
|
||||
modified 26 Oct 2011
|
||||
modified 24 Apr 2012
|
||||
by Tom Igoe and Scott Fitzgerald
|
||||
|
||||
This example code is in the public domain.
|
||||
|
@ -142,83 +142,88 @@ void serialEvent(Serial myPort) {
|
|||
/*
|
||||
|
||||
Max/MSP version 5 patch to run with this example:
|
||||
|
||||
----------begin_max5_patcher----------
|
||||
3365.3oc4bk0iiaiD9Y2+J3JLOrAq6Fhj5LOscRP.lGxtCxDr6CYBFHaQaqL
|
||||
xRNRzcOcBx+8s3grkZac31Vr8jMASKScPU7qNXUTUw+3lIVyx+LqzB80neFM
|
||||
YxebyjIxSINwDc6IVqi977znR4sYMOe8ZVF2Zp5Zb1m4pyuJOujghPkrhjnT
|
||||
zl7BNZQQ9ZDeURIBdlsUOyh7LdYxuyDOGlbms9zYaWmjkx3x2Cd+Iy2xqNa0
|
||||
stIhOeUR1xOVvlyUTuuqOzSHRfs7fspEz.8K5GJIVRn4y90ao90okrn0RZw5
|
||||
dAkaItvedyMh+LcffRF6QnaO.SzPQnmsM5eFskmmugkgrOebfzNNPbbDibJU
|
||||
hCXG2tvArSEsn5b9SaXptwJQviQVV6drKCRslUVFsjcn3SJH8bJ.C4n.Ctcf
|
||||
gRjhDTaO4gPI7DbbbgfaEWtz.RKhNR7XVT1xSASrOYLITJrfUG75VVwqULQR
|
||||
mlAWRyihOUXAepvhiGsNrX2ErPbtFfkMELvzRrzp6nBM9Dk5CUJq3G1IzDXL
|
||||
snsuz4WR3r054+rduzb86jPHxZp3OyxyWK92seS5VFX+lu5128c2e6s3c2w9
|
||||
K7C4wr0G47hG38OkMe2k99jB12m9zsgem+2b66e261CFMYCz1YCdJ7WaLiX2
|
||||
oHJE2qU9FV5EWWiIlU5MZi3vnJ+pANhxagvfNwMxq8r.bz7TVTw3pQqkgHRa
|
||||
dNzNQDZqHhhPMCr.JsEFQJQgIjt8kz40VJo.dwrKjoeRufBNTZrwizInztyB
|
||||
igWks.LhvOJeBLfmd4jVlmmlWnFJXABXeWPnMNzS7Ka8uv0.ki4htxQK2.0b
|
||||
nNcAj9u1BWI77nSA8nlB8TBfNdcgdAcNwmY.veOEsDzP2b9A2P5GTTg031oQ
|
||||
bmqAUyRVJP7HrMBSOekyN7ThXqfDao7le2g3X2su7S2ezTwE64NtAE6Js93D
|
||||
HQGJ4N21CJN701TDHyfvipZTEb3JssP6z1hWuxJWZXoskdSE2B5aiRSu8GYk
|
||||
axyJYn6e+2912h9P1GxdO3ScIJBM6IvKAfXQ7Ur5qR2TTD36cAKBtKp94XYP
|
||||
vLwSQhWoXI81DUDwYwHTR1TDuXa1bYyYOA8aZRFaAiEeG5sx9NCtedIZQdAa
|
||||
Y9VnqkF8mh97l7R065I3Wn7EvyNOo.bbDssD3CR55gHHtoRfZ3aKxf2fdEDa
|
||||
Pv2gjiq+UNm80neRr5hRVIBvIHNvR31iTCxX1CIygwblrEDKFq.Ihy.d0OqK
|
||||
QPmrLWRD4v4EwhfDzDPaJXaghxPdtn+tBht+qDcbIOpfucyc.c.c3mXB53wn
|
||||
D03WQIhNXZEvHYEYZT9dzivYYO.jUBGdLPhFsFfMTbDO5N4fbNvWDHM1Ac+l
|
||||
BQjdgeHCf82OOmyQeeB+2WxJhRik35OAX0aWly9P11MwxGihQ+6477YLwih2
|
||||
o7HXYyAdiT9ASGy0k0QY3UpP45nVTx.uiqR4ZYD8EdQxR.0P+cfC8y7e4qDr
|
||||
p4Bgtjkq32lxV.gckm8.7nIfpDHsceZpRdpH5QgLh.q2TjCOiTt8wD35qjAu
|
||||
hlwDx8neH5yfL7uAhx.KELmokquC8eEhAxUDuhJVjTv.8BP.3.oCPVLp7Sn6
|
||||
Kh2ljkKknp0WGkYNp7Rhx7nGQNKpi9PKSW3YHtYAKIKgCcJLZKkrokfneoT0
|
||||
Bosh.JpQR89EGEzHiIngUt4SUGv5EtwoEPywLf17Ur4epxFECjxlmjnsvAl5
|
||||
.gLA9Hj+lwVljImFXaVBXzGzHDJDK3BaVJbu4UEVRWGEKs3A+bVZ97OgJWsE
|
||||
zChyeL6UPp0wWEo.VYHpximVX.Ti7kg1f9fkvZhD8USB9Aqi5Zi8KILqio6R
|
||||
knfudQ98Te+ivVPgSdku9Orh3nrcQJJI.VgFXzHC7HIohY6JA4jZj6DKv1Ys
|
||||
SOo1iHfyeUExn6zcmBrFVTuCl.VAdHo54CUmDXR2TcwJTPw70qquZ1HmfZN3
|
||||
ArykBIVVbMgpIVwrEmReH9Le6ueaUft09Sy6LIaCLC.nkJ0ed96MZaJ+iGWh
|
||||
n40WDMm05C2BeZh0xhj37LAYz3YEmt5EJr6qzbpS4x6HKZyQdXddd5rnBACY
|
||||
VJqAiFTVhxRVCFn4IJJB7no5hIq2TjnLHr6brrHnOVUNuHOMsQWotxCG4JJ2
|
||||
9dLIluR1W6wqFes65RY0Uiab9NCS64q1zxY.H4V8u52TCFH9N2PWbfesqerv
|
||||
VZW+t0vWTg2hcs2u310il6fUBvuNM1tpdW1CmTYSTqxMV.qs3+MOjRzPpREv
|
||||
MrWH06pARaL0ygQRKjRaGP2M4aqS.29xvzp3o5yTgUG7TQWi6.Kc6DKacIYZ
|
||||
e1Iyftah.Wdr6QhsC.14kJrpz60xpXclvzE.SeoBqlEP+GH7KBHe4Z8MjTc5
|
||||
GHIcBj0Wr4+uCK0FPGLThutfxtlXR9MOmh1DATUND8D5MXzaHn2PQuww7SUo
|
||||
09qNP5cpJ6qlopjidq1PD6WLh3KVOasL2g9v97UeJ3zj7phsV77eA.FXRcMv
|
||||
9Qiv+RiFT6SBM7ruNPC0a15zcMytmI7HA2Qg+ywYp72CCTZXptug79PGEK8S
|
||||
KQgIIMw0ONVTlusXdEnWEACpIAFyJ4IY6hk9m2SqO6FWkDG2LxU0ZKDuIG3m
|
||||
6R.pAw8NY516KT519KS51anzsHliqH5VXEdXzM4KT5FBAAgudn6fgR2WWx2C
|
||||
mtoWW1SHmBcSudna7oP2jqG518.0sVna+qK4D2gh2dWWzMcnzs8Ejt0mr5Cf
|
||||
XUF8.K9ivqA726iQbdQxrsbkKXM95LG6qHLde5gNuXee4iko4yhR0eloc8h0
|
||||
M6QhKyGpydjqII0WCNjtO8qZKeib8uBRlw+1sWhLvpqRuQGWlKd.Hh6U.hHR
|
||||
1.vhpQPEpusJMZ5JuzbMW9nyyWtLcWNKdl0bklwS1UJKcLDo8v3u3r2w0LfN
|
||||
GUcFD609pHMLsG07vrRdOb.0jhSfwSDyz4wmfPuSuIkQ.VuVKd6Nbzhpn8Lv
|
||||
MMoTVHWUG2W8tWxhQxyEkNtEurRQvinxQGxy+XAMPC2WXsKW+iDbgRmpGhRo
|
||||
iZ0s6pRoees+B9cALXqK7nFnxYWhBtpKE9.RswmqWmL9936cT2siCumLp7dc
|
||||
dVNLdefk4F13QcXSB8G7vlX+EnLO00evx7DxqiPuAfgpDSTCCtcBCuR59sLi
|
||||
31r5o5wkXi8vsWbxSU9k5D3rUfJrOfp0ClB7zU.lMBOp0+kda+fnbwpmpV80
|
||||
q9uZMQsSS.IrUrBY1XK2UPddsqLpVg0oT3tMZfNKIJhm0q.nH2TcLIlniNY2
|
||||
VMT2XxEdqFpsBETlEti5ZU4DVaTqlOtsREDatZErMYjusgLxRFWVoZkbQ8MT
|
||||
SPobbkTv57KXHaJUDqq1EmQuoRgUKPAgT82ix6wFawY9s0LdQ9EYwH5evWMC
|
||||
R2UPLwn6FPsYLPkG8ip0.s+GpEqRUorsZMf9paM3GYQwUp8IYa1xQy1tXgnb
|
||||
PefU7jnLzWmjBlGXyyyhKMeQhoS4FsABkUi1pQLrgJrNkETQ8vJpw0wMVOer
|
||||
x9RP+6pT3K7Dphw6rsbd9toOWkTkFS0dQUeiK7wvA5NbXVdQrptm1clkGtoW
|
||||
3GDPnthe43a6FD7rM8hZkCzgEmNVAOOuVhNNGXGybmcoYPDKh8ihr39cmV7z
|
||||
4fBRsAf8cjo09Se6UG9pMRMW+9WTeha26KES6+q5T0oKyxAZPH9VeLpXMMFK
|
||||
MJLq5iEI.oJBLu8Ufm.OZ77fOQ1Rn34+P1W+kPXrawJ7qhXkOUMireP+hUgz
|
||||
+BKVI63l4SoRJ644ofVV6f7SPrNA6SOkVxMARijz4v7R334jvAR9mDM4zCMQ
|
||||
MJIQaj1LsASglGlr6ilLKN4ZO.ZBaaTZxe.jD08zHIhuiHwD7v5HCB105LI1
|
||||
fAPr9FE9bF.EEXTJBODgLmSjgpXgtjPYBmnXuxVWBhkbgIVM4o+9n0ZctDKd
|
||||
Hpulc1.5P31Dr4oo9lN.a1oCFDuidhldItTUBXo2ze8105bmnfN.p08DoVGa
|
||||
o1qiCtlUYYqyjZ8HCAaMK+dH.njtIlyiDxPoIr4noAiSFzKoAI76ZVZxcHzj
|
||||
yKSgTsEm53Enxxs5snpsA.8cJaYhILbMqSTtCwIT2SzWcJUNwuCtNBJactl6
|
||||
F.wFd8ow38BmsvSI4Q205b8XNXDX1mK.ND23cLqe7CI9Uri4iy+RSSUgG5p+
|
||||
HIpz3nQKZUBfJEBksNW2AcFp8b7I6NnNwkbbb10xHTqsY8b.OBxBZWnopDbs
|
||||
BOIm+BGfGCsIpqTxkZqhBPSshVmK0RGCp0OPE7taMpU15boVxUnkJ7PVQRyZ
|
||||
PmNnvjLbn5zqPZZHV6nFdYVFhSeT5UHMYV8Nr2HrbTNZCrNXoAV8xrHZctyg
|
||||
MDIM7IxUE6mpR5SM8u1pqn0kvKf9roQ8N0YETQVpJnPOhptBazRteTK1KOcT
|
||||
a+8meDTjfQXFCepaMuunggpQRiV5jcsxuB+C9dg27m27+.7QBpFG
|
||||
3640.3oc6cs0jZajE94Y9UzKkeHoVloTeSHkm1II0VkeHIthSs6C1obIjZ.E
|
||||
KjHRhY7jT4+9d5KBj.jTCAXfoV6x.sj5VmyWet127ed6MCFm8EQw.z2f9.5l
|
||||
a9yau4F0kjW3FS4aFLO3KgIAEpGaPX174hzxAC02qT7kR80mkkUHPAnBQdbP
|
||||
BZQVdIZRd1bT4r3BDTmkU0YQPY3r3zoeJWDVpe2ttr6cFhvXt7KhyH8W26f9
|
||||
USkhiTulrw+1czQUszjrzxzf4B0sdP9dqtS5x4woIhREQiWewrkkUW0oViTD
|
||||
+GpFASt2Qd0+51akeLzRPIU7DPXagIFnH.4653f9WAKKyxVHRQNcfDXlih2w
|
||||
puvbdWHAlcTPBRKHg4x5mr74EBMINHV1+iFL.8qG.VMWTTDLUrs.TBH+zAvP
|
||||
nTEhvvxun9pBd6FWH38DWH6DWv6ItbX.RKBOJ7XbP5ztvDesvhBLb6VTwcOg
|
||||
DmiBjnXfiIrjjED0CpP490PEmtPExwQA5EGUVjK.CKQJqtcYl0nCMRAJi76D
|
||||
Z7dQflCCVV1i+ENiTy3AwYaghEA4.KVJx+jHMXbhntJPceO3iBpPOPKtZqtU
|
||||
jUoXtw28fkEimmEIlOI.3Q4iMT9wO+iLxc9O7sN28928t6Ve8uMYo.7EUN6t
|
||||
ePVoUW+6E4hOW7CAgeaV1meWd1cuWnYLy8mKhhClGDd25F3ce+C2si1Ud42+
|
||||
bZ3IQJOXg7q96t80e50YvDjqHw7VvkRTXhHHuKEerRwmqfBFsS.g9h.HZN3X
|
||||
hJf5Qd+xHZHgzc.mrqeYjbn4E84evfIDUjDtjNwD2iRHV6anmGdbmsfKxTTJ
|
||||
dd93rjtBJ2U42foCwZDqKfYzKkrh4VgYIY4FxVRmN2646f8ck+xw7KrjzOlZ
|
||||
ZYAVfdZgKlaWn29FzA8nfdR2quj.3ejflBJnKr.Dwpf13cZBm85P0rPj.rOB
|
||||
6fvztPFGkVI0SAPi5NKHmih7E8Ph2e35uOtYN6x6JEQtJVWpV7gRtm2dZy9W
|
||||
+YMCxLHrEvAknQktDVdY7v82SFosgmSGHO56BRRt6mEEKxRKDnGd+2812h9X
|
||||
5GSeODOcAJ.M9YHHAfjPkyD0GIugn.Ht6bQ.7TTS8DoPtCQCQxWobX+jYPUJ
|
||||
hPn3zgnx7kogphieFZ2j3TwDgH5dzaUscJ77kEnIY4hoYKglVYzcH5KKxJzu
|
||||
qmgegxl.0MLNGBNDsr.5IUz0iAPZFE.0TtLOEdClQYrAAeORwW+XVo3aP+hb
|
||||
DHUBCH.mfbEKfGOPyjQhGiCAdNUUBRcQjij4X.u5MZRDzHSyTDQFbcYdHHIM
|
||||
AzlF1lnoLjKG8UZH5guV1vEkA4kKWbOPGPC9YgjNdJHVy+ZJQ1.Cq.FUWQpA
|
||||
ke.8DbUwi.YEWBUCDhPyAXCEETFbuhICg9EIRiYnGVjKyt0+io.r+9vrxRz+
|
||||
Nt7OlJxCRhT35u.X0amlI9X5xEQppQwneJrLarPVU7JkGYWVHz2njevz1UoX
|
||||
XkoEWOkxDWO9kXYocoTwuzF611zXJyimB3F5qf9nOT9qesryJTJ1EOcV4cIh
|
||||
IPVWYoOBUMFTl.4sGRRzRT4AOIkRjn8h7LnNJI2mhg6OSk5JZrPJ4i9gfu.R
|
||||
w+NHLCcpfAMij88n+qTPPMt4UTwj3bAnY.h.aIe.RiAEeF8Pdzx3zLkLUs1Z
|
||||
mcmczah0FH4ZmpLcp.rVbX3d0zalKhSiKAxBZ9BU2zTP3uPobgL1Q.U0.kl+
|
||||
jcBZj1AMOpzsJYjdz0n53QXsfYrqELKblH7yUFoDfPVXbrwDGXqCjwjviT7a
|
||||
rXZbpxOvxzXvpOnPH0GlTJMZog8l2UZJcdPjxjG7ywIYgeFULaInFDk8jpxZ
|
||||
apvMA4cv9X.7.vaRRGFAcPYHMR0dF2BZC7wEJ2TOKeZnCRD+HzJo.OLWSW6r
|
||||
qk2wfI6pGf.pdjC4rpfL2YeK8JYloVf93.ocJEvocv9wAcEiMQgBtl.lb0y9
|
||||
heKnvtGRs+iHOJHM3uaZbN1jDrhED4FfwfLPCEmH8jV.BB0Z+aF.Vkqc4apU
|
||||
EIb9a5zAcGt5Rf3WdsNJ3R4PXDU0mouHzIca0MWO.KpQjT8oq1SIyqV3mP24
|
||||
ToxfHpdyOPNqgwoK.W.fxfRNtwsiDSBVlT9ociSMu+jfPQqUtk9paFLMONJK
|
||||
URFMpq7xUuvOXF1HBuN6ndhzfE6nxPXQkKKFGjKQNyHtSptYYVVRyaspyBD3
|
||||
CRiA0YQYrlbgHdptY77E4wZk5UWSOf9yJByyRRZzT5673NtiNrvmhiJmoZq5
|
||||
fI73wKp5DFrBihhmBNxadsxfoEMuRiIbutfVcM4FWuyr.2bvrlNF5.3U+q9C
|
||||
sKaa5jkMt70iSd8bC2ZbEFUuAa0DWqYF0tJ91p43649br2nZ2usLGuoxrnQq
|
||||
6TArNx+1CjRLPpVWf62Kj59ZFRa38Y6D0kRo8AnT8b0g0e4p8+f6.P4sBnaX
|
||||
TqMmPsOdOcjG+dMtOmdzcgLdIGqjX0J+FAVrmSu.L8fAX19Ky1C.e1.z+IB2
|
||||
qpeCIUV+.I4fARxQGH0i.9ECVZrhZMTheMCkc4XRMsoCgbef2ZFjaF5MXzaH
|
||||
n2PQugYmhe0WjdcU47Z1Ukhb6CwFISy2HNtcvtaNRWdshHNVgHcNMUlopRm4
|
||||
tJByyLXfI0UN6GM7eUiFTm8BMbctZQC8atOegDu6oveXrgpeaGnfaETvsBJN
|
||||
6AKuNsT4n+zRVXJtQd+ciEEYKyCq.8ptRTSdBRQrLNcUd5eXcjoa7fyhihZl
|
||||
UrNQxBYZo5g.vpdt8klkJi1QyPvdH7UFMStbvYu8Amu1nY7ECMKGXBqnY2KH
|
||||
Z18Jjl4aYNnEYiQWVzrUxytWNzL0VZ14xglI6isN5kAMi2GZlbYPyNma6FqC
|
||||
aJRs9qEogO+ovfvYFxxjGV07cLnH3QQzm.R.BG7SAkk4wiWVpC2p9jwX23ka
|
||||
0zSz4M6e1QZY.8mljMNHwLURqZ9FuzslMk8ZJXtcMPeblVut1XYDhdMCpmjZ
|
||||
8BAqsU9DezKxJAa8Hmbbfi+wccuVv7c0qELrEHB+UAhHWzCfCbKPEyBki24Z
|
||||
clythVwfkYSmlHrPdX8tC5v1iPb5ArPuOWc8NVrRZspq24UxhE0wBcAsMyt2
|
||||
2LLuqvkKZRXjEq5CM6S3tq9Zm6HD+8Prm0F+jDWn1paUe+2ZuF259kxkiR5W
|
||||
Qf6vzKBtMm+gFrMeuWsKW.6B61VyWOFjz0Zsmwza+.ikxQcAL3iDtbLWMTKm
|
||||
OtyMEFcjWM9iu0rMa81D8kUl3v2ewcHWP5B2HX6kK7t7DL5fs6JVIrO0Z1l3
|
||||
bEpOP3zih9.gbspPzKDYbRVAQ7CFhtZsYzhW1ko0WEJcG3oAC0aRIyxKsUEI
|
||||
+iDPwOLfp0uNA68MmtSUSmRuNb8d1ttWya7sVWf5Iwf.1LQtZUnqNvT1bS6z
|
||||
E5o2vfqNSH5bufQbuZV09M.E04Mj8XBUiBqNGl5FSt3NGlZaGRpV6wc4kiWi
|
||||
q0twaaORhul1jjsIi7cMjQlJJUaQuhR495nlfRQWRJXkrgmMGXWjKM4jdGJH
|
||||
yovkl4HUetutzWuY5tjFHneGn77rtG3iJ92whCVJxKhBwgGtRaFIzabfNrRn
|
||||
WThd9q24vsZjf9JvHwOKBhprFDmtXYIZ7xISjaO1GE4OK2V9yiS.qFhvrznh
|
||||
8cKyMZs7EVepT01FlCe0rIC0lUk6NX4N9syCyAE660+ovE9hyGqjaGurrLak
|
||||
G0YwoMlFO4YMSZjd9DcWucsjUr1Yqgy8TluCY3N9Q8.+k0JCD3ZTS0CW8Qyb
|
||||
s19nOxrgjw7VFU+3ooYviK66pCfimt8AAxHOOBkK+EajC2yayWtciMzgdvpM
|
||||
NKORj29YyGcS4wFVlql0wcZTg1yw5wvMNiTpuUzpu.Y0miRlgO0w7wpZI2Em
|
||||
SUBGayVM5eqU4C+rV4ZSPkvXqLJbAHlR3mKwT5ISL8+Kv0k.GWEKwpP3ewk3
|
||||
7omKIN7EtDmp4ZtHk0BfatXgLhgasHgZrVYaY8AIO7fq8Pas1fFzjd4ibwpd
|
||||
XO4GXOeOG+lcyasNh1R+wVx2yBxeTOT+wiZFYA0P48PNyiiVjAhJlNT4Qvpb
|
||||
uj3aN2qYqJcBfSWhMbf+YCPcsfbNeTC2l9WNc+5eIlkST0RJgupzIn+kysgC
|
||||
X6GGXnYpdYfP0GP6MKQXM3N1Ih6XVvcLuym7B0B5w8v.ahqBI49qJcJ.TaX.
|
||||
N+xBP4NGHhhqYfkRNM9q1f3ZweqyYCQYdGCSZGQ5wBx47o.Ssw+CkcgQOmud
|
||||
KZic4QKzCw+7ROm8nY2LfMsEDtdfeMKSn5Ev95IQhorcqJcBrzPsQUhRNe8M
|
||||
1X6lhOezC4Bidv1nKcFs8YimJ9n8RWZXiO7aSCxDRLdjd91qU5TnmXCeRvmR
|
||||
9jnm7b15RmJ9rO4Kr+IgO04BfczyOpqx9npzofOsIlaR8Mo0IUMR48i0mYly
|
||||
lVMwlw6gbloGRezy4yKEw6BHBBWik.eRi3DNM5KDahS.SOE1EjmXl7Uyqo9T
|
||||
AtQAO8fG3oLX3cZFxKh0FLNSRfDaoG74gdvW.ZDU9FMGSdFMBt+IQh.6eIvw
|
||||
FujTkJREGKKcJ3X2WtXf7Ub1HywEqxh2tJnE.FcZhMByrcXQw1x+bOWJYjpy
|
||||
lv8oq55aEHLcwD8hJjxbVU5EigcNtL7Ql76KVVp69Huhcb87vpoCkRYT+96v
|
||||
Hd5Ay1rofMqm+FkLYvv0+GL3FkL6bLp21kL6QFNV8BNM48foWBV4zt1wXm5V
|
||||
4jkNEbL45dtNw13Iltmi9sAyY0S0l8BR+3yWjVXax7eOmKrp4m0QKIal6VYo
|
||||
SAf5XQxSrCa5l0qk45k5kAzqEgMNgzkz9FmL5abpnu4IhNzZ+0s+OKCSg0.
|
||||
-----------end_max5_patcher-----------
|
||||
|
||||
*/
|
||||
|
|
|
@ -66,7 +66,7 @@
|
|||
void pulse(int pin, int times);
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
Serial.begin(19200);
|
||||
pinMode(LED_PMODE, OUTPUT);
|
||||
pulse(LED_PMODE, 2);
|
||||
pinMode(LED_ERR, OUTPUT);
|
||||
|
@ -109,7 +109,7 @@ void heartbeat() {
|
|||
if (hbval < 32) hbdelta = -hbdelta;
|
||||
hbval += hbdelta;
|
||||
analogWrite(LED_HB, hbval);
|
||||
delay(40);
|
||||
delay(20);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
HIGH LITERAL1 Constants
|
||||
LOW LITERAL1 Constants
|
||||
INPUT LITERAL1 Constants
|
||||
INPUT_PULLUP LITERAL1 Constants
|
||||
OUTPUT LITERAL1 Constants
|
||||
DEC LITERAL1 Serial_Print
|
||||
BIN LITERAL1 Serial_Print
|
||||
|
@ -30,6 +31,7 @@ byte KEYWORD1 Byte
|
|||
case KEYWORD1 SwitchCase
|
||||
char KEYWORD1 Char
|
||||
class KEYWORD1
|
||||
const KEYWORD1 Const
|
||||
continue KEYWORD1 Continue
|
||||
default KEYWORD1 SwitchCase
|
||||
do KEYWORD1 DoWhile
|
||||
|
|
|
@ -76,11 +76,16 @@ editor.window.width.default = 500
|
|||
editor.window.height.default = 600
|
||||
|
||||
editor.window.width.min = 400
|
||||
editor.window.height.min = 500
|
||||
editor.window.height.min = 290
|
||||
|
||||
# the following commented out to better support netbooks
|
||||
# http://code.google.com/p/arduino/issues/detail?id=52
|
||||
#editor.window.height.min = 500
|
||||
# tested as approx 440 on OS X
|
||||
editor.window.height.min.macosx = 450
|
||||
#editor.window.height.min.macosx = 450
|
||||
# tested to be 515 on Windows XP, this leaves some room
|
||||
editor.window.height.min.windows = 530
|
||||
#editor.window.height.min.windows = 530
|
||||
|
||||
|
||||
# font size for editor
|
||||
editor.font=Monospaced,plain,12
|
||||
|
@ -245,9 +250,15 @@ software=ARDUINO
|
|||
programmer = arduino:avrispmkii
|
||||
|
||||
upload.using = bootloader
|
||||
upload.verify = true
|
||||
|
||||
serial.port=COM1
|
||||
serial.databits=8
|
||||
serial.stopbits=1
|
||||
serial.parity=N
|
||||
serial.debug_rate=9600
|
||||
|
||||
# I18 Preferences
|
||||
|
||||
# default chosen language (none for none)
|
||||
editor.languages.current =
|
||||
|
|
Binary file not shown.
|
@ -0,0 +1,106 @@
|
|||
;************************************************************
|
||||
; Windows USB CDC ACM Setup File
|
||||
; Copyright (c) 2000 Microsoft Corporation
|
||||
|
||||
|
||||
[Version]
|
||||
Signature="$Windows NT$"
|
||||
Class=Ports
|
||||
ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318}
|
||||
Provider=%MFGNAME%
|
||||
LayoutFile=layout.inf
|
||||
CatalogFile=%MFGFILENAME%.cat
|
||||
DriverVer=11/15/2007,5.1.2600.0
|
||||
|
||||
[Manufacturer]
|
||||
%MFGNAME%=DeviceList, NTamd64
|
||||
|
||||
[DestinationDirs]
|
||||
DefaultDestDir=12
|
||||
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; Windows 2000/XP/Vista-32bit Sections
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
[DriverInstall.nt]
|
||||
include=mdmcpq.inf
|
||||
CopyFiles=DriverCopyFiles.nt
|
||||
AddReg=DriverInstall.nt.AddReg
|
||||
|
||||
[DriverCopyFiles.nt]
|
||||
usbser.sys,,,0x20
|
||||
|
||||
[DriverInstall.nt.AddReg]
|
||||
HKR,,DevLoader,,*ntkern
|
||||
HKR,,NTMPDriver,,%DRIVERFILENAME%.sys
|
||||
HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"
|
||||
|
||||
[DriverInstall.nt.Services]
|
||||
AddService=usbser, 0x00000002, DriverService.nt
|
||||
|
||||
[DriverService.nt]
|
||||
DisplayName=%SERVICE%
|
||||
ServiceType=1
|
||||
StartType=3
|
||||
ErrorControl=1
|
||||
ServiceBinary=%12%\%DRIVERFILENAME%.sys
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; Vista-64bit Sections
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
[DriverInstall.NTamd64]
|
||||
include=mdmcpq.inf
|
||||
CopyFiles=DriverCopyFiles.NTamd64
|
||||
AddReg=DriverInstall.NTamd64.AddReg
|
||||
|
||||
[DriverCopyFiles.NTamd64]
|
||||
%DRIVERFILENAME%.sys,,,0x20
|
||||
|
||||
[DriverInstall.NTamd64.AddReg]
|
||||
HKR,,DevLoader,,*ntkern
|
||||
HKR,,NTMPDriver,,%DRIVERFILENAME%.sys
|
||||
HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"
|
||||
|
||||
[DriverInstall.NTamd64.Services]
|
||||
AddService=usbser, 0x00000002, DriverService.NTamd64
|
||||
|
||||
[DriverService.NTamd64]
|
||||
DisplayName=%SERVICE%
|
||||
ServiceType=1
|
||||
StartType=3
|
||||
ErrorControl=1
|
||||
ServiceBinary=%12%\%DRIVERFILENAME%.sys
|
||||
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; Vendor and Product ID Definitions
|
||||
;------------------------------------------------------------------------------
|
||||
; When developing your USB device, the VID and PID used in the PC side
|
||||
; application program and the firmware on the microcontroller must match.
|
||||
; Modify the below line to use your VID and PID. Use the format as shown below.
|
||||
; Note: One INF file can be used for multiple devices with different VID and PIDs.
|
||||
; For each supported device, append ",USB\VID_xxxx&PID_yyyy" to the end of the line.
|
||||
;------------------------------------------------------------------------------
|
||||
[SourceDisksFiles]
|
||||
[SourceDisksNames]
|
||||
[DeviceList]
|
||||
%DESCRIPTION%=DriverInstall, USB\VID_2341&PID_003B
|
||||
|
||||
[DeviceList.NTamd64]
|
||||
%DESCRIPTION%=DriverInstall, USB\VID_2341&PID_003B
|
||||
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; String Definitions
|
||||
;------------------------------------------------------------------------------
|
||||
;Modify these strings to customize your device
|
||||
;------------------------------------------------------------------------------
|
||||
[Strings]
|
||||
MFGFILENAME="CDC_vista"
|
||||
DRIVERFILENAME ="usbser"
|
||||
MFGNAME="Arduino LLC (www.arduino.cc)"
|
||||
INSTDISK="Arduino USBSerial Driver Installer"
|
||||
DESCRIPTION="Arduino UNO"
|
||||
SERVICE="USB RS-232 Emulation Driver"
|
|
@ -20,6 +20,7 @@ extern "C"{
|
|||
|
||||
#define INPUT 0x0
|
||||
#define OUTPUT 0x1
|
||||
#define INPUT_PULLUP 0x2
|
||||
|
||||
#define true 0x1
|
||||
#define false 0x0
|
||||
|
|
|
@ -46,8 +46,8 @@
|
|||
struct ring_buffer
|
||||
{
|
||||
unsigned char buffer[SERIAL_BUFFER_SIZE];
|
||||
volatile int head;
|
||||
volatile int tail;
|
||||
volatile unsigned int head;
|
||||
volatile unsigned int tail;
|
||||
};
|
||||
|
||||
#if defined(USBCON)
|
||||
|
|
|
@ -41,7 +41,7 @@ size_t Print::write(const uint8_t *buffer, size_t size)
|
|||
|
||||
size_t Print::print(const __FlashStringHelper *ifsh)
|
||||
{
|
||||
const prog_char *p = (const prog_char *)ifsh;
|
||||
const char PROGMEM *p = (const char PROGMEM *)ifsh;
|
||||
size_t n = 0;
|
||||
while (1) {
|
||||
unsigned char c = pgm_read_byte(p++);
|
||||
|
|
|
@ -99,25 +99,27 @@ bool Stream::findUntil(char *target, size_t targetLen, char *terminator, size_t
|
|||
size_t index = 0; // maximum target string length is 64k bytes!
|
||||
size_t termIndex = 0;
|
||||
int c;
|
||||
|
||||
|
||||
if( *target == 0)
|
||||
return true; // return true if target is a null string
|
||||
return true; // return true if target is a null string
|
||||
while( (c = timedRead()) > 0){
|
||||
|
||||
if(c != target[index])
|
||||
index = 0; // reset index if any char does not match
|
||||
|
||||
if( c == target[index]){
|
||||
//////Serial.print("found "); Serial.write(c); Serial.print("index now"); Serial.println(index+1);
|
||||
//////Serial.print("found "); Serial.write(c); Serial.print("index now"); Serial.println(index+1);
|
||||
if(++index >= targetLen){ // return true if all chars in the target match
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else{
|
||||
index = 0; // reset index if any char does not match
|
||||
}
|
||||
|
||||
if(termLen > 0 && c == terminator[termIndex]){
|
||||
if(++termIndex >= termLen)
|
||||
return false; // return false if terminate string found before target string
|
||||
if(++termIndex >= termLen)
|
||||
return false; // return false if terminate string found before target string
|
||||
}
|
||||
else
|
||||
termIndex = 0;
|
||||
termIndex = 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
#include "wiring_private.h"
|
||||
|
||||
volatile static voidFuncPtr intFunc[EXTERNAL_NUM_INTERRUPTS];
|
||||
static volatile voidFuncPtr intFunc[EXTERNAL_NUM_INTERRUPTS];
|
||||
// volatile static voidFuncPtr twiIntFunc;
|
||||
|
||||
void attachInterrupt(uint8_t interruptNum, void (*userFunc)(void), int mode) {
|
||||
|
@ -121,8 +121,6 @@ void attachInterrupt(uint8_t interruptNum, void (*userFunc)(void), int mode) {
|
|||
#elif defined(MCUCR) && defined(ISC20) && defined(GIMSK) && defined(GIMSK)
|
||||
MCUCR = (MCUCR & ~((1 << ISC20) | (1 << ISC21))) | (mode << ISC20);
|
||||
GIMSK |= (1 << INT2);
|
||||
#else
|
||||
#warning attachInterrupt may need some more work for this cpu (case 1)
|
||||
#endif
|
||||
break;
|
||||
#endif
|
||||
|
|
|
@ -500,7 +500,7 @@ int String::lastIndexOf( char theChar ) const
|
|||
|
||||
int String::lastIndexOf(char ch, unsigned int fromIndex) const
|
||||
{
|
||||
if (fromIndex >= len || fromIndex < 0) return -1;
|
||||
if (fromIndex >= len) return -1;
|
||||
char tempchar = buffer[fromIndex + 1];
|
||||
buffer[fromIndex + 1] = '\0';
|
||||
char* temp = strrchr( buffer, ch );
|
||||
|
@ -516,7 +516,7 @@ int String::lastIndexOf(const String &s2) const
|
|||
|
||||
int String::lastIndexOf(const String &s2, unsigned int fromIndex) const
|
||||
{
|
||||
if (s2.len == 0 || len == 0 || s2.len > len || fromIndex < 0) return -1;
|
||||
if (s2.len == 0 || len == 0 || s2.len > len) return -1;
|
||||
if (fromIndex >= len) fromIndex = len - 1;
|
||||
int found = -1;
|
||||
for (char *p = buffer; p <= buffer + fromIndex; p++) {
|
||||
|
|
|
@ -45,6 +45,8 @@ int analogRead(uint8_t pin)
|
|||
if (pin >= 54) pin -= 54; // allow for channel or pin numbers
|
||||
#elif defined(__AVR_ATmega32U4__)
|
||||
if (pin >= 18) pin -= 18; // allow for channel or pin numbers
|
||||
#elif defined(__AVR_ATmega1284__)
|
||||
if (pin >= 24) pin -= 24; // allow for channel or pin numbers
|
||||
#else
|
||||
if (pin >= 14) pin -= 14; // allow for channel or pin numbers
|
||||
#endif
|
||||
|
|
|
@ -32,17 +32,25 @@ void pinMode(uint8_t pin, uint8_t mode)
|
|||
{
|
||||
uint8_t bit = digitalPinToBitMask(pin);
|
||||
uint8_t port = digitalPinToPort(pin);
|
||||
volatile uint8_t *reg;
|
||||
volatile uint8_t *reg, *out;
|
||||
|
||||
if (port == NOT_A_PIN) return;
|
||||
|
||||
// JWS: can I let the optimizer do this?
|
||||
reg = portModeRegister(port);
|
||||
out = portOutputRegister(port);
|
||||
|
||||
if (mode == INPUT) {
|
||||
uint8_t oldSREG = SREG;
|
||||
cli();
|
||||
*reg &= ~bit;
|
||||
*out &= ~bit;
|
||||
SREG = oldSREG;
|
||||
} else if (mode == INPUT_PULLUP) {
|
||||
uint8_t oldSREG = SREG;
|
||||
cli();
|
||||
*reg &= ~bit;
|
||||
*out |= bit;
|
||||
SREG = oldSREG;
|
||||
} else {
|
||||
uint8_t oldSREG = SREG;
|
||||
|
|
|
@ -11,13 +11,33 @@
|
|||
|
||||
int DhcpClass::beginWithDHCP(uint8_t *mac, unsigned long timeout, unsigned long responseTimeout)
|
||||
{
|
||||
uint8_t dhcp_state = STATE_DHCP_START;
|
||||
uint8_t messageType = 0;
|
||||
|
||||
// zero out _dhcpMacAddr, _dhcpSubnetMask, _dhcpGatewayIp, _dhcpLocalIp, _dhcpDhcpServerIp, _dhcpDnsServerIp
|
||||
memset(_dhcpMacAddr, 0, 26);
|
||||
_dhcpLeaseTime=0;
|
||||
_dhcpT1=0;
|
||||
_dhcpT2=0;
|
||||
_lastCheck=0;
|
||||
_timeout = timeout;
|
||||
_responseTimeout = responseTimeout;
|
||||
|
||||
// zero out _dhcpMacAddr
|
||||
memset(_dhcpMacAddr, 0, 6);
|
||||
reset_DHCP_lease();
|
||||
|
||||
memcpy((void*)_dhcpMacAddr, (void*)mac, 6);
|
||||
_dhcp_state = STATE_DHCP_START;
|
||||
return request_DHCP_lease();
|
||||
}
|
||||
|
||||
void DhcpClass::reset_DHCP_lease(){
|
||||
// zero out _dhcpSubnetMask, _dhcpGatewayIp, _dhcpLocalIp, _dhcpDhcpServerIp, _dhcpDnsServerIp
|
||||
memset(_dhcpLocalIp, 0, 20);
|
||||
}
|
||||
|
||||
//return:0 on error, 1 if request is sent and response is received
|
||||
int DhcpClass::request_DHCP_lease(){
|
||||
|
||||
uint8_t messageType = 0;
|
||||
|
||||
|
||||
|
||||
// Pick an initial transaction ID
|
||||
_dhcpTransactionId = random(1UL, 2000UL);
|
||||
|
@ -35,55 +55,75 @@ int DhcpClass::beginWithDHCP(uint8_t *mac, unsigned long timeout, unsigned long
|
|||
|
||||
unsigned long startTime = millis();
|
||||
|
||||
while(dhcp_state != STATE_DHCP_LEASED)
|
||||
while(_dhcp_state != STATE_DHCP_LEASED)
|
||||
{
|
||||
if(dhcp_state == STATE_DHCP_START)
|
||||
if(_dhcp_state == STATE_DHCP_START)
|
||||
{
|
||||
_dhcpTransactionId++;
|
||||
|
||||
send_DHCP_MESSAGE(DHCP_DISCOVER, ((millis() - startTime) / 1000));
|
||||
dhcp_state = STATE_DHCP_DISCOVER;
|
||||
_dhcp_state = STATE_DHCP_DISCOVER;
|
||||
}
|
||||
else if(dhcp_state == STATE_DHCP_DISCOVER)
|
||||
else if(_dhcp_state == STATE_DHCP_REREQUEST){
|
||||
_dhcpTransactionId++;
|
||||
send_DHCP_MESSAGE(DHCP_REQUEST, ((millis() - startTime)/1000));
|
||||
_dhcp_state = STATE_DHCP_REQUEST;
|
||||
}
|
||||
else if(_dhcp_state == STATE_DHCP_DISCOVER)
|
||||
{
|
||||
uint32_t respId;
|
||||
messageType = parseDHCPResponse(responseTimeout, respId);
|
||||
messageType = parseDHCPResponse(_responseTimeout, respId);
|
||||
if(messageType == DHCP_OFFER)
|
||||
{
|
||||
// We'll use the transaction ID that the offer came with,
|
||||
// rather than the one we were up to
|
||||
_dhcpTransactionId = respId;
|
||||
send_DHCP_MESSAGE(DHCP_REQUEST, ((millis() - startTime) / 1000));
|
||||
dhcp_state = STATE_DHCP_REQUEST;
|
||||
_dhcp_state = STATE_DHCP_REQUEST;
|
||||
}
|
||||
}
|
||||
else if(dhcp_state == STATE_DHCP_REQUEST)
|
||||
else if(_dhcp_state == STATE_DHCP_REQUEST)
|
||||
{
|
||||
uint32_t respId;
|
||||
messageType = parseDHCPResponse(responseTimeout, respId);
|
||||
messageType = parseDHCPResponse(_responseTimeout, respId);
|
||||
if(messageType == DHCP_ACK)
|
||||
{
|
||||
dhcp_state = STATE_DHCP_LEASED;
|
||||
_dhcp_state = STATE_DHCP_LEASED;
|
||||
result = 1;
|
||||
//use default lease time if we didn't get it
|
||||
if(_dhcpLeaseTime == 0){
|
||||
_dhcpLeaseTime = DEFAULT_LEASE;
|
||||
}
|
||||
//calculate T1 & T2 if we didn't get it
|
||||
if(_dhcpT1 == 0){
|
||||
//T1 should be 50% of _dhcpLeaseTime
|
||||
_dhcpT1 = _dhcpLeaseTime >> 1;
|
||||
}
|
||||
if(_dhcpT2 == 0){
|
||||
//T2 should be 87.5% (7/8ths) of _dhcpLeaseTime
|
||||
_dhcpT2 = _dhcpT1 << 1;
|
||||
}
|
||||
_renewInSec = _dhcpT1;
|
||||
_rebindInSec = _dhcpT2;
|
||||
}
|
||||
else if(messageType == DHCP_NAK)
|
||||
dhcp_state = STATE_DHCP_START;
|
||||
_dhcp_state = STATE_DHCP_START;
|
||||
}
|
||||
|
||||
if(messageType == 255)
|
||||
{
|
||||
messageType = 0;
|
||||
dhcp_state = STATE_DHCP_START;
|
||||
_dhcp_state = STATE_DHCP_START;
|
||||
}
|
||||
|
||||
if(result != 1 && ((millis() - startTime) > timeout))
|
||||
if(result != 1 && ((millis() - startTime) > _timeout))
|
||||
break;
|
||||
}
|
||||
|
||||
// We're done with the socket now
|
||||
_dhcpUdpSocket.stop();
|
||||
_dhcpTransactionId++;
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -302,8 +342,26 @@ uint8_t DhcpClass::parseDHCPResponse(unsigned long responseTimeout, uint32_t& tr
|
|||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case dhcpT1value :
|
||||
opt_len = _dhcpUdpSocket.read();
|
||||
_dhcpUdpSocket.read((uint8_t*)&_dhcpT1, sizeof(_dhcpT1));
|
||||
_dhcpT1 = ntohl(_dhcpT1);
|
||||
break;
|
||||
|
||||
case dhcpT2value :
|
||||
opt_len = _dhcpUdpSocket.read();
|
||||
_dhcpUdpSocket.read((uint8_t*)&_dhcpT2, sizeof(_dhcpT2));
|
||||
_dhcpT2 = ntohl(_dhcpT2);
|
||||
break;
|
||||
|
||||
case dhcpIPaddrLeaseTime :
|
||||
opt_len = _dhcpUdpSocket.read();
|
||||
_dhcpUdpSocket.read((uint8_t*)&_dhcpLeaseTime, sizeof(_dhcpLeaseTime));
|
||||
_dhcpLeaseTime = ntohl(_dhcpLeaseTime);
|
||||
_renewInSec = _dhcpLeaseTime;
|
||||
break;
|
||||
|
||||
default :
|
||||
opt_len = _dhcpUdpSocket.read();
|
||||
// Skip over the rest of this option
|
||||
|
@ -322,6 +380,68 @@ uint8_t DhcpClass::parseDHCPResponse(unsigned long responseTimeout, uint32_t& tr
|
|||
return type;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
returns:
|
||||
0/DHCP_CHECK_NONE: nothing happened
|
||||
1/DHCP_CHECK_RENEW_FAIL: renew failed
|
||||
2/DHCP_CHECK_RENEW_OK: renew success
|
||||
3/DHCP_CHECK_REBIND_FAIL: rebind fail
|
||||
4/DHCP_CHECK_REBIND_OK: rebind success
|
||||
*/
|
||||
int DhcpClass::checkLease(){
|
||||
//this uses a signed / unsigned trick to deal with millis overflow
|
||||
unsigned long now = millis();
|
||||
signed long snow = (long)now;
|
||||
int rc=DHCP_CHECK_NONE;
|
||||
if (_lastCheck != 0){
|
||||
signed long factor;
|
||||
//calc how many ms past the timeout we are
|
||||
factor = snow - (long)_secTimeout;
|
||||
//if on or passed the timeout, reduce the counters
|
||||
if ( factor >= 0 ){
|
||||
//next timeout should be now plus 1000 ms minus parts of second in factor
|
||||
_secTimeout = snow + 1000 - factor % 1000;
|
||||
//how many seconds late are we, minimum 1
|
||||
factor = factor / 1000 +1;
|
||||
|
||||
//reduce the counters by that mouch
|
||||
//if we can assume that the cycle time (factor) is fairly constant
|
||||
//and if the remainder is less than cycle time * 2
|
||||
//do it early instead of late
|
||||
if(_renewInSec < factor*2 )
|
||||
_renewInSec = 0;
|
||||
else
|
||||
_renewInSec -= factor;
|
||||
|
||||
if(_rebindInSec < factor*2 )
|
||||
_rebindInSec = 0;
|
||||
else
|
||||
_rebindInSec -= factor;
|
||||
}
|
||||
|
||||
//if we have a lease but should renew, do it
|
||||
if (_dhcp_state == STATE_DHCP_LEASED && _renewInSec <=0){
|
||||
_dhcp_state = STATE_DHCP_REREQUEST;
|
||||
rc = 1 + request_DHCP_lease();
|
||||
}
|
||||
|
||||
//if we have a lease or is renewing but should bind, do it
|
||||
if( (_dhcp_state == STATE_DHCP_LEASED || _dhcp_state == STATE_DHCP_START) && _rebindInSec <=0){
|
||||
//this should basically restart completely
|
||||
_dhcp_state = STATE_DHCP_START;
|
||||
reset_DHCP_lease();
|
||||
rc = 3 + request_DHCP_lease();
|
||||
}
|
||||
}
|
||||
else{
|
||||
_secTimeout = snow + 1000;
|
||||
}
|
||||
|
||||
_lastCheck = now;
|
||||
return rc;
|
||||
}
|
||||
|
||||
IPAddress DhcpClass::getLocalIp()
|
||||
{
|
||||
return IPAddress(_dhcpLocalIp);
|
||||
|
|
|
@ -45,6 +45,13 @@
|
|||
#define MAX_DHCP_OPT 16
|
||||
|
||||
#define HOST_NAME "WIZnet"
|
||||
#define DEFAULT_LEASE (900) //default lease time in seconds
|
||||
|
||||
#define DHCP_CHECK_NONE (0)
|
||||
#define DHCP_CHECK_RENEW_FAIL (1)
|
||||
#define DHCP_CHECK_RENEW_OK (2)
|
||||
#define DHCP_CHECK_REBIND_FAIL (3)
|
||||
#define DHCP_CHECK_REBIND_OK (4)
|
||||
|
||||
enum
|
||||
{
|
||||
|
@ -139,8 +146,19 @@ private:
|
|||
uint8_t _dhcpGatewayIp[4];
|
||||
uint8_t _dhcpDhcpServerIp[4];
|
||||
uint8_t _dhcpDnsServerIp[4];
|
||||
uint32_t _dhcpLeaseTime;
|
||||
uint32_t _dhcpT1, _dhcpT2;
|
||||
signed long _renewInSec;
|
||||
signed long _rebindInSec;
|
||||
signed long _lastCheck;
|
||||
unsigned long _timeout;
|
||||
unsigned long _responseTimeout;
|
||||
unsigned long _secTimeout;
|
||||
uint8_t _dhcp_state;
|
||||
EthernetUDP _dhcpUdpSocket;
|
||||
|
||||
int request_DHCP_lease();
|
||||
void reset_DHCP_lease();
|
||||
void presend_DHCP();
|
||||
void send_DHCP_MESSAGE(uint8_t, uint16_t);
|
||||
void printByte(char *, uint8_t);
|
||||
|
@ -154,6 +172,7 @@ public:
|
|||
IPAddress getDnsServerIp();
|
||||
|
||||
int beginWithDHCP(uint8_t *, unsigned long timeout = 60000, unsigned long responseTimeout = 4000);
|
||||
int checkLease();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -10,7 +10,8 @@ uint16_t EthernetClass::_server_port[MAX_SOCK_NUM] = {
|
|||
|
||||
int EthernetClass::begin(uint8_t *mac_address)
|
||||
{
|
||||
DhcpClass dhcp;
|
||||
_dhcp = new DhcpClass();
|
||||
|
||||
|
||||
// Initialise the basic info
|
||||
W5100.init();
|
||||
|
@ -18,15 +19,15 @@ int EthernetClass::begin(uint8_t *mac_address)
|
|||
W5100.setIPAddress(IPAddress(0,0,0,0).raw_address());
|
||||
|
||||
// Now try to get our config info from a DHCP server
|
||||
int ret = dhcp.beginWithDHCP(mac_address);
|
||||
int ret = _dhcp->beginWithDHCP(mac_address);
|
||||
if(ret == 1)
|
||||
{
|
||||
// We've successfully found a DHCP server and got our configuration info, so set things
|
||||
// accordingly
|
||||
W5100.setIPAddress(dhcp.getLocalIp().raw_address());
|
||||
W5100.setGatewayIp(dhcp.getGatewayIp().raw_address());
|
||||
W5100.setSubnetMask(dhcp.getSubnetMask().raw_address());
|
||||
_dnsServerAddress = dhcp.getDnsServerIp();
|
||||
W5100.setIPAddress(_dhcp->getLocalIp().raw_address());
|
||||
W5100.setGatewayIp(_dhcp->getGatewayIp().raw_address());
|
||||
W5100.setSubnetMask(_dhcp->getSubnetMask().raw_address());
|
||||
_dnsServerAddress = _dhcp->getDnsServerIp();
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -66,6 +67,31 @@ void EthernetClass::begin(uint8_t *mac, IPAddress local_ip, IPAddress dns_server
|
|||
_dnsServerAddress = dns_server;
|
||||
}
|
||||
|
||||
int EthernetClass::maintain(){
|
||||
int rc = DHCP_CHECK_NONE;
|
||||
if(_dhcp != NULL){
|
||||
//we have a pointer to dhcp, use it
|
||||
rc = _dhcp->checkLease();
|
||||
switch ( rc ){
|
||||
case DHCP_CHECK_NONE:
|
||||
//nothing done
|
||||
break;
|
||||
case DHCP_CHECK_RENEW_OK:
|
||||
case DHCP_CHECK_REBIND_OK:
|
||||
//we might have got a new IP.
|
||||
W5100.setIPAddress(_dhcp->getLocalIp().raw_address());
|
||||
W5100.setGatewayIp(_dhcp->getGatewayIp().raw_address());
|
||||
W5100.setSubnetMask(_dhcp->getSubnetMask().raw_address());
|
||||
_dnsServerAddress = _dhcp->getDnsServerIp();
|
||||
break;
|
||||
default:
|
||||
//this is actually a error, it will retry though
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
IPAddress EthernetClass::localIP()
|
||||
{
|
||||
IPAddress ret;
|
||||
|
|
|
@ -6,12 +6,14 @@
|
|||
#include "IPAddress.h"
|
||||
#include "EthernetClient.h"
|
||||
#include "EthernetServer.h"
|
||||
#include "Dhcp.h"
|
||||
|
||||
#define MAX_SOCK_NUM 4
|
||||
|
||||
class EthernetClass {
|
||||
private:
|
||||
IPAddress _dnsServerAddress;
|
||||
DhcpClass* _dhcp;
|
||||
public:
|
||||
static uint8_t _state[MAX_SOCK_NUM];
|
||||
static uint16_t _server_port[MAX_SOCK_NUM];
|
||||
|
@ -23,6 +25,7 @@ public:
|
|||
void begin(uint8_t *mac_address, IPAddress local_ip, IPAddress dns_server);
|
||||
void begin(uint8_t *mac_address, IPAddress local_ip, IPAddress dns_server, IPAddress gateway);
|
||||
void begin(uint8_t *mac_address, IPAddress local_ip, IPAddress dns_server, IPAddress gateway, IPAddress subnet);
|
||||
int maintain();
|
||||
|
||||
IPAddress localIP();
|
||||
IPAddress subnetMask();
|
||||
|
|
|
@ -41,7 +41,7 @@ int EthernetClient::connect(IPAddress ip, uint16_t port) {
|
|||
|
||||
for (int i = 0; i < MAX_SOCK_NUM; i++) {
|
||||
uint8_t s = W5100.readSnSR(i);
|
||||
if (s == SnSR::CLOSED || s == SnSR::FIN_WAIT) {
|
||||
if (s == SnSR::CLOSED || s == SnSR::FIN_WAIT || s == SnSR::CLOSE_WAIT) {
|
||||
_sock = i;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -52,15 +52,16 @@ uint8_t EthernetUDP::begin(uint16_t port) {
|
|||
return 0;
|
||||
|
||||
_port = port;
|
||||
_remaining = 0;
|
||||
socket(_sock, SnMR::UDP, _port, 0);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Is data available in rx buffer? Returns 0 if no, number of available bytes if yes.
|
||||
* returned value includes 8 byte UDP header!*/
|
||||
/* return number of bytes available in the current packet,
|
||||
will return zero if parsePacket hasn't been called yet */
|
||||
int EthernetUDP::available() {
|
||||
return W5100.getRXReceivedSize(_sock);
|
||||
return _remaining;
|
||||
}
|
||||
|
||||
/* Release any resources being used by this EthernetUDP instance */
|
||||
|
@ -116,11 +117,14 @@ size_t EthernetUDP::write(const uint8_t *buffer, size_t size)
|
|||
|
||||
int EthernetUDP::parsePacket()
|
||||
{
|
||||
if (available() > 0)
|
||||
// discard any remaining bytes in the last packet
|
||||
flush();
|
||||
|
||||
if (W5100.getRXReceivedSize(_sock) > 0)
|
||||
{
|
||||
//HACK - hand-parse the UDP packet using TCP recv method
|
||||
uint8_t tmpBuf[8];
|
||||
int ret =0;
|
||||
int ret =0;
|
||||
//read 8 header bytes and get IP and port from it
|
||||
ret = recv(_sock,tmpBuf,8);
|
||||
if (ret > 0)
|
||||
|
@ -128,8 +132,11 @@ int EthernetUDP::parsePacket()
|
|||
_remoteIP = tmpBuf;
|
||||
_remotePort = tmpBuf[4];
|
||||
_remotePort = (_remotePort << 8) + tmpBuf[5];
|
||||
_remaining = tmpBuf[6];
|
||||
_remaining = (_remaining << 8) + tmpBuf[7];
|
||||
|
||||
// When we get here, any remaining bytes are the data
|
||||
ret = available();
|
||||
ret = _remaining;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@ -140,34 +147,58 @@ int EthernetUDP::parsePacket()
|
|||
int EthernetUDP::read()
|
||||
{
|
||||
uint8_t byte;
|
||||
if (recv(_sock, &byte, 1) > 0)
|
||||
|
||||
if ((_remaining > 0) && (recv(_sock, &byte, 1) > 0))
|
||||
{
|
||||
// We read things without any problems
|
||||
_remaining--;
|
||||
return byte;
|
||||
}
|
||||
|
||||
// If we get here, there's no data available
|
||||
return -1;
|
||||
}
|
||||
|
||||
int EthernetUDP::read(unsigned char* buffer, size_t len)
|
||||
{
|
||||
/* In the readPacket that copes with truncating packets, the buffer was
|
||||
filled with this code. Not sure why it loops round reading out a byte
|
||||
at a time.
|
||||
int i;
|
||||
for(i=0;i<(int)bufLen;i++) {
|
||||
recv(_sock,tmpBuf,1);
|
||||
buf[i]=tmpBuf[0];
|
||||
|
||||
if (_remaining > 0)
|
||||
{
|
||||
|
||||
int got;
|
||||
|
||||
if (_remaining <= len)
|
||||
{
|
||||
// data should fit in the buffer
|
||||
got = recv(_sock, buffer, _remaining);
|
||||
}
|
||||
else
|
||||
{
|
||||
// too much data for the buffer,
|
||||
// grab as much as will fit
|
||||
got = recv(_sock, buffer, len);
|
||||
}
|
||||
|
||||
if (got > 0)
|
||||
{
|
||||
_remaining -= got;
|
||||
return got;
|
||||
}
|
||||
|
||||
}
|
||||
*/
|
||||
return recv(_sock, buffer, len);
|
||||
|
||||
// If we get here, there's no data available or recv failed
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
int EthernetUDP::peek()
|
||||
{
|
||||
uint8_t b;
|
||||
// Unlike recv, peek doesn't check to see if there's any data available, so we must
|
||||
if (!available())
|
||||
// Unlike recv, peek doesn't check to see if there's any data available, so we must.
|
||||
// If the user hasn't called parsePacket yet then return nothing otherwise they
|
||||
// may get the UDP header
|
||||
if (!_remaining)
|
||||
return -1;
|
||||
::peek(_sock, &b);
|
||||
return b;
|
||||
|
@ -175,7 +206,11 @@ int EthernetUDP::peek()
|
|||
|
||||
void EthernetUDP::flush()
|
||||
{
|
||||
while (available())
|
||||
// could this fail (loop endlessly) if _remaining > 0 and recv in read fails?
|
||||
// should only occur if recv fails after telling us the data is there, lets
|
||||
// hope the w5100 always behaves :)
|
||||
|
||||
while (_remaining)
|
||||
{
|
||||
read();
|
||||
}
|
||||
|
|
|
@ -48,6 +48,7 @@ private:
|
|||
IPAddress _remoteIP; // remote IP address for the incoming packet whilst it's being processed
|
||||
uint16_t _remotePort; // remote port for the incoming packet whilst it's being processed
|
||||
uint16_t _offset; // offset into the packet being sent
|
||||
uint16_t _remaining; // remaining bytes of incoming packet yet to be processed
|
||||
|
||||
public:
|
||||
EthernetUDP(); // Constructor
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
created 18 Dec 2009
|
||||
by David A. Mellis
|
||||
modified 10 August 2010
|
||||
modified 12 March 2012
|
||||
by Tom Igoe
|
||||
|
||||
*/
|
||||
|
@ -23,14 +23,16 @@
|
|||
// Enter a MAC address and IP address for your controller below.
|
||||
// The IP address will be dependent on your local network.
|
||||
// gateway and subnet are optional:
|
||||
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
|
||||
byte mac[] = {
|
||||
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
|
||||
IPAddress ip(192,168,1, 177);
|
||||
IPAddress gateway(192,168,1, 1);
|
||||
IPAddress subnet(255, 255, 0, 0);
|
||||
|
||||
|
||||
// telnet defaults to port 23
|
||||
EthernetServer server(23);
|
||||
boolean gotAMessage = false; // whether or not you got a message from the client yet
|
||||
boolean alreadyConnected = false; // whether or not the client was connected previously
|
||||
|
||||
void setup() {
|
||||
// initialize the ethernet device
|
||||
|
@ -39,25 +41,34 @@ void setup() {
|
|||
server.begin();
|
||||
// open the serial port
|
||||
Serial.begin(9600);
|
||||
Serial.print("Chat server address:");
|
||||
Serial.println(Ethernet.localIP());
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// wait for a new client:
|
||||
EthernetClient client = server.available();
|
||||
|
||||
|
||||
// when the client sends the first byte, say hello:
|
||||
if (client) {
|
||||
if (!gotAMessage) {
|
||||
if (!alreadyConnected) {
|
||||
// clead out the input buffer:
|
||||
client.flush();
|
||||
Serial.println("We have a new client");
|
||||
client.println("Hello, client!");
|
||||
gotAMessage = true;
|
||||
alreadyConnected = true;
|
||||
}
|
||||
|
||||
if (client.available() > 0) {
|
||||
// read the bytes incoming from the client:
|
||||
char thisChar = client.read();
|
||||
// echo the bytes back to the client:
|
||||
server.write(thisChar);
|
||||
// echo the bytes to the server as well:
|
||||
Serial.write(thisChar);
|
||||
}
|
||||
|
||||
// read the bytes incoming from the client:
|
||||
char thisChar = client.read();
|
||||
// echo the bytes back to the client:
|
||||
server.write(thisChar);
|
||||
// echo the bytes to the server as well:
|
||||
Serial.print(thisChar);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -6,15 +6,20 @@
|
|||
the Adafruit Ethernet shield, either one will work, as long as it's got
|
||||
a Wiznet Ethernet module on board.
|
||||
|
||||
This example has been updated to use version 2.0 of the Pachube.com API.
|
||||
To make it work, create a feed with a datastream, and give it the ID
|
||||
sensor1. Or change the code below to match your feed.
|
||||
|
||||
|
||||
Circuit:
|
||||
* Analog sensor attached to analog in 0
|
||||
* Ethernet shield attached to pins 10, 11, 12, 13
|
||||
|
||||
created 15 March 2010
|
||||
updated 26 Oct 2011
|
||||
by Tom Igoe
|
||||
updated 16 Mar 2012
|
||||
by Tom Igoe with input from Usman Haque and Joe Saavedra
|
||||
|
||||
http://www.tigoe.net/pcomp/code/category/arduinowiring/873
|
||||
http://arduino.cc/en/Tutorial/PachubeClient
|
||||
This code is in the public domain.
|
||||
|
||||
*/
|
||||
|
@ -22,6 +27,10 @@
|
|||
#include <SPI.h>
|
||||
#include <Ethernet.h>
|
||||
|
||||
#define APIKEY "YOUR API KEY GOES HERE" // replace your pachube api key here
|
||||
#define FEEDID 00000 // replace your feed ID
|
||||
#define USERAGENT "My Project" // user agent is the project name
|
||||
|
||||
// assign a MAC address for the ethernet controller.
|
||||
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
|
||||
// fill in your address here:
|
||||
|
@ -34,26 +43,22 @@ IPAddress ip(10,0,1,20);
|
|||
// initialize the library instance:
|
||||
EthernetClient client;
|
||||
|
||||
long lastConnectionTime = 0; // last time you connected to the server, in milliseconds
|
||||
boolean lastConnected = false; // state of the connection last time through the main loop
|
||||
const int postingInterval = 10000; //delay between updates to Pachube.com
|
||||
// if you don't want to use DNS (and reduce your sketch size)
|
||||
// use the numeric IP instead of the name for the server:
|
||||
IPAddress server(216,52,233,122); // numeric IP for api.pachube.com
|
||||
//char server[] = "api.pachube.com"; // name address for pachube API
|
||||
|
||||
unsigned long lastConnectionTime = 0; // last time you connected to the server, in milliseconds
|
||||
boolean lastConnected = false; // state of the connection last time through the main loop
|
||||
const unsigned long postingInterval = 10*1000; //delay between updates to Pachube.com
|
||||
|
||||
void setup() {
|
||||
// start serial port:
|
||||
Serial.begin(9600);
|
||||
// start the Ethernet connection:
|
||||
// start the Ethernet connection:
|
||||
if (Ethernet.begin(mac) == 0) {
|
||||
Serial.println("Failed to configure Ethernet using DHCP");
|
||||
// no point in carrying on, so do nothing forevermore:
|
||||
for(;;)
|
||||
;
|
||||
}
|
||||
// give the ethernet module time to boot up:
|
||||
delay(1000);
|
||||
// start the Ethernet connection:
|
||||
if (Ethernet.begin(mac) == 0) {
|
||||
Serial.println("Failed to configure Ethernet using DHCP");
|
||||
// Configure manually:
|
||||
// DHCP failed, so use a fixed IP address:
|
||||
Ethernet.begin(mac, ip);
|
||||
}
|
||||
}
|
||||
|
@ -91,34 +96,43 @@ void loop() {
|
|||
// this method makes a HTTP connection to the server:
|
||||
void sendData(int thisData) {
|
||||
// if there's a successful connection:
|
||||
if (client.connect("www.pachube.com", 80)) {
|
||||
if (client.connect(server, 80)) {
|
||||
Serial.println("connecting...");
|
||||
// send the HTTP PUT request.
|
||||
// fill in your feed address here:
|
||||
client.print("PUT /api/YOUR_FEED_HERE.csv HTTP/1.1\n");
|
||||
client.print("Host: www.pachube.com\n");
|
||||
// fill in your Pachube API key here:
|
||||
client.print("X-PachubeApiKey: YOUR_KEY_HERE\n");
|
||||
// send the HTTP PUT request:
|
||||
client.print("PUT /v2/feeds/");
|
||||
client.print(FEEDID);
|
||||
client.println(".csv HTTP/1.1");
|
||||
client.println("Host: api.pachube.com");
|
||||
client.print("X-PachubeApiKey: ");
|
||||
client.println(APIKEY);
|
||||
client.print("User-Agent: ");
|
||||
client.println(USERAGENT);
|
||||
client.print("Content-Length: ");
|
||||
|
||||
// calculate the length of the sensor reading in bytes:
|
||||
int thisLength = getLength(thisData);
|
||||
client.println(thisLength, DEC);
|
||||
// 8 bytes for "sensor1," + number of digits of the data:
|
||||
int thisLength = 8 + getLength(thisData);
|
||||
client.println(thisLength);
|
||||
|
||||
// last pieces of the HTTP PUT request:
|
||||
client.print("Content-Type: text/csv\n");
|
||||
client.println("Connection: close\n");
|
||||
client.println("Content-Type: text/csv");
|
||||
client.println("Connection: close");
|
||||
client.println();
|
||||
|
||||
// here's the actual content of the PUT request:
|
||||
client.println(thisData, DEC);
|
||||
|
||||
// note the time that the connection was made:
|
||||
lastConnectionTime = millis();
|
||||
client.print("sensor1,");
|
||||
client.println(thisData);
|
||||
|
||||
}
|
||||
else {
|
||||
// if you couldn't make a connection:
|
||||
Serial.println("connection failed");
|
||||
Serial.println();
|
||||
Serial.println("disconnecting.");
|
||||
client.stop();
|
||||
}
|
||||
// note the time that the connection was made or attempted:
|
||||
lastConnectionTime = millis();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -6,6 +6,10 @@
|
|||
the Adafruit Ethernet shield, either one will work, as long as it's got
|
||||
a Wiznet Ethernet module on board.
|
||||
|
||||
This example has been updated to use version 2.0 of the Pachube.com API.
|
||||
To make it work, create a feed with two datastreams, and give them the IDs
|
||||
sensor1 and sensor2. Or change the code below to match your feed.
|
||||
|
||||
This example uses the String library, which is part of the Arduino core from
|
||||
version 0019.
|
||||
|
||||
|
@ -14,9 +18,10 @@
|
|||
* Ethernet shield attached to pins 10, 11, 12, 13
|
||||
|
||||
created 15 March 2010
|
||||
updated 26 Oct 2011
|
||||
by Tom Igoe
|
||||
updated 16 Mar 2012
|
||||
by Tom Igoe with input from Usman Haque and Joe Saavedra
|
||||
|
||||
http://arduino.cc/en/Tutorial/PachubeClientString
|
||||
This code is in the public domain.
|
||||
|
||||
*/
|
||||
|
@ -24,9 +29,14 @@
|
|||
#include <SPI.h>
|
||||
#include <Ethernet.h>
|
||||
|
||||
|
||||
#define APIKEY "YOUR API KEY GOES HERE" // replace your pachube api key here
|
||||
#define FEEDID 00000 // replace your feed ID
|
||||
#define USERAGENT "My Project" // user agent is the project name
|
||||
|
||||
// assign a MAC address for the ethernet controller.
|
||||
// fill in your address here:
|
||||
byte mac[] = {
|
||||
byte mac[] = {
|
||||
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
|
||||
// fill in an available IP address on your network here,
|
||||
// for manual configuration:
|
||||
|
@ -35,9 +45,14 @@ IPAddress ip(10,0,1,20);
|
|||
// initialize the library instance:
|
||||
EthernetClient client;
|
||||
|
||||
long lastConnectionTime = 0; // last time you connected to the server, in milliseconds
|
||||
boolean lastConnected = false; // state of the connection last time through the main loop
|
||||
const int postingInterval = 10000; //delay between updates to Pachube.com
|
||||
// if you don't want to use DNS (and reduce your sketch size)
|
||||
// use the numeric IP instead of the name for the server:
|
||||
//IPAddress server(216,52,233,122); // numeric IP for api.pachube.com
|
||||
char server[] = "api.pachube.com"; // name address for pachube API
|
||||
|
||||
unsigned long lastConnectionTime = 0; // last time you connected to the server, in milliseconds
|
||||
boolean lastConnected = false; // state of the connection last time through the main loop
|
||||
const unsigned long postingInterval = 10*1000; //delay between updates to Pachube.com
|
||||
|
||||
void setup() {
|
||||
// start serial port:
|
||||
|
@ -47,7 +62,7 @@ void setup() {
|
|||
// start the Ethernet connection:
|
||||
if (Ethernet.begin(mac) == 0) {
|
||||
Serial.println("Failed to configure Ethernet using DHCP");
|
||||
// Configure manually:
|
||||
// DHCP failed, so use a fixed IP address:
|
||||
Ethernet.begin(mac, ip);
|
||||
}
|
||||
}
|
||||
|
@ -56,13 +71,15 @@ void loop() {
|
|||
// read the analog sensor:
|
||||
int sensorReading = analogRead(A0);
|
||||
// convert the data to a String to send it:
|
||||
String dataString = String(sensorReading);
|
||||
|
||||
String dataString = "sensor1,";
|
||||
dataString += sensorReading;
|
||||
|
||||
// you can append multiple readings to this String if your
|
||||
// pachube feed is set up to handle multiple values:
|
||||
int otherSensorReading = analogRead(A1);
|
||||
dataString += ",";
|
||||
dataString += String(otherSensorReading);
|
||||
dataString += "\nsensor2,";
|
||||
dataString += otherSensorReading;
|
||||
|
||||
// if there's incoming data from the net connection.
|
||||
// send it out the serial port. This is for debugging
|
||||
|
@ -81,7 +98,7 @@ void loop() {
|
|||
}
|
||||
|
||||
// if you're not connected, and ten seconds have passed since
|
||||
// your last connection, then connect again and send data:
|
||||
// your last connection, then connect again and send data:
|
||||
if(!client.connected() && (millis() - lastConnectionTime > postingInterval)) {
|
||||
sendData(dataString);
|
||||
}
|
||||
|
@ -93,29 +110,36 @@ void loop() {
|
|||
// this method makes a HTTP connection to the server:
|
||||
void sendData(String thisData) {
|
||||
// if there's a successful connection:
|
||||
if (client.connect("www.pachube.com", 80)) {
|
||||
if (client.connect(server, 80)) {
|
||||
Serial.println("connecting...");
|
||||
// send the HTTP PUT request.
|
||||
// fill in your feed address here:
|
||||
client.print("PUT /api/YOUR_FEED_HERE.csv HTTP/1.1\n");
|
||||
client.print("Host: www.pachube.com\n");
|
||||
// fill in your Pachube API key here:
|
||||
client.print("X-PachubeApiKey: YOUR_KEY_HERE\n");
|
||||
// send the HTTP PUT request:
|
||||
client.print("PUT /v2/feeds/");
|
||||
client.print(FEEDID);
|
||||
client.println(".csv HTTP/1.1");
|
||||
client.println("Host: api.pachube.com");
|
||||
client.print("X-PachubeApiKey: ");
|
||||
client.println(APIKEY);
|
||||
client.print("User-Agent: ");
|
||||
client.println(USERAGENT);
|
||||
client.print("Content-Length: ");
|
||||
client.println(thisData.length(), DEC);
|
||||
client.println(thisData.length());
|
||||
|
||||
// last pieces of the HTTP PUT request:
|
||||
client.print("Content-Type: text/csv\n");
|
||||
client.println("Connection: close\n");
|
||||
client.println("Content-Type: text/csv");
|
||||
client.println("Connection: close");
|
||||
client.println();
|
||||
|
||||
// here's the actual content of the PUT request:
|
||||
client.println(thisData);
|
||||
|
||||
// note the time that the connection was made:
|
||||
lastConnectionTime = millis();
|
||||
}
|
||||
else {
|
||||
// if you couldn't make a connection:
|
||||
Serial.println("connection failed");
|
||||
Serial.println();
|
||||
Serial.println("disconnecting.");
|
||||
client.stop();
|
||||
}
|
||||
// note the time that the connection was made or attempted:
|
||||
lastConnectionTime = millis();
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
version 0019.
|
||||
|
||||
Circuit:
|
||||
* Ethernet shield attached to pins 10, 11, 12, 13
|
||||
* Ethernet shield attached to pins 10, 11, 12, 13
|
||||
|
||||
created 21 May 2011
|
||||
by Tom Igoe
|
||||
|
@ -35,12 +35,12 @@ IPAddress ip(192,168,1,20);
|
|||
// initialize the library instance:
|
||||
EthernetClient client;
|
||||
|
||||
const int requestInterval = 60000; // delay between requests
|
||||
const unsigned long requestInterval = 60000; // delay between requests
|
||||
|
||||
char serverName[] = "api.twitter.com"; // twitter URL
|
||||
|
||||
boolean requested; // whether you've made a request since connecting
|
||||
long lastAttemptTime = 0; // last time you connected to the server, in milliseconds
|
||||
unsigned long lastAttemptTime = 0; // last time you connected to the server, in milliseconds
|
||||
|
||||
String currentLine = ""; // string to hold the text from server
|
||||
String tweet = ""; // string to hold the tweet
|
||||
|
@ -51,13 +51,17 @@ void setup() {
|
|||
currentLine.reserve(256);
|
||||
tweet.reserve(150);
|
||||
|
||||
// initialize serial:
|
||||
// initialize serial:
|
||||
Serial.begin(9600);
|
||||
// attempt a DHCP connection:
|
||||
Serial.println("Attempting to get an IP address using DHCP:");
|
||||
if (!Ethernet.begin(mac)) {
|
||||
// if DHCP fails, start with a hard-coded address:
|
||||
Serial.println("failed to get an IP address using DHCP, trying manually");
|
||||
Ethernet.begin(mac, ip);
|
||||
}
|
||||
Serial.print("My address:");
|
||||
Serial.println(Ethernet.localIP());
|
||||
// connect to Twitter:
|
||||
connectToServer();
|
||||
}
|
||||
|
@ -114,7 +118,7 @@ void connectToServer() {
|
|||
Serial.println("connecting to server...");
|
||||
if (client.connect(serverName, 80)) {
|
||||
Serial.println("making HTTP request...");
|
||||
// make HTTP GET request to twitter:
|
||||
// make HTTP GET request to twitter:
|
||||
client.println("GET /1/statuses/user_timeline.xml?screen_name=arduino&count=1 HTTP/1.1");
|
||||
client.println("HOST: api.twitter.com");
|
||||
client.println();
|
||||
|
@ -122,3 +126,4 @@ void connectToServer() {
|
|||
// note the time of this connect attempt:
|
||||
lastAttemptTime = millis();
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
created 18 Dec 2009
|
||||
by David A. Mellis
|
||||
modified 4 Sep 2010
|
||||
modified 20 Mar 2012
|
||||
by Tom Igoe
|
||||
|
||||
*/
|
||||
|
@ -20,7 +20,8 @@
|
|||
|
||||
// Enter a MAC address and IP address for your controller below.
|
||||
// The IP address will be dependent on your local network:
|
||||
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
|
||||
byte mac[] = {
|
||||
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
|
||||
IPAddress ip(192,168,1, 177);
|
||||
|
||||
// Initialize the Ethernet server library
|
||||
|
@ -28,23 +29,27 @@ IPAddress ip(192,168,1, 177);
|
|||
// (port 80 is default for HTTP):
|
||||
EthernetServer server(80);
|
||||
|
||||
void setup()
|
||||
{
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
// start the Ethernet connection and the server:
|
||||
Ethernet.begin(mac, ip);
|
||||
server.begin();
|
||||
Serial.print("server is at ");
|
||||
Serial.println(Ethernet.localIP());
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
|
||||
void loop() {
|
||||
// listen for incoming clients
|
||||
EthernetClient client = server.available();
|
||||
if (client) {
|
||||
Serial.println("new client");
|
||||
// an http request ends with a blank line
|
||||
boolean currentLineIsBlank = true;
|
||||
while (client.connected()) {
|
||||
if (client.available()) {
|
||||
char c = client.read();
|
||||
Serial.write(c);
|
||||
// if you've gotten to the end of the line (received a newline
|
||||
// character) and the line is blank, the http request has ended,
|
||||
// so you can send a reply
|
||||
|
@ -52,16 +57,22 @@ void loop()
|
|||
// send a standard http response header
|
||||
client.println("HTTP/1.1 200 OK");
|
||||
client.println("Content-Type: text/html");
|
||||
client.println("Connnection: close");
|
||||
client.println();
|
||||
|
||||
client.println("<!DOCTYPE HTML>");
|
||||
client.println("<html>");
|
||||
// add a meta refresh tag, so the browser pulls again every 5 seconds:
|
||||
client.println("<meta http-equiv=\"refresh\" content=\"5\">");
|
||||
// output the value of each analog input pin
|
||||
for (int analogChannel = 0; analogChannel < 6; analogChannel++) {
|
||||
int sensorReading = analogRead(analogChannel);
|
||||
client.print("analog input ");
|
||||
client.print(analogChannel);
|
||||
client.print(" is ");
|
||||
client.print(analogRead(analogChannel));
|
||||
client.println("<br />");
|
||||
client.print(sensorReading);
|
||||
client.println("<br />");
|
||||
}
|
||||
client.println("</html>");
|
||||
break;
|
||||
}
|
||||
if (c == '\n') {
|
||||
|
@ -78,5 +89,7 @@ void loop()
|
|||
delay(1);
|
||||
// close the connection:
|
||||
client.stop();
|
||||
Serial.println("client disonnected");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ static UNUSEDOK int FreeRam(void) {
|
|||
* \param[in] str Pointer to string stored in flash memory.
|
||||
*/
|
||||
static NOINLINE void SerialPrint_P(PGM_P str) {
|
||||
for (uint8_t c; (c = pgm_read_byte(str)); str++) Serial.print(c);
|
||||
for (uint8_t c; (c = pgm_read_byte(str)); str++) Serial.write(c);
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
|
|
|
@ -89,7 +89,7 @@ static inline void handle_interrupts(timer16_Sequence_t timer, volatile uint16_t
|
|||
}
|
||||
else {
|
||||
// finished all channels so wait for the refresh period to expire before starting over
|
||||
if( (unsigned)*TCNTn < (usToTicks(REFRESH_INTERVAL) + 4) ) // allow a few ticks to ensure the next OCR1A not missed
|
||||
if( ((unsigned)*TCNTn) + 4 < usToTicks(REFRESH_INTERVAL) ) // allow a few ticks to ensure the next OCR1A not missed
|
||||
*OCRnA = (unsigned int)usToTicks(REFRESH_INTERVAL);
|
||||
else
|
||||
*OCRnA = *TCNTn + 4; // at least REFRESH_INTERVAL has elapsed
|
||||
|
@ -298,7 +298,7 @@ void Servo::writeMicroseconds(int value)
|
|||
{
|
||||
// calculate and store the values for the given channel
|
||||
byte channel = this->servoIndex;
|
||||
if( (channel >= 0) && (channel < MAX_SERVOS) ) // ensure channel is valid
|
||||
if( (channel < MAX_SERVOS) ) // ensure channel is valid
|
||||
{
|
||||
if( value < SERVO_MIN() ) // ensure pulse width is valid
|
||||
value = SERVO_MIN();
|
||||
|
|
|
@ -1,6 +1,23 @@
|
|||
/*
|
||||
Software serial multple serial test
|
||||
|
||||
Receives from the hardware serial, sends to software serial.
|
||||
Receives from software serial, sends to hardware serial.
|
||||
|
||||
The circuit:
|
||||
* RX is digital pin 2 (connect to TX of other device)
|
||||
* TX is digital pin 3 (connect to RX of other device)
|
||||
|
||||
created back in the mists of time
|
||||
by Tom Igoe
|
||||
based on Mikal Hart's example
|
||||
|
||||
This example code is in the public domain.
|
||||
|
||||
*/
|
||||
#include <SoftwareSerial.h>
|
||||
|
||||
SoftwareSerial mySerial(2, 3);
|
||||
SoftwareSerial mySerial(2, 3); // RX, TX
|
||||
|
||||
void setup()
|
||||
{
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Modified 2012 by Todd Krein (todd@krein.org) to implement repeated starts
|
||||
*/
|
||||
|
||||
extern "C" {
|
||||
|
@ -73,14 +75,14 @@ void TwoWire::begin(int address)
|
|||
begin((uint8_t)address);
|
||||
}
|
||||
|
||||
uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity)
|
||||
uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint8_t sendStop)
|
||||
{
|
||||
// clamp to buffer length
|
||||
if(quantity > BUFFER_LENGTH){
|
||||
quantity = BUFFER_LENGTH;
|
||||
}
|
||||
// perform blocking read into buffer
|
||||
uint8_t read = twi_readFrom(address, rxBuffer, quantity);
|
||||
uint8_t read = twi_readFrom(address, rxBuffer, quantity, sendStop);
|
||||
// set rx buffer iterator vars
|
||||
rxBufferIndex = 0;
|
||||
rxBufferLength = read;
|
||||
|
@ -88,9 +90,19 @@ uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity)
|
|||
return read;
|
||||
}
|
||||
|
||||
uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity)
|
||||
{
|
||||
return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)true);
|
||||
}
|
||||
|
||||
uint8_t TwoWire::requestFrom(int address, int quantity)
|
||||
{
|
||||
return requestFrom((uint8_t)address, (uint8_t)quantity);
|
||||
return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)true);
|
||||
}
|
||||
|
||||
uint8_t TwoWire::requestFrom(int address, int quantity, int sendStop)
|
||||
{
|
||||
return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)sendStop);
|
||||
}
|
||||
|
||||
void TwoWire::beginTransmission(uint8_t address)
|
||||
|
@ -109,10 +121,23 @@ void TwoWire::beginTransmission(int address)
|
|||
beginTransmission((uint8_t)address);
|
||||
}
|
||||
|
||||
uint8_t TwoWire::endTransmission(void)
|
||||
//
|
||||
// Originally, 'endTransmission' was an f(void) function.
|
||||
// It has been modified to take one parameter indicating
|
||||
// whether or not a STOP should be performed on the bus.
|
||||
// Calling endTransmission(false) allows a sketch to
|
||||
// perform a repeated start.
|
||||
//
|
||||
// WARNING: Nothing in the library keeps track of whether
|
||||
// the bus tenure has been properly ended with a STOP. It
|
||||
// is very possible to leave the bus in a hung state if
|
||||
// no call to endTransmission(true) is made. Some I2C
|
||||
// devices will behave oddly if they do not see a STOP.
|
||||
//
|
||||
uint8_t TwoWire::endTransmission(uint8_t sendStop)
|
||||
{
|
||||
// transmit buffer (blocking)
|
||||
int8_t ret = twi_writeTo(txAddress, txBuffer, txBufferLength, 1);
|
||||
int8_t ret = twi_writeTo(txAddress, txBuffer, txBufferLength, 1, sendStop);
|
||||
// reset tx buffer iterator vars
|
||||
txBufferIndex = 0;
|
||||
txBufferLength = 0;
|
||||
|
@ -121,6 +146,14 @@ uint8_t TwoWire::endTransmission(void)
|
|||
return ret;
|
||||
}
|
||||
|
||||
// This provides backwards compatibility with the original
|
||||
// definition, and expected behaviour, of endTransmission
|
||||
//
|
||||
uint8_t TwoWire::endTransmission(void)
|
||||
{
|
||||
return endTransmission(true);
|
||||
}
|
||||
|
||||
// must be called in:
|
||||
// slave tx event callback
|
||||
// or after beginTransmission(address)
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Modified 2012 by Todd Krein (todd@krein.org) to implement repeated starts
|
||||
*/
|
||||
|
||||
#ifndef TwoWire_h
|
||||
|
@ -50,8 +52,11 @@ class TwoWire : public Stream
|
|||
void beginTransmission(uint8_t);
|
||||
void beginTransmission(int);
|
||||
uint8_t endTransmission(void);
|
||||
uint8_t endTransmission(uint8_t);
|
||||
uint8_t requestFrom(uint8_t, uint8_t);
|
||||
uint8_t requestFrom(uint8_t, uint8_t, uint8_t);
|
||||
uint8_t requestFrom(int, int);
|
||||
uint8_t requestFrom(int, int, int);
|
||||
virtual size_t write(uint8_t);
|
||||
virtual size_t write(const uint8_t *, size_t);
|
||||
virtual int available(void);
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Modified 2012 by Todd Krein (todd@krein.org) to implement repeated starts
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
|
@ -37,14 +39,16 @@
|
|||
#include "twi.h"
|
||||
|
||||
static volatile uint8_t twi_state;
|
||||
static uint8_t twi_slarw;
|
||||
static volatile uint8_t twi_slarw;
|
||||
static volatile uint8_t twi_sendStop; // should the transaction end with a stop
|
||||
static volatile uint8_t twi_inRepStart; // in the middle of a repeated start
|
||||
|
||||
static void (*twi_onSlaveTransmit)(void);
|
||||
static void (*twi_onSlaveReceive)(uint8_t*, int);
|
||||
|
||||
static uint8_t twi_masterBuffer[TWI_BUFFER_LENGTH];
|
||||
static volatile uint8_t twi_masterBufferIndex;
|
||||
static uint8_t twi_masterBufferLength;
|
||||
static volatile uint8_t twi_masterBufferLength;
|
||||
|
||||
static uint8_t twi_txBuffer[TWI_BUFFER_LENGTH];
|
||||
static volatile uint8_t twi_txBufferIndex;
|
||||
|
@ -65,6 +69,8 @@ void twi_init(void)
|
|||
{
|
||||
// initialize state
|
||||
twi_state = TWI_READY;
|
||||
twi_sendStop = true; // default value
|
||||
twi_inRepStart = false;
|
||||
|
||||
// activate internal pullups for twi.
|
||||
digitalWrite(SDA, 1);
|
||||
|
@ -103,9 +109,10 @@ void twi_setAddress(uint8_t address)
|
|||
* Input address: 7bit i2c device address
|
||||
* data: pointer to byte array
|
||||
* length: number of bytes to read into array
|
||||
* sendStop: Boolean indicating whether to send a stop at the end
|
||||
* Output number of bytes read
|
||||
*/
|
||||
uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length)
|
||||
uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length, uint8_t sendStop)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
|
@ -119,6 +126,7 @@ uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length)
|
|||
continue;
|
||||
}
|
||||
twi_state = TWI_MRX;
|
||||
twi_sendStop = sendStop;
|
||||
// reset error state (0xFF.. no error occured)
|
||||
twi_error = 0xFF;
|
||||
|
||||
|
@ -135,8 +143,20 @@ uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length)
|
|||
twi_slarw = TW_READ;
|
||||
twi_slarw |= address << 1;
|
||||
|
||||
// send start condition
|
||||
TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA);
|
||||
if (true == twi_inRepStart) {
|
||||
// if we're in the repeated start state, then we've already sent the start,
|
||||
// (@@@ we hope), and the TWI statemachine is just waiting for the address byte.
|
||||
// We need to remove ourselves from the repeated start state before we enable interrupts,
|
||||
// since the ISR is ASYNC, and we could get confused if we hit the ISR before cleaning
|
||||
// up. Also, don't enable the START interrupt. There may be one pending from the
|
||||
// repeated start that we sent outselves, and that would really confuse things.
|
||||
twi_inRepStart = false; // remember, we're dealing with an ASYNC ISR
|
||||
TWDR = twi_slarw;
|
||||
TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE); // enable INTs, but not START
|
||||
}
|
||||
else
|
||||
// send start condition
|
||||
TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA);
|
||||
|
||||
// wait for read operation to complete
|
||||
while(TWI_MRX == twi_state){
|
||||
|
@ -162,13 +182,14 @@ uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length)
|
|||
* data: pointer to byte array
|
||||
* length: number of bytes in array
|
||||
* wait: boolean indicating to wait for write or not
|
||||
* sendStop: boolean indicating whether or not to send a stop at the end
|
||||
* Output 0 .. success
|
||||
* 1 .. length to long for buffer
|
||||
* 2 .. address send, NACK received
|
||||
* 3 .. data send, NACK received
|
||||
* 4 .. other twi error (lost bus arbitration, bus error, ..)
|
||||
*/
|
||||
uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait)
|
||||
uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait, uint8_t sendStop)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
|
@ -182,6 +203,7 @@ uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait
|
|||
continue;
|
||||
}
|
||||
twi_state = TWI_MTX;
|
||||
twi_sendStop = sendStop;
|
||||
// reset error state (0xFF.. no error occured)
|
||||
twi_error = 0xFF;
|
||||
|
||||
|
@ -198,8 +220,23 @@ uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait
|
|||
twi_slarw = TW_WRITE;
|
||||
twi_slarw |= address << 1;
|
||||
|
||||
// send start condition
|
||||
TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA);
|
||||
// if we're in a repeated start, then we've already sent the START
|
||||
// in the ISR. Don't do it again.
|
||||
//
|
||||
if (true == twi_inRepStart) {
|
||||
// if we're in the repeated start state, then we've already sent the start,
|
||||
// (@@@ we hope), and the TWI statemachine is just waiting for the address byte.
|
||||
// We need to remove ourselves from the repeated start state before we enable interrupts,
|
||||
// since the ISR is ASYNC, and we could get confused if we hit the ISR before cleaning
|
||||
// up. Also, don't enable the START interrupt. There may be one pending from the
|
||||
// repeated start that we sent outselves, and that would really confuse things.
|
||||
twi_inRepStart = false; // remember, we're dealing with an ASYNC ISR
|
||||
TWDR = twi_slarw;
|
||||
TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE); // enable INTs, but not START
|
||||
}
|
||||
else
|
||||
// send start condition
|
||||
TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE) | _BV(TWSTA); // enable INTs
|
||||
|
||||
// wait for write operation to complete
|
||||
while(wait && (TWI_MTX == twi_state)){
|
||||
|
@ -343,7 +380,16 @@ SIGNAL(TWI_vect)
|
|||
TWDR = twi_masterBuffer[twi_masterBufferIndex++];
|
||||
twi_reply(1);
|
||||
}else{
|
||||
twi_stop();
|
||||
if (twi_sendStop)
|
||||
twi_stop();
|
||||
else {
|
||||
twi_inRepStart = true; // we're gonna send the START
|
||||
// don't enable the interrupt. We'll generate the start, but we
|
||||
// avoid handling the interrupt until we're in the next transaction,
|
||||
// at the point where we would normally issue the start.
|
||||
TWCR = _BV(TWINT) | _BV(TWSTA)| _BV(TWEN) ;
|
||||
twi_state = TWI_READY;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case TW_MT_SLA_NACK: // address sent, nack received
|
||||
|
@ -374,6 +420,17 @@ SIGNAL(TWI_vect)
|
|||
case TW_MR_DATA_NACK: // data received, nack sent
|
||||
// put final byte into buffer
|
||||
twi_masterBuffer[twi_masterBufferIndex++] = TWDR;
|
||||
if (twi_sendStop)
|
||||
twi_stop();
|
||||
else {
|
||||
twi_inRepStart = true; // we're gonna send the START
|
||||
// don't enable the interrupt. We'll generate the start, but we
|
||||
// avoid handling the interrupt until we're in the next transaction,
|
||||
// at the point where we would normally issue the start.
|
||||
TWCR = _BV(TWINT) | _BV(TWSTA)| _BV(TWEN) ;
|
||||
twi_state = TWI_READY;
|
||||
}
|
||||
break;
|
||||
case TW_MR_SLA_NACK: // address sent, nack received
|
||||
twi_stop();
|
||||
break;
|
||||
|
|
|
@ -40,8 +40,8 @@
|
|||
|
||||
void twi_init(void);
|
||||
void twi_setAddress(uint8_t);
|
||||
uint8_t twi_readFrom(uint8_t, uint8_t*, uint8_t);
|
||||
uint8_t twi_writeTo(uint8_t, uint8_t*, uint8_t, uint8_t);
|
||||
uint8_t twi_readFrom(uint8_t, uint8_t*, uint8_t, uint8_t);
|
||||
uint8_t twi_writeTo(uint8_t, uint8_t*, uint8_t, uint8_t, uint8_t);
|
||||
uint8_t twi_transmit(const uint8_t*, uint8_t);
|
||||
void twi_attachSlaveRxEvent( void (*)(uint8_t*, int) );
|
||||
void twi_attachSlaveTxEvent( void (*)(void) );
|
||||
|
|
|
@ -35,29 +35,29 @@
|
|||
#define RXLED0 PORTB |= (1<<0)
|
||||
#define RXLED1 PORTB &= ~(1<<0)
|
||||
|
||||
const static uint8_t SDA = 2;
|
||||
const static uint8_t SCL = 3;
|
||||
static const uint8_t SDA = 2;
|
||||
static const uint8_t SCL = 3;
|
||||
|
||||
// Map SPI port to 'new' pins D14..D17
|
||||
const static uint8_t SS = 17;
|
||||
const static uint8_t MOSI = 16;
|
||||
const static uint8_t MISO = 14;
|
||||
const static uint8_t SCK = 15;
|
||||
static const uint8_t SS = 17;
|
||||
static const uint8_t MOSI = 16;
|
||||
static const uint8_t MISO = 14;
|
||||
static const uint8_t SCK = 15;
|
||||
|
||||
// Mapping of analog pins as digital I/O
|
||||
// A6-A11 share with digital pins
|
||||
const static uint8_t A0 = 18;
|
||||
const static uint8_t A1 = 19;
|
||||
const static uint8_t A2 = 20;
|
||||
const static uint8_t A3 = 21;
|
||||
const static uint8_t A4 = 22;
|
||||
const static uint8_t A5 = 23;
|
||||
const static uint8_t A6 = 24; // D4
|
||||
const static uint8_t A7 = 25; // D6
|
||||
const static uint8_t A8 = 26; // D8
|
||||
const static uint8_t A9 = 27; // D9
|
||||
const static uint8_t A10 = 28; // D10
|
||||
const static uint8_t A11 = 29; // D12
|
||||
static const uint8_t A0 = 18;
|
||||
static const uint8_t A1 = 19;
|
||||
static const uint8_t A2 = 20;
|
||||
static const uint8_t A3 = 21;
|
||||
static const uint8_t A4 = 22;
|
||||
static const uint8_t A5 = 23;
|
||||
static const uint8_t A6 = 24; // D4
|
||||
static const uint8_t A7 = 25; // D6
|
||||
static const uint8_t A8 = 26; // D8
|
||||
static const uint8_t A9 = 27; // D9
|
||||
static const uint8_t A10 = 28; // D10
|
||||
static const uint8_t A11 = 29; // D12
|
||||
|
||||
// __AVR_ATmega32U4__ has an unusual mapping of pins to channels
|
||||
extern const uint8_t PROGMEM analog_pin_to_channel_PGM[];
|
||||
|
|
|
@ -32,31 +32,31 @@
|
|||
#define analogInputToDigitalPin(p) ((p < 16) ? (p) + 54 : -1)
|
||||
#define digitalPinHasPWM(p) (((p) >= 2 && (p) <= 13) || ((p) >= 44 && (p)<= 46))
|
||||
|
||||
const static uint8_t SS = 53;
|
||||
const static uint8_t MOSI = 51;
|
||||
const static uint8_t MISO = 50;
|
||||
const static uint8_t SCK = 52;
|
||||
static const uint8_t SS = 53;
|
||||
static const uint8_t MOSI = 51;
|
||||
static const uint8_t MISO = 50;
|
||||
static const uint8_t SCK = 52;
|
||||
|
||||
const static uint8_t SDA = 20;
|
||||
const static uint8_t SCL = 21;
|
||||
const static uint8_t LED_BUILTIN = 13;
|
||||
static const uint8_t SDA = 20;
|
||||
static const uint8_t SCL = 21;
|
||||
static const uint8_t LED_BUILTIN = 13;
|
||||
|
||||
const static uint8_t A0 = 54;
|
||||
const static uint8_t A1 = 55;
|
||||
const static uint8_t A2 = 56;
|
||||
const static uint8_t A3 = 57;
|
||||
const static uint8_t A4 = 58;
|
||||
const static uint8_t A5 = 59;
|
||||
const static uint8_t A6 = 60;
|
||||
const static uint8_t A7 = 61;
|
||||
const static uint8_t A8 = 62;
|
||||
const static uint8_t A9 = 63;
|
||||
const static uint8_t A10 = 64;
|
||||
const static uint8_t A11 = 65;
|
||||
const static uint8_t A12 = 66;
|
||||
const static uint8_t A13 = 67;
|
||||
const static uint8_t A14 = 68;
|
||||
const static uint8_t A15 = 69;
|
||||
static const uint8_t A0 = 54;
|
||||
static const uint8_t A1 = 55;
|
||||
static const uint8_t A2 = 56;
|
||||
static const uint8_t A3 = 57;
|
||||
static const uint8_t A4 = 58;
|
||||
static const uint8_t A5 = 59;
|
||||
static const uint8_t A6 = 60;
|
||||
static const uint8_t A7 = 61;
|
||||
static const uint8_t A8 = 62;
|
||||
static const uint8_t A9 = 63;
|
||||
static const uint8_t A10 = 64;
|
||||
static const uint8_t A11 = 65;
|
||||
static const uint8_t A12 = 66;
|
||||
static const uint8_t A13 = 67;
|
||||
static const uint8_t A14 = 68;
|
||||
static const uint8_t A15 = 69;
|
||||
|
||||
// A majority of the pins are NOT PCINTs, SO BE WARNED (i.e. you cannot use them as receive pins)
|
||||
// Only pins available for RECEIVE (TRANSMIT can be on any pin):
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue