1
0
mirror of https://github.com/arduino/Arduino.git synced 2025-01-19 08:52:15 +01:00

Added first tests for library manager engine

This commit is contained in:
Cristian Maglie 2017-12-28 00:02:19 +01:00
parent 31de5b61c1
commit 86441e4341
139 changed files with 20707 additions and 6 deletions

View File

@ -73,12 +73,9 @@ public class ContributionsSelfCheck extends TimerTask {
updateContributionIndex();
updateLibrariesIndex();
boolean updatablePlatforms = BaseNoGui.indexer.getPackages().stream()
.flatMap(pack -> pack.getPlatforms().stream())
.anyMatch(new UpdatablePlatformPredicate());
boolean updatablePlatforms = checkForUpdatablePlatforms();
boolean updatableLibraries = BaseNoGui.librariesIndexer.getIndex().getLibraries().stream()
.anyMatch(new UpdatableLibraryPredicate());
boolean updatableLibraries = checkForUpdatableLibraries();
if (!updatableLibraries && !updatablePlatforms) {
return;
@ -125,6 +122,17 @@ public class ContributionsSelfCheck extends TimerTask {
});
}
static boolean checkForUpdatablePlatforms() {
return BaseNoGui.indexer.getPackages().stream()
.flatMap(pack -> pack.getPlatforms().stream())
.anyMatch(new UpdatablePlatformPredicate());
}
static boolean checkForUpdatableLibraries() {
return BaseNoGui.librariesIndexer.getIndex().getLibraries().stream()
.anyMatch(new UpdatableLibraryPredicate());
}
@Override
public boolean cancel() {
cancelled = true;

View File

@ -31,6 +31,7 @@ package cc.arduino.contributions.libraries.filters;
import cc.arduino.contributions.VersionComparator;
import cc.arduino.contributions.libraries.ContributedLibrary;
import cc.arduino.contributions.libraries.LibrariesIndexer;
import processing.app.BaseNoGui;
import processing.app.packages.UserLibrary;
@ -40,6 +41,16 @@ import java.util.function.Predicate;
public class UpdatableLibraryPredicate implements Predicate<ContributedLibrary> {
LibrariesIndexer librariesIndexer;
public UpdatableLibraryPredicate() {
librariesIndexer = BaseNoGui.librariesIndexer;
}
public UpdatableLibraryPredicate(LibrariesIndexer indexer) {
librariesIndexer = indexer;
}
@Override
public boolean test(ContributedLibrary lib) {
Optional<UserLibrary> installed = lib.getInstalledLibrary();
@ -48,7 +59,7 @@ public class UpdatableLibraryPredicate implements Predicate<ContributedLibrary>
}
String installedVersion = installed.get().getVersion();
String libraryName = lib.getName();
List<ContributedLibrary> libraries = BaseNoGui.librariesIndexer.getIndex().find(libraryName);
List<ContributedLibrary> libraries = librariesIndexer.getIndex().find(libraryName);
return libraries.stream()
.anyMatch(library -> VersionComparator.greaterThan(library.getParsedVersion(), installedVersion));
}

View File

@ -0,0 +1,82 @@
package cc.arduino.contributions;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
import cc.arduino.contributions.libraries.ContributedLibrary;
import cc.arduino.contributions.libraries.LibrariesIndexer;
import processing.app.BaseNoGui;
import processing.app.packages.UserLibraryFolder;
import processing.app.packages.UserLibraryFolder.Location;
public class UpdatableLibraryTest {
File testdata = new File(
UpdatableLibraryTest.class.getResource("/").getFile(),
"../testdata/libraries");
File index_SD_only = new File(testdata, "index_SD_only");
File SD111 = new File(testdata, "SD_1.1.1");
File SD121 = new File(testdata, "SD_1.2.1");
File index_Bridge_only = new File(testdata, "index_Bridge_only");
File Bridge163 = new File(testdata, "Bridge_1.6.3");
File Bridge170 = new File(testdata, "Bridge_1.7.0");
@Test
public void testUpdatableLibrary() throws Exception {
List<UserLibraryFolder> folders = new ArrayList<>();
folders.add(new UserLibraryFolder(SD111, Location.IDE_BUILTIN));
LibrariesIndexer indexer = new LibrariesIndexer(index_SD_only);
BaseNoGui.librariesIndexer = indexer;
indexer.parseIndex();
indexer.setLibrariesFolders(folders);
ContributedLibrary sdLib = indexer.getIndex().getInstalled("SD").get();
assertTrue("SD lib is installed", sdLib.isLibraryInstalled());
assertEquals("SD installed version", "1.1.1", sdLib.getParsedVersion());
assertTrue(ContributionsSelfCheck.checkForUpdatableLibraries());
folders.add(new UserLibraryFolder(SD121, Location.SKETCHBOOK));
indexer.setLibrariesFolders(folders);
sdLib = indexer.getIndex().getInstalled("SD").get();
assertTrue("SD lib is installed", sdLib.isLibraryInstalled());
assertEquals("SD installed version", "1.2.1", sdLib.getParsedVersion());
assertFalse(ContributionsSelfCheck.checkForUpdatableLibraries());
}
@Test
public void testUpdatableLibraryWithBundled() throws Exception {
List<UserLibraryFolder> folders = new ArrayList<>();
folders.add(new UserLibraryFolder(Bridge163, Location.IDE_BUILTIN));
LibrariesIndexer indexer = new LibrariesIndexer(index_Bridge_only);
BaseNoGui.librariesIndexer = indexer;
indexer.parseIndex();
indexer.setLibrariesFolders(folders);
ContributedLibrary l = indexer.getIndex().getInstalled("Bridge").get();
assertTrue("Bridge lib is installed", l.isLibraryInstalled());
assertEquals("Bridge installed version", "1.6.3", l.getParsedVersion());
assertTrue(ContributionsSelfCheck.checkForUpdatableLibraries());
folders.add(new UserLibraryFolder(Bridge170, Location.SKETCHBOOK));
indexer.setLibrariesFolders(folders);
l = indexer.getIndex().getInstalled("Bridge").get();
assertTrue("Bridge lib is installed", l.isLibraryInstalled());
assertEquals("Bridge installed version", "1.7.0", l.getParsedVersion());
assertFalse(ContributionsSelfCheck.checkForUpdatableLibraries());
}
}

View File

@ -0,0 +1,24 @@
= Bridge Library for Arduino =
The Bridge library simplifies communication between the ATmega32U4 and the AR9331.
For more information about this library please visit us at
http://www.arduino.cc/en/Reference/YunBridgeLibrary
== License ==
Copyright (c) 2014 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
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

View File

@ -0,0 +1,183 @@
/*
Arduino Yún Bridge example
This example for the YunShield/Yún shows how
to use the Bridge library to access the digital and
analog pins on the board through REST calls.
It demonstrates how you can create your own API when
using REST style calls through the browser.
Possible commands created in this shetch:
"/arduino/digital/13" -> digitalRead(13)
"/arduino/digital/13/1" -> digitalWrite(13, HIGH)
"/arduino/analog/2/123" -> analogWrite(2, 123)
"/arduino/analog/2" -> analogRead(2)
"/arduino/mode/13/input" -> pinMode(13, INPUT)
"/arduino/mode/13/output" -> pinMode(13, OUTPUT)
This example code is part of the public domain
http://www.arduino.cc/en/Tutorial/Bridge
*/
#include <Bridge.h>
#include <BridgeServer.h>
#include <BridgeClient.h>
// Listen to the default port 5555, the Yún webserver
// will forward there all the HTTP requests you send
BridgeServer server;
void setup() {
// Bridge startup
pinMode(13, OUTPUT);
digitalWrite(13, LOW);
Bridge.begin();
digitalWrite(13, HIGH);
// Listen for incoming connection only from localhost
// (no one from the external network could connect)
server.listenOnLocalhost();
server.begin();
}
void loop() {
// Get clients coming from server
BridgeClient client = server.accept();
// There is a new client?
if (client) {
// Process request
process(client);
// Close connection and free resources.
client.stop();
}
delay(50); // Poll every 50ms
}
void process(BridgeClient client) {
// read the command
String command = client.readStringUntil('/');
// is "digital" command?
if (command == "digital") {
digitalCommand(client);
}
// is "analog" command?
if (command == "analog") {
analogCommand(client);
}
// is "mode" command?
if (command == "mode") {
modeCommand(client);
}
}
void digitalCommand(BridgeClient client) {
int pin, value;
// Read pin number
pin = client.parseInt();
// If the next character is a '/' it means we have an URL
// with a value like: "/digital/13/1"
if (client.read() == '/') {
value = client.parseInt();
digitalWrite(pin, value);
} else {
value = digitalRead(pin);
}
// Send feedback to client
client.print(F("Pin D"));
client.print(pin);
client.print(F(" set to "));
client.println(value);
// Update datastore key with the current pin value
String key = "D";
key += pin;
Bridge.put(key, String(value));
}
void analogCommand(BridgeClient client) {
int pin, value;
// Read pin number
pin = client.parseInt();
// If the next character is a '/' it means we have an URL
// with a value like: "/analog/5/120"
if (client.read() == '/') {
// Read value and execute command
value = client.parseInt();
analogWrite(pin, value);
// Send feedback to client
client.print(F("Pin D"));
client.print(pin);
client.print(F(" set to analog "));
client.println(value);
// Update datastore key with the current pin value
String key = "D";
key += pin;
Bridge.put(key, String(value));
} else {
// Read analog pin
value = analogRead(pin);
// Send feedback to client
client.print(F("Pin A"));
client.print(pin);
client.print(F(" reads analog "));
client.println(value);
// Update datastore key with the current pin value
String key = "A";
key += pin;
Bridge.put(key, String(value));
}
}
void modeCommand(BridgeClient client) {
int pin;
// Read pin number
pin = client.parseInt();
// If the next character is not a '/' we have a malformed URL
if (client.read() != '/') {
client.println(F("error"));
return;
}
String mode = client.readStringUntil('\r');
if (mode == "input") {
pinMode(pin, INPUT);
// Send feedback to client
client.print(F("Pin D"));
client.print(pin);
client.print(F(" configured as INPUT!"));
return;
}
if (mode == "output") {
pinMode(pin, OUTPUT);
// Send feedback to client
client.print(F("Pin D"));
client.print(pin);
client.print(F(" configured as OUTPUT!"));
return;
}
client.print(F("error: invalid mode "));
client.print(mode);
}

View File

@ -0,0 +1,95 @@
/*
Console ASCII table for YunShield/Yún
Prints out byte values in all possible formats:
* as raw binary values
* as ASCII-encoded decimal, hex, octal, and binary values
For more on ASCII, see http://www.asciitable.com and http://en.wikipedia.org/wiki/ASCII
The circuit:
- YunShield/Yún
created 2006
by Nicholas Zambetti
http://www.zambetti.com
modified 9 Apr 2012
by Tom Igoe
modified 22 May 2013
by Cristian Maglie
This example code is in the public domain.
http://www.arduino.cc/en/Tutorial/ConsoleAsciiTable
*/
#include <Console.h>
void setup() {
//Initialize Console and wait for port to open:
Bridge.begin();
Console.begin();
// Uncomment the following line to enable buffering:
// - better transmission speed and efficiency
// - needs to call Console.flush() to ensure that all
// transmitted data is sent
//Console.buffer(64);
while (!Console) {
; // wait for Console port to connect.
}
// prints title with ending line break
Console.println("ASCII Table ~ Character Map");
}
// first visible ASCIIcharacter '!' is number 33:
int thisByte = 33;
// you can also write ASCII characters in single quotes.
// for example. '!' is the same as 33, so you could also use this:
//int thisByte = '!';
void loop() {
// prints value unaltered, i.e. the raw binary version of the
// byte. The Console monitor interprets all bytes as
// ASCII, so 33, the first number, will show up as '!'
Console.write(thisByte);
Console.print(", dec: ");
// prints value as string as an ASCII-encoded decimal (base 10).
// Decimal is the default format for Console.print() and Console.println(),
// so no modifier is needed:
Console.print(thisByte);
// But you can declare the modifier for decimal if you want to.
//this also works if you uncomment it:
// Console.print(thisByte, DEC);
Console.print(", hex: ");
// prints value as string in hexadecimal (base 16):
Console.print(thisByte, HEX);
Console.print(", oct: ");
// prints value as string in octal (base 8);
Console.print(thisByte, OCT);
Console.print(", bin: ");
// prints value as string in binary (base 2)
// also prints ending line break:
Console.println(thisByte, BIN);
// if printed last visible character '~' or 126, stop:
if (thisByte == 126) { // you could also use if (thisByte == '~') {
// ensure the latest bit of data is sent
Console.flush();
// This loop loops forever and does nothing
while (true) {
continue;
}
}
// go on to the next character
thisByte++;
}

View File

@ -0,0 +1,63 @@
/*
Console Pixel
An example of using YunShield/Yún board to receive data from the
Console on the Yún. In this case, the board turns on an LED when
it receives the character 'H', and turns off the LED when it
receives the character 'L'.
To see the Console, pick your Yún's name and IP address in the Port menu
then open the Port Monitor. You can also see it by opening a terminal window
and typing
ssh root@ yourYunsName.local 'telnet localhost 6571'
then pressing enter. When prompted for the password, enter it.
The circuit:
* LED connected from digital pin 13 to ground
created 2006
by David A. Mellis
modified 25 Jun 2013
by Tom Igoe
This example code is in the public domain.
http://www.arduino.cc/en/Tutorial/ConsolePixel
*/
#include <Console.h>
const int ledPin = 13; // the pin that the LED is attached to
char incomingByte; // a variable to read incoming Console data into
void setup() {
Bridge.begin(); // Initialize Bridge
Console.begin(); // Initialize Console
// Wait for the Console port to connect
while (!Console);
Console.println("type H or L to turn pin 13 on or off");
// initialize the LED pin as an output:
pinMode(ledPin, OUTPUT);
}
void loop() {
// see if there's incoming Console data:
if (Console.available() > 0) {
// read the oldest byte in the Console buffer:
incomingByte = Console.read();
Console.println(incomingByte);
// if it's a capital H (ASCII 72), turn on the LED:
if (incomingByte == 'H') {
digitalWrite(ledPin, HIGH);
}
// if it's an L (ASCII 76) turn off the LED:
if (incomingByte == 'L') {
digitalWrite(ledPin, LOW);
}
}
}

View File

@ -0,0 +1,58 @@
/*
Console Read example for YunShield/Yún
Read data coming from bridge using the Console.read() function
and store it in a string.
To see the Console, pick your Yún's name and IP address in the Port menu
then open the Port Monitor. You can also see it by opening a terminal window
and typing:
ssh root@ yourYunsName.local 'telnet localhost 6571'
then pressing enter. When prompted for the password, enter it.
created 13 Jun 2013
by Angelo Scialabba
modified 16 June 2013
by Tom Igoe
This example code is in the public domain.
http://www.arduino.cc/en/Tutorial/ConsoleRead
*/
#include <Console.h>
String name;
void setup() {
// Initialize Console and wait for port to open:
Bridge.begin();
Console.begin();
// Wait for Console port to connect
while (!Console);
Console.println("Hi, what's your name?");
}
void loop() {
if (Console.available() > 0) {
char c = Console.read(); // read the next char received
// look for the newline character, this is the last character in the string
if (c == '\n') {
//print text with the name received
Console.print("Hi ");
Console.print(name);
Console.println("! Nice to meet you!");
Console.println();
// Ask again for name and clear the old name
Console.println("Hi, what's your name?");
name = ""; // clear the name string
} else { // if the buffer is empty Cosole.read() returns -1
name += c; // append the read char from Console to the name string
}
} else {
delay(100);
}
}

View File

@ -0,0 +1,102 @@
/*
SD card datalogger
This example shows how to log data from three analog sensors
to an SD card mounted on the YunShield/Yún using the Bridge library.
The circuit:
* analog sensors on analog pins 0, 1 and 2
* SD card attached to SD card slot of the YunShield/Yún
Prepare your SD card creating an empty folder in the SD root
named "arduino". This will ensure that the Yún will create a link
to the SD to the "/mnt/sd" path.
You can remove the SD card while the Linux and the
sketch are running but be careful not to remove it while
the system is writing to it.
created 24 Nov 2010
modified 9 Apr 2012
by Tom Igoe
adapted to the Yún Bridge library 20 Jun 2013
by Federico Vanzati
modified 21 Jun 2013
by Tom Igoe
This example code is in the public domain.
http://www.arduino.cc/en/Tutorial/YunDatalogger
*/
#include <FileIO.h>
void setup() {
// Initialize the Bridge and the Serial
Bridge.begin();
Serial.begin(9600);
FileSystem.begin();
while (!SerialUSB); // wait for Serial port to connect.
SerialUSB.println("Filesystem datalogger\n");
}
void loop() {
// make a string that start with a timestamp for assembling the data to log:
String dataString;
dataString += getTimeStamp();
dataString += " = ";
// read three sensors and append to the string:
for (int analogPin = 0; analogPin < 3; analogPin++) {
int sensor = analogRead(analogPin);
dataString += String(sensor);
if (analogPin < 2) {
dataString += ","; // separate the values with a comma
}
}
// open the file. note that only one file can be open at a time,
// so you have to close this one before opening another.
// The FileSystem card is mounted at the following "/mnt/FileSystema1"
File dataFile = FileSystem.open("/mnt/sd/datalog.txt", FILE_APPEND);
// if the file is available, write to it:
if (dataFile) {
dataFile.println(dataString);
dataFile.close();
// print to the serial port too:
SerialUSB.println(dataString);
}
// if the file isn't open, pop up an error:
else {
SerialUSB.println("error opening datalog.txt");
}
delay(15000);
}
// This function return a string with the time stamp
String getTimeStamp() {
String result;
Process time;
// date is a command line utility to get the date and the time
// in different formats depending on the additional parameter
time.begin("date");
time.addParameter("+%D-%T"); // parameters: D for the complete date mm/dd/yy
// T for the time hh:mm:ss
time.run(); // run the command
// read the output of the command
while (time.available() > 0) {
char c = time.read();
if (c != '\n') {
result += c;
}
}
return result;
}

View File

@ -0,0 +1,83 @@
/*
Write to file using FileIO classes.
This sketch demonstrate how to write file into the YunShield/Yún filesystem.
A shell script file is created in /tmp, and it is executed afterwards.
created 7 June 2010
by Cristian Maglie
This example code is in the public domain.
http://www.arduino.cc/en/Tutorial/FileWriteScript
*/
#include <FileIO.h>
void setup() {
// Setup Bridge (needed every time we communicate with the Arduino Yún)
Bridge.begin();
// Initialize the Serial
SerialUSB.begin(9600);
while (!SerialUSB); // wait for Serial port to connect.
SerialUSB.println("File Write Script example\n\n");
// Setup File IO
FileSystem.begin();
// Upload script used to gain network statistics
uploadScript();
}
void loop() {
// Run stats script every 5 secs.
runScript();
delay(5000);
}
// this function creates a file into the linux processor that contains a shell script
// to check the network traffic of the WiFi interface
void uploadScript() {
// Write our shell script in /tmp
// Using /tmp stores the script in RAM this way we can preserve
// the limited amount of FLASH erase/write cycles
File script = FileSystem.open("/tmp/wlan-stats.sh", FILE_WRITE);
// Shell script header
script.print("#!/bin/sh\n");
// shell commands:
// ifconfig: is a command line utility for controlling the network interfaces.
// wlan0 is the interface we want to query
// grep: search inside the output of the ifconfig command the "RX bytes" keyword
// and extract the line that contains it
script.print("ifconfig wlan0 | grep 'RX bytes'\n");
script.close(); // close the file
// Make the script executable
Process chmod;
chmod.begin("chmod"); // chmod: change mode
chmod.addParameter("+x"); // x stays for executable
chmod.addParameter("/tmp/wlan-stats.sh"); // path to the file to make it executable
chmod.run();
}
// this function run the script and read the output data
void runScript() {
// Run the script and show results on the Serial
Process myscript;
myscript.begin("/tmp/wlan-stats.sh");
myscript.run();
String output = "";
// read the output of the script
while (myscript.available()) {
output += (char)myscript.read();
}
// remove the blank spaces at the beginning and the ending of the string
output.trim();
SerialUSB.println(output);
SerialUSB.flush();
}

View File

@ -0,0 +1,51 @@
/*
Yún HTTP Client
This example for the YunShield/Yún shows how create a basic
HTTP client that connects to the internet and downloads
content. In this case, you'll connect to the Arduino
website and download a version of the logo as ASCII text.
created by Tom igoe
May 2013
This example code is in the public domain.
http://www.arduino.cc/en/Tutorial/HttpClient
*/
#include <Bridge.h>
#include <HttpClient.h>
void setup() {
// Bridge takes about two seconds to start up
// it can be helpful to use the on-board LED
// as an indicator for when it has initialized
pinMode(13, OUTPUT);
digitalWrite(13, LOW);
Bridge.begin();
digitalWrite(13, HIGH);
SerialUSB.begin(9600);
while (!SerialUSB); // wait for a serial connection
}
void loop() {
// Initialize the client library
HttpClient client;
// Make a HTTP request:
client.get("http://www.arduino.cc/asciilogo.txt");
// if there are incoming bytes available
// from the server, read them and print them:
while (client.available()) {
char c = client.read();
SerialUSB.print(c);
}
SerialUSB.flush();
delay(5000);
}

View File

@ -0,0 +1,53 @@
/*
Yún HTTP Client Console version for Arduino Uno and Mega using Yún Shield
This example for the YunShield/Yún shows how create a basic
HTTP client that connects to the internet and downloads
content. In this case, you'll connect to the Arduino
website and download a version of the logo as ASCII text.
created by Tom igoe
May 2013
modified by Marco Brianza to use Console
This example code is in the public domain.
http://www.arduino.cc/en/Tutorial/HttpClient
*/
#include <Bridge.h>
#include <HttpClient.h>
#include <Console.h>
void setup() {
// Bridge takes about two seconds to start up
// it can be helpful to use the on-board LED
// as an indicator for when it has initialized
pinMode(13, OUTPUT);
digitalWrite(13, LOW);
Bridge.begin();
digitalWrite(13, HIGH);
Console.begin();
while (!Console); // wait for a serial connection
}
void loop() {
// Initialize the client library
HttpClient client;
// Make a HTTP request:
client.get("http://www.arduino.cc/asciilogo.txt");
// if there are incoming bytes available
// from the server, read them and print them:
while (client.available()) {
char c = client.read();
Console.print(c);
}
Console.flush();
delay(5000);
}

View File

@ -0,0 +1,58 @@
/*
Read Messages from the Mailbox
This example for the YunShield/Yún shows how to
read the messages queue, called Mailbox, using the
Bridge library.
The messages can be sent to the queue through REST calls.
Appen the message in the URL after the keyword "/mailbox".
Example
"/mailbox/hello"
created 3 Feb 2014
by Federico Vanzati & Federico Fissore
This example code is in the public domain.
http://www.arduino.cc/en/Tutorial/MailboxReadMessage
*/
#include <Mailbox.h>
void setup() {
pinMode(13, OUTPUT);
digitalWrite(13, LOW);
// Initialize Bridge and Mailbox
Bridge.begin();
Mailbox.begin();
digitalWrite(13, HIGH);
// Initialize Serial
SerialUSB.begin(9600);
// Wait until a Serial Monitor is connected.
while (!SerialUSB);
SerialUSB.println("Mailbox Read Message\n");
SerialUSB.println("The Mailbox is checked every 10 seconds. The incoming messages will be shown below.\n");
}
void loop() {
String message;
// if there is a message in the Mailbox
if (Mailbox.messageAvailable()) {
// read all the messages present in the queue
while (Mailbox.messageAvailable()) {
Mailbox.readMessage(message);
SerialUSB.println(message);
}
SerialUSB.println("Waiting 10 seconds before checking the Mailbox again");
}
// wait 10 seconds
delay(10000);
}

View File

@ -0,0 +1,71 @@
/*
Running process using Process class.
This sketch demonstrate how to run linux processes
using a YunShield/Yún
created 5 Jun 2013
by Cristian Maglie
This example code is in the public domain.
http://www.arduino.cc/en/Tutorial/Process
*/
#include <Process.h>
void setup() {
// Initialize Bridge
Bridge.begin();
// Initialize Serial
SerialUSB.begin(9600);
// Wait until a Serial Monitor is connected.
while (!SerialUSB);
// run various example processes
runCurl();
runCpuInfo();
}
void loop() {
// Do nothing here.
}
void runCurl() {
// Launch "curl" command and get Arduino ascii art logo from the network
// curl is command line program for transferring data using different internet protocols
Process p; // Create a process and call it "p"
p.begin("curl"); // Process that launch the "curl" command
p.addParameter("http://www.arduino.cc/asciilogo.txt"); // Add the URL parameter to "curl"
p.run(); // Run the process and wait for its termination
// Print arduino logo over the Serial
// A process output can be read with the stream methods
while (p.available() > 0) {
char c = p.read();
SerialUSB.print(c);
}
// Ensure the last bit of data is sent.
SerialUSB.flush();
}
void runCpuInfo() {
// Launch "cat /proc/cpuinfo" command (shows info on Atheros CPU)
// cat is a command line utility that shows the content of a file
Process p; // Create a process and call it "p"
p.begin("cat"); // Process that launch the "cat" command
p.addParameter("/proc/cpuinfo"); // Add the cpuifo file path as parameter to cut
p.run(); // Run the process and wait for its termination
// Print command output on the SerialUSB.
// A process output can be read with the stream methods
while (p.available() > 0) {
char c = p.read();
SerialUSB.print(c);
}
// Ensure the last bit of data is sent.
SerialUSB.flush();
}

View File

@ -0,0 +1,33 @@
/*
Blink
Turns on an LED on for one second, then off for one second, repeatedly.
Most Arduinos have an on-board LED you can control. On the Uno and
Leonardo, it is attached to digital pin 13. If you're unsure what
pin the on-board LED is connected to on your Arduino model, check
the documentation at http://www.arduino.cc
This example code is in the public domain.
modified 8 May 2014
by Scott Fitzgerald
modified by Marco Brianza to show the remote sketch update feature on Arduino Due using Yún Shield
*/
#include <Bridge.h>
// the setup function runs once when you press reset or power the board
void setup() {
checkForRemoteSketchUpdate();
// initialize digital pin 13 as an output.
pinMode(13, OUTPUT);
}
// the loop function runs over and over again forever
void loop() {
digitalWrite(13, HIGH); // turn the LED on (HIGH is the voltage level)
delay(100); // wait for a second
digitalWrite(13, LOW); // turn the LED off by making the voltage LOW
delay(100); // wait for a second
}

View File

@ -0,0 +1,52 @@
/*
Running shell commands using Process class.
This sketch demonstrate how to run linux shell commands
using a YunShield/Yún. It runs the wifiCheck script on the Linux side
of the Yún, then uses grep to get just the signal strength line.
Then it uses parseInt() to read the wifi signal strength as an integer,
and finally uses that number to fade an LED using analogWrite().
The circuit:
* YunShield/Yún with LED connected to pin 9
created 12 Jun 2013
by Cristian Maglie
modified 25 June 2013
by Tom Igoe
This example code is in the public domain.
http://www.arduino.cc/en/Tutorial/ShellCommands
*/
#include <Process.h>
void setup() {
Bridge.begin(); // Initialize the Bridge
SerialUSB.begin(9600); // Initialize the Serial
// Wait until a Serial Monitor is connected.
while (!SerialUSB);
}
void loop() {
Process p;
// This command line runs the WifiStatus script, (/usr/bin/pretty-wifi-info.lua), then
// sends the result to the grep command to look for a line containing the word
// "Signal:" the result is passed to this sketch:
p.runShellCommand("/usr/bin/pretty-wifi-info.lua | grep Signal");
// do nothing until the process finishes, so you get the whole output:
while (p.running());
// Read command output. runShellCommand() should have passed "Signal: xx&":
while (p.available()) {
int result = p.parseInt(); // look for an integer
int signal = map(result, 0, 100, 0, 255); // map result from 0-100 range to 0-255
analogWrite(9, signal); // set the brightness of LED on pin 9
SerialUSB.println(result); // print the number as well
}
delay(5000); // wait 5 seconds before you do it again
}

View File

@ -0,0 +1,122 @@
/*
Temperature web interface
This example shows how to serve data from an analog input
via the YunShield/Yún built-in webserver using the Bridge library.
The circuit:
* TMP36 temperature sensor on analog pin A1
* SD card attached to SD card slot of the YunShield/Yún
This sketch must be uploaded via wifi. REST API must be set to "open".
Prepare your SD card with an empty folder in the SD root
named "arduino" and a subfolder of that named "www".
This will ensure that the Yún will create a link
to the SD to the "/mnt/sd" path.
In this sketch folder is a basic webpage and a copy of zepto.js, a
minimized version of jQuery. When you upload your sketch, these files
will be placed in the /arduino/www/TemperatureWebPanel folder on your SD card.
You can then go to http://arduino.local/sd/TemperatureWebPanel
to see the output of this sketch.
You can remove the SD card while the Linux and the
sketch are running but be careful not to remove it while
the system is writing to it.
created 6 July 2013
by Tom Igoe
This example code is in the public domain.
http://www.arduino.cc/en/Tutorial/TemperatureWebPanel
*/
#include <Bridge.h>
#include <BridgeServer.h>
#include <BridgeClient.h>
// Listen on default port 5555, the webserver on the Yún
// will forward there all the HTTP requests for us.
BridgeServer server;
String startString;
long hits = 0;
void setup() {
SerialUSB.begin(9600);
// Bridge startup
pinMode(13, OUTPUT);
digitalWrite(13, LOW);
Bridge.begin();
digitalWrite(13, HIGH);
// using A0 and A2 as vcc and gnd for the TMP36 sensor:
pinMode(A0, OUTPUT);
pinMode(A2, OUTPUT);
digitalWrite(A0, HIGH);
digitalWrite(A2, LOW);
// Listen for incoming connection only from localhost
// (no one from the external network could connect)
server.listenOnLocalhost();
server.begin();
// get the time that this sketch started:
Process startTime;
startTime.runShellCommand("date");
while (startTime.available()) {
char c = startTime.read();
startString += c;
}
}
void loop() {
// Get clients coming from server
BridgeClient client = server.accept();
// There is a new client?
if (client) {
// read the command
String command = client.readString();
command.trim(); //kill whitespace
SerialUSB.println(command);
// is "temperature" command?
if (command == "temperature") {
// get the time from the server:
Process time;
time.runShellCommand("date");
String timeString = "";
while (time.available()) {
char c = time.read();
timeString += c;
}
SerialUSB.println(timeString);
int sensorValue = analogRead(A1);
// convert the reading to millivolts:
float voltage = sensorValue * (5000.0f / 1024.0f);
// convert the millivolts to temperature celsius:
float temperature = (voltage - 500.0f) / 10.0f;
// print the temperature:
client.print("Current time on the Y&uacute;n: ");
client.println(timeString);
client.print("<br>Current temperature: ");
client.print(temperature);
client.print(" &deg;C");
client.print("<br>This sketch has been running since ");
client.print(startString);
client.print("<br>Hits so far: ");
client.print(hits);
}
// Close connection and free resources.
client.stop();
hits++;
}
delay(50); // Poll every 50ms
}

View File

@ -0,0 +1,16 @@
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="zepto.min.js"></script>
<script type="text/javascript">
function refresh() {
$('#content').load('/arduino/temperature');
}
</script>
</head>
<body onload="setInterval(refresh, 2000);">
<span id="content">0</span>
</body>
</html>

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,88 @@
/*
Time Check
Gets the time from Linux via Bridge then parses out hours,
minutes and seconds using a YunShield/Yún.
created 27 May 2013
modified 21 June 2013
By Tom Igoe
This example code is in the public domain.
http://www.arduino.cc/en/Tutorial/TimeCheck
*/
#include <Process.h>
Process date; // process used to get the date
int hours, minutes, seconds; // for the results
int lastSecond = -1; // need an impossible value for comparison
void setup() {
Bridge.begin(); // initialize Bridge
SerialUSB.begin(9600); // initialize serial
while (!Serial); // wait for Serial Monitor to open
SerialUSB.println("Time Check"); // Title of sketch
// run an initial date process. Should return:
// hh:mm:ss :
if (!date.running()) {
date.begin("date");
date.addParameter("+%T");
date.run();
}
}
void loop() {
if (lastSecond != seconds) { // if a second has passed
// print the time:
if (hours <= 9) {
SerialUSB.print("0"); // adjust for 0-9
}
SerialUSB.print(hours);
SerialUSB.print(":");
if (minutes <= 9) {
SerialUSB.print("0"); // adjust for 0-9
}
SerialUSB.print(minutes);
SerialUSB.print(":");
if (seconds <= 9) {
SerialUSB.print("0"); // adjust for 0-9
}
SerialUSB.println(seconds);
// restart the date process:
if (!date.running()) {
date.begin("date");
date.addParameter("+%T");
date.run();
}
}
//if there's a result from the date process, parse it:
while (date.available() > 0) {
// get the result of the date process (should be hh:mm:ss):
String timeString = date.readString();
// find the colons:
int firstColon = timeString.indexOf(":");
int secondColon = timeString.lastIndexOf(":");
// get the substrings for hour, minute second:
String hourString = timeString.substring(0, firstColon);
String minString = timeString.substring(firstColon + 1, secondColon);
String secString = timeString.substring(secondColon + 1);
// convert to ints,saving the previous second:
hours = hourString.toInt();
minutes = minString.toInt();
lastSecond = seconds; // save to do a time comparison
seconds = secString.toInt();
}
}

View File

@ -0,0 +1,51 @@
/*
WiFi Status
This sketch runs a script called "pretty-wifi-info.lua"
installed on your Yún in folder /usr/bin.
It prints information about the status of your wifi connection.
It uses Serial to print, so you need to connect your YunShield/Yún to your
computer using a USB cable and select the appropriate port from
the Port menu
created 18 June 2013
By Federico Fissore
This example code is in the public domain.
http://www.arduino.cc/en/Tutorial/YunWiFiStatus
*/
#include <Process.h>
void setup() {
SerialUSB.begin(9600); // initialize serial communication
while (!SerialUSB); // do nothing until the serial monitor is opened
SerialUSB.println("Starting bridge...\n");
pinMode(13, OUTPUT);
digitalWrite(13, LOW);
Bridge.begin(); // make contact with the linux processor
digitalWrite(13, HIGH); // Led on pin 13 turns on when the bridge is ready
delay(2000); // wait 2 seconds
}
void loop() {
Process wifiCheck; // initialize a new process
wifiCheck.runShellCommand("/usr/bin/pretty-wifi-info.lua"); // command you want to run
// while there's any characters coming back from the
// process, print them to the serial monitor:
while (wifiCheck.available() > 0) {
char c = wifiCheck.read();
SerialUSB.print(c);
}
SerialUSB.println();
delay(5000);
}

View File

@ -0,0 +1,328 @@
/*
Arduino Yún First configuration sketch
Configures the YunShield/Yún WiFi and infos via the Bridge
Works correctly if Line Ending is set as "NewLine"
If your board has two USB ports, use the Native one
The circuit:
Arduino YunShield
(or any Yun model with firmware > 1.6.1)
created March 2016
by Arduino LLC
This example code is in the public domain.
http://www.arduino.cc/en/Tutorial/YunFirstConfig
*/
#include <Process.h>
#define MAX_WIFI_LIST 10
String networks[MAX_WIFI_LIST];
String yunName;
String yunPassword;
void setup() {
SERIAL_PORT_USBVIRTUAL.begin(9600); // initialize serial communication
while (!SERIAL_PORT_USBVIRTUAL); // do nothing until the serial monitor is opened
SERIAL_PORT_USBVIRTUAL.println(F("Hi! Nice to see you!"));
SERIAL_PORT_USBVIRTUAL.println(F("I'm your YunShield assistant sketch"));
SERIAL_PORT_USBVIRTUAL.println(F("I'll help you configuring your Yun in a matter of minutes"));
SERIAL_PORT_USBVIRTUAL.println(F("Let's start by communicating with the Linux processor"));
SERIAL_PORT_USBVIRTUAL.println(F("When LED (L13) will light up we'll be ready to go!"));
SERIAL_PORT_USBVIRTUAL.println(F("Waiting..."));
SERIAL_PORT_USBVIRTUAL.println(F("(in the meanwhile, if you are using the IDE's serial monitor, make sure that it's configured to send a \"Newline\")\n"));
pinMode(13, OUTPUT);
digitalWrite(13, LOW);
Bridge.begin(); // make contact with the linux processor
digitalWrite(13, HIGH); // Led on pin 13 turns on when the bridge is ready
// Recover if the board is in AP mode - unused
Process wifiList;
bool master = false;
wifiList.runShellCommand(F("iwinfo | grep \"Mode: Master\""));
while (wifiList.available() > 0) {
wifiList.read();
master = true;
}
// Get the list of reachable networks
wifiList.runShellCommand(F("iwinfo wlan0 scan | grep ESSID | cut -d\"\\\"\" -f2"));
uint8_t num_networks = 0;
uint8_t i = 0;
char c;
bool dropNet = false;
networks[0].reserve(32);
while (wifiList.available() > 0) {
c = wifiList.read();
if (c != '\n') {
networks[i] += c;
} else {
// check if we already found networks[i] and eventually drop it
for (uint8_t s = 0; s < i; s++) {
if (networks[i].equals(networks[s])) {
dropNet = true;
}
}
if (i <= MAX_WIFI_LIST && dropNet == false) {
networks[i++].reserve(32);
} else {
dropNet = false;
networks[i]="";
}
}
}
num_networks = i;
String encryption;
String password;
int chose = 0;
// If networks number is 0, start manual configuration
if (num_networks == 0) {
SERIAL_PORT_USBVIRTUAL.println(F("Oops, it seems that you have no WiFi network available"));
SERIAL_PORT_USBVIRTUAL.println(F("Let's configure it manually"));
SERIAL_PORT_USBVIRTUAL.println(F("SSID of the network you want to connect to: "));
networks[0] = getUserInput(networks[0], false);
SERIAL_PORT_USBVIRTUAL.println(F("Password for the network you want to connect to: "));
password = getUserInput(password, true);
SERIAL_PORT_USBVIRTUAL.print(F("Encryption (eg WPA, WPA2, WEP): "));
encryption = getUserInput(encryption, false);
} else {
// else print them prepending a number
SERIAL_PORT_USBVIRTUAL.print(F("It looks like you have "));
SERIAL_PORT_USBVIRTUAL.print(num_networks);
SERIAL_PORT_USBVIRTUAL.println(F(" networks around you "));
SERIAL_PORT_USBVIRTUAL.println(F("Which one do you want to connect to?\n"));
for (i = 0; i < num_networks && i < MAX_WIFI_LIST; i++) {
SERIAL_PORT_USBVIRTUAL.print(i);
SERIAL_PORT_USBVIRTUAL.println(") " + networks[i]);
}
String selection;
selection = getUserInput(selection, false);
chose = atoi(selection.c_str());
}
// Extract the selected network security
bool openNet = false;
wifiList.runShellCommand("iwinfo wlan0 scan | grep \"" + networks[chose] + "\" -A5 | grep Encryption | cut -f2 -d\":\"");
while (wifiList.available() > 0) {
c = wifiList.read();
encryption += c;
}
if (encryption.indexOf("none") >= 0) {
openNet = true;
encryption = "none";
}
if (encryption.indexOf("WPA2") >= 0) {
encryption = "psk2";
}
if (encryption.indexOf("WPA") >= 0) {
encryption = "psk";
}
if (encryption.indexOf("WEP") >= 0) {
encryption = "wep";
}
if (openNet == false && password.length() == 0) {
SERIAL_PORT_USBVIRTUAL.print(F("It looks like you need a password to connect to "));
SERIAL_PORT_USBVIRTUAL.println(networks[chose]);
SERIAL_PORT_USBVIRTUAL.print(F("Write it here: "));
password = getUserInput(password, true);
}
// Change hostname/root password
SERIAL_PORT_USBVIRTUAL.println(F("We are almost done! Give a name and a password to your Yun"));
SERIAL_PORT_USBVIRTUAL.print(F("Name: "));
yunName = getUserInput(yunName, false);
SERIAL_PORT_USBVIRTUAL.print(F("Password: "));
yunPassword = getUserInput(yunPassword, true);
// Select a country code
String countryCode;
SERIAL_PORT_USBVIRTUAL.println(F("One last question: where do you live?"));
SERIAL_PORT_USBVIRTUAL.print(F("Insert a two letters county code (eg IT, US, DE): "));
countryCode = getUserInput(countryCode, false);
yunName.trim();
yunPassword.trim();
networks[chose].trim();
password.trim();
countryCode.trim();
// Configure the Yun with user provided strings
wifiConfig(yunName, yunPassword, networks[chose], password, "YUN" + yunName + "AP", countryCode, encryption);
SERIAL_PORT_USBVIRTUAL.print(F("Waiting for the Yun to connect to the network"));
}
bool Connected = false;
bool serialTerminalMode = false;
int runs = 0;
void loop() {
if (!serialTerminalMode) {
String resultStr = "";
if (!Connected) {
SERIAL_PORT_USBVIRTUAL.print(".");
runs++;
}
// If it takes more than 20 seconds to connect, stop trying
if (runs > 20) {
SERIAL_PORT_USBVIRTUAL.println("");
SERIAL_PORT_USBVIRTUAL.println(F("We couldn't connect to the network."));
SERIAL_PORT_USBVIRTUAL.println(F("Restart the board if you want to execute the wizard again"));
resultStr = getUserInput(resultStr, false);
}
// Check if we have an IP address
Process wifiCheck;
wifiCheck.runShellCommand(F("/usr/bin/pretty-wifi-info.lua | grep \"IP address\" | cut -f2 -d\":\" | cut -f1 -d\"/\"" )); // command you want to run
while (wifiCheck.available() > 0) {
char c = wifiCheck.read();
resultStr += c;
}
delay(1000);
if (resultStr != "") {
// We got an IP, freeze the loop, display the value and "spawn" a serial terminal
Connected = true;
resultStr.trim();
SERIAL_PORT_USBVIRTUAL.println("");
SERIAL_PORT_USBVIRTUAL.print(F("\nGreat! You can now reach your Yun from a browser typing http://"));
SERIAL_PORT_USBVIRTUAL.println(resultStr);
SERIAL_PORT_USBVIRTUAL.print(F("Press 'Enter' key twice to start a serial terminal"));
resultStr = getUserInput(resultStr, false);
serialTerminalMode = true;
//startSerialTerminal();
SERIAL_PORT_HARDWARE.write((uint8_t *)"\xff\0\0\x05XXXXX\x7f\xf9", 11); // send "bridge shutdown" command
delay(100);
SERIAL_PORT_HARDWARE.println("\nreset\n\n");
SERIAL_PORT_HARDWARE.flush();
SERIAL_PORT_HARDWARE.println("\nreset\n\n");
SERIAL_PORT_HARDWARE.write((uint8_t *)"\n", 1);
}
} else {
loopSerialTerminal();
}
}
String getUserInput(String out, bool obfuscated) {
/*
while (SerialUSB.available() <= 0) {}
while (SerialUSB.available() > 0) {
char c = SerialUSB.read();
out += c;
}
return out;
*/
while (SERIAL_PORT_USBVIRTUAL.available() <= 0) {}
while (1) {
char c = SERIAL_PORT_USBVIRTUAL.read();
if (c == '\n' || c == '\r')
break;
else {
if (c != -1) {
out += c;
if (obfuscated)
SERIAL_PORT_USBVIRTUAL.print("*");
else
SERIAL_PORT_USBVIRTUAL.print(c);
}
}
}
SERIAL_PORT_USBVIRTUAL.println("");
return out;
}
void wifiConfig(String yunName, String yunPsw, String wifissid, String wifipsw, String wifiAPname, String countryCode, String encryption) {
Process p;
p.runShellCommand("blink-start 100"); //start the blue blink
p.runShellCommand("hostname " + yunName); //change the current hostname
p.runShellCommand("uci set system.@system[0].hostname='" + yunName + "'"); //change teh hostname in uci
p.runShellCommand("uci set arduino.@arduino[0].access_point_wifi_name='" + wifiAPname + "'");
//this block resets the wifi psw
p.runShellCommand("uci set wireless.@wifi-iface[0].encryption='" + encryption + "'");
p.runShellCommand("uci set wireless.@wifi-iface[0].mode='sta'\n");
p.runShellCommand("uci set wireless.@wifi-iface[0].ssid='" + wifissid + "'");
p.runShellCommand("uci set wireless.@wifi-iface[0].key='" + wifipsw + "'");
p.runShellCommand("uci set wireless.radio0.channel='auto'");
p.runShellCommand("uci set wireless.radio0.country='" + countryCode + "'");
p.runShellCommand("uci delete network.lan.ipaddr");
p.runShellCommand("uci delete network.lan.netmask");
p.runShellCommand("uci set network.lan.proto='dhcp'");
p.runShellCommand("echo -e \"" + yunPsw + "\n" + yunPsw + "\" | passwd root"); //change the passwors
p.runShellCommand("uci commit"); //save the mods done via UCI
p.runShellCommand("blink-stop"); //start the blue blink
p.runShellCommand("wifi ");
}
long linuxBaud = 250000;
void startSerialTerminal() {
SERIAL_PORT_USBVIRTUAL.begin(115200); // open serial connection via USB-Serial
SERIAL_PORT_HARDWARE.begin(linuxBaud); // open serial connection to Linux
}
boolean commandMode = false;
void loopSerialTerminal() {
// copy from USB-CDC to UART
int c = SERIAL_PORT_USBVIRTUAL.read(); // read from USB-CDC
if (c != -1) { // got anything?
if (commandMode == false) { // if we aren't in command mode...
if (c == '~') { // Tilde '~' key pressed?
commandMode = true; // enter in command mode
} else {
SERIAL_PORT_HARDWARE.write(c); // otherwise write char to UART
}
} else { // if we are in command mode...
if (c == '0') { // '0' key pressed?
SERIAL_PORT_HARDWARE.begin(57600); // set speed to 57600
SERIAL_PORT_USBVIRTUAL.println("Speed set to 57600");
} else if (c == '1') { // '1' key pressed?
SERIAL_PORT_HARDWARE.begin(115200); // set speed to 115200
SERIAL_PORT_USBVIRTUAL.println("Speed set to 115200");
} else if (c == '2') { // '2' key pressed?
SERIAL_PORT_HARDWARE.begin(250000); // set speed to 250000
SERIAL_PORT_USBVIRTUAL.println("Speed set to 250000");
} else if (c == '3') { // '3' key pressed?
SERIAL_PORT_HARDWARE.begin(500000); // set speed to 500000
SERIAL_PORT_USBVIRTUAL.println("Speed set to 500000");
} else if (c == '~') { // '~` key pressed?
SERIAL_PORT_HARDWARE.write((uint8_t *)"\xff\0\0\x05XXXXX\x7f\xf9", 11); // send "bridge shutdown" command
SERIAL_PORT_USBVIRTUAL.println("Sending bridge's shutdown command");
} else { // any other key pressed?
SERIAL_PORT_HARDWARE.write('~'); // write '~' to UART
SERIAL_PORT_HARDWARE.write(c); // write char to UART
}
commandMode = false; // in all cases exit from command mode
}
}
// copy from UART to USB-CDC
c = SERIAL_PORT_HARDWARE.read(); // read from UART
if (c != -1) { // got anything?
SERIAL_PORT_USBVIRTUAL.write(c); // write to USB-CDC
}
}

View File

@ -0,0 +1,82 @@
/*
Arduino Yún USB-to-Serial
Allows you to use the YunShield/Yún processor as a
serial terminal for the Linux side on the Yún.
Upload this to a YunShield/Yún via serial (not WiFi) then open
the serial monitor at 115200 to see the boot process of Linux.
You can also use the serial monitor as a basic command line
interface for Linux using this sketch.
From the serial monitor the following commands can be issued:
'~' followed by '0' -> Set the UART speed to 57600 baud
'~' followed by '1' -> Set the UART speed to 115200 baud
'~' followed by '2' -> Set the UART speed to 250000 baud
'~' followed by '3' -> Set the UART speed to 500000 baud
'~' followed by '~' -> Sends the bridge's shutdown command to
obtain the console.
The circuit:
YunShield/Yún
created March 2013
by Massimo Banzi
modified by Cristian Maglie
This example code is in the public domain.
http://www.arduino.cc/en/Tutorial/YunSerialTerminal
*/
long linuxBaud = 250000;
void setup() {
SERIAL_PORT_USBVIRTUAL.begin(115200); // open serial connection via USB-Serial
SERIAL_PORT_HARDWARE.begin(linuxBaud); // open serial connection to Linux
}
boolean commandMode = false;
void loop() {
// copy from USB-CDC to UART
int c = SERIAL_PORT_USBVIRTUAL.read(); // read from USB-CDC
if (c != -1) { // got anything?
if (commandMode == false) { // if we aren't in command mode...
if (c == '~') { // Tilde '~' key pressed?
commandMode = true; // enter in command mode
} else {
SERIAL_PORT_HARDWARE.write(c); // otherwise write char to UART
}
} else { // if we are in command mode...
if (c == '0') { // '0' key pressed?
SERIAL_PORT_HARDWARE.begin(57600); // set speed to 57600
SERIAL_PORT_USBVIRTUAL.println("Speed set to 57600");
} else if (c == '1') { // '1' key pressed?
SERIAL_PORT_HARDWARE.begin(115200); // set speed to 115200
SERIAL_PORT_USBVIRTUAL.println("Speed set to 115200");
} else if (c == '2') { // '2' key pressed?
SERIAL_PORT_HARDWARE.begin(250000); // set speed to 250000
SERIAL_PORT_USBVIRTUAL.println("Speed set to 250000");
} else if (c == '3') { // '3' key pressed?
SERIAL_PORT_HARDWARE.begin(500000); // set speed to 500000
SERIAL_PORT_USBVIRTUAL.println("Speed set to 500000");
} else if (c == '~') { // '~` key pressed?
SERIAL_PORT_HARDWARE.write((uint8_t *)"\xff\0\0\x05XXXXX\x7f\xf9", 11); // send "bridge shutdown" command
SERIAL_PORT_USBVIRTUAL.println("Sending bridge's shutdown command");
} else { // any other key pressed?
SERIAL_PORT_HARDWARE.write('~'); // write '~' to UART
SERIAL_PORT_HARDWARE.write(c); // write char to UART
}
commandMode = false; // in all cases exit from command mode
}
}
// copy from UART to USB-CDC
c = SERIAL_PORT_HARDWARE.read(); // read from UART
if (c != -1) { // got anything?
SERIAL_PORT_USBVIRTUAL.write(c); // write to USB-CDC
}
}

View File

@ -0,0 +1,92 @@
#######################################
# Syntax Coloring Map For Bridge
#######################################
#######################################
# Class (KEYWORD1)
#######################################
Bridge KEYWORD1 YunBridgeLibrary
FileIO KEYWORD4 YunFileIOConstructor
FileSystem KEYWORD1 YunFileIOConstructor
Console KEYWORD1 YunConsoleConstructor
Process KEYWORD1 YunProcessConstructor
Mailbox KEYWORD1 YunMailboxConstructor
HttpClient KEYWORD1 YunHttpClientConstructor
YunServer KEYWORD1 YunServerConstructor
YunClient KEYWORD1 YunClientConstructor
BridgeServer KEYWORD1 YunServerConstructor
BridgeClient KEYWORD1 YunClientConstructor
BridgeSSLClient KEYWORD1 YunClientConstructor
#######################################
# Methods and Functions (KEYWORD2)
#######################################
# methods names in commond
begin KEYWORD2
end KEYWORD2
available KEYWORD2
read KEYWORD2
peek KEYWORD2
write KEYWORD2
flush KEYWORD2
bool KEYWORD2
# Bridge Class
transfer KEYWORD2
put KEYWORD2
get KEYWORD2
# Console Class
buffer KEYWORD2
noBuffer KEYWORD2
connected KEYWORD2
# FileIO Class
File KEYWORD2
BridgeFile KEYWORD2
seek KEYWORD2
position KEYWORD2
size KEYWORD2
close KEYWORD2
name KEYWORD2
isDirectory KEYWORD2
openNextFile KEYWORD2
rewindDirectory KEYWORD2
# Process Class
addParameter KEYWORD2
runAsynchronously KEYWORD2
run KEYWORD2
running KEYWORD2
exitValue KEYWORD2
runShellCommand KEYWORD2
runShellCommandAsynchronously KEYWORD2
# Mailbox Class
readMessage KEYWORD2
writeMessage KEYWORD2
writeJSON KEYWORD2
message Available KEYWORD2
# HttpClient Class
getAsynchronously KEYWORD2
ready KEYWORD2
getResult KEYWORD2
# BridgeServer Class
accept KEYWORD2
stop KEYWORD2
connect KEYWORD2
connectSSL KEYWORD2
connected KEYWORD2
#######################################
# Constants (LITERAL1)
#######################################
FILE_READ LITERAL1
FILE_WRITE LITERAL1
FILE_APPEND LITERAL1

View File

@ -0,0 +1,10 @@
name=Bridge
version=1.6.3
author=Arduino
maintainer=Arduino <info@arduino.cc>
sentence=Enables the communication between the Linux processor and the microcontroller. For Arduino/Genuino Yún, Yún Shield and TRE only.
paragraph=The Bridge library feature: access to the shared storage, run and manage linux processes, open a remote console, access to the linux file system, including the SD card, enstablish http clients or servers.
category=Communication
url=http://www.arduino.cc/en/Reference/YunBridgeLibrary
architectures=*
dot_a_linkage=true

View File

@ -0,0 +1,281 @@
/*
Copyright (c) 2013 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
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
*/
#include "Bridge.h"
BridgeClass::BridgeClass(Stream &_stream) :
index(0), stream(_stream), started(false), max_retries(0) {
// Empty
}
void BridgeClass::begin() {
if (started)
return;
started = true;
// Wait for U-boot to finish startup
do {
dropAll();
delay(1000);
} while (stream.available() > 0);
while (true) {
// Bridge interrupt:
// - Ask the bridge to close itself
uint8_t quit_cmd[] = {'X', 'X', 'X', 'X', 'X'};
max_retries = 1;
transfer(quit_cmd, 5);
// Bridge startup:
// - If the bridge is not running starts it safely
stream.print(CTRL_C);
delay(250);
stream.print(F("\n"));
delay(250);
stream.print(F("\n"));
delay(500);
// Wait for OpenWRT message
// "Press enter to activate console"
stream.print(F("run-bridge\n"));
delay(500);
dropAll();
// Reset the brigde to check if it is running
uint8_t cmd[] = {'X', 'X', '1', '0', '0'};
uint8_t res[4];
max_retries = 50;
uint16_t l = transfer(cmd, 5, res, 4);
if (l == TRANSFER_TIMEOUT) {
// Bridge didn't start...
// Maybe the board is starting-up?
// Wait and retry
delay(1000);
continue;
}
if (res[0] != 0)
while (true);
// Detect bridge version
if (l == 4) {
bridgeVersion = (res[1]-'0')*100 + (res[2]-'0')*10 + (res[3]-'0');
} else {
// Bridge v1.0.0 didn't send any version info
bridgeVersion = 100;
}
max_retries = 50;
return;
}
}
void BridgeClass::put(const char *key, const char *value) {
// TODO: do it in a more efficient way
String cmd = "D";
uint8_t res[1];
cmd += key;
cmd += "\xFE";
cmd += value;
transfer((uint8_t*)cmd.c_str(), cmd.length(), res, 1);
}
unsigned int BridgeClass::get(const char *key, uint8_t *value, unsigned int maxlen) {
uint8_t cmd[] = {'d'};
unsigned int l = transfer(cmd, 1, (uint8_t *)key, strlen(key), value, maxlen);
if (l < maxlen)
value[l] = 0; // Zero-terminate string
return l;
}
#if defined(ARDUINO_ARCH_AVR)
// AVR use an optimized implementation of CRC
#include <util/crc16.h>
#else
// Generic implementation for non-AVR architectures
uint16_t _crc_ccitt_update(uint16_t crc, uint8_t data)
{
data ^= crc & 0xff;
data ^= data << 4;
return ((((uint16_t)data << 8) | ((crc >> 8) & 0xff)) ^
(uint8_t)(data >> 4) ^
((uint16_t)data << 3));
}
#endif
void BridgeClass::crcUpdate(uint8_t c) {
CRC = _crc_ccitt_update(CRC, c);
}
void BridgeClass::crcReset() {
CRC = 0xFFFF;
}
void BridgeClass::crcWrite() {
stream.write((char)(CRC >> 8));
stream.write((char)(CRC & 0xFF));
}
bool BridgeClass::crcCheck(uint16_t _CRC) {
return CRC == _CRC;
}
uint16_t BridgeClass::transfer(const uint8_t *buff1, uint16_t len1,
const uint8_t *buff2, uint16_t len2,
const uint8_t *buff3, uint16_t len3,
uint8_t *rxbuff, uint16_t rxlen)
{
uint16_t len = len1 + len2 + len3;
uint8_t retries = 0;
for ( ; retries < max_retries; retries++, delay(100), dropAll() /* Delay for retransmission */) {
// Send packet
crcReset();
stream.write((char)0xFF); // Start of packet (0xFF)
crcUpdate(0xFF);
stream.write((char)index); // Message index
crcUpdate(index);
stream.write((char)((len >> 8) & 0xFF)); // Message length (hi)
crcUpdate((len >> 8) & 0xFF);
stream.write((char)(len & 0xFF)); // Message length (lo)
crcUpdate(len & 0xFF);
for (uint16_t i = 0; i < len1; i++) { // Payload
stream.write((char)buff1[i]);
crcUpdate(buff1[i]);
}
for (uint16_t i = 0; i < len2; i++) { // Payload
stream.write((char)buff2[i]);
crcUpdate(buff2[i]);
}
for (uint16_t i = 0; i < len3; i++) { // Payload
stream.write((char)buff3[i]);
crcUpdate(buff3[i]);
}
crcWrite(); // CRC
// Wait for ACK in 100ms
if (timedRead(100) != 0xFF)
continue;
crcReset();
crcUpdate(0xFF);
// Check packet index
if (timedRead(5) != index)
continue;
crcUpdate(index);
// Recv len
int lh = timedRead(10);
if (lh < 0)
continue;
crcUpdate(lh);
int ll = timedRead(10);
if (ll < 0)
continue;
crcUpdate(ll);
uint16_t l = lh;
l <<= 8;
l += ll;
// Recv data
for (uint16_t i = 0; i < l; i++) {
// Cut received data if rxbuffer is too small
if (i >= rxlen)
break;
int c = timedRead(5);
if (c < 0)
continue;
rxbuff[i] = c;
crcUpdate(c);
}
// Check CRC
int crc_hi = timedRead(5);
if (crc_hi < 0)
continue;
int crc_lo = timedRead(5);
if (crc_lo < 0)
continue;
if (!crcCheck((crc_hi << 8) + crc_lo))
continue;
// Increase index
index++;
// Return bytes received
if (l > rxlen)
return rxlen;
return l;
}
// Max retries exceeded
return TRANSFER_TIMEOUT;
}
int BridgeClass::timedRead(unsigned int timeout) {
int c;
unsigned long _startMillis = millis();
do {
c = stream.read();
if (c >= 0) return c;
} while (millis() - _startMillis < timeout);
return -1; // -1 indicates timeout
}
void BridgeClass::dropAll() {
while (stream.available() > 0) {
stream.read();
}
}
#if defined(ARDUINO_ARCH_SAM)
#include <Reset.h>
#endif
#if defined(ARDUINO_ARCH_SAM)
void checkForRemoteSketchUpdate(uint8_t pin) {
// The host force pin LOW to signal that a new sketch is coming
pinMode(pin, INPUT_PULLUP);
delay(50);
if (digitalRead(pin) == LOW) {
initiateReset(1);
while (true)
; // Wait for reset to SAM-BA
}
// Restore in standard state
pinMode(pin, INPUT);
}
#else
void checkForRemoteSketchUpdate(uint8_t /* pin */) {
// Empty, bootloader is enough.
}
#endif
// Bridge instance
#if defined(SERIAL_PORT_LINUXBRIDGE)
SerialBridgeClass Bridge(SERIAL_PORT_LINUXBRIDGE);
#elif defined(SERIAL_PORT_HARDWARE)
SerialBridgeClass Bridge(SERIAL_PORT_HARDWARE);
#elif defined(SERIAL_PORT_HARDWARE_OPEN)
SerialBridgeClass Bridge(SERIAL_PORT_HARDWARE_OPEN);
#elif defined(__AVR_ATmega32U4__) // Legacy fallback
// Leonardo variants (where HardwareSerial is Serial1)
SerialBridgeClass Bridge(Serial1);
#else
SerialBridgeClass Bridge(Serial);
#endif

View File

@ -0,0 +1,125 @@
/*
Copyright (c) 2013 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
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
*/
#ifndef BRIDGE_H_
#define BRIDGE_H_
#ifndef BRIDGE_BAUDRATE
#define BRIDGE_BAUDRATE 250000
#endif
#include <Arduino.h>
#include <Stream.h>
class BridgeClass {
public:
BridgeClass(Stream &_stream);
void begin();
// Methods to handle key/value datastore
void put(const char *key, const char *value);
void put(const String &key, const String &value)
{
put(key.c_str(), value.c_str());
}
unsigned int get(const char *key, uint8_t *buff, unsigned int size);
unsigned int get(const char *key, char *value, unsigned int maxlen)
{
return get(key, reinterpret_cast<uint8_t *>(value), maxlen);
}
// Trasnfer a frame (with error correction and response)
uint16_t transfer(const uint8_t *buff1, uint16_t len1,
const uint8_t *buff2, uint16_t len2,
const uint8_t *buff3, uint16_t len3,
uint8_t *rxbuff, uint16_t rxlen);
// multiple inline versions of the same function to allow efficient frame concatenation
uint16_t transfer(const uint8_t *buff1, uint16_t len1)
{
return transfer(buff1, len1, NULL, 0);
}
uint16_t transfer(const uint8_t *buff1, uint16_t len1,
uint8_t *rxbuff, uint16_t rxlen)
{
return transfer(buff1, len1, NULL, 0, rxbuff, rxlen);
}
uint16_t transfer(const uint8_t *buff1, uint16_t len1,
const uint8_t *buff2, uint16_t len2,
uint8_t *rxbuff, uint16_t rxlen)
{
return transfer(buff1, len1, buff2, len2, NULL, 0, rxbuff, rxlen);
}
uint16_t getBridgeVersion()
{
return bridgeVersion;
}
static const uint16_t TRANSFER_TIMEOUT = 0xFFFF;
private:
uint8_t index;
int timedRead(unsigned int timeout);
void dropAll();
uint16_t bridgeVersion;
private:
void crcUpdate(uint8_t c);
void crcReset();
void crcWrite();
bool crcCheck(uint16_t _CRC);
uint16_t CRC;
private:
static const char CTRL_C = 3;
Stream &stream;
bool started;
uint8_t max_retries;
};
// This subclass uses a serial port Stream
class SerialBridgeClass : public BridgeClass {
public:
SerialBridgeClass(HardwareSerial &_serial)
: BridgeClass(_serial), serial(_serial) {
// Empty
}
void begin(unsigned long baudrate = BRIDGE_BAUDRATE) {
serial.begin(baudrate);
BridgeClass::begin();
}
private:
HardwareSerial &serial;
};
extern SerialBridgeClass Bridge;
// Some microcrontrollers don't start the bootloader after a reset.
// This function is intended to let the microcontroller erase its
// flash after checking a specific signal coming from the external
// device without the need to press the erase button on the board.
// The purpose is to enable a software update that does not require
// a manual interaction with the board.
extern void checkForRemoteSketchUpdate(uint8_t pin = 7);
#endif /* BRIDGE_H_ */
#include <Console.h>
#include <Process.h>

View File

@ -0,0 +1,207 @@
/*
Copyright (c) 2013 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
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
*/
#include <BridgeClient.h>
BridgeClient::BridgeClient(uint8_t _h, BridgeClass &_b) :
bridge(_b), handle(_h), opened(true), buffered(0) {
}
BridgeClient::BridgeClient(BridgeClass &_b) :
bridge(_b), handle(0), opened(false), buffered(0) {
}
BridgeClient::~BridgeClient() {
}
BridgeClient& BridgeClient::operator=(const BridgeClient &_x) {
opened = _x.opened;
handle = _x.handle;
return *this;
}
void BridgeClient::stop() {
if (opened) {
uint8_t cmd[] = {'j', handle};
bridge.transfer(cmd, 2);
}
opened = false;
buffered = 0;
readPos = 0;
}
void BridgeClient::doBuffer() {
// If there are already char in buffer exit
if (buffered > 0)
return;
// Try to buffer up to 32 characters
readPos = 0;
uint8_t cmd[] = {'K', handle, sizeof(buffer)};
buffered = bridge.transfer(cmd, 3, buffer, sizeof(buffer));
}
int BridgeClient::available() {
// Look if there is new data available
doBuffer();
return buffered;
}
int BridgeClient::read() {
doBuffer();
if (buffered == 0)
return -1; // no chars available
else {
buffered--;
return buffer[readPos++];
}
}
int BridgeClient::read(uint8_t *buff, size_t size) {
size_t readed = 0;
do {
if (buffered == 0) {
doBuffer();
if (buffered == 0)
return readed;
}
buff[readed++] = buffer[readPos++];
buffered--;
} while (readed < size);
return readed;
}
int BridgeClient::peek() {
doBuffer();
if (buffered == 0)
return -1; // no chars available
else
return buffer[readPos];
}
size_t BridgeClient::write(uint8_t c) {
if (!opened)
return 0;
uint8_t cmd[] = {'l', handle, c};
bridge.transfer(cmd, 3);
return 1;
}
size_t BridgeClient::write(const uint8_t *buf, size_t size) {
if (!opened)
return 0;
uint8_t cmd[] = {'l', handle};
bridge.transfer(cmd, 2, buf, size, NULL, 0);
return size;
}
void BridgeClient::flush() {
}
uint8_t BridgeClient::connected() {
if (!opened)
return false;
// Client is "connected" if it has unread bytes
if (available())
return true;
uint8_t cmd[] = {'L', handle};
uint8_t res[1];
bridge.transfer(cmd, 2, res, 1);
return (res[0] == 1);
}
int BridgeClient::connect(IPAddress ip, uint16_t port) {
String address;
address.reserve(18);
address += ip[0];
address += '.';
address += ip[1];
address += '.';
address += ip[2];
address += '.';
address += ip[3];
return connect(address.c_str(), port);
}
int BridgeClient::connect(const char *host, uint16_t port) {
uint8_t tmp[] = {
'C',
static_cast<uint8_t>(port >> 8),
static_cast<uint8_t>(port)
};
uint8_t res[1];
int l = bridge.transfer(tmp, 3, (const uint8_t *)host, strlen(host), res, 1);
if (l == 0)
return 0;
handle = res[0];
// wait for connection
uint8_t tmp2[] = { 'c', handle };
uint8_t res2[1];
while (true) {
bridge.transfer(tmp2, 2, res2, 1);
if (res2[0] == 0)
break;
delay(1);
}
opened = true;
// check for successful connection
if (connected())
return 1;
stop();
handle = 0;
return 0;
}
int BridgeClient::connectSSL(const char *host, uint16_t port) {
if (bridge.getBridgeVersion() < 161)
return -1;
uint8_t tmp[] = {
'Z',
static_cast<uint8_t>(port >> 8),
static_cast<uint8_t>(port)
};
uint8_t res[1];
int l = bridge.transfer(tmp, 3, (const uint8_t *)host, strlen(host), res, 1);
if (l == 0)
return 0;
handle = res[0];
// wait for connection
uint8_t tmp2[] = { 'c', handle };
uint8_t res2[1];
while (true) {
bridge.transfer(tmp2, 2, res2, 1);
if (res2[0] == 0)
break;
delay(1);
}
opened = true;
// check for successful connection
if (connected())
return 1;
stop();
handle = 0;
return 0;
}

View File

@ -0,0 +1,71 @@
/*
Copyright (c) 2013 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
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
*/
#ifndef _BRIDGE_CLIENT_H_
#define _BRIDGE_CLIENT_H_
#include <Bridge.h>
#include <Client.h>
class BridgeClient : public Client {
public:
// Constructor with a user provided BridgeClass instance
BridgeClient(uint8_t _h, BridgeClass &_b = Bridge);
BridgeClient(BridgeClass &_b = Bridge);
~BridgeClient();
// Stream methods
// (read message)
virtual int available();
virtual int read();
virtual int read(uint8_t *buf, size_t size);
virtual int peek();
// (write response)
virtual size_t write(uint8_t);
virtual size_t write(const uint8_t *buf, size_t size);
virtual void flush();
// TODO: add optimized function for block write
virtual operator bool () {
return opened;
}
virtual BridgeClient& operator=(const BridgeClient &_x);
virtual void stop();
virtual uint8_t connected();
virtual int connect(IPAddress ip, uint16_t port);
virtual int connect(const char *host, uint16_t port);
int connectSSL(const char* host, uint16_t port);
private:
BridgeClass &bridge;
uint8_t handle;
boolean opened;
private:
void doBuffer();
uint8_t buffered;
uint8_t readPos;
static const int BUFFER_SIZE = 64;
uint8_t buffer[BUFFER_SIZE];
};
#endif // _BRIDGE_CLIENT_H_

View File

@ -0,0 +1,36 @@
/*
Copyright (c) 2016 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
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
*/
#include <BridgeSSLClient.h>
BridgeSSLClient::BridgeSSLClient(uint8_t _h, BridgeClass &_b) :
BridgeClient(_h, _b)
{
}
BridgeSSLClient::BridgeSSLClient(BridgeClass &_b):
BridgeClient(_b)
{
}
BridgeSSLClient::~BridgeSSLClient() {
}
int BridgeSSLClient::connect(const char *host, uint16_t port) {
return BridgeClient::connectSSL(host, port);
}

View File

@ -0,0 +1,36 @@
/*
Copyright (c) 2016 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
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
*/
#ifndef _BRIDGE_SSL_CLIENT_H_
#define _BRIDGE_SSL_CLIENT_H_
#include <Bridge.h>
#include <Client.h>
#include <BridgeClient.h>
class BridgeSSLClient : public BridgeClient {
public:
// Constructor with a user provided BridgeClass instance
BridgeSSLClient(uint8_t _h, BridgeClass &_b = Bridge);
BridgeSSLClient(BridgeClass &_b = Bridge);
~BridgeSSLClient();
virtual int connect(const char* host, uint16_t port);
};
#endif // _BRIDGE_SSL_CLIENT_H_

View File

@ -0,0 +1,54 @@
/*
Copyright (c) 2013 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
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
*/
#include <BridgeServer.h>
#include <BridgeClient.h>
BridgeServer::BridgeServer(uint16_t _p, BridgeClass &_b) :
bridge(_b), port(_p), listening(false), useLocalhost(false) {
}
void BridgeServer::begin() {
uint8_t tmp[] = {
'N',
static_cast<uint8_t>(port >> 8),
static_cast<uint8_t>(port)
};
uint8_t res[1];
String address = F("127.0.0.1");
if (!useLocalhost)
address = F("0.0.0.0");
bridge.transfer(tmp, 3, (const uint8_t *)address.c_str(), address.length(), res, 1);
listening = (res[0] == 1);
}
BridgeClient BridgeServer::accept() {
uint8_t cmd[] = {'k'};
uint8_t res[1];
unsigned int l = bridge.transfer(cmd, 1, res, 1);
if (l == 0)
return BridgeClient();
return BridgeClient(res[0]);
}
size_t BridgeServer::write(uint8_t c) {
uint8_t cmd[] = { 'b', c };
bridge.transfer(cmd, 2);
return 1;
}

View File

@ -0,0 +1,51 @@
/*
Copyright (c) 2013 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
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
*/
#ifndef _BRIDGE_SERVER_H_
#define _BRIDGE_SERVER_H_
#include <Bridge.h>
#include <Server.h>
class BridgeClient;
class BridgeServer : public Server {
public:
// Constructor with a user provided BridgeClass instance
BridgeServer(uint16_t port = 5555, BridgeClass &_b = Bridge);
void begin();
BridgeClient accept();
virtual size_t write(uint8_t c);
void listenOnLocalhost() {
useLocalhost = true;
}
void noListenOnLocalhost() {
useLocalhost = false;
}
private:
BridgeClass &bridge;
uint16_t port;
bool listening;
bool useLocalhost;
};
#endif // _BRIDGE_SERVER_H_

View File

@ -0,0 +1,198 @@
/*
Copyright (c) 2015 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
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
*/
#include "BridgeUdp.h"
BridgeUDP::BridgeUDP(BridgeClass &_b) :
bridge(_b), opened(false), avail(0), buffered(0), readPos(0) {
}
/* Start BridgeUDP socket, listening at local port PORT */
uint8_t BridgeUDP::begin(uint16_t port) {
if (opened)
return 0;
uint8_t cmd[] = {'e', (uint8_t)((port >> 8) & 0xFF), (uint8_t)(port & 0xFF)};
uint8_t res[2];
bridge.transfer(cmd, 3, res, 2);
if (res[1] == 1) // Error...
return 0;
handle = res[0];
opened = true;
return 1;
}
/* Release any resources being used by this BridgeUDP instance */
void BridgeUDP::stop()
{
if (!opened)
return;
uint8_t cmd[] = {'q', handle};
bridge.transfer(cmd, 2);
opened = false;
}
int BridgeUDP::beginPacket(const char *host, uint16_t port)
{
if (!opened)
return 0;
uint8_t cmd[] = {'E', handle, (uint8_t)((port >> 8) & 0xFF), (uint8_t)(port & 0xFF)};
uint8_t res[1];
bridge.transfer(cmd, 4, (const uint8_t *)host, strlen(host), res, 1);
return res[0]; // 1=Success, 0=Error
}
int BridgeUDP::beginBroadcastPacket(uint16_t port)
{
if (!opened)
return 0;
uint8_t cmd[] = {'v', handle, (uint8_t)((port >> 8) & 0xFF), (uint8_t)(port & 0xFF)};
uint8_t res[1];
bridge.transfer(cmd, 4, res, 1);
return res[0]; // 1=Success, 0=Error
}
int BridgeUDP::beginPacket(IPAddress ip, uint16_t port)
{
if (!opened)
return 0;
String address;
address.reserve(18);
address += ip[0];
address += '.';
address += ip[1];
address += '.';
address += ip[2];
address += '.';
address += ip[3];
return beginPacket(address.c_str(), port);
}
int BridgeUDP::endPacket()
{
if (!opened)
return 0;
uint8_t cmd[] = {'H', handle};
uint8_t res[1];
bridge.transfer(cmd, 2, res, 1);
return res[0]; // 1=Success, 0=Error
}
size_t BridgeUDP::write(const uint8_t *buffer, size_t size)
{
if (!opened)
return 0;
uint8_t cmd[] = {'h', handle};
uint8_t res[1];
bridge.transfer(cmd, 2, buffer, size, res, 1);
return res[0]; // 1=Success, 0=Error
}
int BridgeUDP::parsePacket()
{
if (!opened)
return 0;
buffered = 0;
readPos = 0;
uint8_t cmd[] = {'Q', handle};
uint8_t res[3];
bridge.transfer(cmd, 2, res, 3);
if (res[0] == 0) {
// There aren't any packets available
return 0;
}
avail = (res[1] << 8) + res[2];
return 1;
}
void BridgeUDP::doBuffer() {
// If there are already char in buffer exit
if (buffered > 0)
return;
if (avail == 0)
return;
// Try to buffer up to 32 characters
readPos = 0;
uint8_t cmd[] = {'u', handle, sizeof(buffer)};
buffered = bridge.transfer(cmd, 3, buffer, sizeof(buffer));
}
int BridgeUDP::read()
{
if (!opened)
return -1;
doBuffer();
if (buffered == 0) {
return -1; // no chars available
}
buffered--;
avail--;
return buffer[readPos++];
}
int BridgeUDP::read(unsigned char* buff, size_t size)
{
if (!opened)
return -1;
size_t readed = 0;
do {
if (buffered == 0) {
doBuffer();
if (buffered == 0)
return readed;
}
buff[readed++] = buffer[readPos++];
buffered--;
avail--;
} while (readed < size);
return readed;
}
int BridgeUDP::peek()
{
if (!opened)
return -1;
doBuffer();
if (buffered == 0)
return -1; // no chars available
return buffer[readPos];
}
IPAddress BridgeUDP::remoteIP()
{
if (!opened)
return -1;
uint8_t cmd[] = {'T', handle};
uint8_t res[7];
bridge.transfer(cmd, 2, res, 7);
if (res[0] == 0)
return IPAddress(0,0,0,0);
return IPAddress(res[1], res[2], res[3], res[4]);
}
uint16_t BridgeUDP::remotePort()
{
if (!opened)
return -1;
uint8_t cmd[] = {'T', handle};
uint8_t res[7];
bridge.transfer(cmd, 2, res, 7);
if (res[0] == 0)
return 0;
return (res[5] << 8) + res[6];
}

View File

@ -0,0 +1,65 @@
/*
Copyright (c) 2015 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
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
*/
#pragma once
#include <Udp.h>
#include "Bridge.h"
class BridgeUDP : public UDP {
public:
BridgeUDP(BridgeClass &_b = Bridge);
virtual uint8_t begin(uint16_t);
virtual void stop();
virtual int beginPacket(IPAddress ip, uint16_t port);
virtual int beginPacket(const char *host, uint16_t port);
virtual int beginBroadcastPacket(uint16_t port);
virtual int endPacket();
virtual size_t write(uint8_t d) { return write(&d, 1); }
virtual size_t write(const uint8_t *buffer, size_t size);
using Print::write;
virtual int parsePacket();
/* return number of bytes available in the current packet,
will return zero if parsePacket hasn't been called yet */
virtual int available() { return avail; }
virtual int read();
virtual int read(unsigned char* buffer, size_t len);
virtual int read(char* buffer, size_t len) { return read((unsigned char*)buffer, len); };
virtual int peek();
virtual void flush() { avail = 0; }
virtual IPAddress remoteIP();
virtual uint16_t remotePort();
private:
BridgeClass &bridge;
uint8_t handle;
boolean opened;
private:
void doBuffer();
uint16_t avail;
uint8_t buffered;
uint8_t readPos;
static const int BUFFER_SIZE = 64;
uint8_t buffer[BUFFER_SIZE];
};

View File

@ -0,0 +1,150 @@
/*
Copyright (c) 2013 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
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
*/
#include <Console.h>
// Default constructor uses global Bridge instance
ConsoleClass::ConsoleClass() :
bridge(Bridge), inBuffered(0), inReadPos(0), inBuffer(NULL),
autoFlush(true)
{
// Empty
}
// Constructor with a user provided BridgeClass instance
ConsoleClass::ConsoleClass(BridgeClass &_b) :
bridge(_b), inBuffered(0), inReadPos(0), inBuffer(NULL),
autoFlush(true)
{
// Empty
}
ConsoleClass::~ConsoleClass() {
end();
}
size_t ConsoleClass::write(uint8_t c) {
if (autoFlush) {
uint8_t tmp[] = { 'P', c };
bridge.transfer(tmp, 2);
} else {
outBuffer[outBuffered++] = c;
if (outBuffered == outBufferSize)
flush();
}
return 1;
}
size_t ConsoleClass::write(const uint8_t *buff, size_t size) {
if (autoFlush) {
uint8_t tmp[] = { 'P' };
bridge.transfer(tmp, 1, buff, size, NULL, 0);
} else {
size_t sent = size;
while (sent > 0) {
outBuffer[outBuffered++] = *buff++;
sent--;
if (outBuffered == outBufferSize)
flush();
}
}
return size;
}
void ConsoleClass::flush() {
if (autoFlush)
return;
bridge.transfer(outBuffer, outBuffered);
outBuffered = 1;
}
void ConsoleClass::noBuffer() {
if (autoFlush)
return;
delete[] outBuffer;
autoFlush = true;
}
void ConsoleClass::buffer(uint8_t size) {
noBuffer();
if (size == 0)
return;
outBuffer = new uint8_t[size + 1];
outBuffer[0] = 'P'; // WRITE tag
outBufferSize = size + 1;
outBuffered = 1;
autoFlush = false;
}
bool ConsoleClass::connected() {
uint8_t tmp = 'a';
bridge.transfer(&tmp, 1, &tmp, 1);
return tmp == 1;
}
int ConsoleClass::available() {
// Look if there is new data available
doBuffer();
return inBuffered;
}
int ConsoleClass::read() {
doBuffer();
if (inBuffered == 0)
return -1; // no chars available
else {
inBuffered--;
return inBuffer[inReadPos++];
}
}
int ConsoleClass::peek() {
doBuffer();
if (inBuffered == 0)
return -1; // no chars available
else
return inBuffer[inReadPos];
}
void ConsoleClass::doBuffer() {
// If there are already char in buffer exit
if (inBuffered > 0)
return;
// Try to buffer up to 32 characters
inReadPos = 0;
uint8_t tmp[] = { 'p', BUFFER_SIZE };
inBuffered = bridge.transfer(tmp, 2, inBuffer, BUFFER_SIZE);
}
void ConsoleClass::begin() {
bridge.begin();
end();
inBuffer = new uint8_t[BUFFER_SIZE];
}
void ConsoleClass::end() {
noBuffer();
if (inBuffer) {
delete[] inBuffer;
inBuffer = NULL;
}
}
ConsoleClass Console;

View File

@ -0,0 +1,71 @@
/*
Copyright (c) 2013 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
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
*/
#ifndef CONSOLE_H_
#define CONSOLE_H_
#include <Bridge.h>
class ConsoleClass : public Stream {
public:
// Default constructor uses global Bridge instance
ConsoleClass();
// Constructor with a user provided BridgeClass instance
ConsoleClass(BridgeClass &_b);
~ConsoleClass();
void begin();
void end();
void buffer(uint8_t size);
void noBuffer();
bool connected();
// Stream methods
// (read from console socket)
int available();
int read();
int peek();
// (write to console socket)
size_t write(uint8_t);
size_t write(const uint8_t *buffer, size_t size);
void flush();
operator bool () {
return connected();
}
private:
BridgeClass &bridge;
void doBuffer();
uint8_t inBuffered;
uint8_t inReadPos;
static const int BUFFER_SIZE = 32;
uint8_t *inBuffer;
bool autoFlush;
uint8_t outBuffered;
uint8_t outBufferSize;
uint8_t *outBuffer;
};
extern ConsoleClass Console;
#endif

View File

@ -0,0 +1,283 @@
/*
Copyright (c) 2013 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
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
*/
#include <FileIO.h>
namespace BridgeLib {
File::File(BridgeClass &b) : bridge(b), mode(255) {
// Empty
}
File::File(const char *_filename, uint8_t _mode, BridgeClass &b) : bridge(b), mode(_mode) {
filename = _filename;
uint8_t modes[] = {'r', 'w', 'a'};
uint8_t cmd[] = {'F', modes[mode]};
uint8_t res[2];
dirPosition = 1;
bridge.transfer(cmd, 2, (uint8_t*)filename.c_str(), filename.length(), res, 2);
if (res[0] != 0) { // res[0] contains error code
mode = 255; // In case of error keep the file closed
return;
}
handle = res[1];
buffered = 0;
}
File::operator bool() {
return (mode != 255);
}
File::~File() {
close();
}
size_t File::write(uint8_t c) {
return write(&c, 1);
}
size_t File::write(const uint8_t *buf, size_t size) {
if (mode == 255)
return -1;
uint8_t cmd[] = {'g', handle};
uint8_t res[1];
bridge.transfer(cmd, 2, buf, size, res, 1);
if (res[0] != 0) // res[0] contains error code
return -res[0];
return size;
}
int File::read() {
doBuffer();
if (buffered == 0)
return -1; // no chars available
else {
buffered--;
return buffer[readPos++];
}
}
int File::peek() {
doBuffer();
if (buffered == 0)
return -1; // no chars available
else
return buffer[readPos];
}
boolean File::seek(uint32_t position) {
uint8_t cmd[] = {
's',
handle,
static_cast<uint8_t>(position >> 24),
static_cast<uint8_t>(position >> 16),
static_cast<uint8_t>(position >> 8),
static_cast<uint8_t>(position)
};
uint8_t res[1];
bridge.transfer(cmd, 6, res, 1);
if (res[0] == 0) {
// If seek succeed then flush buffers
buffered = 0;
return true;
}
return false;
}
uint32_t File::position() {
uint8_t cmd[] = {'S', handle};
uint8_t res[5];
bridge.transfer(cmd, 2, res, 5);
//err = res[0]; // res[0] contains error code
uint32_t pos;
pos = static_cast<uint32_t>(res[1]) << 24;
pos += static_cast<uint32_t>(res[2]) << 16;
pos += static_cast<uint32_t>(res[3]) << 8;
pos += static_cast<uint32_t>(res[4]);
return pos - buffered;
}
void File::doBuffer() {
// If there are already char in buffer exit
if (buffered > 0)
return;
// Try to buffer up to BUFFER_SIZE characters
readPos = 0;
uint8_t cmd[] = {'G', handle, BUFFER_SIZE - 1};
uint16_t readed = bridge.transfer(cmd, 3, buffer, BUFFER_SIZE);
//err = buff[0]; // First byte is error code
if (readed == BridgeClass::TRANSFER_TIMEOUT || readed == 0) {
// transfer failed to retrieve any data
buffered = 0;
} else {
// transfer retrieved at least one byte of data so skip the error code character
readPos++;
buffered = readed - 1;
}
}
int File::available() {
// Look if there is new data available
doBuffer();
return buffered;
}
void File::flush() {
}
int File::read(void *buff, uint16_t nbyte) {
uint16_t n = 0;
uint8_t *p = reinterpret_cast<uint8_t *>(buff);
while (n < nbyte) {
if (buffered == 0) {
doBuffer();
if (buffered == 0)
break;
}
*p++ = buffer[readPos++];
buffered--;
n++;
}
return n;
}
uint32_t File::size() {
if (bridge.getBridgeVersion() < 101)
return 0;
uint8_t cmd[] = {'t', handle};
uint8_t buff[5];
bridge.transfer(cmd, 2, buff, 5);
//err = res[0]; // First byte is error code
uint32_t res;
res = ((uint32_t)buff[1]) << 24;
res |= ((uint32_t)buff[2]) << 16;
res |= ((uint32_t)buff[3]) << 8;
res |= ((uint32_t)buff[4]);
return res;
}
void File::close() {
if (mode == 255)
return;
uint8_t cmd[] = {'f', handle};
uint8_t ret[1];
bridge.transfer(cmd, 2, ret, 1);
mode = 255;
}
const char *File::name() {
return filename.c_str();
}
boolean File::isDirectory() {
uint8_t res[1];
uint8_t cmd[] = {'i'};
if (mode != 255)
return 0;
bridge.transfer(cmd, 1, (uint8_t *)filename.c_str(), filename.length(), res, 1);
return res[0];
}
File File::openNextFile(uint8_t mode) {
Process awk;
char tmp;
String command;
String filepath;
if (dirPosition == 0xFFFF) return File();
command = "ls ";
command += filename;
command += " | awk 'NR==";
command += dirPosition;
command += "'";
awk.runShellCommand(command);
while (awk.running());
command = "";
while (awk.available()) {
tmp = awk.read();
if (tmp != '\n') command += tmp;
}
if (command.length() == 0)
return File();
dirPosition++;
filepath = filename + "/" + command;
return File(filepath.c_str(), mode);
}
void File::rewindDirectory(void) {
dirPosition = 1;
}
boolean FileSystemClass::begin() {
return true;
}
File FileSystemClass::open(const char *filename, uint8_t mode) {
return File(filename, mode);
}
boolean FileSystemClass::exists(const char *filepath) {
Process ls;
ls.begin("ls");
ls.addParameter(filepath);
int res = ls.run();
return (res == 0);
}
boolean FileSystemClass::mkdir(const char *filepath) {
Process mk;
mk.begin("mkdir");
mk.addParameter("-p");
mk.addParameter(filepath);
int res = mk.run();
return (res == 0);
}
boolean FileSystemClass::remove(const char *filepath) {
Process rm;
rm.begin("rm");
rm.addParameter(filepath);
int res = rm.run();
return (res == 0);
}
boolean FileSystemClass::rmdir(const char *filepath) {
Process rm;
rm.begin("rmdir");
rm.addParameter(filepath);
int res = rm.run();
return (res == 0);
}
FileSystemClass FileSystem;
}

View File

@ -0,0 +1,120 @@
/*
Copyright (c) 2013 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
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
*/
#ifndef __FILEIO_H__
#define __FILEIO_H__
#include <Process.h>
#define FILE_READ 0
#define FILE_WRITE 1
#define FILE_APPEND 2
namespace BridgeLib {
class File : public Stream {
public:
File(BridgeClass &b = Bridge);
File(const char *_filename, uint8_t _mode, BridgeClass &b = Bridge);
~File();
virtual size_t write(uint8_t);
virtual size_t write(const uint8_t *buf, size_t size);
virtual int read();
virtual int peek();
virtual int available();
virtual void flush();
int read(void *buf, uint16_t nbyte);
boolean seek(uint32_t pos);
uint32_t position();
uint32_t size();
void close();
operator bool();
const char * name();
boolean isDirectory();
File openNextFile(uint8_t mode = FILE_READ);
void rewindDirectory(void);
//using Print::write;
private:
void doBuffer();
uint8_t buffered;
uint8_t readPos;
uint16_t dirPosition;
static const int BUFFER_SIZE = 64;
uint8_t buffer[BUFFER_SIZE];
private:
BridgeClass &bridge;
String filename;
uint8_t mode;
uint8_t handle;
};
class FileSystemClass {
public:
FileSystemClass() : bridge(Bridge) { }
FileSystemClass(BridgeClass &_b) : bridge(_b) { }
boolean begin();
// Open the specified file/directory with the supplied mode (e.g. read or
// write, etc). Returns a File object for interacting with the file.
// Note that currently only one file can be open at a time.
File open(const char *filename, uint8_t mode = FILE_READ);
// Methods to determine if the requested file path exists.
boolean exists(const char *filepath);
// Create the requested directory hierarchy--if intermediate directories
// do not exist they will be created.
boolean mkdir(const char *filepath);
// Delete the file.
boolean remove(const char *filepath);
boolean rmdir(const char *filepath);
private:
friend class File;
BridgeClass &bridge;
};
extern FileSystemClass FileSystem;
};
// We enclose File and FileSystem classes in namespace BridgeLib to avoid
// conflicts with legacy SD library.
// This ensure compatibility with older sketches that uses only Bridge lib
// (the user can still use File instead of BridgeFile)
using namespace BridgeLib;
// This allows sketches to use BridgeLib::File together with SD library
// (you must use BridgeFile instead of File when needed to disambiguate)
typedef BridgeLib::File BridgeFile;
typedef BridgeLib::FileSystemClass BridgeFileSystemClass;
#define BridgeFileSystem BridgeLib::FileSystem
#endif

View File

@ -0,0 +1,204 @@
/*
Copyright (c) 2013-2014 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
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
*/
#include "HttpClient.h"
HttpClient::HttpClient() :
insecure(false) {
// Empty
}
unsigned int HttpClient::get(String &url) {
begin("curl");
if (insecure) {
addParameter("-k");
}
addHeader();
addParameter(url);
return run();
}
unsigned int HttpClient::get(const char *url) {
begin("curl");
if (insecure) {
addParameter("-k");
}
addHeader();
addParameter(url);
return run();
}
void HttpClient::getAsynchronously(String &url) {
begin("curl");
if (insecure) {
addParameter("-k");
}
addHeader();
addParameter(url);
runAsynchronously();
}
void HttpClient::getAsynchronously(const char *url) {
begin("curl");
if (insecure) {
addParameter("-k");
}
addHeader();
addParameter(url);
runAsynchronously();
}
unsigned int HttpClient::post(String &url, String &data) {
return post(url.c_str(), data.c_str());
}
unsigned int HttpClient::post(const char *url, const char *data) {
begin("curl");
if (insecure) {
addParameter("-k");
}
addParameter("--request");
addParameter("POST");
addParameter("--data");
addParameter(data);
addHeader();
addParameter(url);
return run();
}
void HttpClient::postAsynchronously(String &url, String &data) {
postAsynchronously(url.c_str(), data.c_str());
}
void HttpClient::postAsynchronously(const char *url, const char *data) {
begin("curl");
if (insecure) {
addParameter("-k");
}
addParameter("--request");
addParameter("POST");
addParameter("--data");
addParameter(data);
addHeader();
addParameter(url);
runAsynchronously();
}
unsigned int HttpClient::patch(String &url, String &data) {
return patch(url.c_str(), data.c_str());
}
unsigned int HttpClient::patch(const char *url, const char *data) {
begin("curl");
if (insecure) {
addParameter("-k");
}
addParameter("--request");
addParameter("PATCH");
addParameter("--data");
addParameter(data);
addHeader();
addParameter(url);
return run();
}
void HttpClient::patchAsynchronously(String &url, String &data) {
patchAsynchronously(url.c_str(), data.c_str());
}
void HttpClient::patchAsynchronously(const char *url, const char *data) {
begin("curl");
if (insecure) {
addParameter("-k");
}
addParameter("--request");
addParameter("PATCH");
addParameter("--data");
addParameter(data);
addHeader();
addParameter(url);
runAsynchronously();
}
unsigned int HttpClient::put(String &url, String &data) {
return put(url.c_str(), data.c_str());
}
unsigned int HttpClient::put(const char *url, const char *data) {
begin("curl");
if (insecure) {
addParameter("-k");
}
addParameter("--request");
addParameter("PUT");
addParameter("--data");
addParameter(data);
addHeader();
addParameter(url);
return run();
}
void HttpClient::putAsynchronously(String &url, String &data) {
putAsynchronously(url.c_str(), data.c_str());
}
void HttpClient::putAsynchronously(const char *url, const char *data) {
begin("curl");
if (insecure) {
addParameter("-k");
}
addParameter("--request");
addParameter("PUT");
addParameter("--data");
addParameter(data);
addHeader();
addParameter(url);
runAsynchronously();
}
boolean HttpClient::ready() {
return !running();
}
unsigned int HttpClient::getResult() {
return exitValue();
}
void HttpClient::noCheckSSL() {
insecure = true;
}
void HttpClient::checkSSL() {
insecure = false;
}
void HttpClient::setHeader(String &header) {
this->header = header;
}
void HttpClient::setHeader(const char * header) {
this->header = String(header);
}
void HttpClient::addHeader() {
if (header.length() > 0) {
addParameter("--header");
addParameter(header);
}
}

View File

@ -0,0 +1,59 @@
/*
Copyright (c) 2013-2014 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
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
*/
#ifndef HTTPCLIENT_H_
#define HTTPCLIENT_H_
#include <Process.h>
class HttpClient : public Process {
public:
HttpClient();
unsigned int get(String &url);
unsigned int get(const char * url);
void getAsynchronously(String &url);
void getAsynchronously(const char * url);
unsigned int post(String &url, String &data);
unsigned int post(const char * url, const char * data);
void postAsynchronously(String &url, String &data);
void postAsynchronously(const char * url, const char * data);
unsigned int patch(String &url, String &data);
unsigned int patch(const char * url, const char * data);
void patchAsynchronously(String &url, String &data);
void patchAsynchronously(const char * url, const char * data);
unsigned int put(String &url, String &data);
unsigned int put(const char * url, const char * data);
void putAsynchronously(String &url, String &data);
void putAsynchronously(const char * url, const char * data);
void setHeader(String &header);
void setHeader(const char * header);
boolean ready();
unsigned int getResult();
void noCheckSSL();
void checkSSL();
private:
boolean insecure;
private:
void addHeader();
String header;
};
#endif /* HTTPCLIENT_H_ */

View File

@ -0,0 +1,56 @@
/*
Copyright (c) 2013 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
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
*/
#include <Mailbox.h>
unsigned int MailboxClass::readMessage(uint8_t *buff, unsigned int size) {
uint8_t tmp[] = { 'm' };
return bridge.transfer(tmp, 1, buff, size);
}
void MailboxClass::readMessage(String &str, unsigned int maxLength) {
uint8_t tmp[] = { 'm' };
// XXX: Is there a better way to create the string?
uint8_t buff[maxLength + 1];
int l = bridge.transfer(tmp, 1, buff, maxLength);
buff[l] = 0;
str = (const char *)buff;
}
void MailboxClass::writeMessage(const uint8_t *buff, unsigned int size) {
uint8_t cmd[] = {'M'};
bridge.transfer(cmd, 1, buff, size, NULL, 0);
}
void MailboxClass::writeMessage(const String& str) {
writeMessage((uint8_t*) str.c_str(), str.length());
}
void MailboxClass::writeJSON(const String& str) {
uint8_t cmd[] = {'J'};
bridge.transfer(cmd, 1, (uint8_t*) str.c_str(), str.length(), NULL, 0);
}
unsigned int MailboxClass::messageAvailable() {
uint8_t tmp[] = {'n'};
uint8_t res[2];
bridge.transfer(tmp, 1, res, 2);
return (res[0] << 8) + res[1];
}
MailboxClass Mailbox(Bridge);

View File

@ -0,0 +1,53 @@
/*
Copyright (c) 2013 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
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
*/
#ifndef _MAILBOX_CLASS_H_INCLUDED_
#define _MAILBOX_CLASS_H_INCLUDED_
#include <Bridge.h>
class MailboxClass {
public:
MailboxClass(BridgeClass &b = Bridge) : bridge(b) { }
void begin() { }
void end() { }
// Receive a message and store it inside a buffer
unsigned int readMessage(uint8_t *buffer, unsigned int size);
// Receive a message and store it inside a String
void readMessage(String &str, unsigned int maxLength = 128);
// Send a message
void writeMessage(const uint8_t *buffer, unsigned int size);
// Send a message
void writeMessage(const String& str);
// Send a JSON message
void writeJSON(const String& str);
// Return the size of the next available message, 0 if there are
// no messages in queue.
unsigned int messageAvailable();
private:
BridgeClass &bridge;
};
extern MailboxClass Mailbox;
#endif // _MAILBOX_CLASS_H_INCLUDED_

View File

@ -0,0 +1,142 @@
/*
Copyright (c) 2013 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
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
*/
#include <Process.h>
Process::~Process() {
close();
}
size_t Process::write(uint8_t c) {
uint8_t cmd[] = {'I', handle, c};
bridge.transfer(cmd, 3);
return 1;
}
void Process::flush() {
}
int Process::available() {
// Look if there is new data available
doBuffer();
return buffered;
}
int Process::read() {
doBuffer();
if (buffered == 0)
return -1; // no chars available
else {
buffered--;
return buffer[readPos++];
}
}
int Process::peek() {
doBuffer();
if (buffered == 0)
return -1; // no chars available
else
return buffer[readPos];
}
void Process::doBuffer() {
// If there are already char in buffer exit
if (buffered > 0)
return;
// Try to buffer up to 32 characters
readPos = 0;
uint8_t cmd[] = {'O', handle, sizeof(buffer)};
buffered = bridge.transfer(cmd, 3, buffer, sizeof(buffer));
}
void Process::begin(const String &command) {
close();
cmdline = new String(command);
}
void Process::addParameter(const String &param) {
*cmdline += "\xFE";
*cmdline += param;
}
void Process::runAsynchronously() {
uint8_t cmd[] = {'R'};
uint8_t res[2];
bridge.transfer(cmd, 1, (uint8_t*)cmdline->c_str(), cmdline->length(), res, 2);
handle = res[1];
delete cmdline;
cmdline = NULL;
if (res[0] == 0) // res[0] contains error code
started = true;
}
boolean Process::running() {
uint8_t cmd[] = {'r', handle};
uint8_t res[1];
bridge.transfer(cmd, 2, res, 1);
return (res[0] == 1);
}
unsigned int Process::exitValue() {
uint8_t cmd[] = {'W', handle};
uint8_t res[2];
bridge.transfer(cmd, 2, res, 2);
return (res[0] << 8) + res[1];
}
unsigned int Process::run() {
runAsynchronously();
while (running())
delay(100);
return exitValue();
}
void Process::close() {
if (started) {
uint8_t cmd[] = {'w', handle};
bridge.transfer(cmd, 2);
}
started = false;
}
unsigned int Process::runShellCommand(const String &command) {
runShellCommandAsynchronously(command);
while (running())
delay(100);
return exitValue();
}
void Process::runShellCommandAsynchronously(const String &command) {
begin("/bin/ash");
addParameter("-c");
addParameter(command);
runAsynchronously();
}
// This method is currently unused
//static unsigned int __commandOutputAvailable(uint8_t handle) {
// uint8_t cmd[] = {'o', handle};
// uint8_t res[1];
// Bridge.transfer(cmd, 2, res, 1);
// return res[0];
//}

View File

@ -0,0 +1,71 @@
/*
Copyright (c) 2013 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
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
*/
#ifndef PROCESS_H_
#define PROCESS_H_
#include <Bridge.h>
class Process : public Stream {
public:
// Constructor with a user provided BridgeClass instance
Process(BridgeClass &_b = Bridge) :
bridge(_b), started(false), buffered(0), readPos(0) { }
~Process();
void begin(const String &command);
void addParameter(const String &param);
unsigned int run();
void runAsynchronously();
boolean running();
unsigned int exitValue();
void close();
unsigned int runShellCommand(const String &command);
void runShellCommandAsynchronously(const String &command);
operator bool () {
return started;
}
// Stream methods
// (read from process stdout)
int available();
int read();
int peek();
// (write to process stdin)
size_t write(uint8_t);
void flush();
// TODO: add optimized function for block write
private:
BridgeClass &bridge;
uint8_t handle;
String *cmdline;
boolean started;
private:
void doBuffer();
uint8_t buffered;
uint8_t readPos;
static const int BUFFER_SIZE = 64;
uint8_t buffer[BUFFER_SIZE];
};
#endif

View File

@ -0,0 +1,27 @@
/*
Copyright (c) 2014 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
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
*/
#ifndef _YUN_CLIENT_H_
#define _YUN_CLIENT_H_
#include <BridgeClient.h>
#warning "The use of YunClient is deprecated. Use BridgeClient instead!"
typedef BridgeClient YunClient;
#endif // _YUN_CLIENT_H_

View File

@ -0,0 +1,27 @@
/*
Copyright (c) 2014 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
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
*/
#ifndef _YUN_SERVER_H_
#define _YUN_SERVER_H_
#include <BridgeServer.h>
#warning "The use of YunServer is deprecated. Use BridgeServer instead!"
typedef BridgeServer YunServer;
#endif // _YUN_SERVER_H_

View File

@ -0,0 +1,24 @@
= Bridge Library for Arduino =
The Bridge library simplifies communication between the ATmega32U4 and the AR9331.
For more information about this library please visit us at
http://www.arduino.cc/en/Reference/YunBridgeLibrary
== License ==
Copyright (c) 2014 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
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

View File

@ -0,0 +1,183 @@
/*
Arduino Yún Bridge example
This example for the YunShield/Yún shows how
to use the Bridge library to access the digital and
analog pins on the board through REST calls.
It demonstrates how you can create your own API when
using REST style calls through the browser.
Possible commands created in this shetch:
"/arduino/digital/13" -> digitalRead(13)
"/arduino/digital/13/1" -> digitalWrite(13, HIGH)
"/arduino/analog/2/123" -> analogWrite(2, 123)
"/arduino/analog/2" -> analogRead(2)
"/arduino/mode/13/input" -> pinMode(13, INPUT)
"/arduino/mode/13/output" -> pinMode(13, OUTPUT)
This example code is part of the public domain
http://www.arduino.cc/en/Tutorial/Bridge
*/
#include <Bridge.h>
#include <BridgeServer.h>
#include <BridgeClient.h>
// Listen to the default port 5555, the Yún webserver
// will forward there all the HTTP requests you send
BridgeServer server;
void setup() {
// Bridge startup
pinMode(13, OUTPUT);
digitalWrite(13, LOW);
Bridge.begin();
digitalWrite(13, HIGH);
// Listen for incoming connection only from localhost
// (no one from the external network could connect)
server.listenOnLocalhost();
server.begin();
}
void loop() {
// Get clients coming from server
BridgeClient client = server.accept();
// There is a new client?
if (client) {
// Process request
process(client);
// Close connection and free resources.
client.stop();
}
delay(50); // Poll every 50ms
}
void process(BridgeClient client) {
// read the command
String command = client.readStringUntil('/');
// is "digital" command?
if (command == "digital") {
digitalCommand(client);
}
// is "analog" command?
if (command == "analog") {
analogCommand(client);
}
// is "mode" command?
if (command == "mode") {
modeCommand(client);
}
}
void digitalCommand(BridgeClient client) {
int pin, value;
// Read pin number
pin = client.parseInt();
// If the next character is a '/' it means we have an URL
// with a value like: "/digital/13/1"
if (client.read() == '/') {
value = client.parseInt();
digitalWrite(pin, value);
} else {
value = digitalRead(pin);
}
// Send feedback to client
client.print(F("Pin D"));
client.print(pin);
client.print(F(" set to "));
client.println(value);
// Update datastore key with the current pin value
String key = "D";
key += pin;
Bridge.put(key, String(value));
}
void analogCommand(BridgeClient client) {
int pin, value;
// Read pin number
pin = client.parseInt();
// If the next character is a '/' it means we have an URL
// with a value like: "/analog/5/120"
if (client.read() == '/') {
// Read value and execute command
value = client.parseInt();
analogWrite(pin, value);
// Send feedback to client
client.print(F("Pin D"));
client.print(pin);
client.print(F(" set to analog "));
client.println(value);
// Update datastore key with the current pin value
String key = "D";
key += pin;
Bridge.put(key, String(value));
} else {
// Read analog pin
value = analogRead(pin);
// Send feedback to client
client.print(F("Pin A"));
client.print(pin);
client.print(F(" reads analog "));
client.println(value);
// Update datastore key with the current pin value
String key = "A";
key += pin;
Bridge.put(key, String(value));
}
}
void modeCommand(BridgeClient client) {
int pin;
// Read pin number
pin = client.parseInt();
// If the next character is not a '/' we have a malformed URL
if (client.read() != '/') {
client.println(F("error"));
return;
}
String mode = client.readStringUntil('\r');
if (mode == "input") {
pinMode(pin, INPUT);
// Send feedback to client
client.print(F("Pin D"));
client.print(pin);
client.print(F(" configured as INPUT!"));
return;
}
if (mode == "output") {
pinMode(pin, OUTPUT);
// Send feedback to client
client.print(F("Pin D"));
client.print(pin);
client.print(F(" configured as OUTPUT!"));
return;
}
client.print(F("error: invalid mode "));
client.print(mode);
}

View File

@ -0,0 +1,95 @@
/*
Console ASCII table for YunShield/Yún
Prints out byte values in all possible formats:
* as raw binary values
* as ASCII-encoded decimal, hex, octal, and binary values
For more on ASCII, see http://www.asciitable.com and http://en.wikipedia.org/wiki/ASCII
The circuit:
- YunShield/Yún
created 2006
by Nicholas Zambetti
http://www.zambetti.com
modified 9 Apr 2012
by Tom Igoe
modified 22 May 2013
by Cristian Maglie
This example code is in the public domain.
http://www.arduino.cc/en/Tutorial/ConsoleAsciiTable
*/
#include <Console.h>
void setup() {
//Initialize Console and wait for port to open:
Bridge.begin();
Console.begin();
// Uncomment the following line to enable buffering:
// - better transmission speed and efficiency
// - needs to call Console.flush() to ensure that all
// transmitted data is sent
//Console.buffer(64);
while (!Console) {
; // wait for Console port to connect.
}
// prints title with ending line break
Console.println("ASCII Table ~ Character Map");
}
// first visible ASCIIcharacter '!' is number 33:
int thisByte = 33;
// you can also write ASCII characters in single quotes.
// for example. '!' is the same as 33, so you could also use this:
//int thisByte = '!';
void loop() {
// prints value unaltered, i.e. the raw binary version of the
// byte. The Console monitor interprets all bytes as
// ASCII, so 33, the first number, will show up as '!'
Console.write(thisByte);
Console.print(", dec: ");
// prints value as string as an ASCII-encoded decimal (base 10).
// Decimal is the default format for Console.print() and Console.println(),
// so no modifier is needed:
Console.print(thisByte);
// But you can declare the modifier for decimal if you want to.
//this also works if you uncomment it:
// Console.print(thisByte, DEC);
Console.print(", hex: ");
// prints value as string in hexadecimal (base 16):
Console.print(thisByte, HEX);
Console.print(", oct: ");
// prints value as string in octal (base 8);
Console.print(thisByte, OCT);
Console.print(", bin: ");
// prints value as string in binary (base 2)
// also prints ending line break:
Console.println(thisByte, BIN);
// if printed last visible character '~' or 126, stop:
if (thisByte == 126) { // you could also use if (thisByte == '~') {
// ensure the latest bit of data is sent
Console.flush();
// This loop loops forever and does nothing
while (true) {
continue;
}
}
// go on to the next character
thisByte++;
}

View File

@ -0,0 +1,63 @@
/*
Console Pixel
An example of using YunShield/Yún board to receive data from the
Console on the Yún. In this case, the board turns on an LED when
it receives the character 'H', and turns off the LED when it
receives the character 'L'.
To see the Console, pick your Yún's name and IP address in the Port menu
then open the Port Monitor. You can also see it by opening a terminal window
and typing
ssh root@ yourYunsName.local 'telnet localhost 6571'
then pressing enter. When prompted for the password, enter it.
The circuit:
* LED connected from digital pin 13 to ground
created 2006
by David A. Mellis
modified 25 Jun 2013
by Tom Igoe
This example code is in the public domain.
http://www.arduino.cc/en/Tutorial/ConsolePixel
*/
#include <Console.h>
const int ledPin = 13; // the pin that the LED is attached to
char incomingByte; // a variable to read incoming Console data into
void setup() {
Bridge.begin(); // Initialize Bridge
Console.begin(); // Initialize Console
// Wait for the Console port to connect
while (!Console);
Console.println("type H or L to turn pin 13 on or off");
// initialize the LED pin as an output:
pinMode(ledPin, OUTPUT);
}
void loop() {
// see if there's incoming Console data:
if (Console.available() > 0) {
// read the oldest byte in the Console buffer:
incomingByte = Console.read();
Console.println(incomingByte);
// if it's a capital H (ASCII 72), turn on the LED:
if (incomingByte == 'H') {
digitalWrite(ledPin, HIGH);
}
// if it's an L (ASCII 76) turn off the LED:
if (incomingByte == 'L') {
digitalWrite(ledPin, LOW);
}
}
}

View File

@ -0,0 +1,58 @@
/*
Console Read example for YunShield/Yún
Read data coming from bridge using the Console.read() function
and store it in a string.
To see the Console, pick your Yún's name and IP address in the Port menu
then open the Port Monitor. You can also see it by opening a terminal window
and typing:
ssh root@ yourYunsName.local 'telnet localhost 6571'
then pressing enter. When prompted for the password, enter it.
created 13 Jun 2013
by Angelo Scialabba
modified 16 June 2013
by Tom Igoe
This example code is in the public domain.
http://www.arduino.cc/en/Tutorial/ConsoleRead
*/
#include <Console.h>
String name;
void setup() {
// Initialize Console and wait for port to open:
Bridge.begin();
Console.begin();
// Wait for Console port to connect
while (!Console);
Console.println("Hi, what's your name?");
}
void loop() {
if (Console.available() > 0) {
char c = Console.read(); // read the next char received
// look for the newline character, this is the last character in the string
if (c == '\n') {
//print text with the name received
Console.print("Hi ");
Console.print(name);
Console.println("! Nice to meet you!");
Console.println();
// Ask again for name and clear the old name
Console.println("Hi, what's your name?");
name = ""; // clear the name string
} else { // if the buffer is empty Cosole.read() returns -1
name += c; // append the read char from Console to the name string
}
} else {
delay(100);
}
}

View File

@ -0,0 +1,102 @@
/*
SD card datalogger
This example shows how to log data from three analog sensors
to an SD card mounted on the YunShield/Yún using the Bridge library.
The circuit:
* analog sensors on analog pins 0, 1 and 2
* SD card attached to SD card slot of the YunShield/Yún
Prepare your SD card creating an empty folder in the SD root
named "arduino". This will ensure that the Yún will create a link
to the SD to the "/mnt/sd" path.
You can remove the SD card while the Linux and the
sketch are running but be careful not to remove it while
the system is writing to it.
created 24 Nov 2010
modified 9 Apr 2012
by Tom Igoe
adapted to the Yún Bridge library 20 Jun 2013
by Federico Vanzati
modified 21 Jun 2013
by Tom Igoe
This example code is in the public domain.
http://www.arduino.cc/en/Tutorial/YunDatalogger
*/
#include <FileIO.h>
void setup() {
// Initialize the Bridge and the Serial
Bridge.begin();
Serial.begin(9600);
FileSystem.begin();
while (!SerialUSB); // wait for Serial port to connect.
SerialUSB.println("Filesystem datalogger\n");
}
void loop() {
// make a string that start with a timestamp for assembling the data to log:
String dataString;
dataString += getTimeStamp();
dataString += " = ";
// read three sensors and append to the string:
for (int analogPin = 0; analogPin < 3; analogPin++) {
int sensor = analogRead(analogPin);
dataString += String(sensor);
if (analogPin < 2) {
dataString += ","; // separate the values with a comma
}
}
// open the file. note that only one file can be open at a time,
// so you have to close this one before opening another.
// The FileSystem card is mounted at the following "/mnt/FileSystema1"
File dataFile = FileSystem.open("/mnt/sd/datalog.txt", FILE_APPEND);
// if the file is available, write to it:
if (dataFile) {
dataFile.println(dataString);
dataFile.close();
// print to the serial port too:
SerialUSB.println(dataString);
}
// if the file isn't open, pop up an error:
else {
SerialUSB.println("error opening datalog.txt");
}
delay(15000);
}
// This function return a string with the time stamp
String getTimeStamp() {
String result;
Process time;
// date is a command line utility to get the date and the time
// in different formats depending on the additional parameter
time.begin("date");
time.addParameter("+%D-%T"); // parameters: D for the complete date mm/dd/yy
// T for the time hh:mm:ss
time.run(); // run the command
// read the output of the command
while (time.available() > 0) {
char c = time.read();
if (c != '\n') {
result += c;
}
}
return result;
}

View File

@ -0,0 +1,83 @@
/*
Write to file using FileIO classes.
This sketch demonstrate how to write file into the YunShield/Yún filesystem.
A shell script file is created in /tmp, and it is executed afterwards.
created 7 June 2010
by Cristian Maglie
This example code is in the public domain.
http://www.arduino.cc/en/Tutorial/FileWriteScript
*/
#include <FileIO.h>
void setup() {
// Setup Bridge (needed every time we communicate with the Arduino Yún)
Bridge.begin();
// Initialize the Serial
SerialUSB.begin(9600);
while (!SerialUSB); // wait for Serial port to connect.
SerialUSB.println("File Write Script example\n\n");
// Setup File IO
FileSystem.begin();
// Upload script used to gain network statistics
uploadScript();
}
void loop() {
// Run stats script every 5 secs.
runScript();
delay(5000);
}
// this function creates a file into the linux processor that contains a shell script
// to check the network traffic of the WiFi interface
void uploadScript() {
// Write our shell script in /tmp
// Using /tmp stores the script in RAM this way we can preserve
// the limited amount of FLASH erase/write cycles
File script = FileSystem.open("/tmp/wlan-stats.sh", FILE_WRITE);
// Shell script header
script.print("#!/bin/sh\n");
// shell commands:
// ifconfig: is a command line utility for controlling the network interfaces.
// wlan0 is the interface we want to query
// grep: search inside the output of the ifconfig command the "RX bytes" keyword
// and extract the line that contains it
script.print("ifconfig wlan0 | grep 'RX bytes'\n");
script.close(); // close the file
// Make the script executable
Process chmod;
chmod.begin("chmod"); // chmod: change mode
chmod.addParameter("+x"); // x stays for executable
chmod.addParameter("/tmp/wlan-stats.sh"); // path to the file to make it executable
chmod.run();
}
// this function run the script and read the output data
void runScript() {
// Run the script and show results on the Serial
Process myscript;
myscript.begin("/tmp/wlan-stats.sh");
myscript.run();
String output = "";
// read the output of the script
while (myscript.available()) {
output += (char)myscript.read();
}
// remove the blank spaces at the beginning and the ending of the string
output.trim();
SerialUSB.println(output);
SerialUSB.flush();
}

View File

@ -0,0 +1,51 @@
/*
Yún HTTP Client
This example for the YunShield/Yún shows how create a basic
HTTP client that connects to the internet and downloads
content. In this case, you'll connect to the Arduino
website and download a version of the logo as ASCII text.
created by Tom igoe
May 2013
This example code is in the public domain.
http://www.arduino.cc/en/Tutorial/HttpClient
*/
#include <Bridge.h>
#include <HttpClient.h>
void setup() {
// Bridge takes about two seconds to start up
// it can be helpful to use the on-board LED
// as an indicator for when it has initialized
pinMode(13, OUTPUT);
digitalWrite(13, LOW);
Bridge.begin();
digitalWrite(13, HIGH);
SerialUSB.begin(9600);
while (!SerialUSB); // wait for a serial connection
}
void loop() {
// Initialize the client library
HttpClient client;
// Make a HTTP request:
client.get("http://www.arduino.cc/asciilogo.txt");
// if there are incoming bytes available
// from the server, read them and print them:
while (client.available()) {
char c = client.read();
SerialUSB.print(c);
}
SerialUSB.flush();
delay(5000);
}

View File

@ -0,0 +1,53 @@
/*
Yún HTTP Client Console version for Arduino Uno and Mega using Yún Shield
This example for the YunShield/Yún shows how create a basic
HTTP client that connects to the internet and downloads
content. In this case, you'll connect to the Arduino
website and download a version of the logo as ASCII text.
created by Tom igoe
May 2013
modified by Marco Brianza to use Console
This example code is in the public domain.
http://www.arduino.cc/en/Tutorial/HttpClient
*/
#include <Bridge.h>
#include <HttpClient.h>
#include <Console.h>
void setup() {
// Bridge takes about two seconds to start up
// it can be helpful to use the on-board LED
// as an indicator for when it has initialized
pinMode(13, OUTPUT);
digitalWrite(13, LOW);
Bridge.begin();
digitalWrite(13, HIGH);
Console.begin();
while (!Console); // wait for a serial connection
}
void loop() {
// Initialize the client library
HttpClient client;
// Make a HTTP request:
client.get("http://www.arduino.cc/asciilogo.txt");
// if there are incoming bytes available
// from the server, read them and print them:
while (client.available()) {
char c = client.read();
Console.print(c);
}
Console.flush();
delay(5000);
}

View File

@ -0,0 +1,58 @@
/*
Read Messages from the Mailbox
This example for the YunShield/Yún shows how to
read the messages queue, called Mailbox, using the
Bridge library.
The messages can be sent to the queue through REST calls.
Appen the message in the URL after the keyword "/mailbox".
Example
"/mailbox/hello"
created 3 Feb 2014
by Federico Vanzati & Federico Fissore
This example code is in the public domain.
http://www.arduino.cc/en/Tutorial/MailboxReadMessage
*/
#include <Mailbox.h>
void setup() {
pinMode(13, OUTPUT);
digitalWrite(13, LOW);
// Initialize Bridge and Mailbox
Bridge.begin();
Mailbox.begin();
digitalWrite(13, HIGH);
// Initialize Serial
SerialUSB.begin(9600);
// Wait until a Serial Monitor is connected.
while (!SerialUSB);
SerialUSB.println("Mailbox Read Message\n");
SerialUSB.println("The Mailbox is checked every 10 seconds. The incoming messages will be shown below.\n");
}
void loop() {
String message;
// if there is a message in the Mailbox
if (Mailbox.messageAvailable()) {
// read all the messages present in the queue
while (Mailbox.messageAvailable()) {
Mailbox.readMessage(message);
SerialUSB.println(message);
}
SerialUSB.println("Waiting 10 seconds before checking the Mailbox again");
}
// wait 10 seconds
delay(10000);
}

View File

@ -0,0 +1,71 @@
/*
Running process using Process class.
This sketch demonstrate how to run linux processes
using a YunShield/Yún
created 5 Jun 2013
by Cristian Maglie
This example code is in the public domain.
http://www.arduino.cc/en/Tutorial/Process
*/
#include <Process.h>
void setup() {
// Initialize Bridge
Bridge.begin();
// Initialize Serial
SerialUSB.begin(9600);
// Wait until a Serial Monitor is connected.
while (!SerialUSB);
// run various example processes
runCurl();
runCpuInfo();
}
void loop() {
// Do nothing here.
}
void runCurl() {
// Launch "curl" command and get Arduino ascii art logo from the network
// curl is command line program for transferring data using different internet protocols
Process p; // Create a process and call it "p"
p.begin("curl"); // Process that launch the "curl" command
p.addParameter("http://www.arduino.cc/asciilogo.txt"); // Add the URL parameter to "curl"
p.run(); // Run the process and wait for its termination
// Print arduino logo over the Serial
// A process output can be read with the stream methods
while (p.available() > 0) {
char c = p.read();
SerialUSB.print(c);
}
// Ensure the last bit of data is sent.
SerialUSB.flush();
}
void runCpuInfo() {
// Launch "cat /proc/cpuinfo" command (shows info on Atheros CPU)
// cat is a command line utility that shows the content of a file
Process p; // Create a process and call it "p"
p.begin("cat"); // Process that launch the "cat" command
p.addParameter("/proc/cpuinfo"); // Add the cpuifo file path as parameter to cut
p.run(); // Run the process and wait for its termination
// Print command output on the SerialUSB.
// A process output can be read with the stream methods
while (p.available() > 0) {
char c = p.read();
SerialUSB.print(c);
}
// Ensure the last bit of data is sent.
SerialUSB.flush();
}

View File

@ -0,0 +1,33 @@
/*
Blink
Turns on an LED on for one second, then off for one second, repeatedly.
Most Arduinos have an on-board LED you can control. On the Uno and
Leonardo, it is attached to digital pin 13. If you're unsure what
pin the on-board LED is connected to on your Arduino model, check
the documentation at http://www.arduino.cc
This example code is in the public domain.
modified 8 May 2014
by Scott Fitzgerald
modified by Marco Brianza to show the remote sketch update feature on Arduino Due using Yún Shield
*/
#include <Bridge.h>
// the setup function runs once when you press reset or power the board
void setup() {
checkForRemoteSketchUpdate();
// initialize digital pin 13 as an output.
pinMode(13, OUTPUT);
}
// the loop function runs over and over again forever
void loop() {
digitalWrite(13, HIGH); // turn the LED on (HIGH is the voltage level)
delay(100); // wait for a second
digitalWrite(13, LOW); // turn the LED off by making the voltage LOW
delay(100); // wait for a second
}

View File

@ -0,0 +1,52 @@
/*
Running shell commands using Process class.
This sketch demonstrate how to run linux shell commands
using a YunShield/Yún. It runs the wifiCheck script on the Linux side
of the Yún, then uses grep to get just the signal strength line.
Then it uses parseInt() to read the wifi signal strength as an integer,
and finally uses that number to fade an LED using analogWrite().
The circuit:
* YunShield/Yún with LED connected to pin 9
created 12 Jun 2013
by Cristian Maglie
modified 25 June 2013
by Tom Igoe
This example code is in the public domain.
http://www.arduino.cc/en/Tutorial/ShellCommands
*/
#include <Process.h>
void setup() {
Bridge.begin(); // Initialize the Bridge
SerialUSB.begin(9600); // Initialize the Serial
// Wait until a Serial Monitor is connected.
while (!SerialUSB);
}
void loop() {
Process p;
// This command line runs the WifiStatus script, (/usr/bin/pretty-wifi-info.lua), then
// sends the result to the grep command to look for a line containing the word
// "Signal:" the result is passed to this sketch:
p.runShellCommand("/usr/bin/pretty-wifi-info.lua | grep Signal");
// do nothing until the process finishes, so you get the whole output:
while (p.running());
// Read command output. runShellCommand() should have passed "Signal: xx&":
while (p.available()) {
int result = p.parseInt(); // look for an integer
int signal = map(result, 0, 100, 0, 255); // map result from 0-100 range to 0-255
analogWrite(9, signal); // set the brightness of LED on pin 9
SerialUSB.println(result); // print the number as well
}
delay(5000); // wait 5 seconds before you do it again
}

View File

@ -0,0 +1,122 @@
/*
Temperature web interface
This example shows how to serve data from an analog input
via the YunShield/Yún built-in webserver using the Bridge library.
The circuit:
* TMP36 temperature sensor on analog pin A1
* SD card attached to SD card slot of the YunShield/Yún
This sketch must be uploaded via wifi. REST API must be set to "open".
Prepare your SD card with an empty folder in the SD root
named "arduino" and a subfolder of that named "www".
This will ensure that the Yún will create a link
to the SD to the "/mnt/sd" path.
In this sketch folder is a basic webpage and a copy of zepto.js, a
minimized version of jQuery. When you upload your sketch, these files
will be placed in the /arduino/www/TemperatureWebPanel folder on your SD card.
You can then go to http://arduino.local/sd/TemperatureWebPanel
to see the output of this sketch.
You can remove the SD card while the Linux and the
sketch are running but be careful not to remove it while
the system is writing to it.
created 6 July 2013
by Tom Igoe
This example code is in the public domain.
http://www.arduino.cc/en/Tutorial/TemperatureWebPanel
*/
#include <Bridge.h>
#include <BridgeServer.h>
#include <BridgeClient.h>
// Listen on default port 5555, the webserver on the Yún
// will forward there all the HTTP requests for us.
BridgeServer server;
String startString;
long hits = 0;
void setup() {
SerialUSB.begin(9600);
// Bridge startup
pinMode(13, OUTPUT);
digitalWrite(13, LOW);
Bridge.begin();
digitalWrite(13, HIGH);
// using A0 and A2 as vcc and gnd for the TMP36 sensor:
pinMode(A0, OUTPUT);
pinMode(A2, OUTPUT);
digitalWrite(A0, HIGH);
digitalWrite(A2, LOW);
// Listen for incoming connection only from localhost
// (no one from the external network could connect)
server.listenOnLocalhost();
server.begin();
// get the time that this sketch started:
Process startTime;
startTime.runShellCommand("date");
while (startTime.available()) {
char c = startTime.read();
startString += c;
}
}
void loop() {
// Get clients coming from server
BridgeClient client = server.accept();
// There is a new client?
if (client) {
// read the command
String command = client.readString();
command.trim(); //kill whitespace
SerialUSB.println(command);
// is "temperature" command?
if (command == "temperature") {
// get the time from the server:
Process time;
time.runShellCommand("date");
String timeString = "";
while (time.available()) {
char c = time.read();
timeString += c;
}
SerialUSB.println(timeString);
int sensorValue = analogRead(A1);
// convert the reading to millivolts:
float voltage = sensorValue * (5000.0f / 1024.0f);
// convert the millivolts to temperature celsius:
float temperature = (voltage - 500.0f) / 10.0f;
// print the temperature:
client.print("Current time on the Y&uacute;n: ");
client.println(timeString);
client.print("<br>Current temperature: ");
client.print(temperature);
client.print(" &deg;C");
client.print("<br>This sketch has been running since ");
client.print(startString);
client.print("<br>Hits so far: ");
client.print(hits);
}
// Close connection and free resources.
client.stop();
hits++;
}
delay(50); // Poll every 50ms
}

View File

@ -0,0 +1,16 @@
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="zepto.min.js"></script>
<script type="text/javascript">
function refresh() {
$('#content').load('/arduino/temperature');
}
</script>
</head>
<body onload="setInterval(refresh, 2000);">
<span id="content">0</span>
</body>
</html>

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,88 @@
/*
Time Check
Gets the time from Linux via Bridge then parses out hours,
minutes and seconds using a YunShield/Yún.
created 27 May 2013
modified 21 June 2013
By Tom Igoe
This example code is in the public domain.
http://www.arduino.cc/en/Tutorial/TimeCheck
*/
#include <Process.h>
Process date; // process used to get the date
int hours, minutes, seconds; // for the results
int lastSecond = -1; // need an impossible value for comparison
void setup() {
Bridge.begin(); // initialize Bridge
SerialUSB.begin(9600); // initialize serial
while (!Serial); // wait for Serial Monitor to open
SerialUSB.println("Time Check"); // Title of sketch
// run an initial date process. Should return:
// hh:mm:ss :
if (!date.running()) {
date.begin("date");
date.addParameter("+%T");
date.run();
}
}
void loop() {
if (lastSecond != seconds) { // if a second has passed
// print the time:
if (hours <= 9) {
SerialUSB.print("0"); // adjust for 0-9
}
SerialUSB.print(hours);
SerialUSB.print(":");
if (minutes <= 9) {
SerialUSB.print("0"); // adjust for 0-9
}
SerialUSB.print(minutes);
SerialUSB.print(":");
if (seconds <= 9) {
SerialUSB.print("0"); // adjust for 0-9
}
SerialUSB.println(seconds);
// restart the date process:
if (!date.running()) {
date.begin("date");
date.addParameter("+%T");
date.run();
}
}
//if there's a result from the date process, parse it:
while (date.available() > 0) {
// get the result of the date process (should be hh:mm:ss):
String timeString = date.readString();
// find the colons:
int firstColon = timeString.indexOf(":");
int secondColon = timeString.lastIndexOf(":");
// get the substrings for hour, minute second:
String hourString = timeString.substring(0, firstColon);
String minString = timeString.substring(firstColon + 1, secondColon);
String secString = timeString.substring(secondColon + 1);
// convert to ints,saving the previous second:
hours = hourString.toInt();
minutes = minString.toInt();
lastSecond = seconds; // save to do a time comparison
seconds = secString.toInt();
}
}

View File

@ -0,0 +1,51 @@
/*
WiFi Status
This sketch runs a script called "pretty-wifi-info.lua"
installed on your Yún in folder /usr/bin.
It prints information about the status of your wifi connection.
It uses Serial to print, so you need to connect your YunShield/Yún to your
computer using a USB cable and select the appropriate port from
the Port menu
created 18 June 2013
By Federico Fissore
This example code is in the public domain.
http://www.arduino.cc/en/Tutorial/YunWiFiStatus
*/
#include <Process.h>
void setup() {
SerialUSB.begin(9600); // initialize serial communication
while (!SerialUSB); // do nothing until the serial monitor is opened
SerialUSB.println("Starting bridge...\n");
pinMode(13, OUTPUT);
digitalWrite(13, LOW);
Bridge.begin(); // make contact with the linux processor
digitalWrite(13, HIGH); // Led on pin 13 turns on when the bridge is ready
delay(2000); // wait 2 seconds
}
void loop() {
Process wifiCheck; // initialize a new process
wifiCheck.runShellCommand("/usr/bin/pretty-wifi-info.lua"); // command you want to run
// while there's any characters coming back from the
// process, print them to the serial monitor:
while (wifiCheck.available() > 0) {
char c = wifiCheck.read();
SerialUSB.print(c);
}
SerialUSB.println();
delay(5000);
}

View File

@ -0,0 +1,328 @@
/*
Arduino Yún First configuration sketch
Configures the YunShield/Yún WiFi and infos via the Bridge
Works correctly if Line Ending is set as "NewLine"
If your board has two USB ports, use the Native one
The circuit:
Arduino YunShield
(or any Yun model with firmware > 1.6.1)
created March 2016
by Arduino LLC
This example code is in the public domain.
http://www.arduino.cc/en/Tutorial/YunFirstConfig
*/
#include <Process.h>
#define MAX_WIFI_LIST 10
String networks[MAX_WIFI_LIST];
String yunName;
String yunPassword;
void setup() {
SERIAL_PORT_USBVIRTUAL.begin(9600); // initialize serial communication
while (!SERIAL_PORT_USBVIRTUAL); // do nothing until the serial monitor is opened
SERIAL_PORT_USBVIRTUAL.println(F("Hi! Nice to see you!"));
SERIAL_PORT_USBVIRTUAL.println(F("I'm your YunShield assistant sketch"));
SERIAL_PORT_USBVIRTUAL.println(F("I'll help you configuring your Yun in a matter of minutes"));
SERIAL_PORT_USBVIRTUAL.println(F("Let's start by communicating with the Linux processor"));
SERIAL_PORT_USBVIRTUAL.println(F("When LED (L13) will light up we'll be ready to go!"));
SERIAL_PORT_USBVIRTUAL.println(F("Waiting..."));
SERIAL_PORT_USBVIRTUAL.println(F("(in the meanwhile, if you are using the IDE's serial monitor, make sure that it's configured to send a \"Newline\")\n"));
pinMode(13, OUTPUT);
digitalWrite(13, LOW);
Bridge.begin(); // make contact with the linux processor
digitalWrite(13, HIGH); // Led on pin 13 turns on when the bridge is ready
// Recover if the board is in AP mode - unused
Process wifiList;
bool master = false;
wifiList.runShellCommand(F("iwinfo | grep \"Mode: Master\""));
while (wifiList.available() > 0) {
wifiList.read();
master = true;
}
// Get the list of reachable networks
wifiList.runShellCommand(F("iwinfo wlan0 scan | grep ESSID | cut -d\"\\\"\" -f2"));
uint8_t num_networks = 0;
uint8_t i = 0;
char c;
bool dropNet = false;
networks[0].reserve(32);
while (wifiList.available() > 0) {
c = wifiList.read();
if (c != '\n') {
networks[i] += c;
} else {
// check if we already found networks[i] and eventually drop it
for (uint8_t s = 0; s < i; s++) {
if (networks[i].equals(networks[s])) {
dropNet = true;
}
}
if (i <= MAX_WIFI_LIST && dropNet == false) {
networks[i++].reserve(32);
} else {
dropNet = false;
networks[i]="";
}
}
}
num_networks = i;
String encryption;
String password;
int chose = 0;
// If networks number is 0, start manual configuration
if (num_networks == 0) {
SERIAL_PORT_USBVIRTUAL.println(F("Oops, it seems that you have no WiFi network available"));
SERIAL_PORT_USBVIRTUAL.println(F("Let's configure it manually"));
SERIAL_PORT_USBVIRTUAL.println(F("SSID of the network you want to connect to: "));
networks[0] = getUserInput(networks[0], false);
SERIAL_PORT_USBVIRTUAL.println(F("Password for the network you want to connect to: "));
password = getUserInput(password, true);
SERIAL_PORT_USBVIRTUAL.print(F("Encryption (eg WPA, WPA2, WEP): "));
encryption = getUserInput(encryption, false);
} else {
// else print them prepending a number
SERIAL_PORT_USBVIRTUAL.print(F("It looks like you have "));
SERIAL_PORT_USBVIRTUAL.print(num_networks);
SERIAL_PORT_USBVIRTUAL.println(F(" networks around you "));
SERIAL_PORT_USBVIRTUAL.println(F("Which one do you want to connect to?\n"));
for (i = 0; i < num_networks && i < MAX_WIFI_LIST; i++) {
SERIAL_PORT_USBVIRTUAL.print(i);
SERIAL_PORT_USBVIRTUAL.println(") " + networks[i]);
}
String selection;
selection = getUserInput(selection, false);
chose = atoi(selection.c_str());
}
// Extract the selected network security
bool openNet = false;
wifiList.runShellCommand("iwinfo wlan0 scan | grep \"" + networks[chose] + "\" -A5 | grep Encryption | cut -f2 -d\":\"");
while (wifiList.available() > 0) {
c = wifiList.read();
encryption += c;
}
if (encryption.indexOf("none") >= 0) {
openNet = true;
encryption = "none";
}
if (encryption.indexOf("WPA2") >= 0) {
encryption = "psk2";
}
if (encryption.indexOf("WPA") >= 0) {
encryption = "psk";
}
if (encryption.indexOf("WEP") >= 0) {
encryption = "wep";
}
if (openNet == false && password.length() == 0) {
SERIAL_PORT_USBVIRTUAL.print(F("It looks like you need a password to connect to "));
SERIAL_PORT_USBVIRTUAL.println(networks[chose]);
SERIAL_PORT_USBVIRTUAL.print(F("Write it here: "));
password = getUserInput(password, true);
}
// Change hostname/root password
SERIAL_PORT_USBVIRTUAL.println(F("We are almost done! Give a name and a password to your Yun"));
SERIAL_PORT_USBVIRTUAL.print(F("Name: "));
yunName = getUserInput(yunName, false);
SERIAL_PORT_USBVIRTUAL.print(F("Password: "));
yunPassword = getUserInput(yunPassword, true);
// Select a country code
String countryCode;
SERIAL_PORT_USBVIRTUAL.println(F("One last question: where do you live?"));
SERIAL_PORT_USBVIRTUAL.print(F("Insert a two letters county code (eg IT, US, DE): "));
countryCode = getUserInput(countryCode, false);
yunName.trim();
yunPassword.trim();
networks[chose].trim();
password.trim();
countryCode.trim();
// Configure the Yun with user provided strings
wifiConfig(yunName, yunPassword, networks[chose], password, "YUN" + yunName + "AP", countryCode, encryption);
SERIAL_PORT_USBVIRTUAL.print(F("Waiting for the Yun to connect to the network"));
}
bool Connected = false;
bool serialTerminalMode = false;
int runs = 0;
void loop() {
if (!serialTerminalMode) {
String resultStr = "";
if (!Connected) {
SERIAL_PORT_USBVIRTUAL.print(".");
runs++;
}
// If it takes more than 20 seconds to connect, stop trying
if (runs > 20) {
SERIAL_PORT_USBVIRTUAL.println("");
SERIAL_PORT_USBVIRTUAL.println(F("We couldn't connect to the network."));
SERIAL_PORT_USBVIRTUAL.println(F("Restart the board if you want to execute the wizard again"));
resultStr = getUserInput(resultStr, false);
}
// Check if we have an IP address
Process wifiCheck;
wifiCheck.runShellCommand(F("/usr/bin/pretty-wifi-info.lua | grep \"IP address\" | cut -f2 -d\":\" | cut -f1 -d\"/\"" )); // command you want to run
while (wifiCheck.available() > 0) {
char c = wifiCheck.read();
resultStr += c;
}
delay(1000);
if (resultStr != "") {
// We got an IP, freeze the loop, display the value and "spawn" a serial terminal
Connected = true;
resultStr.trim();
SERIAL_PORT_USBVIRTUAL.println("");
SERIAL_PORT_USBVIRTUAL.print(F("\nGreat! You can now reach your Yun from a browser typing http://"));
SERIAL_PORT_USBVIRTUAL.println(resultStr);
SERIAL_PORT_USBVIRTUAL.print(F("Press 'Enter' key twice to start a serial terminal"));
resultStr = getUserInput(resultStr, false);
serialTerminalMode = true;
//startSerialTerminal();
SERIAL_PORT_HARDWARE.write((uint8_t *)"\xff\0\0\x05XXXXX\x7f\xf9", 11); // send "bridge shutdown" command
delay(100);
SERIAL_PORT_HARDWARE.println("\nreset\n\n");
SERIAL_PORT_HARDWARE.flush();
SERIAL_PORT_HARDWARE.println("\nreset\n\n");
SERIAL_PORT_HARDWARE.write((uint8_t *)"\n", 1);
}
} else {
loopSerialTerminal();
}
}
String getUserInput(String out, bool obfuscated) {
/*
while (SerialUSB.available() <= 0) {}
while (SerialUSB.available() > 0) {
char c = SerialUSB.read();
out += c;
}
return out;
*/
while (SERIAL_PORT_USBVIRTUAL.available() <= 0) {}
while (1) {
char c = SERIAL_PORT_USBVIRTUAL.read();
if (c == '\n' || c == '\r')
break;
else {
if (c != -1) {
out += c;
if (obfuscated)
SERIAL_PORT_USBVIRTUAL.print("*");
else
SERIAL_PORT_USBVIRTUAL.print(c);
}
}
}
SERIAL_PORT_USBVIRTUAL.println("");
return out;
}
void wifiConfig(String yunName, String yunPsw, String wifissid, String wifipsw, String wifiAPname, String countryCode, String encryption) {
Process p;
p.runShellCommand("blink-start 100"); //start the blue blink
p.runShellCommand("hostname " + yunName); //change the current hostname
p.runShellCommand("uci set system.@system[0].hostname='" + yunName + "'"); //change teh hostname in uci
p.runShellCommand("uci set arduino.@arduino[0].access_point_wifi_name='" + wifiAPname + "'");
//this block resets the wifi psw
p.runShellCommand("uci set wireless.@wifi-iface[0].encryption='" + encryption + "'");
p.runShellCommand("uci set wireless.@wifi-iface[0].mode='sta'\n");
p.runShellCommand("uci set wireless.@wifi-iface[0].ssid='" + wifissid + "'");
p.runShellCommand("uci set wireless.@wifi-iface[0].key='" + wifipsw + "'");
p.runShellCommand("uci set wireless.radio0.channel='auto'");
p.runShellCommand("uci set wireless.radio0.country='" + countryCode + "'");
p.runShellCommand("uci delete network.lan.ipaddr");
p.runShellCommand("uci delete network.lan.netmask");
p.runShellCommand("uci set network.lan.proto='dhcp'");
p.runShellCommand("echo -e \"" + yunPsw + "\n" + yunPsw + "\" | passwd root"); //change the passwors
p.runShellCommand("uci commit"); //save the mods done via UCI
p.runShellCommand("blink-stop"); //start the blue blink
p.runShellCommand("wifi ");
}
long linuxBaud = 250000;
void startSerialTerminal() {
SERIAL_PORT_USBVIRTUAL.begin(115200); // open serial connection via USB-Serial
SERIAL_PORT_HARDWARE.begin(linuxBaud); // open serial connection to Linux
}
boolean commandMode = false;
void loopSerialTerminal() {
// copy from USB-CDC to UART
int c = SERIAL_PORT_USBVIRTUAL.read(); // read from USB-CDC
if (c != -1) { // got anything?
if (commandMode == false) { // if we aren't in command mode...
if (c == '~') { // Tilde '~' key pressed?
commandMode = true; // enter in command mode
} else {
SERIAL_PORT_HARDWARE.write(c); // otherwise write char to UART
}
} else { // if we are in command mode...
if (c == '0') { // '0' key pressed?
SERIAL_PORT_HARDWARE.begin(57600); // set speed to 57600
SERIAL_PORT_USBVIRTUAL.println("Speed set to 57600");
} else if (c == '1') { // '1' key pressed?
SERIAL_PORT_HARDWARE.begin(115200); // set speed to 115200
SERIAL_PORT_USBVIRTUAL.println("Speed set to 115200");
} else if (c == '2') { // '2' key pressed?
SERIAL_PORT_HARDWARE.begin(250000); // set speed to 250000
SERIAL_PORT_USBVIRTUAL.println("Speed set to 250000");
} else if (c == '3') { // '3' key pressed?
SERIAL_PORT_HARDWARE.begin(500000); // set speed to 500000
SERIAL_PORT_USBVIRTUAL.println("Speed set to 500000");
} else if (c == '~') { // '~` key pressed?
SERIAL_PORT_HARDWARE.write((uint8_t *)"\xff\0\0\x05XXXXX\x7f\xf9", 11); // send "bridge shutdown" command
SERIAL_PORT_USBVIRTUAL.println("Sending bridge's shutdown command");
} else { // any other key pressed?
SERIAL_PORT_HARDWARE.write('~'); // write '~' to UART
SERIAL_PORT_HARDWARE.write(c); // write char to UART
}
commandMode = false; // in all cases exit from command mode
}
}
// copy from UART to USB-CDC
c = SERIAL_PORT_HARDWARE.read(); // read from UART
if (c != -1) { // got anything?
SERIAL_PORT_USBVIRTUAL.write(c); // write to USB-CDC
}
}

View File

@ -0,0 +1,82 @@
/*
Arduino Yún USB-to-Serial
Allows you to use the YunShield/Yún processor as a
serial terminal for the Linux side on the Yún.
Upload this to a YunShield/Yún via serial (not WiFi) then open
the serial monitor at 115200 to see the boot process of Linux.
You can also use the serial monitor as a basic command line
interface for Linux using this sketch.
From the serial monitor the following commands can be issued:
'~' followed by '0' -> Set the UART speed to 57600 baud
'~' followed by '1' -> Set the UART speed to 115200 baud
'~' followed by '2' -> Set the UART speed to 250000 baud
'~' followed by '3' -> Set the UART speed to 500000 baud
'~' followed by '~' -> Sends the bridge's shutdown command to
obtain the console.
The circuit:
YunShield/Yún
created March 2013
by Massimo Banzi
modified by Cristian Maglie
This example code is in the public domain.
http://www.arduino.cc/en/Tutorial/YunSerialTerminal
*/
long linuxBaud = 250000;
void setup() {
SERIAL_PORT_USBVIRTUAL.begin(115200); // open serial connection via USB-Serial
SERIAL_PORT_HARDWARE.begin(linuxBaud); // open serial connection to Linux
}
boolean commandMode = false;
void loop() {
// copy from USB-CDC to UART
int c = SERIAL_PORT_USBVIRTUAL.read(); // read from USB-CDC
if (c != -1) { // got anything?
if (commandMode == false) { // if we aren't in command mode...
if (c == '~') { // Tilde '~' key pressed?
commandMode = true; // enter in command mode
} else {
SERIAL_PORT_HARDWARE.write(c); // otherwise write char to UART
}
} else { // if we are in command mode...
if (c == '0') { // '0' key pressed?
SERIAL_PORT_HARDWARE.begin(57600); // set speed to 57600
SERIAL_PORT_USBVIRTUAL.println("Speed set to 57600");
} else if (c == '1') { // '1' key pressed?
SERIAL_PORT_HARDWARE.begin(115200); // set speed to 115200
SERIAL_PORT_USBVIRTUAL.println("Speed set to 115200");
} else if (c == '2') { // '2' key pressed?
SERIAL_PORT_HARDWARE.begin(250000); // set speed to 250000
SERIAL_PORT_USBVIRTUAL.println("Speed set to 250000");
} else if (c == '3') { // '3' key pressed?
SERIAL_PORT_HARDWARE.begin(500000); // set speed to 500000
SERIAL_PORT_USBVIRTUAL.println("Speed set to 500000");
} else if (c == '~') { // '~` key pressed?
SERIAL_PORT_HARDWARE.write((uint8_t *)"\xff\0\0\x05XXXXX\x7f\xf9", 11); // send "bridge shutdown" command
SERIAL_PORT_USBVIRTUAL.println("Sending bridge's shutdown command");
} else { // any other key pressed?
SERIAL_PORT_HARDWARE.write('~'); // write '~' to UART
SERIAL_PORT_HARDWARE.write(c); // write char to UART
}
commandMode = false; // in all cases exit from command mode
}
}
// copy from UART to USB-CDC
c = SERIAL_PORT_HARDWARE.read(); // read from UART
if (c != -1) { // got anything?
SERIAL_PORT_USBVIRTUAL.write(c); // write to USB-CDC
}
}

View File

@ -0,0 +1,92 @@
#######################################
# Syntax Coloring Map For Bridge
#######################################
#######################################
# Class (KEYWORD1)
#######################################
Bridge KEYWORD1 YunBridgeLibrary
FileIO KEYWORD4 YunFileIOConstructor
FileSystem KEYWORD1 YunFileIOConstructor
Console KEYWORD1 YunConsoleConstructor
Process KEYWORD1 YunProcessConstructor
Mailbox KEYWORD1 YunMailboxConstructor
HttpClient KEYWORD1 YunHttpClientConstructor
YunServer KEYWORD1 YunServerConstructor
YunClient KEYWORD1 YunClientConstructor
BridgeServer KEYWORD1 YunServerConstructor
BridgeClient KEYWORD1 YunClientConstructor
BridgeSSLClient KEYWORD1 YunClientConstructor
#######################################
# Methods and Functions (KEYWORD2)
#######################################
# methods names in commond
begin KEYWORD2
end KEYWORD2
available KEYWORD2
read KEYWORD2
peek KEYWORD2
write KEYWORD2
flush KEYWORD2
bool KEYWORD2
# Bridge Class
transfer KEYWORD2
put KEYWORD2
get KEYWORD2
# Console Class
buffer KEYWORD2
noBuffer KEYWORD2
connected KEYWORD2
# FileIO Class
File KEYWORD2
BridgeFile KEYWORD2
seek KEYWORD2
position KEYWORD2
size KEYWORD2
close KEYWORD2
name KEYWORD2
isDirectory KEYWORD2
openNextFile KEYWORD2
rewindDirectory KEYWORD2
# Process Class
addParameter KEYWORD2
runAsynchronously KEYWORD2
run KEYWORD2
running KEYWORD2
exitValue KEYWORD2
runShellCommand KEYWORD2
runShellCommandAsynchronously KEYWORD2
# Mailbox Class
readMessage KEYWORD2
writeMessage KEYWORD2
writeJSON KEYWORD2
messageAvailable KEYWORD2
# HttpClient Class
getAsynchronously KEYWORD2
ready KEYWORD2
getResult KEYWORD2
# BridgeServer Class
accept KEYWORD2
stop KEYWORD2
connect KEYWORD2
connectSSL KEYWORD2
connected KEYWORD2
#######################################
# Constants (LITERAL1)
#######################################
FILE_READ LITERAL1
FILE_WRITE LITERAL1
FILE_APPEND LITERAL1

View File

@ -0,0 +1,10 @@
name=Bridge
version=1.7.0
author=Arduino
maintainer=Arduino <info@arduino.cc>
sentence=Enables the communication between the Linux processor and the microcontroller. For Arduino/Genuino Yún, Yún Shield and TRE only.
paragraph=The Bridge library feature: access to the shared storage, run and manage linux processes, open a remote console, access to the linux file system, including the SD card, enstablish http clients or servers.
category=Communication
url=http://www.arduino.cc/en/Reference/YunBridgeLibrary
architectures=*
dot_a_linkage=true

View File

@ -0,0 +1,312 @@
/*
Copyright (c) 2013 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
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
*/
#include "Bridge.h"
BridgeClass::BridgeClass(Stream &_stream) :
index(0), stream(_stream), started(false), max_retries(0) {
// Empty
}
void BridgeClass::begin() {
if (started)
return;
started = true;
// Wait for U-boot to finish startup
do {
dropAll();
delay(1000);
} while (stream.available() > 0);
while (true) {
// Bridge interrupt:
// - Ask the bridge to close itself
uint8_t quit_cmd[] = {'X', 'X', 'X', 'X', 'X'};
max_retries = 1;
transfer(quit_cmd, 5);
// Bridge startup:
// - If the bridge is not running starts it safely
stream.print(CTRL_C);
delay(250);
stream.print(F("\n"));
delay(250);
stream.print(F("\n"));
delay(500);
// Wait for OpenWRT message
// "Press enter to activate console"
stream.print(F("run-bridge\n"));
delay(500);
dropAll();
// Reset the brigde to check if it is running
uint8_t cmd[] = {'X', 'X', '1', '0', '0'};
uint8_t res[4];
max_retries = 50;
uint16_t l = transfer(cmd, 5, res, 4);
if (l == TRANSFER_TIMEOUT) {
// Bridge didn't start...
// Maybe the board is starting-up?
// Wait and retry
delay(1000);
continue;
}
if (res[0] != 0)
while (true);
// Detect bridge version
if (l == 4) {
bridgeVersion = (res[1]-'0')*100 + (res[2]-'0')*10 + (res[3]-'0');
} else {
// Bridge v1.0.0 didn't send any version info
bridgeVersion = 100;
}
max_retries = 50;
return;
}
}
void BridgeClass::end() {
while (true) {
// Bridge interrupt:
// - Ask the bridge to close itself
uint8_t quit_cmd[] = {'X', 'X', 'X', 'X', 'X'};
max_retries = 1;
transfer(quit_cmd, 5);
delay(100);
stream.print(CTRL_C);
delay(250);
stream.print(F("cd \n"));
//expect a shell
bool done = false;
delay(100);
while (stream.available()) {
char c = stream.read();
if (c == '#') {
done = true;
break;
}
}
if (done) {
stream.print(F("reset\n"));
break;
}
}
delay(100);
dropAll();
}
void BridgeClass::put(const char *key, const char *value) {
// TODO: do it in a more efficient way
String cmd = "D";
uint8_t res[1];
cmd += key;
cmd += "\xFE";
cmd += value;
transfer((uint8_t*)cmd.c_str(), cmd.length(), res, 1);
}
unsigned int BridgeClass::get(const char *key, uint8_t *value, unsigned int maxlen) {
uint8_t cmd[] = {'d'};
unsigned int l = transfer(cmd, 1, (uint8_t *)key, strlen(key), value, maxlen);
if (l < maxlen)
value[l] = 0; // Zero-terminate string
return l;
}
#if defined(ARDUINO_ARCH_AVR)
// AVR use an optimized implementation of CRC
#include <util/crc16.h>
#else
// Generic implementation for non-AVR architectures
uint16_t _crc_ccitt_update(uint16_t crc, uint8_t data)
{
data ^= crc & 0xff;
data ^= data << 4;
return ((((uint16_t)data << 8) | ((crc >> 8) & 0xff)) ^
(uint8_t)(data >> 4) ^
((uint16_t)data << 3));
}
#endif
void BridgeClass::crcUpdate(uint8_t c) {
CRC = _crc_ccitt_update(CRC, c);
}
void BridgeClass::crcReset() {
CRC = 0xFFFF;
}
void BridgeClass::crcWrite() {
stream.write((char)(CRC >> 8));
stream.write((char)(CRC & 0xFF));
}
bool BridgeClass::crcCheck(uint16_t _CRC) {
return CRC == _CRC;
}
uint16_t BridgeClass::transfer(const uint8_t *buff1, uint16_t len1,
const uint8_t *buff2, uint16_t len2,
const uint8_t *buff3, uint16_t len3,
uint8_t *rxbuff, uint16_t rxlen)
{
uint16_t len = len1 + len2 + len3;
uint8_t retries = 0;
for ( ; retries < max_retries; retries++, delay(100), dropAll() /* Delay for retransmission */) {
// Send packet
crcReset();
stream.write((char)0xFF); // Start of packet (0xFF)
crcUpdate(0xFF);
stream.write((char)index); // Message index
crcUpdate(index);
stream.write((char)((len >> 8) & 0xFF)); // Message length (hi)
crcUpdate((len >> 8) & 0xFF);
stream.write((char)(len & 0xFF)); // Message length (lo)
crcUpdate(len & 0xFF);
for (uint16_t i = 0; i < len1; i++) { // Payload
stream.write((char)buff1[i]);
crcUpdate(buff1[i]);
}
for (uint16_t i = 0; i < len2; i++) { // Payload
stream.write((char)buff2[i]);
crcUpdate(buff2[i]);
}
for (uint16_t i = 0; i < len3; i++) { // Payload
stream.write((char)buff3[i]);
crcUpdate(buff3[i]);
}
crcWrite(); // CRC
// Wait for ACK in 200ms
if (timedRead(200) != 0xFF)
continue;
crcReset();
crcUpdate(0xFF);
// Check packet index
if (timedRead(5) != index)
continue;
crcUpdate(index);
// Recv len
int lh = timedRead(10);
if (lh < 0)
continue;
crcUpdate(lh);
int ll = timedRead(10);
if (ll < 0)
continue;
crcUpdate(ll);
uint16_t l = lh;
l <<= 8;
l += ll;
// Recv data
for (uint16_t i = 0; i < l; i++) {
// Cut received data if rxbuffer is too small
if (i >= rxlen)
break;
int c = timedRead(5);
if (c < 0)
continue;
rxbuff[i] = c;
crcUpdate(c);
}
// Check CRC
int crc_hi = timedRead(5);
if (crc_hi < 0)
continue;
int crc_lo = timedRead(5);
if (crc_lo < 0)
continue;
if (!crcCheck((crc_hi << 8) + crc_lo))
continue;
// Increase index
index++;
// Return bytes received
if (l > rxlen)
return rxlen;
return l;
}
// Max retries exceeded
return TRANSFER_TIMEOUT;
}
int BridgeClass::timedRead(unsigned int timeout) {
int c;
unsigned long _startMillis = millis();
do {
c = stream.read();
if (c >= 0) return c;
} while (millis() - _startMillis < timeout);
return -1; // -1 indicates timeout
}
void BridgeClass::dropAll() {
while (stream.available() > 0) {
stream.read();
}
}
#if defined(ARDUINO_ARCH_SAM)
#include <Reset.h>
#endif
#if defined(ARDUINO_ARCH_SAM)
void checkForRemoteSketchUpdate(uint8_t pin) {
// The host force pin LOW to signal that a new sketch is coming
pinMode(pin, INPUT_PULLUP);
delay(50);
if (digitalRead(pin) == LOW) {
initiateReset(1);
while (true)
; // Wait for reset to SAM-BA
}
// Restore in standard state
pinMode(pin, INPUT);
}
#else
void checkForRemoteSketchUpdate(uint8_t /* pin */) {
// Empty, bootloader is enough.
}
#endif
// Bridge instance
#if defined(SERIAL_PORT_LINUXBRIDGE)
SerialBridgeClass Bridge(SERIAL_PORT_LINUXBRIDGE);
#elif defined(SERIAL_PORT_HARDWARE)
SerialBridgeClass Bridge(SERIAL_PORT_HARDWARE);
#elif defined(SERIAL_PORT_HARDWARE_OPEN)
SerialBridgeClass Bridge(SERIAL_PORT_HARDWARE_OPEN);
#elif defined(__AVR_ATmega32U4__) // Legacy fallback
// Leonardo variants (where HardwareSerial is Serial1)
SerialBridgeClass Bridge(Serial1);
#else
SerialBridgeClass Bridge(Serial);
#endif

View File

@ -0,0 +1,131 @@
/*
Copyright (c) 2013 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
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
*/
#ifndef BRIDGE_H_
#define BRIDGE_H_
#ifndef BRIDGE_BAUDRATE
#define BRIDGE_BAUDRATE 250000
#endif
#include <Arduino.h>
#include <Stream.h>
class BridgeClass {
public:
BridgeClass(Stream &_stream);
void begin();
void end();
// Methods to handle key/value datastore
void put(const char *key, const char *value);
void put(const String &key, const String &value)
{
put(key.c_str(), value.c_str());
}
unsigned int get(const char *key, uint8_t *buff, unsigned int size);
unsigned int get(const char *key, char *value, unsigned int maxlen)
{
return get(key, reinterpret_cast<uint8_t *>(value), maxlen);
}
// Trasnfer a frame (with error correction and response)
uint16_t transfer(const uint8_t *buff1, uint16_t len1,
const uint8_t *buff2, uint16_t len2,
const uint8_t *buff3, uint16_t len3,
uint8_t *rxbuff, uint16_t rxlen);
// multiple inline versions of the same function to allow efficient frame concatenation
uint16_t transfer(const uint8_t *buff1, uint16_t len1)
{
return transfer(buff1, len1, NULL, 0);
}
uint16_t transfer(const uint8_t *buff1, uint16_t len1,
uint8_t *rxbuff, uint16_t rxlen)
{
return transfer(buff1, len1, NULL, 0, rxbuff, rxlen);
}
uint16_t transfer(const uint8_t *buff1, uint16_t len1,
const uint8_t *buff2, uint16_t len2,
uint8_t *rxbuff, uint16_t rxlen)
{
return transfer(buff1, len1, buff2, len2, NULL, 0, rxbuff, rxlen);
}
uint16_t getBridgeVersion()
{
return bridgeVersion;
}
static const uint16_t TRANSFER_TIMEOUT = 0xFFFF;
private:
uint8_t index;
int timedRead(unsigned int timeout);
void dropAll();
uint16_t bridgeVersion;
private:
void crcUpdate(uint8_t c);
void crcReset();
void crcWrite();
bool crcCheck(uint16_t _CRC);
uint16_t CRC;
private:
static const char CTRL_C = 3;
Stream &stream;
bool started;
uint8_t max_retries;
};
// This subclass uses a serial port Stream
class SerialBridgeClass : public BridgeClass {
public:
SerialBridgeClass(HardwareSerial &_serial)
: BridgeClass(_serial), serial(_serial) {
// Empty
}
void begin(unsigned long baudrate = BRIDGE_BAUDRATE) {
serial.begin(baudrate);
BridgeClass::begin();
}
void end(unsigned long baudrate = BRIDGE_BAUDRATE) {
serial.begin(baudrate);
BridgeClass::end();
}
private:
HardwareSerial &serial;
};
extern SerialBridgeClass Bridge;
// Some microcrontrollers don't start the bootloader after a reset.
// This function is intended to let the microcontroller erase its
// flash after checking a specific signal coming from the external
// device without the need to press the erase button on the board.
// The purpose is to enable a software update that does not require
// a manual interaction with the board.
extern void checkForRemoteSketchUpdate(uint8_t pin = 7);
#endif /* BRIDGE_H_ */
#include <Console.h>
#include <Process.h>

View File

@ -0,0 +1,207 @@
/*
Copyright (c) 2013 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
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
*/
#include <BridgeClient.h>
BridgeClient::BridgeClient(uint8_t _h, BridgeClass &_b) :
bridge(_b), handle(_h), opened(true), buffered(0) {
}
BridgeClient::BridgeClient(BridgeClass &_b) :
bridge(_b), handle(0), opened(false), buffered(0) {
}
BridgeClient::~BridgeClient() {
}
BridgeClient& BridgeClient::operator=(const BridgeClient &_x) {
opened = _x.opened;
handle = _x.handle;
return *this;
}
void BridgeClient::stop() {
if (opened) {
uint8_t cmd[] = {'j', handle};
bridge.transfer(cmd, 2);
}
opened = false;
buffered = 0;
readPos = 0;
}
void BridgeClient::doBuffer() {
// If there are already char in buffer exit
if (buffered > 0)
return;
// Try to buffer up to 32 characters
readPos = 0;
uint8_t cmd[] = {'K', handle, sizeof(buffer)};
buffered = bridge.transfer(cmd, 3, buffer, sizeof(buffer));
}
int BridgeClient::available() {
// Look if there is new data available
doBuffer();
return buffered;
}
int BridgeClient::read() {
doBuffer();
if (buffered == 0)
return -1; // no chars available
else {
buffered--;
return buffer[readPos++];
}
}
int BridgeClient::read(uint8_t *buff, size_t size) {
size_t readed = 0;
do {
if (buffered == 0) {
doBuffer();
if (buffered == 0)
return readed;
}
buff[readed++] = buffer[readPos++];
buffered--;
} while (readed < size);
return readed;
}
int BridgeClient::peek() {
doBuffer();
if (buffered == 0)
return -1; // no chars available
else
return buffer[readPos];
}
size_t BridgeClient::write(uint8_t c) {
if (!opened)
return 0;
uint8_t cmd[] = {'l', handle, c};
bridge.transfer(cmd, 3);
return 1;
}
size_t BridgeClient::write(const uint8_t *buf, size_t size) {
if (!opened)
return 0;
uint8_t cmd[] = {'l', handle};
bridge.transfer(cmd, 2, buf, size, NULL, 0);
return size;
}
void BridgeClient::flush() {
}
uint8_t BridgeClient::connected() {
if (!opened)
return false;
// Client is "connected" if it has unread bytes
if (available())
return true;
uint8_t cmd[] = {'L', handle};
uint8_t res[1];
bridge.transfer(cmd, 2, res, 1);
return (res[0] == 1);
}
int BridgeClient::connect(IPAddress ip, uint16_t port) {
String address;
address.reserve(18);
address += ip[0];
address += '.';
address += ip[1];
address += '.';
address += ip[2];
address += '.';
address += ip[3];
return connect(address.c_str(), port);
}
int BridgeClient::connect(const char *host, uint16_t port) {
uint8_t tmp[] = {
'C',
static_cast<uint8_t>(port >> 8),
static_cast<uint8_t>(port)
};
uint8_t res[1];
int l = bridge.transfer(tmp, 3, (const uint8_t *)host, strlen(host), res, 1);
if (l == 0)
return 0;
handle = res[0];
// wait for connection
uint8_t tmp2[] = { 'c', handle };
uint8_t res2[1];
while (true) {
bridge.transfer(tmp2, 2, res2, 1);
if (res2[0] == 0)
break;
delay(1);
}
opened = true;
// check for successful connection
if (connected())
return 1;
stop();
handle = 0;
return 0;
}
int BridgeClient::connectSSL(const char *host, uint16_t port) {
if (bridge.getBridgeVersion() < 161)
return -1;
uint8_t tmp[] = {
'Z',
static_cast<uint8_t>(port >> 8),
static_cast<uint8_t>(port)
};
uint8_t res[1];
int l = bridge.transfer(tmp, 3, (const uint8_t *)host, strlen(host), res, 1);
if (l == 0)
return 0;
handle = res[0];
// wait for connection
uint8_t tmp2[] = { 'c', handle };
uint8_t res2[1];
while (true) {
bridge.transfer(tmp2, 2, res2, 1);
if (res2[0] == 0)
break;
delay(1);
}
opened = true;
// check for successful connection
if (connected())
return 1;
stop();
handle = 0;
return 0;
}

View File

@ -0,0 +1,71 @@
/*
Copyright (c) 2013 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
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
*/
#ifndef _BRIDGE_CLIENT_H_
#define _BRIDGE_CLIENT_H_
#include <Bridge.h>
#include <Client.h>
class BridgeClient : public Client {
public:
// Constructor with a user provided BridgeClass instance
BridgeClient(uint8_t _h, BridgeClass &_b = Bridge);
BridgeClient(BridgeClass &_b = Bridge);
~BridgeClient();
// Stream methods
// (read message)
virtual int available();
virtual int read();
virtual int read(uint8_t *buf, size_t size);
virtual int peek();
// (write response)
virtual size_t write(uint8_t);
virtual size_t write(const uint8_t *buf, size_t size);
virtual void flush();
// TODO: add optimized function for block write
virtual operator bool () {
return opened;
}
virtual BridgeClient& operator=(const BridgeClient &_x);
virtual void stop();
virtual uint8_t connected();
virtual int connect(IPAddress ip, uint16_t port);
virtual int connect(const char *host, uint16_t port);
int connectSSL(const char* host, uint16_t port);
private:
BridgeClass &bridge;
uint8_t handle;
boolean opened;
private:
void doBuffer();
uint8_t buffered;
uint8_t readPos;
static const int BUFFER_SIZE = 64;
uint8_t buffer[BUFFER_SIZE];
};
#endif // _BRIDGE_CLIENT_H_

View File

@ -0,0 +1,36 @@
/*
Copyright (c) 2016 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
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
*/
#include <BridgeSSLClient.h>
BridgeSSLClient::BridgeSSLClient(uint8_t _h, BridgeClass &_b) :
BridgeClient(_h, _b)
{
}
BridgeSSLClient::BridgeSSLClient(BridgeClass &_b):
BridgeClient(_b)
{
}
BridgeSSLClient::~BridgeSSLClient() {
}
int BridgeSSLClient::connect(const char *host, uint16_t port) {
return BridgeClient::connectSSL(host, port);
}

View File

@ -0,0 +1,36 @@
/*
Copyright (c) 2016 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
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
*/
#ifndef _BRIDGE_SSL_CLIENT_H_
#define _BRIDGE_SSL_CLIENT_H_
#include <Bridge.h>
#include <Client.h>
#include <BridgeClient.h>
class BridgeSSLClient : public BridgeClient {
public:
// Constructor with a user provided BridgeClass instance
BridgeSSLClient(uint8_t _h, BridgeClass &_b = Bridge);
BridgeSSLClient(BridgeClass &_b = Bridge);
~BridgeSSLClient();
virtual int connect(const char* host, uint16_t port);
};
#endif // _BRIDGE_SSL_CLIENT_H_

View File

@ -0,0 +1,54 @@
/*
Copyright (c) 2013 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
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
*/
#include <BridgeServer.h>
#include <BridgeClient.h>
BridgeServer::BridgeServer(uint16_t _p, BridgeClass &_b) :
bridge(_b), port(_p), listening(false), useLocalhost(false) {
}
void BridgeServer::begin() {
uint8_t tmp[] = {
'N',
static_cast<uint8_t>(port >> 8),
static_cast<uint8_t>(port)
};
uint8_t res[1];
String address = F("127.0.0.1");
if (!useLocalhost)
address = F("0.0.0.0");
bridge.transfer(tmp, 3, (const uint8_t *)address.c_str(), address.length(), res, 1);
listening = (res[0] == 1);
}
BridgeClient BridgeServer::accept() {
uint8_t cmd[] = {'k'};
uint8_t res[1];
unsigned int l = bridge.transfer(cmd, 1, res, 1);
if (l == 0)
return BridgeClient();
return BridgeClient(res[0]);
}
size_t BridgeServer::write(uint8_t c) {
uint8_t cmd[] = { 'b', c };
bridge.transfer(cmd, 2);
return 1;
}

View File

@ -0,0 +1,51 @@
/*
Copyright (c) 2013 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
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
*/
#ifndef _BRIDGE_SERVER_H_
#define _BRIDGE_SERVER_H_
#include <Bridge.h>
#include <Server.h>
class BridgeClient;
class BridgeServer : public Server {
public:
// Constructor with a user provided BridgeClass instance
BridgeServer(uint16_t port = 5555, BridgeClass &_b = Bridge);
void begin();
BridgeClient accept();
virtual size_t write(uint8_t c);
void listenOnLocalhost() {
useLocalhost = true;
}
void noListenOnLocalhost() {
useLocalhost = false;
}
private:
BridgeClass &bridge;
uint16_t port;
bool listening;
bool useLocalhost;
};
#endif // _BRIDGE_SERVER_H_

View File

@ -0,0 +1,198 @@
/*
Copyright (c) 2015 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
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
*/
#include "BridgeUdp.h"
BridgeUDP::BridgeUDP(BridgeClass &_b) :
bridge(_b), opened(false), avail(0), buffered(0), readPos(0) {
}
/* Start BridgeUDP socket, listening at local port PORT */
uint8_t BridgeUDP::begin(uint16_t port) {
if (opened)
return 0;
uint8_t cmd[] = {'e', (uint8_t)((port >> 8) & 0xFF), (uint8_t)(port & 0xFF)};
uint8_t res[2];
bridge.transfer(cmd, 3, res, 2);
if (res[1] == 1) // Error...
return 0;
handle = res[0];
opened = true;
return 1;
}
/* Release any resources being used by this BridgeUDP instance */
void BridgeUDP::stop()
{
if (!opened)
return;
uint8_t cmd[] = {'q', handle};
bridge.transfer(cmd, 2);
opened = false;
}
int BridgeUDP::beginPacket(const char *host, uint16_t port)
{
if (!opened)
return 0;
uint8_t cmd[] = {'E', handle, (uint8_t)((port >> 8) & 0xFF), (uint8_t)(port & 0xFF)};
uint8_t res[1];
bridge.transfer(cmd, 4, (const uint8_t *)host, strlen(host), res, 1);
return res[0]; // 1=Success, 0=Error
}
int BridgeUDP::beginBroadcastPacket(uint16_t port)
{
if (!opened)
return 0;
uint8_t cmd[] = {'v', handle, (uint8_t)((port >> 8) & 0xFF), (uint8_t)(port & 0xFF)};
uint8_t res[1];
bridge.transfer(cmd, 4, res, 1);
return res[0]; // 1=Success, 0=Error
}
int BridgeUDP::beginPacket(IPAddress ip, uint16_t port)
{
if (!opened)
return 0;
String address;
address.reserve(18);
address += ip[0];
address += '.';
address += ip[1];
address += '.';
address += ip[2];
address += '.';
address += ip[3];
return beginPacket(address.c_str(), port);
}
int BridgeUDP::endPacket()
{
if (!opened)
return 0;
uint8_t cmd[] = {'H', handle};
uint8_t res[1];
bridge.transfer(cmd, 2, res, 1);
return res[0]; // 1=Success, 0=Error
}
size_t BridgeUDP::write(const uint8_t *buffer, size_t size)
{
if (!opened)
return 0;
uint8_t cmd[] = {'h', handle};
uint8_t res[1];
bridge.transfer(cmd, 2, buffer, size, res, 1);
return res[0]; // 1=Success, 0=Error
}
int BridgeUDP::parsePacket()
{
if (!opened)
return 0;
buffered = 0;
readPos = 0;
uint8_t cmd[] = {'Q', handle};
uint8_t res[3];
bridge.transfer(cmd, 2, res, 3);
if (res[0] == 0) {
// There aren't any packets available
return 0;
}
avail = (res[1] << 8) + res[2];
return 1;
}
void BridgeUDP::doBuffer() {
// If there are already char in buffer exit
if (buffered > 0)
return;
if (avail == 0)
return;
// Try to buffer up to 32 characters
readPos = 0;
uint8_t cmd[] = {'u', handle, sizeof(buffer)};
buffered = bridge.transfer(cmd, 3, buffer, sizeof(buffer));
}
int BridgeUDP::read()
{
if (!opened)
return -1;
doBuffer();
if (buffered == 0) {
return -1; // no chars available
}
buffered--;
avail--;
return buffer[readPos++];
}
int BridgeUDP::read(unsigned char* buff, size_t size)
{
if (!opened)
return -1;
size_t readed = 0;
do {
if (buffered == 0) {
doBuffer();
if (buffered == 0)
return readed;
}
buff[readed++] = buffer[readPos++];
buffered--;
avail--;
} while (readed < size);
return readed;
}
int BridgeUDP::peek()
{
if (!opened)
return -1;
doBuffer();
if (buffered == 0)
return -1; // no chars available
return buffer[readPos];
}
IPAddress BridgeUDP::remoteIP()
{
if (!opened)
return -1;
uint8_t cmd[] = {'T', handle};
uint8_t res[7];
bridge.transfer(cmd, 2, res, 7);
if (res[0] == 0)
return IPAddress(0,0,0,0);
return IPAddress(res[1], res[2], res[3], res[4]);
}
uint16_t BridgeUDP::remotePort()
{
if (!opened)
return -1;
uint8_t cmd[] = {'T', handle};
uint8_t res[7];
bridge.transfer(cmd, 2, res, 7);
if (res[0] == 0)
return 0;
return (res[5] << 8) + res[6];
}

View File

@ -0,0 +1,65 @@
/*
Copyright (c) 2015 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
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
*/
#pragma once
#include <Udp.h>
#include "Bridge.h"
class BridgeUDP : public UDP {
public:
BridgeUDP(BridgeClass &_b = Bridge);
virtual uint8_t begin(uint16_t);
virtual void stop();
virtual int beginPacket(IPAddress ip, uint16_t port);
virtual int beginPacket(const char *host, uint16_t port);
virtual int beginBroadcastPacket(uint16_t port);
virtual int endPacket();
virtual size_t write(uint8_t d) { return write(&d, 1); }
virtual size_t write(const uint8_t *buffer, size_t size);
using Print::write;
virtual int parsePacket();
/* return number of bytes available in the current packet,
will return zero if parsePacket hasn't been called yet */
virtual int available() { return avail; }
virtual int read();
virtual int read(unsigned char* buffer, size_t len);
virtual int read(char* buffer, size_t len) { return read((unsigned char*)buffer, len); };
virtual int peek();
virtual void flush() { avail = 0; }
virtual IPAddress remoteIP();
virtual uint16_t remotePort();
private:
BridgeClass &bridge;
uint8_t handle;
boolean opened;
private:
void doBuffer();
uint16_t avail;
uint8_t buffered;
uint8_t readPos;
static const int BUFFER_SIZE = 64;
uint8_t buffer[BUFFER_SIZE];
};

View File

@ -0,0 +1,150 @@
/*
Copyright (c) 2013 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
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
*/
#include <Console.h>
// Default constructor uses global Bridge instance
ConsoleClass::ConsoleClass() :
bridge(Bridge), inBuffered(0), inReadPos(0), inBuffer(NULL),
autoFlush(true)
{
// Empty
}
// Constructor with a user provided BridgeClass instance
ConsoleClass::ConsoleClass(BridgeClass &_b) :
bridge(_b), inBuffered(0), inReadPos(0), inBuffer(NULL),
autoFlush(true)
{
// Empty
}
ConsoleClass::~ConsoleClass() {
end();
}
size_t ConsoleClass::write(uint8_t c) {
if (autoFlush) {
uint8_t tmp[] = { 'P', c };
bridge.transfer(tmp, 2);
} else {
outBuffer[outBuffered++] = c;
if (outBuffered == outBufferSize)
flush();
}
return 1;
}
size_t ConsoleClass::write(const uint8_t *buff, size_t size) {
if (autoFlush) {
uint8_t tmp[] = { 'P' };
bridge.transfer(tmp, 1, buff, size, NULL, 0);
} else {
size_t sent = size;
while (sent > 0) {
outBuffer[outBuffered++] = *buff++;
sent--;
if (outBuffered == outBufferSize)
flush();
}
}
return size;
}
void ConsoleClass::flush() {
if (autoFlush)
return;
bridge.transfer(outBuffer, outBuffered);
outBuffered = 1;
}
void ConsoleClass::noBuffer() {
if (autoFlush)
return;
delete[] outBuffer;
autoFlush = true;
}
void ConsoleClass::buffer(uint8_t size) {
noBuffer();
if (size == 0)
return;
outBuffer = new uint8_t[size + 1];
outBuffer[0] = 'P'; // WRITE tag
outBufferSize = size + 1;
outBuffered = 1;
autoFlush = false;
}
bool ConsoleClass::connected() {
uint8_t tmp = 'a';
bridge.transfer(&tmp, 1, &tmp, 1);
return tmp == 1;
}
int ConsoleClass::available() {
// Look if there is new data available
doBuffer();
return inBuffered;
}
int ConsoleClass::read() {
doBuffer();
if (inBuffered == 0)
return -1; // no chars available
else {
inBuffered--;
return inBuffer[inReadPos++];
}
}
int ConsoleClass::peek() {
doBuffer();
if (inBuffered == 0)
return -1; // no chars available
else
return inBuffer[inReadPos];
}
void ConsoleClass::doBuffer() {
// If there are already char in buffer exit
if (inBuffered > 0)
return;
// Try to buffer up to 32 characters
inReadPos = 0;
uint8_t tmp[] = { 'p', BUFFER_SIZE };
inBuffered = bridge.transfer(tmp, 2, inBuffer, BUFFER_SIZE);
}
void ConsoleClass::begin() {
bridge.begin();
end();
inBuffer = new uint8_t[BUFFER_SIZE];
}
void ConsoleClass::end() {
noBuffer();
if (inBuffer) {
delete[] inBuffer;
inBuffer = NULL;
}
}
ConsoleClass Console;

View File

@ -0,0 +1,71 @@
/*
Copyright (c) 2013 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
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
*/
#ifndef CONSOLE_H_
#define CONSOLE_H_
#include <Bridge.h>
class ConsoleClass : public Stream {
public:
// Default constructor uses global Bridge instance
ConsoleClass();
// Constructor with a user provided BridgeClass instance
ConsoleClass(BridgeClass &_b);
~ConsoleClass();
void begin();
void end();
void buffer(uint8_t size);
void noBuffer();
bool connected();
// Stream methods
// (read from console socket)
int available();
int read();
int peek();
// (write to console socket)
size_t write(uint8_t);
size_t write(const uint8_t *buffer, size_t size);
void flush();
operator bool () {
return connected();
}
private:
BridgeClass &bridge;
void doBuffer();
uint8_t inBuffered;
uint8_t inReadPos;
static const int BUFFER_SIZE = 32;
uint8_t *inBuffer;
bool autoFlush;
uint8_t outBuffered;
uint8_t outBufferSize;
uint8_t *outBuffer;
};
extern ConsoleClass Console;
#endif

View File

@ -0,0 +1,283 @@
/*
Copyright (c) 2013 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
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
*/
#include <FileIO.h>
namespace BridgeLib {
File::File(BridgeClass &b) : bridge(b), mode(255) {
// Empty
}
File::File(const char *_filename, uint8_t _mode, BridgeClass &b) : bridge(b), mode(_mode) {
filename = _filename;
uint8_t modes[] = {'r', 'w', 'a'};
uint8_t cmd[] = {'F', modes[mode]};
uint8_t res[2];
dirPosition = 1;
bridge.transfer(cmd, 2, (uint8_t*)filename.c_str(), filename.length(), res, 2);
if (res[0] != 0) { // res[0] contains error code
mode = 255; // In case of error keep the file closed
return;
}
handle = res[1];
buffered = 0;
}
File::operator bool() {
return (mode != 255);
}
File::~File() {
close();
}
size_t File::write(uint8_t c) {
return write(&c, 1);
}
size_t File::write(const uint8_t *buf, size_t size) {
if (mode == 255)
return -1;
uint8_t cmd[] = {'g', handle};
uint8_t res[1];
bridge.transfer(cmd, 2, buf, size, res, 1);
if (res[0] != 0) // res[0] contains error code
return -res[0];
return size;
}
int File::read() {
doBuffer();
if (buffered == 0)
return -1; // no chars available
else {
buffered--;
return buffer[readPos++];
}
}
int File::peek() {
doBuffer();
if (buffered == 0)
return -1; // no chars available
else
return buffer[readPos];
}
boolean File::seek(uint32_t position) {
uint8_t cmd[] = {
's',
handle,
static_cast<uint8_t>(position >> 24),
static_cast<uint8_t>(position >> 16),
static_cast<uint8_t>(position >> 8),
static_cast<uint8_t>(position)
};
uint8_t res[1];
bridge.transfer(cmd, 6, res, 1);
if (res[0] == 0) {
// If seek succeed then flush buffers
buffered = 0;
return true;
}
return false;
}
uint32_t File::position() {
uint8_t cmd[] = {'S', handle};
uint8_t res[5];
bridge.transfer(cmd, 2, res, 5);
//err = res[0]; // res[0] contains error code
uint32_t pos;
pos = static_cast<uint32_t>(res[1]) << 24;
pos += static_cast<uint32_t>(res[2]) << 16;
pos += static_cast<uint32_t>(res[3]) << 8;
pos += static_cast<uint32_t>(res[4]);
return pos - buffered;
}
void File::doBuffer() {
// If there are already char in buffer exit
if (buffered > 0)
return;
// Try to buffer up to BUFFER_SIZE characters
readPos = 0;
uint8_t cmd[] = {'G', handle, BUFFER_SIZE - 1};
uint16_t readed = bridge.transfer(cmd, 3, buffer, BUFFER_SIZE);
//err = buff[0]; // First byte is error code
if (readed == BridgeClass::TRANSFER_TIMEOUT || readed == 0) {
// transfer failed to retrieve any data
buffered = 0;
} else {
// transfer retrieved at least one byte of data so skip the error code character
readPos++;
buffered = readed - 1;
}
}
int File::available() {
// Look if there is new data available
doBuffer();
return buffered;
}
void File::flush() {
}
int File::read(void *buff, uint16_t nbyte) {
uint16_t n = 0;
uint8_t *p = reinterpret_cast<uint8_t *>(buff);
while (n < nbyte) {
if (buffered == 0) {
doBuffer();
if (buffered == 0)
break;
}
*p++ = buffer[readPos++];
buffered--;
n++;
}
return n;
}
uint32_t File::size() {
if (bridge.getBridgeVersion() < 101)
return 0;
uint8_t cmd[] = {'t', handle};
uint8_t buff[5];
bridge.transfer(cmd, 2, buff, 5);
//err = res[0]; // First byte is error code
uint32_t res;
res = ((uint32_t)buff[1]) << 24;
res |= ((uint32_t)buff[2]) << 16;
res |= ((uint32_t)buff[3]) << 8;
res |= ((uint32_t)buff[4]);
return res;
}
void File::close() {
if (mode == 255)
return;
uint8_t cmd[] = {'f', handle};
uint8_t ret[1];
bridge.transfer(cmd, 2, ret, 1);
mode = 255;
}
const char *File::name() {
return filename.c_str();
}
boolean File::isDirectory() {
uint8_t res[1];
uint8_t cmd[] = {'i'};
if (mode != 255)
return 0;
bridge.transfer(cmd, 1, (uint8_t *)filename.c_str(), filename.length(), res, 1);
return res[0];
}
File File::openNextFile(uint8_t mode) {
Process awk;
char tmp;
String command;
String filepath;
if (dirPosition == 0xFFFF) return File();
command = "ls ";
command += filename;
command += " | awk 'NR==";
command += dirPosition;
command += "'";
awk.runShellCommand(command);
while (awk.running());
command = "";
while (awk.available()) {
tmp = awk.read();
if (tmp != '\n') command += tmp;
}
if (command.length() == 0)
return File();
dirPosition++;
filepath = filename + "/" + command;
return File(filepath.c_str(), mode);
}
void File::rewindDirectory(void) {
dirPosition = 1;
}
boolean FileSystemClass::begin() {
return true;
}
File FileSystemClass::open(const char *filename, uint8_t mode) {
return File(filename, mode);
}
boolean FileSystemClass::exists(const char *filepath) {
Process ls;
ls.begin("ls");
ls.addParameter(filepath);
int res = ls.run();
return (res == 0);
}
boolean FileSystemClass::mkdir(const char *filepath) {
Process mk;
mk.begin("mkdir");
mk.addParameter("-p");
mk.addParameter(filepath);
int res = mk.run();
return (res == 0);
}
boolean FileSystemClass::remove(const char *filepath) {
Process rm;
rm.begin("rm");
rm.addParameter(filepath);
int res = rm.run();
return (res == 0);
}
boolean FileSystemClass::rmdir(const char *filepath) {
Process rm;
rm.begin("rmdir");
rm.addParameter(filepath);
int res = rm.run();
return (res == 0);
}
FileSystemClass FileSystem;
}

View File

@ -0,0 +1,120 @@
/*
Copyright (c) 2013 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
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
*/
#ifndef __FILEIO_H__
#define __FILEIO_H__
#include <Process.h>
#define FILE_READ 0
#define FILE_WRITE 1
#define FILE_APPEND 2
namespace BridgeLib {
class File : public Stream {
public:
File(BridgeClass &b = Bridge);
File(const char *_filename, uint8_t _mode, BridgeClass &b = Bridge);
~File();
virtual size_t write(uint8_t);
virtual size_t write(const uint8_t *buf, size_t size);
virtual int read();
virtual int peek();
virtual int available();
virtual void flush();
int read(void *buf, uint16_t nbyte);
boolean seek(uint32_t pos);
uint32_t position();
uint32_t size();
void close();
operator bool();
const char * name();
boolean isDirectory();
File openNextFile(uint8_t mode = FILE_READ);
void rewindDirectory(void);
//using Print::write;
private:
void doBuffer();
uint8_t buffered;
uint8_t readPos;
uint16_t dirPosition;
static const int BUFFER_SIZE = 64;
uint8_t buffer[BUFFER_SIZE];
private:
BridgeClass &bridge;
String filename;
uint8_t mode;
uint8_t handle;
};
class FileSystemClass {
public:
FileSystemClass() : bridge(Bridge) { }
FileSystemClass(BridgeClass &_b) : bridge(_b) { }
boolean begin();
// Open the specified file/directory with the supplied mode (e.g. read or
// write, etc). Returns a File object for interacting with the file.
// Note that currently only one file can be open at a time.
File open(const char *filename, uint8_t mode = FILE_READ);
// Methods to determine if the requested file path exists.
boolean exists(const char *filepath);
// Create the requested directory hierarchy--if intermediate directories
// do not exist they will be created.
boolean mkdir(const char *filepath);
// Delete the file.
boolean remove(const char *filepath);
boolean rmdir(const char *filepath);
private:
friend class File;
BridgeClass &bridge;
};
extern FileSystemClass FileSystem;
};
// We enclose File and FileSystem classes in namespace BridgeLib to avoid
// conflicts with legacy SD library.
// This ensure compatibility with older sketches that uses only Bridge lib
// (the user can still use File instead of BridgeFile)
using namespace BridgeLib;
// This allows sketches to use BridgeLib::File together with SD library
// (you must use BridgeFile instead of File when needed to disambiguate)
typedef BridgeLib::File BridgeFile;
typedef BridgeLib::FileSystemClass BridgeFileSystemClass;
#define BridgeFileSystem BridgeLib::FileSystem
#endif

View File

@ -0,0 +1,204 @@
/*
Copyright (c) 2013-2014 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
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
*/
#include "HttpClient.h"
HttpClient::HttpClient() :
insecure(false) {
// Empty
}
unsigned int HttpClient::get(String &url) {
begin("curl");
if (insecure) {
addParameter("-k");
}
addHeader();
addParameter(url);
return run();
}
unsigned int HttpClient::get(const char *url) {
begin("curl");
if (insecure) {
addParameter("-k");
}
addHeader();
addParameter(url);
return run();
}
void HttpClient::getAsynchronously(String &url) {
begin("curl");
if (insecure) {
addParameter("-k");
}
addHeader();
addParameter(url);
runAsynchronously();
}
void HttpClient::getAsynchronously(const char *url) {
begin("curl");
if (insecure) {
addParameter("-k");
}
addHeader();
addParameter(url);
runAsynchronously();
}
unsigned int HttpClient::post(String &url, String &data) {
return post(url.c_str(), data.c_str());
}
unsigned int HttpClient::post(const char *url, const char *data) {
begin("curl");
if (insecure) {
addParameter("-k");
}
addParameter("--request");
addParameter("POST");
addParameter("--data");
addParameter(data);
addHeader();
addParameter(url);
return run();
}
void HttpClient::postAsynchronously(String &url, String &data) {
postAsynchronously(url.c_str(), data.c_str());
}
void HttpClient::postAsynchronously(const char *url, const char *data) {
begin("curl");
if (insecure) {
addParameter("-k");
}
addParameter("--request");
addParameter("POST");
addParameter("--data");
addParameter(data);
addHeader();
addParameter(url);
runAsynchronously();
}
unsigned int HttpClient::patch(String &url, String &data) {
return patch(url.c_str(), data.c_str());
}
unsigned int HttpClient::patch(const char *url, const char *data) {
begin("curl");
if (insecure) {
addParameter("-k");
}
addParameter("--request");
addParameter("PATCH");
addParameter("--data");
addParameter(data);
addHeader();
addParameter(url);
return run();
}
void HttpClient::patchAsynchronously(String &url, String &data) {
patchAsynchronously(url.c_str(), data.c_str());
}
void HttpClient::patchAsynchronously(const char *url, const char *data) {
begin("curl");
if (insecure) {
addParameter("-k");
}
addParameter("--request");
addParameter("PATCH");
addParameter("--data");
addParameter(data);
addHeader();
addParameter(url);
runAsynchronously();
}
unsigned int HttpClient::put(String &url, String &data) {
return put(url.c_str(), data.c_str());
}
unsigned int HttpClient::put(const char *url, const char *data) {
begin("curl");
if (insecure) {
addParameter("-k");
}
addParameter("--request");
addParameter("PUT");
addParameter("--data");
addParameter(data);
addHeader();
addParameter(url);
return run();
}
void HttpClient::putAsynchronously(String &url, String &data) {
putAsynchronously(url.c_str(), data.c_str());
}
void HttpClient::putAsynchronously(const char *url, const char *data) {
begin("curl");
if (insecure) {
addParameter("-k");
}
addParameter("--request");
addParameter("PUT");
addParameter("--data");
addParameter(data);
addHeader();
addParameter(url);
runAsynchronously();
}
boolean HttpClient::ready() {
return !running();
}
unsigned int HttpClient::getResult() {
return exitValue();
}
void HttpClient::noCheckSSL() {
insecure = true;
}
void HttpClient::checkSSL() {
insecure = false;
}
void HttpClient::setHeader(String &header) {
this->header = header;
}
void HttpClient::setHeader(const char * header) {
this->header = String(header);
}
void HttpClient::addHeader() {
if (header.length() > 0) {
addParameter("--header");
addParameter(header);
}
}

View File

@ -0,0 +1,59 @@
/*
Copyright (c) 2013-2014 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
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
*/
#ifndef HTTPCLIENT_H_
#define HTTPCLIENT_H_
#include <Process.h>
class HttpClient : public Process {
public:
HttpClient();
unsigned int get(String &url);
unsigned int get(const char * url);
void getAsynchronously(String &url);
void getAsynchronously(const char * url);
unsigned int post(String &url, String &data);
unsigned int post(const char * url, const char * data);
void postAsynchronously(String &url, String &data);
void postAsynchronously(const char * url, const char * data);
unsigned int patch(String &url, String &data);
unsigned int patch(const char * url, const char * data);
void patchAsynchronously(String &url, String &data);
void patchAsynchronously(const char * url, const char * data);
unsigned int put(String &url, String &data);
unsigned int put(const char * url, const char * data);
void putAsynchronously(String &url, String &data);
void putAsynchronously(const char * url, const char * data);
void setHeader(String &header);
void setHeader(const char * header);
boolean ready();
unsigned int getResult();
void noCheckSSL();
void checkSSL();
private:
boolean insecure;
private:
void addHeader();
String header;
};
#endif /* HTTPCLIENT_H_ */

View File

@ -0,0 +1,56 @@
/*
Copyright (c) 2013 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
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
*/
#include <Mailbox.h>
unsigned int MailboxClass::readMessage(uint8_t *buff, unsigned int size) {
uint8_t tmp[] = { 'm' };
return bridge.transfer(tmp, 1, buff, size);
}
void MailboxClass::readMessage(String &str, unsigned int maxLength) {
uint8_t tmp[] = { 'm' };
// XXX: Is there a better way to create the string?
uint8_t buff[maxLength + 1];
int l = bridge.transfer(tmp, 1, buff, maxLength);
buff[l] = 0;
str = (const char *)buff;
}
void MailboxClass::writeMessage(const uint8_t *buff, unsigned int size) {
uint8_t cmd[] = {'M'};
bridge.transfer(cmd, 1, buff, size, NULL, 0);
}
void MailboxClass::writeMessage(const String& str) {
writeMessage((uint8_t*) str.c_str(), str.length());
}
void MailboxClass::writeJSON(const String& str) {
uint8_t cmd[] = {'J'};
bridge.transfer(cmd, 1, (uint8_t*) str.c_str(), str.length(), NULL, 0);
}
unsigned int MailboxClass::messageAvailable() {
uint8_t tmp[] = {'n'};
uint8_t res[2];
bridge.transfer(tmp, 1, res, 2);
return (res[0] << 8) + res[1];
}
MailboxClass Mailbox(Bridge);

View File

@ -0,0 +1,53 @@
/*
Copyright (c) 2013 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
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
*/
#ifndef _MAILBOX_CLASS_H_INCLUDED_
#define _MAILBOX_CLASS_H_INCLUDED_
#include <Bridge.h>
class MailboxClass {
public:
MailboxClass(BridgeClass &b = Bridge) : bridge(b) { }
void begin() { }
void end() { }
// Receive a message and store it inside a buffer
unsigned int readMessage(uint8_t *buffer, unsigned int size);
// Receive a message and store it inside a String
void readMessage(String &str, unsigned int maxLength = 128);
// Send a message
void writeMessage(const uint8_t *buffer, unsigned int size);
// Send a message
void writeMessage(const String& str);
// Send a JSON message
void writeJSON(const String& str);
// Return the size of the next available message, 0 if there are
// no messages in queue.
unsigned int messageAvailable();
private:
BridgeClass &bridge;
};
extern MailboxClass Mailbox;
#endif // _MAILBOX_CLASS_H_INCLUDED_

View File

@ -0,0 +1,142 @@
/*
Copyright (c) 2013 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
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
*/
#include <Process.h>
Process::~Process() {
close();
}
size_t Process::write(uint8_t c) {
uint8_t cmd[] = {'I', handle, c};
bridge.transfer(cmd, 3);
return 1;
}
void Process::flush() {
}
int Process::available() {
// Look if there is new data available
doBuffer();
return buffered;
}
int Process::read() {
doBuffer();
if (buffered == 0)
return -1; // no chars available
else {
buffered--;
return buffer[readPos++];
}
}
int Process::peek() {
doBuffer();
if (buffered == 0)
return -1; // no chars available
else
return buffer[readPos];
}
void Process::doBuffer() {
// If there are already char in buffer exit
if (buffered > 0)
return;
// Try to buffer up to 32 characters
readPos = 0;
uint8_t cmd[] = {'O', handle, sizeof(buffer)};
buffered = bridge.transfer(cmd, 3, buffer, sizeof(buffer));
}
void Process::begin(const String &command) {
close();
cmdline = new String(command);
}
void Process::addParameter(const String &param) {
*cmdline += "\xFE";
*cmdline += param;
}
void Process::runAsynchronously() {
uint8_t cmd[] = {'R'};
uint8_t res[2];
bridge.transfer(cmd, 1, (uint8_t*)cmdline->c_str(), cmdline->length(), res, 2);
handle = res[1];
delete cmdline;
cmdline = NULL;
if (res[0] == 0) // res[0] contains error code
started = true;
}
boolean Process::running() {
uint8_t cmd[] = {'r', handle};
uint8_t res[1];
bridge.transfer(cmd, 2, res, 1);
return (res[0] == 1);
}
unsigned int Process::exitValue() {
uint8_t cmd[] = {'W', handle};
uint8_t res[2];
bridge.transfer(cmd, 2, res, 2);
return (res[0] << 8) + res[1];
}
unsigned int Process::run() {
runAsynchronously();
while (running())
delay(100);
return exitValue();
}
void Process::close() {
if (started) {
uint8_t cmd[] = {'w', handle};
bridge.transfer(cmd, 2);
}
started = false;
}
unsigned int Process::runShellCommand(const String &command) {
runShellCommandAsynchronously(command);
while (running())
delay(100);
return exitValue();
}
void Process::runShellCommandAsynchronously(const String &command) {
begin("/bin/ash");
addParameter("-c");
addParameter(command);
runAsynchronously();
}
// This method is currently unused
//static unsigned int __commandOutputAvailable(uint8_t handle) {
// uint8_t cmd[] = {'o', handle};
// uint8_t res[1];
// Bridge.transfer(cmd, 2, res, 1);
// return res[0];
//}

View File

@ -0,0 +1,71 @@
/*
Copyright (c) 2013 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
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
*/
#ifndef PROCESS_H_
#define PROCESS_H_
#include <Bridge.h>
class Process : public Stream {
public:
// Constructor with a user provided BridgeClass instance
Process(BridgeClass &_b = Bridge) :
bridge(_b), started(false), buffered(0), readPos(0) { }
~Process();
void begin(const String &command);
void addParameter(const String &param);
unsigned int run();
void runAsynchronously();
boolean running();
unsigned int exitValue();
void close();
unsigned int runShellCommand(const String &command);
void runShellCommandAsynchronously(const String &command);
operator bool () {
return started;
}
// Stream methods
// (read from process stdout)
int available();
int read();
int peek();
// (write to process stdin)
size_t write(uint8_t);
void flush();
// TODO: add optimized function for block write
private:
BridgeClass &bridge;
uint8_t handle;
String *cmdline;
boolean started;
private:
void doBuffer();
uint8_t buffered;
uint8_t readPos;
static const int BUFFER_SIZE = 64;
uint8_t buffer[BUFFER_SIZE];
};
#endif

View File

@ -0,0 +1,27 @@
/*
Copyright (c) 2014 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
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
*/
#ifndef _YUN_CLIENT_H_
#define _YUN_CLIENT_H_
#include <BridgeClient.h>
#warning "The use of YunClient is deprecated. Use BridgeClient instead!"
typedef BridgeClient YunClient;
#endif // _YUN_CLIENT_H_

View File

@ -0,0 +1,27 @@
/*
Copyright (c) 2014 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
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
*/
#ifndef _YUN_SERVER_H_
#define _YUN_SERVER_H_
#include <BridgeServer.h>
#warning "The use of YunServer is deprecated. Use BridgeServer instead!"
typedef BridgeServer YunServer;
#endif // _YUN_SERVER_H_

View File

@ -0,0 +1,24 @@
= SD Library for Arduino =
The SD library allows for reading from and writing to SD cards.
For more information about this library please visit us at
http://www.arduino.cc/en/Reference/SD
== License ==
Copyright (C) 2009 by William Greiman
Copyright (c) 2010 SparkFun Electronics
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.

View File

@ -0,0 +1,112 @@
/*
SD card test
This example shows how use the utility libraries on which the'
SD library is based in order to get info about your SD card.
Very useful for testing a card when you're not sure whether its working or not.
The circuit:
* SD card attached to SPI bus as follows:
** MOSI - pin 11 on Arduino Uno/Duemilanove/Diecimila
** MISO - pin 12 on Arduino Uno/Duemilanove/Diecimila
** CLK - pin 13 on Arduino Uno/Duemilanove/Diecimila
** CS - depends on your SD card shield or module.
Pin 4 used here for consistency with other Arduino examples
created 28 Mar 2011
by Limor Fried
modified 9 Apr 2012
by Tom Igoe
*/
// include the SD library:
#include <SPI.h>
#include <SD.h>
// set up variables using the SD utility library functions:
Sd2Card card;
SdVolume volume;
SdFile root;
// change this to match your SD shield or module;
// Arduino Ethernet shield: pin 4
// Adafruit SD shields and modules: pin 10
// Sparkfun SD shield: pin 8
// MKRZero SD: SDCARD_SS_PIN
const int chipSelect = 4;
void setup() {
// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
Serial.print("\nInitializing SD card...");
// we'll use the initialization code from the utility libraries
// since we're just testing if the card is working!
if (!card.init(SPI_HALF_SPEED, chipSelect)) {
Serial.println("initialization failed. Things to check:");
Serial.println("* is a card inserted?");
Serial.println("* is your wiring correct?");
Serial.println("* did you change the chipSelect pin to match your shield or module?");
return;
} else {
Serial.println("Wiring is correct and a card is present.");
}
// print the type of card
Serial.print("\nCard type: ");
switch (card.type()) {
case SD_CARD_TYPE_SD1:
Serial.println("SD1");
break;
case SD_CARD_TYPE_SD2:
Serial.println("SD2");
break;
case SD_CARD_TYPE_SDHC:
Serial.println("SDHC");
break;
default:
Serial.println("Unknown");
}
// Now we will try to open the 'volume'/'partition' - it should be FAT16 or FAT32
if (!volume.init(card)) {
Serial.println("Could not find FAT16/FAT32 partition.\nMake sure you've formatted the card");
return;
}
// print the type and size of the first FAT-type volume
uint32_t volumesize;
Serial.print("\nVolume type is FAT");
Serial.println(volume.fatType(), DEC);
Serial.println();
volumesize = volume.blocksPerCluster(); // clusters are collections of blocks
volumesize *= volume.clusterCount(); // we'll have a lot of clusters
volumesize *= 512; // SD card blocks are always 512 bytes
Serial.print("Volume size (bytes): ");
Serial.println(volumesize);
Serial.print("Volume size (Kbytes): ");
volumesize /= 1024;
Serial.println(volumesize);
Serial.print("Volume size (Mbytes): ");
volumesize /= 1024;
Serial.println(volumesize);
Serial.println("\nFiles found on the card (name, date and size in bytes): ");
root.openRoot(volume);
// list all files in the card with date and size
root.ls(LS_R | LS_DATE | LS_SIZE);
}
void loop(void) {
}

View File

@ -0,0 +1,84 @@
/*
SD card datalogger
This example shows how to log data from three analog sensors
to an SD card using the SD library.
The circuit:
* analog sensors on analog ins 0, 1, and 2
* SD card attached to SPI bus as follows:
** MOSI - pin 11
** MISO - pin 12
** CLK - pin 13
** CS - pin 4 (for MKRZero SD: SDCARD_SS_PIN)
created 24 Nov 2010
modified 9 Apr 2012
by Tom Igoe
This example code is in the public domain.
*/
#include <SPI.h>
#include <SD.h>
const int chipSelect = 4;
void setup() {
// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
Serial.print("Initializing SD card...");
// see if the card is present and can be initialized:
if (!SD.begin(chipSelect)) {
Serial.println("Card failed, or not present");
// don't do anything more:
return;
}
Serial.println("card initialized.");
}
void loop() {
// make a string for assembling the data to log:
String dataString = "";
// read three sensors and append to the string:
for (int analogPin = 0; analogPin < 3; analogPin++) {
int sensor = analogRead(analogPin);
dataString += String(sensor);
if (analogPin < 2) {
dataString += ",";
}
}
// open the file. note that only one file can be open at a time,
// so you have to close this one before opening another.
File dataFile = SD.open("datalog.txt", FILE_WRITE);
// if the file is available, write to it:
if (dataFile) {
dataFile.println(dataString);
dataFile.close();
// print to the serial port too:
Serial.println(dataString);
}
// if the file isn't open, pop up an error:
else {
Serial.println("error opening datalog.txt");
}
}

View File

@ -0,0 +1,65 @@
/*
SD card file dump
This example shows how to read a file from the SD card using the
SD library and send it over the serial port.
The circuit:
* SD card attached to SPI bus as follows:
** MOSI - pin 11
** MISO - pin 12
** CLK - pin 13
** CS - pin 4 (for MKRZero SD: SDCARD_SS_PIN)
created 22 December 2010
by Limor Fried
modified 9 Apr 2012
by Tom Igoe
This example code is in the public domain.
*/
#include <SPI.h>
#include <SD.h>
const int chipSelect = 4;
void setup() {
// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
Serial.print("Initializing SD card...");
// see if the card is present and can be initialized:
if (!SD.begin(chipSelect)) {
Serial.println("Card failed, or not present");
// don't do anything more:
return;
}
Serial.println("card initialized.");
// open the file. note that only one file can be open at a time,
// so you have to close this one before opening another.
File dataFile = SD.open("datalog.txt");
// if the file is available, write to it:
if (dataFile) {
while (dataFile.available()) {
Serial.write(dataFile.read());
}
dataFile.close();
}
// if the file isn't open, pop up an error:
else {
Serial.println("error opening datalog.txt");
}
}
void loop() {
}

View File

@ -0,0 +1,75 @@
/*
SD card basic file example
This example shows how to create and destroy an SD card file
The circuit:
* SD card attached to SPI bus as follows:
** MOSI - pin 11
** MISO - pin 12
** CLK - pin 13
** CS - pin 4 (for MKRZero SD: SDCARD_SS_PIN)
created Nov 2010
by David A. Mellis
modified 9 Apr 2012
by Tom Igoe
This example code is in the public domain.
*/
#include <SPI.h>
#include <SD.h>
File myFile;
void setup() {
// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
Serial.print("Initializing SD card...");
if (!SD.begin(4)) {
Serial.println("initialization failed!");
return;
}
Serial.println("initialization done.");
if (SD.exists("example.txt")) {
Serial.println("example.txt exists.");
} else {
Serial.println("example.txt doesn't exist.");
}
// open a new file and immediately close it:
Serial.println("Creating example.txt...");
myFile = SD.open("example.txt", FILE_WRITE);
myFile.close();
// Check to see if the file exists:
if (SD.exists("example.txt")) {
Serial.println("example.txt exists.");
} else {
Serial.println("example.txt doesn't exist.");
}
// delete the file:
Serial.println("Removing example.txt...");
SD.remove("example.txt");
if (SD.exists("example.txt")) {
Serial.println("example.txt exists.");
} else {
Serial.println("example.txt doesn't exist.");
}
}
void loop() {
// nothing happens after setup finishes.
}

View File

@ -0,0 +1,79 @@
/*
SD card read/write
This example shows how to read and write data to and from an SD card file
The circuit:
* SD card attached to SPI bus as follows:
** MOSI - pin 11
** MISO - pin 12
** CLK - pin 13
** CS - pin 4 (for MKRZero SD: SDCARD_SS_PIN)
created Nov 2010
by David A. Mellis
modified 9 Apr 2012
by Tom Igoe
This example code is in the public domain.
*/
#include <SPI.h>
#include <SD.h>
File myFile;
void setup() {
// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
Serial.print("Initializing SD card...");
if (!SD.begin(4)) {
Serial.println("initialization failed!");
return;
}
Serial.println("initialization done.");
// open the file. note that only one file can be open at a time,
// so you have to close this one before opening another.
myFile = SD.open("test.txt", FILE_WRITE);
// if the file opened okay, write to it:
if (myFile) {
Serial.print("Writing to test.txt...");
myFile.println("testing 1, 2, 3.");
// close the file:
myFile.close();
Serial.println("done.");
} else {
// if the file didn't open, print an error:
Serial.println("error opening test.txt");
}
// re-open the file for reading:
myFile = SD.open("test.txt");
if (myFile) {
Serial.println("test.txt:");
// read from the file until there's nothing else in it:
while (myFile.available()) {
Serial.write(myFile.read());
}
// close the file:
myFile.close();
} else {
// if the file didn't open, print an error:
Serial.println("error opening test.txt");
}
}
void loop() {
// nothing happens after setup
}

View File

@ -0,0 +1,80 @@
/*
Listfiles
This example shows how print out the files in a
directory on a SD card
The circuit:
* SD card attached to SPI bus as follows:
** MOSI - pin 11
** MISO - pin 12
** CLK - pin 13
** CS - pin 4 (for MKRZero SD: SDCARD_SS_PIN)
created Nov 2010
by David A. Mellis
modified 9 Apr 2012
by Tom Igoe
modified 2 Feb 2014
by Scott Fitzgerald
This example code is in the public domain.
*/
#include <SPI.h>
#include <SD.h>
File root;
void setup() {
// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
Serial.print("Initializing SD card...");
if (!SD.begin(4)) {
Serial.println("initialization failed!");
return;
}
Serial.println("initialization done.");
root = SD.open("/");
printDirectory(root, 0);
Serial.println("done!");
}
void loop() {
// nothing happens after setup finishes.
}
void printDirectory(File dir, int numTabs) {
while (true) {
File entry = dir.openNextFile();
if (! entry) {
// no more files
break;
}
for (uint8_t i = 0; i < numTabs; i++) {
Serial.print('\t');
}
Serial.print(entry.name());
if (entry.isDirectory()) {
Serial.println("/");
printDirectory(entry, numTabs + 1);
} else {
// files have sizes, directories do not
Serial.print("\t\t");
Serial.println(entry.size(), DEC);
}
entry.close();
}
}

View File

@ -0,0 +1,31 @@
#######################################
# Syntax Coloring Map SD
#######################################
#######################################
# Datatypes (KEYWORD1)
#######################################
SD KEYWORD1 SD
File KEYWORD1 SD
SDFile KEYWORD1 SD
#######################################
# Methods and Functions (KEYWORD2)
#######################################
begin KEYWORD2
exists KEYWORD2
mkdir KEYWORD2
remove KEYWORD2
rmdir KEYWORD2
open KEYWORD2
close KEYWORD2
seek KEYWORD2
position KEYWORD2
size KEYWORD2
#######################################
# Constants (LITERAL1)
#######################################
FILE_READ LITERAL1
FILE_WRITE LITERAL1

View File

@ -0,0 +1,9 @@
name=SD
version=1.1.1
author=Arduino, SparkFun
maintainer=Arduino <info@arduino.cc>
sentence=Enables reading and writing on SD cards.
paragraph=Once an SD memory card is connected to the SPI interface of the Arduino or Genuino board you can create files and read/write on them. You can also move through directories on the SD card.
category=Data Storage
url=http://www.arduino.cc/en/Reference/SD
architectures=*

Some files were not shown because too many files have changed in this diff Show More