diff options
Diffstat (limited to 'libraries')
20 files changed, 1891 insertions, 0 deletions
diff --git a/libraries/Bridge/Bridge.cpp b/libraries/Bridge/Bridge.cpp new file mode 100644 index 0000000..e612ad8 --- /dev/null +++ b/libraries/Bridge/Bridge.cpp @@ -0,0 +1,264 @@ +/* + 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) { + // Empty +} + +void BridgeClass::begin() { + if (started) + return; + started = true; + + // TODO: A more robust restart + + // Wait for Atheros bootloader to finish startup + do { + dropAll(); + delay(1100); + } while (available()>0); + + // Bridge startup: + // - If the bridge is not running starts it safely + print(CTRL_C); + print(F("\n")); + delay(500); + // Wait for OpenWRT message + // "Press enter to activate console" + print(F("run-bridge\n")); + delay(1000); + dropAll(); + + // - If the bridge was already running previous commands + // are ignored as "invalid packets". + + // Reset the brigde + uint8_t cmd[] = {'X','X'}; + transfer(cmd, 2); +} + +uint8_t BridgeClass::runCommand(String &command) { + uint8_t cmd[] = {'R'}; + uint8_t res[1]; + transfer(cmd, 1, (uint8_t*)command.c_str(), command.length(), res, 1); + return res[0]; +} + +bool BridgeClass::commandIsRunning(uint8_t handle) { + uint8_t cmd[] = {'r', handle}; + uint8_t res[1]; + transfer(cmd, 2, res, 1); + return (res[0] == 1); +} + +unsigned int BridgeClass::commandExitValue(uint8_t handle) { + uint8_t cmd[] = {'W', handle}; + uint8_t res[2]; + transfer(cmd, 2, res, 2); + return (res[0] << 8) + res[1]; +} + +void BridgeClass::cleanCommand(uint8_t handle) { + uint8_t cmd[] = {'w', handle}; + transfer(cmd, 2); +} + +unsigned int BridgeClass::commandOutputAvailable(uint8_t handle) { + uint8_t cmd[] = {'o', handle}; + uint8_t res[1]; + transfer(cmd, 2, res, 1); + return res[0]; +} + +unsigned int BridgeClass::readCommandOutput(uint8_t handle, + uint8_t *buffer, unsigned int size) { + if (size > 255) + size = 255; + uint8_t cmd[] = {'O', handle, size}; + return transfer(cmd, 3, buffer, size); +} + +void BridgeClass::writeCommandInput(uint8_t handle, + const uint8_t *buff, unsigned int size) { + uint8_t cmd[] = {'I', handle}; + transfer(cmd, 2, buff, size, NULL, 0); +} + +unsigned int BridgeClass::readMessage(uint8_t *buff, unsigned int size) { + uint8_t tmp[] = { 'm' }; + return transfer(tmp, 1, buff, size); +} + +void BridgeClass::writeMessage(const uint8_t *buff, unsigned int size) { + uint8_t cmd[] = {'M'}; + transfer(cmd, 1, buff, size, NULL, 0); +} + +unsigned int BridgeClass::messageAvailable() { + uint8_t tmp[] = {'n'}; + uint8_t res[2]; + transfer(tmp, 1, res, 2); + return (res[0] << 8) + res[1]; +} + +void BridgeClass::put(const char *key, const char *value) { + // TODO: do it in a more efficient way + String cmd = "D"; + cmd += key; + cmd += "\xFE"; + cmd += value; + transfer((uint8_t*)cmd.c_str(), cmd.length()); +} + +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; +} + +void BridgeClass::crcUpdate(uint8_t c) { + CRC = CRC ^ c; + CRC = (CRC >> 8) + (CRC << 8); +} + +void BridgeClass::crcReset() { + CRC = 0xAAAA; +} + +void BridgeClass::crcWrite() { + write((char)(CRC >> 8)); + write((char)(CRC & 0xFF)); +} + +bool BridgeClass::crcCheck(uint16_t _CRC) { + return CRC == _CRC; +} + +uint8_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; + for ( ; ; delay(100), dropAll() /* Delay for retransmission */) { + // Send packet + crcReset(); + write((char)0xFF); // Start of packet (0xFF) + crcUpdate(0xFF); + write((char)index); // Message index + crcUpdate(index); + write((char)((len >> 8) & 0xFF)); // Message length (hi) + crcUpdate((len >> 8) & 0xFF); + write((char)(len & 0xFF)); // Message length (lo) + crcUpdate(len & 0xFF); + for (uint16_t i=0; i<len1; i++) { // Payload + write((char)buff1[i]); + crcUpdate(buff1[i]); + } + for (uint16_t i=0; i<len2; i++) { // Payload + write((char)buff2[i]); + crcUpdate(buff2[i]); + } + for (uint16_t i=0; i<len3; i++) { // Payload + 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(5); + if (lh < 0) + continue; + crcUpdate(lh); + int ll = timedRead(5); + if (ll < 0) + continue; + crcUpdate(ll); + uint16_t l = lh; + l <<= 8; + l += ll; + + // Recv data + for (uint16_t i=0; i<l; i++) { + int c = timedRead(5); + if (c < 0) + continue; + // Cut received data if rxbuffer is too small + if (i < rxlen) + 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; + } +} + +int BridgeClass::timedRead(unsigned int timeout) { + int c; + unsigned long _startMillis = millis(); + do { + c = read(); + if (c >= 0) return c; + } while(millis() - _startMillis < timeout); + return -1; // -1 indicates timeout +} + +void BridgeClass::dropAll() { + while (available() > 0) { + read(); + } +} + +// Bridge instance +#ifdef __AVR_ATmega32U4__ + // Leonardo variants (where HardwareSerial is Serial1) + SerialBridgeClass Bridge(Serial1); +#else + SerialBridgeClass Bridge(Serial); +#endif diff --git a/libraries/Bridge/Bridge.h b/libraries/Bridge/Bridge.h new file mode 100644 index 0000000..c7b5361 --- /dev/null +++ b/libraries/Bridge/Bridge.h @@ -0,0 +1,122 @@ +/* + 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_ + +#include <Arduino.h> +#include <Stream.h> + +class BridgeClass: public Stream { +public: + BridgeClass(Stream &_stream); + void begin(); + + // Methods to handle processes on the linux side + uint8_t runCommand(String &command); + bool commandIsRunning(uint8_t handle); + unsigned int commandExitValue(uint8_t handle); + void cleanCommand(uint8_t handle); + + unsigned int commandOutputAvailable(uint8_t handle); + unsigned int readCommandOutput(uint8_t handle, uint8_t *buff, unsigned int size); + unsigned int readCommandOutput(uint8_t handle, char *buff, unsigned int size) + { return readCommandOutput(handle, reinterpret_cast<uint8_t *>(buff), size); } + + void writeCommandInput(uint8_t handle, const uint8_t *buff, unsigned int size); + void writeCommandInput(uint8_t handle, const char *buff, unsigned int size) + { writeCommandInput(handle, reinterpret_cast<const uint8_t *>(buff), size); } + + // Methods to handle mailbox messages + unsigned int readMessage(uint8_t *buffer, unsigned int size); + void writeMessage(const uint8_t *buffer, unsigned int size); + unsigned int messageAvailable(); + + // Methods to handle key/value datastore + void put(const char *key, const char *value); + unsigned int get(const char *key, uint8_t *buff, unsigned int size); + unsigned int get(const char *key, char *value, unsigned int maxlen) + { get(key, reinterpret_cast<uint8_t *>(value), maxlen); } + + // Print methods (proxy to "stream" object) [CM: are these really needed?] + size_t write(uint8_t c) { return stream.write(c); } + size_t write(const uint8_t *buffer, size_t size) + { return stream.write(buffer, size); } + + // Stream methods (proxy to "stream" object) [CM: are these really needed?] + int available() { return stream.available(); } + int read() { return stream.read(); } + int peek() { return stream.peek(); } + void flush() { stream.flush(); } + + // Trasnfer a frame (with error correction and response) + uint8_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 + uint8_t transfer(const uint8_t *buff1, uint16_t len1) + { transfer(buff1, len1, NULL, 0); } + uint8_t transfer(const uint8_t *buff1, uint16_t len1, + uint8_t *rxbuff, uint16_t rxlen) + { transfer(buff1, len1, NULL, 0, rxbuff, rxlen); } + uint8_t transfer(const uint8_t *buff1, uint16_t len1, + const uint8_t *buff2, uint16_t len2, + uint8_t *rxbuff, uint16_t rxlen) + { transfer(buff1, len1, buff2, len2, NULL, 0, rxbuff, rxlen); } +private: + uint8_t index; + int timedRead(unsigned int timeout); + void dropAll(); + +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; +}; + +// This subclass uses a serial port Stream +class SerialBridgeClass : public BridgeClass { +public: + SerialBridgeClass(HardwareSerial &_serial) + : BridgeClass(_serial), serial(_serial) { + // Empty + } + + void begin() { + serial.begin(57600); + BridgeClass::begin(); + } + +private: + HardwareSerial &serial; +}; + +extern SerialBridgeClass Bridge; + +#endif /* BRIDGE_H_ */ + +#include <Console.h> +#include <Process.h> diff --git a/libraries/Bridge/Console.cpp b/libraries/Bridge/Console.cpp new file mode 100644 index 0000000..8607421 --- /dev/null +++ b/libraries/Bridge/Console.cpp @@ -0,0 +1,153 @@ +/* + 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); + return 1; + } else { + outBuffer[outBuffered++] = c; + if (outBuffered == outBufferSize) + flush(); + } +} + +size_t ConsoleClass::write(const uint8_t *buff, size_t size) { + if (autoFlush) { + // TODO: do it in a more efficient way + uint8_t *tmp = new uint8_t[size+1]; + tmp[0] = 'P'; + memcpy(tmp+1, buff, size); + bridge.transfer(tmp, size+1); + delete[] tmp; + return size; + } else { + while (size > 0) { + outBuffer[outBuffered++] = *buff++; + size--; + if (outBuffered == outBufferSize) + flush(); + } + } +} + +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; diff --git a/libraries/Bridge/Console.h b/libraries/Bridge/Console.h new file mode 100644 index 0000000..73a9739 --- /dev/null +++ b/libraries/Bridge/Console.h @@ -0,0 +1,69 @@ +/* + 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 diff --git a/libraries/Bridge/FileIO.cpp.disabled b/libraries/Bridge/FileIO.cpp.disabled new file mode 100644 index 0000000..fc6d3df --- /dev/null +++ b/libraries/Bridge/FileIO.cpp.disabled @@ -0,0 +1,162 @@ +/* + 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> + +File::File() : mode(255), filename(NULL) { + // Empty +} + +File::File(const char *_filename, uint8_t _mode) : mode(_mode) { + filename = new char[strlen(_filename)+1]; + strcpy(filename, _filename); +} + +File::operator bool() { + return (mode != 255); +} + +File::~File() { + if (filename) + delete[] filename; +} + +char toHex(uint8_t c) { + if (c<10) + return '0' + c; + else + return 'A' + c - 10; +} + +size_t File::write(uint8_t c) { + Process echo; + echo.begin("arduino-append"); + echo.addParameter(filename); + char chars[] = { '\\', 'x', toHex(c >> 4), toHex(c & 0x0F), '\0' }; + echo.addParameter(chars); + echo.run(); + return 1; +} + +size_t File::write(const uint8_t *buf, size_t size) { + Process echo; + echo.begin("arduino-append"); + echo.addParameter(filename); + echo.addParameter(" \"", true); + for (unsigned int i=0; i<size; i++) { + // slow but requires less memory + char c = buf[i]; + char chars[] = { '\\', 'x', toHex(c >> 4), toHex(c & 0x0F), '\0' }; + echo.addParameter(chars, true); + } + echo.addParameter("\"", true); + echo.run(); + return size; +} + +int File::read() { + return 1; +} + +int File::peek() { + return 1; +} + +int File::available() { + return 1; +} + +void File::flush() { +} + +//int read(void *buf, uint16_t nbyte) +//boolean seek(uint32_t pos) +//uint32_t position() +//uint32_t size() + +void File::close() { + mode = 255; +} + +char *File::name() { + return filename; +} + +//boolean isDirectory(void) +//File openNextFile(uint8_t mode = O_RDONLY); +//void rewindDirectory(void) + + + + + + +boolean SDClass::begin() { + return true; +} + +File SDClass::open(const char *filename, uint8_t mode) { + if (mode == FILE_READ) { + if (exists(filename)) + return File(filename, mode); + } + if (mode == FILE_WRITE) { + Process touch; + touch.begin(">"); + touch.addParameter(filename); + int res = touch.run(); + if (res == 0) + return File(filename, mode); + } + return File(); +} + +boolean SDClass::exists(const char *filepath) { + Process ls; + ls.begin("ls"); + ls.addParameter(filepath); + int res = ls.run(); + return (res == 0); +} + +boolean SDClass::mkdir(const char *filepath) { + Process mk; + mk.begin("mkdir"); + mk.addParameter("-p"); + mk.addParameter(filepath); + int res = mk.run(); + return (res == 0); +} + +boolean SDClass::remove(const char *filepath) { + Process rm; + rm.begin("rm"); + rm.addParameter(filepath); + int res = rm.run(); + return (res == 0); +} + +boolean SDClass::rmdir(const char *filepath) { + Process rm; + rm.begin("rmdir"); + rm.addParameter(filepath); + int res = rm.run(); + return (res == 0); +} + +SDClass SD; diff --git a/libraries/Bridge/FileIO.h b/libraries/Bridge/FileIO.h new file mode 100644 index 0000000..a90ff46 --- /dev/null +++ b/libraries/Bridge/FileIO.h @@ -0,0 +1,96 @@ +/* + 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 __SD_H__ +#define __SD_H__ + +#include <Process.h> + +//#define FILE_READ O_READ +//#define FILE_WRITE (O_READ | O_WRITE | O_CREAT) + +#define FILE_READ 0 +#define FILE_WRITE 1 + +class File : public Process { + +public: + File(); + File(const char *_filename, uint8_t _mode); + ~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(); + char * name(); + + boolean isDirectory(void); + //File openNextFile(uint8_t mode = O_RDONLY); + void rewindDirectory(void); + + using Print::write; + +private: + char *filename; + uint8_t mode; +}; + +class SDClass { +public: + SDClass() : bridge(Bridge) { } + SDClass(BridgeClass &_b) : bridge(_b) { } + + // This needs to be called to set up the connection to the SD card + // before other methods are used. + 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 heirarchy--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 SDClass SD; + +#endif diff --git a/libraries/Bridge/HttpClient.cpp b/libraries/Bridge/HttpClient.cpp new file mode 100644 index 0000000..510af38 --- /dev/null +++ b/libraries/Bridge/HttpClient.cpp @@ -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 +*/ + +#include "HttpClient.h" + +unsigned int HttpClient::get(String &url) { + begin("curl"); + addParameter(url); + return run(); +} + +unsigned int HttpClient::get(const char *url) { + begin("curl"); + addParameter(url); + return run(); +} + +void HttpClient::getAsynchronously(String &url) { + begin("curl"); + addParameter(url); + runAsynchronously(); +} + +void HttpClient::getAsynchronously(const char *url) { + begin("curl"); + addParameter(url); + runAsynchronously(); +} + +boolean HttpClient::ready() { + return running(); +} + +unsigned int HttpClient::getResult() { + return exitValue(); +} + + diff --git a/libraries/Bridge/HttpClient.h b/libraries/Bridge/HttpClient.h new file mode 100644 index 0000000..940a66d --- /dev/null +++ b/libraries/Bridge/HttpClient.h @@ -0,0 +1,36 @@ +/* + 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 HTTPCLIENT_H_ +#define HTTPCLIENT_H_ + +#include <Process.h> + +class HttpClient : public Process { +public: + + unsigned int get(String &url); + unsigned int get(const char * url); + void getAsynchronously(String &url); + void getAsynchronously(const char * url); + boolean ready(); + unsigned int getResult(); + +}; + +#endif /* HTTPCLIENT_H_ */ diff --git a/libraries/Bridge/Process.cpp b/libraries/Bridge/Process.cpp new file mode 100644 index 0000000..7265119 --- /dev/null +++ b/libraries/Bridge/Process.cpp @@ -0,0 +1,115 @@ +/* + 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) { + bridge.writeCommandInput(handle, &c, 1); + 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; + buffered = bridge.readCommandOutput(handle, buffer, sizeof(buffer)); +} + +void Process::begin(String &command) { + close(); + cmdline = new String(command); +} + +void Process::begin(const char *command) { + close(); + cmdline = new String(command); +} + +void Process::addParameter(const char *param) { + *cmdline += "\xFE"; + *cmdline += param; +} + +void Process::addParameter(String ¶m) { + *cmdline += "\xFE"; + *cmdline += param; +} + +void Process::runAsynchronously() { + handle = bridge.runCommand(*cmdline); + delete cmdline; + cmdline = NULL; + + started = true; +} + +boolean Process::running() { + return bridge.commandIsRunning(handle); +} + +unsigned int Process::exitValue() { + return bridge.commandExitValue(handle); +} + +unsigned int Process::run() { + runAsynchronously(); + while (running()) + delay(100); + return exitValue(); +} + +void Process::close() { + if (started) + bridge.cleanCommand(handle); + started = false; +} + diff --git a/libraries/Bridge/Process.h b/libraries/Bridge/Process.h new file mode 100644 index 0000000..b48e046 --- /dev/null +++ b/libraries/Bridge/Process.h @@ -0,0 +1,66 @@ +/* + 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: + // Default constructor uses global Bridge instance + Process() : bridge(Bridge), started(false), buffered(0), readPos(0) { } + // Constructor with a user provided BridgeClass instance + Process(BridgeClass &_b) : bridge(_b), started(false), buffered(0), readPos(0) { } + ~Process(); + + void begin(String &command); + void begin(const char *command); + void addParameter(String ¶m); + void addParameter(const char *param); + unsigned int run(); + void runAsynchronously(); + boolean running(); + unsigned int exitValue(); + void close(); + + // Stream methods + // (read from process stdout) + int available(); + int read(); + int peek(); + // (write to process stdin) + size_t write(uint8_t); + void flush(); + +private: + BridgeClass &bridge; + unsigned int 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 diff --git a/libraries/Bridge/examples/BootWatcher001/BootWatcher001.ino b/libraries/Bridge/examples/BootWatcher001/BootWatcher001.ino new file mode 100644 index 0000000..7833d54 --- /dev/null +++ b/libraries/Bridge/examples/BootWatcher001/BootWatcher001.ino @@ -0,0 +1,90 @@ + +/* + Arduino Yun Boot watcher + + Allows you to use the Yun's 32U4 processor as a + serial terminal for the linino processor + + Upload this to an Arduino Yun via serial (not WiFi) + then open the serial monitor at 115200 to see the boot process + of the linino processor. You can also use the serial monitor + as a basic command line interface for the linino processor using + this sketch. + + The circuit: + * Arduino Yun + + created March 2013 + by Massimo Banzi + modified 26 May 2013 + by Tom Igoe + + This example code is in the public domain. + */ + +long baud = 115200; + +// Pin 13 has an LED connected on most Arduino boards. +// give it a name: +int led = 13; +int ledState = HIGH; // whether the LED is high or low + +String bootString = ""; +int bootLineCount = 0; +boolean booting = true; + +void setup() { + Serial.begin(baud); // open serial connection to Linino + Serial1.begin(baud); // open serial connection via USB-Serial + + // initialize the digital pin as an output. + pinMode(led, OUTPUT); + digitalWrite(led, ledState); // turn the LED on (HIGH is the voltage level) + while(booting) { + listenForBoot(); + } + delay(500); +} + + +void loop() { + // After booting, become a serial terminal: + if (Serial.available()) { // got anything from USB-Serial? + char c = (char)Serial.read(); // read from USB-serial + Serial1.write(c); // write to Linino + ledState=!ledState; // invert LED state + digitalWrite(led, ledState); // toggle the LED + } + if (Serial1.available()) { // got anything from Linino? + char c = (char)Serial1.read(); // read from Linino + Serial.write(c); // write to USB-serial + } + +} + +void listenForBoot() { + char c; + if (Serial1.available()) { // got anything from Linino? + c = (char)Serial1.read(); // read from Linino + + if (c == '\n') { // clear the bootString every newline + bootLineCount++; // increment the boot line counter + Serial.println(bootLineCount); // print the count + bootString = ""; // clear the boot string + } + else { // anything other than newline, add to string + bootString += c; + } + } + + // look for the final boot string message: + if (bootString.endsWith("entered forwarding state")) { + Serial1.println(); + } + + // look for the command prompt: + if (bootString.endsWith(":/#")) { + Serial.println("Ready for action."); + booting = false; + } +} diff --git a/libraries/Bridge/examples/Bridge/Bridge.ino b/libraries/Bridge/examples/Bridge/Bridge.ino new file mode 100644 index 0000000..dc453c4 --- /dev/null +++ b/libraries/Bridge/examples/Bridge/Bridge.ino @@ -0,0 +1,104 @@ + +#include <Bridge.h> + +void setup() { + pinMode(13,OUTPUT); + digitalWrite(13, LOW); + Bridge.begin(); + digitalWrite(13, HIGH); +} + +void loop() { + while (Bridge.messageAvailable()) { + uint8_t buff[64]; + int l = Bridge.readMessage(buff, 64); + process(buff, l); + } + delay(100); // Poll every 0.100s +} + +void process(uint8_t buff[], int l) { + // "DWppv" -> digitalWrite(pp, v) + // "DRpp" -> digitalRead(pp) -> "Dpp0" / "Dpp1" + // "AWppvvv" -> analogWrite(pp, vvv) + // "ARpp" -> analogRead(pp) -> "App0000" - "App1023" + // "PIpp" -> pinMode(pp, INPUT) + // "POpp" -> pinMode(pp, OUTPUT) + + // Sanity check + if (l<4 || l>7) + return; + if (buff[2]<'0' || buff[2]>'9') + return; + if (buff[3]<'0' || buff[3]>'9') + return; + char cmd0 = buff[0]; + char cmd1 = buff[1]; + int pin = (buff[2]-'0')*10 + (buff[3]-'0'); + if (pin<0 || pin>13) + return; + + // Command selection + if (l==5 && cmd0=='D' && cmd1=='W') { + char c = buff[4]; + if (c=='0' || c=='1') { + digitalWrite(pin, c-'0'); + reportDigitalRead(pin, true, true); + } + } else if (l==4 && cmd0=='D' && cmd1=='R') { + reportDigitalRead(pin, true, true); + } else if (l==7 && cmd0=='A' && cmd1=='W') { + analogWrite(pin, buff[4]); + reportAnalogRead(pin); + } else if (l==4 && cmd0=='A' && cmd1=='R') { + reportAnalogRead(pin); + } else if (l==4 && cmd0=='P' && cmd1=='I') { + pinMode(pin, INPUT); + reportPinMode(pin, INPUT); + } else if (l==4 && cmd0=='P' && cmd1=='O') { + pinMode(pin, OUTPUT); + reportPinMode(pin, OUTPUT); + } +} + +void reportPinMode(int pin, uint8_t dir) { + uint8_t buff[] = { 'P', 'I', '0', '0' }; + buff[1] = dir == INPUT ? 'I' : 'O'; + buff[2] += pin/10; + buff[3] += pin%10; + Bridge.writeMessage(buff, 4); +} + +void reportDigitalRead(int pin, boolean raw, boolean dataset) { + // "Dpp0" - "Dpp1" + // 0 1 2 3 + uint8_t buff[] = { 'D', '0', '0', '0' }; + buff[1] += pin/10; + buff[2] += pin%10; + if (digitalRead(pin) == HIGH) + buff[3] = '1'; + if (raw) + Bridge.writeMessage(buff, 4); + if (dataset) { + char *val = "0"; + val[0] = buff[3]; + buff[3] = 0; + Bridge.put((const char *)buff, val); + } +} + +void reportAnalogRead(int pin) { + // "App0000" - "App1023" + // 0 1 2 3 4 5 6 + uint8_t buff[] = { 'A', '0', '0', '0', '0', '0', '0' }; + buff[1] += pin/10; + buff[2] += pin%10; + + int v = analogRead(pin); + buff[6] += v%10; v /= 10; + buff[5] += v%10; v /= 10; + buff[4] += v%10; v /= 10; + buff[3] += v; + Bridge.writeMessage(buff, 7); +} + diff --git a/libraries/Bridge/examples/ConsoleAsciiTable/ConsoleAsciiTable.ino b/libraries/Bridge/examples/ConsoleAsciiTable/ConsoleAsciiTable.ino new file mode 100644 index 0000000..4cdf4c1 --- /dev/null +++ b/libraries/Bridge/examples/ConsoleAsciiTable/ConsoleAsciiTable.ino @@ -0,0 +1,94 @@ +/* + ASCII table + + 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: No external hardware needed. + + created 2006 + by Nicholas Zambetti + modified 9 Apr 2012 + by Tom Igoe + modified 22 May 2013 + by Cristian Maglie + + This example code is in the public domain. + + <http://www.zambetti.com> + + */ + +#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++; +} diff --git a/libraries/Bridge/examples/FileTest/FileTest.ino b/libraries/Bridge/examples/FileTest/FileTest.ino new file mode 100644 index 0000000..3fd7ce9 --- /dev/null +++ b/libraries/Bridge/examples/FileTest/FileTest.ino @@ -0,0 +1,50 @@ + +#include <FileIO.h> + +void setup() { + Bridge.begin(); + SD.begin(); + + boolean r; + r=SD.exists("/arduino/test"); + if (r) error("1"); + r=SD.exists("/arduino"); + if (!r) error("2"); + + r=SD.mkdir("/arduino/test"); + if (!r) error("3"); + r=SD.exists("/arduino/test"); + if (!r) error("4"); + + File f = SD.open("/arduino/test/bla", FILE_WRITE); + if (!f) error("5"); + f.println("CIAO!"); + f.close(); + + delay(10000); + + r=SD.rmdir("/arduino/test"); + if (r) error("6"); + r=SD.remove("/arduino/test"); + if (r) error("7"); + + r=SD.remove("/arduino/test/bla"); + if (!r) error("8"); + r=SD.rmdir("/arduino/test"); + if (!r) error("9"); + r=SD.exists("/arduino/test"); + if (r) error("10"); +} + + +void error(const char *s) { + Bridge.print("# ERROR "); + Bridge.println(s); + while (true); +} + +void loop() { +} + + + diff --git a/libraries/Bridge/examples/HttpClient/HttpClient.ino b/libraries/Bridge/examples/HttpClient/HttpClient.ino new file mode 100644 index 0000000..bf5e8ff --- /dev/null +++ b/libraries/Bridge/examples/HttpClient/HttpClient.ino @@ -0,0 +1,23 @@ + +#include <HttpClient.h> + +void setup() { + pinMode(13, OUTPUT); + digitalWrite(13, LOW); + Bridge.begin(); +} + +void loop() { + HttpClient client; + client.get("http://my.server.address/file.php"); + + char c = client.read(); + if (c=='1') + digitalWrite(13, HIGH); + if (c=='0') + digitalWrite(13, LOW); + + delay(5000); +} + + diff --git a/libraries/Bridge/examples/Process/Process.ino b/libraries/Bridge/examples/Process/Process.ino new file mode 100644 index 0000000..919cea7 --- /dev/null +++ b/libraries/Bridge/examples/Process/Process.ino @@ -0,0 +1,70 @@ +/* + Running process using Process class. + + This sketch demonstrate how to run linux processes + using an Arduino Yún. + + created 5 Jun 2013 + by Cristian Maglie + + */ + +#include <Process.h> + +void setup() { + // Setup Bridge (needed every time we communicate with the Arduino Yún) + Bridge.begin(); + + // Setup Console + Console.begin(); + // Buffering improves Console performance, but we must remember to + // finish sending using the Console.flush() command. + Console.buffer(64); + + // Wait until a Network Monitor is connected. + while (!Console); + + // run various example processes + runCurl(); + runCpuInfo(); +} + +void loop() { + // Do nothing here. +} + +void runCurl() { + // Launch "curl" command and get Arduino asciilogo from the network + + Process p; // Create a process and call it "p" + p.begin("curl"); // Process should launch the "curl" command + p.addParameter("http://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 console. + // A process output can be read with the stream methods + while (p.available()>0) { + char c = p.read(); + Console.print(c); + } + // Ensure the latest bit of data is sent. + Console.flush(); +} + +void runCpuInfo() { + // Launch "cat /proc/cpuinfo" command (shows info on Atheros CPU) + Process p; + p.begin("cat"); + p.addParameter("/proc/cpuinfo"); + p.run(); + + // Print command output on the Console. + // A process output can be read with the stream methods + while (p.available()>0) { + char c = p.read(); + Console.print(c); + } + // Ensure the latest bit of data is sent. + Console.flush(); +} + diff --git a/libraries/Bridge/examples/TimeCheck/TimeCheck.ino b/libraries/Bridge/examples/TimeCheck/TimeCheck.ino new file mode 100644 index 0000000..54fd131 --- /dev/null +++ b/libraries/Bridge/examples/TimeCheck/TimeCheck.ino @@ -0,0 +1,79 @@ + +/* + Time Check + + Gets the time from the linino processor via Bridge + then parses out hours, minutes and seconds for the Arduino + using an Arduino Yun. + + created 27 May 2013 + By Tom Igoe + */ + + +#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() { + Serial.begin(9600); // initialize serial + Bridge.begin(); // initialize Bridge + delay(2000); // wait 2 seconds + + while(!Serial); // wait for Serial Monitor to open + Serial.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) Serial.print("0"); // adjust for 0-9 + Serial.print(hours); + Serial.print(":"); + if (minutes <= 9) Serial.print("0"); // adjust for 0-9 + Serial.print(minutes); + Serial.print(":"); + if (seconds <= 9) Serial.print("0"); // adjust for 0-9 + Serial.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(); + } + +} diff --git a/libraries/Bridge/examples/WiFiCheck/WiFiCheck.ino b/libraries/Bridge/examples/WiFiCheck/WiFiCheck.ino new file mode 100644 index 0000000..1cb9f03 --- /dev/null +++ b/libraries/Bridge/examples/WiFiCheck/WiFiCheck.ino @@ -0,0 +1,53 @@ +/* + Arduino Yun Wireless Config Check + + Checks the wireless state of Arduino Yun by calling + the linux command iwconfig. + + Upload this to an Arduino Yun via serial (not WiFi) + then open the serial monitor to see the status of + your Yun's WiFi connection. If it's connected to + a wireless network, the ESSID (name) of that network + and the signal strength will appear. + + The circuit: + * Arduino Yun + + created 22 May 2013 + by Tom Igoe + + This example code is in the public domain. + */ + +#include <Process.h> + +void setup() { + Serial.begin(9600); // initialize serial communication + while(!Serial); // do nothing until the serial monitor is opened + + pinMode(13,OUTPUT); + digitalWrite(13, LOW); + Bridge.begin(); // make contact with the linux processor + digitalWrite(13, HIGH); + + delay(2000); // wait 2 seconds + + Process wifiCheck; // initialize a new process + + + wifiCheck.begin("iwconfig"); // command you want to run + wifiCheck.addParameter("wlan0"); // parameter of the command + wifiCheck.run(); // run the command + + // while there's any characters coming back from the + // process, print them to the serial monitor: + while (wifiCheck.available() > 0) { + char thisChar = wifiCheck.read(); + Serial.print(thisChar); + } +} + +void loop() { + // nothing to do here. +} + diff --git a/libraries/Bridge/examples/XivelyClient/XivelyClient.ino b/libraries/Bridge/examples/XivelyClient/XivelyClient.ino new file mode 100644 index 0000000..48b1403 --- /dev/null +++ b/libraries/Bridge/examples/XivelyClient/XivelyClient.ino @@ -0,0 +1,110 @@ +/* + Xively sensor client with Strings + + This sketch connects an analog sensor to Xively, + using an Arduino Yún. + + created 15 March 2010 + updated 27 May 2013 + by Tom Igoe + + */ + +// include all Libraries needed: +#include <Process.h> +#include "passwords.h" // contains my passwords, see below + +/* + NOTE: passwords.h is not included with this repo because it contains my passwords. + You need to create it for your own version of this application. To do so, make + a new tab in Arduino, call it passwords.h, and include the following variables and constants: + + #define APIKEY "foo" // replace your pachube api key here + #define FEEDID 0000 // replace your feed ID + #define USERAGENT "my-project" // user agent is the project name + */ + + +// set up net client info: +const unsigned long postingInterval = 60000; //delay between updates to xively.com +unsigned long lastRequest = 0; // when you last made a request +String dataString = ""; + +void setup() { + // start serial port: + Bridge.begin(); + Console.begin(); + + while(!Console); // wait for Network Console to open + Console.println("Xively client"); + + // Do a first update immediately + updateData(); + sendData(); + lastRequest = millis(); +} + +void loop() { + // get a timestamp so you can calculate reading and sending intervals: + long now = millis(); + + // if the sending interval has passed since your + // last connection, then connect again and send data: + if (now - lastRequest >= postingInterval) { + updateData(); + sendData(); + lastRequest = now; + } +} + +void updateData() { + // convert the readings to a String to send it: + dataString = "Temperature,"; + dataString += random(10) + 20; + // add pressure: + dataString += "\nPressure,"; + dataString += random(5) + 100; +} + +// this method makes a HTTP connection to the server: +void sendData() { + // form the string for the API header parameter: + String apiString = "X-ApiKey: "; + apiString += APIKEY; + + // form the string for the URL parameter: + String url = "https://api.xively.com/v2/feeds/"; + url += FEEDID; + url += ".csv"; + + // Send the HTTP PUT request + + // Is better to declare the Process here, so when the + // sendData function finishes the resources are immediately + // released. Declaring it global works too, BTW. + Process xively; + Console.print("\n\nSending data... "); + xively.begin("curl"); + xively.addParameter("-k"); + xively.addParameter("--request"); + xively.addParameter("PUT"); + xively.addParameter("--data"); + xively.addParameter(dataString); + xively.addParameter("--header"); + xively.addParameter(apiString); + xively.addParameter(url); + xively.run(); + Console.println("done!"); + + // If there's incoming data from the net connection, + // send it out the Console: + while (xively.available()>0) { + char c = xively.read(); + Console.write(c); + } + +} + + + + diff --git a/libraries/Bridge/examples/YunSerialTerminal/YunSerialTerminal.ino b/libraries/Bridge/examples/YunSerialTerminal/YunSerialTerminal.ino new file mode 100644 index 0000000..aa152e1 --- /dev/null +++ b/libraries/Bridge/examples/YunSerialTerminal/YunSerialTerminal.ino @@ -0,0 +1,82 @@ +/* + Arduino Yun USB-to-Serial + + Allows you to use the Yun's 32U4 processor as a + serial terminal for the linino processor. + + Upload this to an Arduino Yun via serial (not WiFi) + then open the serial monitor at 115200 to see the boot process + of the linino processor. You can also use the serial monitor + as a basic command line interface for the linino processor 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 + + The circuit: + * Arduino Yun + + created March 2013 + by Massimo Banzi + modified by Cristian Maglie + + This example code is in the public domain. + */ + +long lininoBaud = 57600; + +// Pin 13 has an LED connected on most Arduino boards. +int led = 13; +int ledState = HIGH; // whether the LED is high or low + + +void setup() { + Serial.begin(115200); // open serial connection via USB-Serial + Serial1.begin(lininoBaud); // open serial connection to Linino + + // initialize the digital pin as an output. + pinMode(led, OUTPUT); + digitalWrite(led, ledState); // turn the LED on (HIGH is the voltage level) +} + + +boolean commandMode = false; + +void loop() { + // copy from virtual serial line to uart and vice versa + if (Serial.available()) { // got anything from USB-Serial? + char c = (char)Serial.read(); // read from USB-serial + if (commandMode == false) { // if we aren't in command mode... + if (c == '~') { // Tilde '~' key pressed? + commandMode = true; // enter in command mode + } else { + Serial1.write(c); // otherwise write char to Linino + } + } else { // if we are in command mode... + if (c == '0') { // '0' key pressed? + Serial1.begin(57600); // set speed to 57600 + Serial.println("Speed set to 57600"); + } else if (c == '1') { // '1' key pressed? + Serial1.begin(115200); // set speed to 115200 + Serial.println("Speed set to 115200"); + } else { // any other key pressed? + Serial1.write('~'); // write '~' to Linino + Serial1.write(c); // write char to Linino + } + commandMode = false; // in all cases exit from command mode + } + ledState=!ledState; // invert LED state + digitalWrite(led, ledState); // toggle the LED + } + if (Serial1.available()) { // got anything from Linino? + char c = (char)Serial1.read(); // read from Linino + Serial.write(c); // write to USB-serial + } +} + + + + + |