diff --git a/hardware/arduino/avr/libraries/Bridge/Bridge.cpp b/hardware/arduino/avr/libraries/Bridge/Bridge.cpp index 6e9cafc85..c929ed8d9 100644 --- a/hardware/arduino/avr/libraries/Bridge/Bridge.cpp +++ b/hardware/arduino/avr/libraries/Bridge/Bridge.cpp @@ -58,32 +58,6 @@ void BridgeClass::begin() { while (true); } -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); -} - -void BridgeClass::writeMessage(const String& str) { - writeMessage((uint8_t*) str.c_str(), str.length()); -} - -void BridgeClass::writeJSON(const String& str) { - uint8_t cmd[] = {'J'}; - transfer(cmd, 1, (uint8_t*) str.c_str(), str.length(), 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"; diff --git a/hardware/arduino/avr/libraries/Bridge/Bridge.h b/hardware/arduino/avr/libraries/Bridge/Bridge.h index 3aabeff3f..abd757aef 100644 --- a/hardware/arduino/avr/libraries/Bridge/Bridge.h +++ b/hardware/arduino/avr/libraries/Bridge/Bridge.h @@ -27,13 +27,6 @@ public: BridgeClass(Stream &_stream); void begin(); - // Methods to handle mailbox messages - unsigned int readMessage(uint8_t *buffer, unsigned int size); - void writeMessage(const uint8_t *buffer, unsigned int size); - void writeMessage(const String& str); - void writeJSON(const String& str); - 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); diff --git a/hardware/arduino/avr/libraries/Bridge/Mailbox.cpp b/hardware/arduino/avr/libraries/Bridge/Mailbox.cpp new file mode 100644 index 000000000..cf2b9e504 --- /dev/null +++ b/hardware/arduino/avr/libraries/Bridge/Mailbox.cpp @@ -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 + +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); diff --git a/hardware/arduino/avr/libraries/Bridge/Mailbox.h b/hardware/arduino/avr/libraries/Bridge/Mailbox.h new file mode 100644 index 000000000..35bd1d600 --- /dev/null +++ b/hardware/arduino/avr/libraries/Bridge/Mailbox.h @@ -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 + +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_ diff --git a/hardware/arduino/avr/libraries/Bridge/examples/Bridge/Bridge.ino b/hardware/arduino/avr/libraries/Bridge/examples/Bridge/Bridge.ino index df1e0697b..c7627b219 100644 --- a/hardware/arduino/avr/libraries/Bridge/examples/Bridge/Bridge.ino +++ b/hardware/arduino/avr/libraries/Bridge/examples/Bridge/Bridge.ino @@ -1,51 +1,50 @@ -#include +//#include +#include void setup() { pinMode(13,OUTPUT); digitalWrite(13, LOW); Bridge.begin(); - digitalWrite(13, HIGH); + digitalWrite(13, HIGH); + Serial.begin(9600); } void loop() { - while (Bridge.messageAvailable()) { - uint8_t buff[64]; - int l = Bridge.readMessage(buff, 64); - process(buff, l); + while (Mailbox.messageAvailable()) { + String msg; + Mailbox.readMessage(msg); + process(msg); } delay(100); // Poll every 0.100s } -void process(uint8_t buff[], int length) { - // "digital/13/1" -> digitalWrite(13, HIGH) +void process(String command) { + Serial.println(command); // "digital/13" -> digitalRead(13) + // "digital/13/1" -> digitalWrite(13, HIGH) // "analog/2/123" -> analogWrite(2, 123) // "analog/2" -> analogRead(2) // "mode/13/input" -> pinMode(13, INPUT) // "mode/13/output" -> pinMode(13, OUTPUT) - // Sanity check - if (length < 9 || length > 14) - return; - - // string terminator - buff[length] = '\0'; - - String command = String((char*)buff); - - // digital command - if (command.indexOf("digital/") == 0) { + // is digital command? + if (command.startsWith("digital/")) { + // extract subcommand (after the "/") command = command.substring(8); digitalCommand(command); - // analog command - } else if (command.indexOf("analog/") == 0) { + } + // is analog command? + else if (command.startsWith("analog/")) { + // extract subcommand (after the "/") command = command.substring(7); analogCommand(command); - - // mode command - } else if (command.indexOf("mode/") == 0) { + + } + // is mode command? + else if (command.startsWith("mode/")) { + // extract subcommand (after the "/") command = command.substring(5); modeCommand(command); } @@ -53,12 +52,27 @@ void process(uint8_t buff[], int length) { void digitalCommand(String command) { int pin, value; - if (command.indexOf("/") != -1) { - pin = command.substring(0, command.indexOf("/")).toInt(); - value = command.substring(command.indexOf("/") + 1, command.length()).toInt(); - digitalWrite(pin, value); - } else { + + // Find the position of the "/" inside the command + int slashIndex = command.indexOf("/"); + + // If there are no slashes + if (slashIndex == -1) { + // then we are in the following case: + // "digital/13" -> digitalRead(13) + + // so we can extract the pin number from the remainder of the command string pin = command.toInt(); + } + else { + // else, we found a slash, so we are in the following case: + // "digital/13/1" -> digitalWrite(13, HIGH) + + // we must estract pin number before the "/" + pin = command.substring(0, slashIndex).toInt(); + // and value after the "/" + value = command.substring(slashIndex+1).toInt(); + digitalWrite(pin, value); } reportDigitalRead(pin, true); } @@ -69,7 +83,8 @@ void analogCommand(String command) { pin = command.substring(0, command.indexOf("/")).toInt(); value = command.substring(command.indexOf("/") + 1, command.length()).toInt(); analogWrite(pin, value); - } else { + } + else { pin = command.toInt(); } reportAnalogRead(pin, true); @@ -83,7 +98,8 @@ void modeCommand(String command) { if (strValue == "output") { pinMode(pin, OUTPUT); reportPinMode(pin, strValue); - } else if (strValue == "input") { + } + else if (strValue == "input") { pinMode(pin, INPUT); reportPinMode(pin, strValue); } @@ -95,18 +111,18 @@ void reportPinMode(int pin, String mode) { json += ", \"mode\": \""; json += mode; json += "\"}"; - Bridge.writeJSON(json); + Mailbox.writeJSON(json); } void reportDigitalRead(int pin, boolean dataset) { int value = digitalRead(pin); - + String json = "{\"pin\":"; json += pin; json += ", \"value\": "; json += value; json += "}"; - Bridge.writeJSON(json); + Mailbox.writeJSON(json); if (dataset) { String key = "D"; @@ -117,13 +133,13 @@ void reportDigitalRead(int pin, boolean dataset) { void reportAnalogRead(int pin, boolean dataset) { int value = analogRead(pin); - + String json = "{\"pin\":"; json += pin; json += ", \"value\": "; json += value; json += "}"; - Bridge.writeJSON(json); + Mailbox.writeJSON(json); if (dataset) { String key = "A"; @@ -131,3 +147,4 @@ void reportAnalogRead(int pin, boolean dataset) { Bridge.put(key.c_str(), String(value).c_str()); } } +