spacebrew update

This commit is contained in:
Federico Fissore 2013-08-07 17:16:13 +02:00
parent 8fd9b8f8ee
commit 7832a997cc
6 changed files with 473 additions and 64 deletions

View File

@ -1,35 +1,54 @@
/*
Input Output
Demonstrates how to create a sketch that sends and receives all standard
spacebrew data types, and a custom data type. Every time data is
received it is output to the Serial monitor.
Make sure that your Yun is connected to the internet for this example
to function properly.
The circuit:
- No circuit required
created 2013
by Julio Terra
This example code is in the public domain.
More information about Spacebrew is available at:
http://spacebrew.cc/
*/
#include <Bridge.h>
#include <SpacebrewYun.h>
/**
* Arduino Yun Spacebrew Library Example
*
* This example code is in the public domain.
*
* @date July 16, 2013
* @author Julio Terra
*
*/
// create a variable of type SpacebrewYun and initialize it with the constructor
SpacebrewYun sb = SpacebrewYun("aYun", "Arduino Yun spacebrew test");
int counter = 0;
// create variables to manage interval between each time we send a string
long last = 0;
int interval = 2000;
int counter = 0;
void setup() {
// start the serial port
Serial.begin(57600);
// for debugging, wait until a serial console is connected
delay(4000);
while (!Serial) { Serial.println("connecting"); }
while (!Serial) { ; }
//Initialize Console and wait for port to open:
// start-up the bridge
Bridge.begin();
Serial.println("Bridge Started");
Serial.println("Configuring Spacebrew Client");
// configure the spacebrew object to print status messages to serial
sb.verbose(true);
// configure the spacebrew publisher and subscriber
sb.addPublish("string test", "string");
sb.addPublish("range test", "range");
sb.addPublish("boolean test", "boolean");
@ -38,18 +57,27 @@ void setup() {
sb.addSubscribe("range test", "range");
sb.addSubscribe("boolean test", "boolean");
sb.addSubscribe("custom test", "crazy");
// register the string message handler method
sb.onRangeMessage(handleRange);
sb.onStringMessage(handleString);
sb.onBooleanMessage(handleBoolean);
sb.onCustomMessage(handleCustom);
// connect to cloud spacebrew server at "sandbox.spacebrew.cc"
sb.connect("sandbox.spacebrew.cc");
}
void loop() {
// monitor spacebrew connection for new data
sb.monitor();
// connected to spacebrew then send a string every 2 seconds
if ( sb.connected() ) {
// check if it is time to send a new message
if ( (millis() - last) > interval ) {
String test_str_msg = "testing, testing, ";
test_str_msg += counter;
@ -66,6 +94,8 @@ void loop() {
}
}
// define handler methods, all standard data type handlers take two appropriate arguments
void handleRange (String route, int value) {
Serial.print("Range msg ");
Serial.print(route);
@ -87,6 +117,8 @@ void handleBoolean (String route, boolean value) {
Serial.println(value ? "true" : "false");
}
// custom data type handlers takes three String arguments
void handleCustom (String route, String value, String type) {
Serial.print("Custom msg ");
Serial.print(route);

View File

@ -0,0 +1,89 @@
/*
Spacebrew Boolean
Demonstrates how to create a sketch that sends and receives a
boolean value to and from Spacebrew. Every time the buttton is
pressed (or other digital input component) a spacebrew message
is sent. The sketch also accepts analog range messages from
other Spacebrew apps.
Make sure that your Yun is connected to the internet for this example
to function properly.
The circuit:
- Button connected to Yun, using the Arduino's internal pullup resistor.
created 2013
by Julio Terra
This example code is in the public domain.
More information about Spacebrew is available at:
http://spacebrew.cc/
*/
#include <Bridge.h>
#include <SpacebrewYun.h>
// create a variable of type SpacebrewYun and initialize it with the constructor
SpacebrewYun sb = SpacebrewYun("spacebrewYun Boolean", "Boolean sender and receiver");
// variable that holds the last potentiometer value
int last_value = 0;
// create variables to manage interval between each time we send a string
void setup() {
// start the serial port
Serial.begin(57600);
// for debugging, wait until a serial console is connected
delay(4000);
while (!Serial) { ; }
// start-up the bridge
Bridge.begin();
// configure the spacebrew object to print status messages to serial
sb.verbose(true);
// configure the spacebrew publisher and subscriber
sb.addPublish("physical button", "boolean");
sb.addSubscribe("virtual button", "boolean");
// register the string message handler method
sb.onBooleanMessage(handleBoolean);
// connect to cloud spacebrew server at "sandbox.spacebrew.cc"
sb.connect("sandbox.spacebrew.cc");
pinMode(3, INPUT);
digitalWrite(3, HIGH);
}
void loop() {
// monitor spacebrew connection for new data
sb.monitor();
// connected to spacebrew then send a new value whenever the pot value changes
if ( sb.connected() ) {
int cur_value = digitalRead(3);
if ( last_value != cur_value ) {
if (cur_value == HIGH) sb.send("physical button", false);
else sb.send("physical button", true);
last_value = cur_value;
}
}
}
// handler method that is called whenever a new string message is received
void handleBoolean (String route, boolean value) {
// print the message that was received
Serial.print("From ");
Serial.print(route);
Serial.print(", received msg: ");
Serial.println(value ? "true" : "false");
}

View File

@ -0,0 +1,86 @@
/*
Spacebrew Range
Demonstrates how to create a sketch that sends and receives analog
range value to and from Spacebrew. Every time the state of the
potentiometer (or other analog input component) change a spacebrew
message is sent. The sketch also accepts analog range messages from
other Spacebrew apps.
Make sure that your Yun is connected to the internet for this example
to function properly.
The circuit:
- Potentiometer connected to Yun. Middle pin connected to analog pin A0,
other pins connected to 5v and GND pins.
created 2013
by Julio Terra
This example code is in the public domain.
More information about Spacebrew is available at:
http://spacebrew.cc/
*/
#include <Bridge.h>
#include <SpacebrewYun.h>
// create a variable of type SpacebrewYun and initialize it with the constructor
SpacebrewYun sb = SpacebrewYun("spacebrewYun Range", "Range sender and receiver");
// variable that holds the last potentiometer value
int last_value = 0;
// create variables to manage interval between each time we send a string
void setup() {
// start the serial port
Serial.begin(57600);
// for debugging, wait until a serial console is connected
delay(4000);
while (!Serial) { ; }
// start-up the bridge
Bridge.begin();
// configure the spacebrew object to print status messages to serial
sb.verbose(true);
// configure the spacebrew publisher and subscriber
sb.addPublish("physical pot", "range");
sb.addSubscribe("virtual pot", "range");
// register the string message handler method
sb.onRangeMessage(handleRange);
// connect to cloud spacebrew server at "sandbox.spacebrew.cc"
sb.connect("sandbox.spacebrew.cc");
}
void loop() {
// monitor spacebrew connection for new data
sb.monitor();
// connected to spacebrew then send a new value whenever the pot value changes
if ( sb.connected() ) {
int cur_value = analogRead(A0);
if ( last_value != cur_value ) {
sb.send("physical pot", cur_value);
last_value = cur_value;
}
}
}
// handler method that is called whenever a new string message is received
void handleRange (String route, int value) {
// print the message that was received
Serial.print("From ");
Serial.print(route);
Serial.print(", received msg: ");
Serial.println(value);
}

View File

@ -0,0 +1,84 @@
/*
Spacebrew String
Demonstrates how to create a sketch that sends and receives strings
to and from Spacebrew. Every time string data is received it
is output to the Serial monitor.
Make sure that your Yun is connected to the internet for this example
to function properly.
The circuit:
- No circuit required
created 2013
by Julio Terra
This example code is in the public domain.
More information about Spacebrew is available at:
http://spacebrew.cc/
*/
#include <Bridge.h>
#include <SpacebrewYun.h>
// create a variable of type SpacebrewYun and initialize it with the constructor
SpacebrewYun sb = SpacebrewYun("spacebrewYun Strings", "String sender and receiver");
// create variables to manage interval between each time we send a string
long last_time = 0;
int interval = 2000;
void setup() {
// start the serial port
Serial.begin(57600);
// for debugging, wait until a serial console is connected
delay(4000);
while (!Serial) { ; }
// start-up the bridge
Bridge.begin();
// configure the spacebrew object to print status messages to serial
sb.verbose(true);
// configure the spacebrew publisher and subscriber
sb.addPublish("speak", "string");
sb.addSubscribe("listen", "string");
// register the string message handler method
sb.onStringMessage(handleString);
// connect to cloud spacebrew server at "sandbox.spacebrew.cc"
sb.connect("sandbox.spacebrew.cc");
}
void loop() {
// monitor spacebrew connection for new data
sb.monitor();
// connected to spacebrew then send a string every 2 seconds
if ( sb.connected() ) {
// check if it is time to send a new message
if ( (millis() - last_time) > interval ) {
sb.send("speak", "is anybody out there?");
last_time = millis();
}
}
}
// handler method that is called whenever a new string message is received
void handleString (String route, String value) {
// print the message that was received
Serial.print("From ");
Serial.print(route);
Serial.print(", received msg: ");
Serial.println(value);
}

View File

@ -4,6 +4,8 @@
SpacebrewYun::SpacebrewYun(const String& _name, const String& _description) {
name = _name;
description = _description;
subscribers = NULL;
publishers = NULL;
server = "sandbox.spacebrew.cc";
port = 9000;
@ -18,8 +20,6 @@ SpacebrewYun::SpacebrewYun(const String& _name, const String& _description) {
read_name = false;
read_msg = false;
sub_name_max = 25;
sub_msg_max = 50;
for ( int i = 0; i < pidLength; i++ ) {
pid [i] = '\0';
@ -33,7 +33,10 @@ SpacebrewYun::SpacebrewYun(const String& _name, const String& _description) {
}
// boolean SpacebrewYun::_connected = false;
int SpacebrewYun::sub_msg_int_max = 6;
int SpacebrewYun::sub_msg_bool_max = 5;
int SpacebrewYun::sub_msg_str_max = 50;
int SpacebrewYun::sub_name_max = 20;
SpacebrewYun::OnBooleanMessage SpacebrewYun::_onBooleanMessage = NULL;
SpacebrewYun::OnRangeMessage SpacebrewYun::_onRangeMessage = NULL;
SpacebrewYun::OnStringMessage SpacebrewYun::_onStringMessage = NULL;
@ -65,40 +68,57 @@ void SpacebrewYun::onError(OnSBError function){
}
void SpacebrewYun::addPublish(const String& name, const String& type) {
Publisher *p = new Publisher();
struct Publisher *p = new Publisher();
p->name = createString(name.length() + 1);
p->type = createString(type.length() + 1);
p->confirmed = false;
p->time = 0;
if (type == "range") {
p->lastMsg = createString(sub_msg_int_max);
emptyString(p->lastMsg, sub_msg_int_max);
}
else if (type == "boolean") {
p->lastMsg = createString(sub_msg_bool_max);
emptyString(p->lastMsg, sub_msg_bool_max);
}
else {
p->lastMsg = createString(sub_msg_str_max);
emptyString(p->lastMsg, sub_msg_str_max);
}
name.toCharArray(p->name, name.length() + 1);
type.toCharArray(p->type, type.length() + 1);
if (publishers == NULL){
publishers = p;
} else {
Publisher *curr = publishers;
}
else {
struct Publisher *curr = publishers;
int counter = 1;
while(curr->next != NULL){
curr = curr->next;
counter++;
}
curr->next = p;
}
p->next = NULL;
}
void SpacebrewYun::addSubscribe(const String& name, const String& type) {
Subscriber *p = new Subscriber();
p->name = createString(name.length() + 1);
p->type = createString(type.length() + 1);
name.toCharArray(p->name, name.length() + 1);
type.toCharArray(p->type, type.length() + 1);
Subscriber *s = new Subscriber();
s->name = createString(name.length() + 1);
s->type = createString(type.length() + 1);
name.toCharArray(s->name, name.length() + 1);
type.toCharArray(s->type, type.length() + 1);
if (subscribers == NULL){
subscribers = p;
subscribers = s;
}
else {
Subscriber *curr = subscribers;
struct Subscriber *curr = subscribers;
while(curr->next != NULL){
curr = curr->next;
}
curr->next = p;
curr->next = s;
}
}
@ -108,8 +128,9 @@ void SpacebrewYun::connect(String _server, int _port) {
killPids();
brew.begin("python"); // Process should launch the "curl" command
brew.addParameter("/usr/lib/python2.7/spacebrew/spacebrew.py"); // Process should launch the "curl" command
brew.begin("run-spacebrew"); // Process should launch the "curl" command
// brew.begin("python"); // Process should launch the "curl" command
// brew.addParameter("/usr/lib/python2.7/spacebrew/spacebrew.py"); // Process should launch the "curl" command
brew.addParameter("--server");
brew.addParameter(server);
brew.addParameter("--port");
@ -120,11 +141,13 @@ void SpacebrewYun::connect(String _server, int _port) {
brew.addParameter(description);
if (subscribers != NULL) {
Subscriber *curr = subscribers;
struct Subscriber *curr = subscribers;
while(curr != NULL){
if (_verbose) {
Serial.print(F("Creating subcribers: "));
Serial.println(curr->name);
Serial.print(F("Creating subscribers: "));
Serial.print(curr->name);
Serial.print(F(" of type: "));
Serial.println(curr->type);
}
brew.addParameter("-s"); // Add the URL parameter to "curl"
@ -132,29 +155,40 @@ void SpacebrewYun::connect(String _server, int _port) {
brew.addParameter(","); // Add the URL parameter to "curl"
brew.addParameter(curr->type); // Add the URL parameter to "curl"
if (curr->next == NULL) curr = NULL;
else curr = curr->next;
// if (curr->next == NULL) curr = NULL;
// else curr = curr->next;
curr = curr->next;
}
}
if (publishers != NULL) {
Publisher *curr = publishers;
struct Publisher *curr = publishers;
while(curr != NULL){
if (_verbose) {
Serial.print(F("Creating publishers: "));
Serial.println(curr->name);
Serial.print(curr->name);
Serial.print(F(" of type: "));
Serial.println(curr->type);
}
brew.addParameter("-p"); // Add the URL parameter to "curl"
brew.addParameter(curr->name); // Add the URL parameter to "curl"
brew.addParameter(","); // Add the URL parameter to "curl"
brew.addParameter(curr->type); // Add the URL parameter to "curl"
if (curr->next == NULL) curr = NULL;
else curr = curr->next;
curr = curr->next;
}
}
Console.begin();
if (_verbose) {
Serial.println(F("Console started "));
}
brew.runAsynchronously();
if (_verbose) {
Serial.println(F("Brew started "));
}
while (!Console) { ; }
}
@ -163,7 +197,6 @@ void SpacebrewYun::monitor() {
char c = Console.read();
if (c == char(CONNECTION_START) && !_connected) {
_connected = true;
if (_verbose) {
Serial.print(F("Connected to spacebrew server at: "));
Serial.println(server);
@ -173,6 +206,7 @@ void SpacebrewYun::monitor() {
if (_onOpen != NULL){
_onOpen();
}
_connected = true;
}
else if (c == char(CONNECTION_END) && _connected) {
_connected = false;
@ -205,12 +239,24 @@ void SpacebrewYun::monitor() {
} else if (c == char(MSG_DIV) || sub_name.length() > sub_name_max) {
read_name = false;
read_msg = true;
} else if (c == char(MSG_END) || sub_msg.length() > sub_msg_max) {
read_msg = false;
onMessage();
} else if (c == char(MSG_END) || sub_msg.length() > sub_msg_str_max) {
if (read_msg == true) {
read_msg = false;
onMessage();
// delay(2);
}
if (read_confirm == true) {
read_confirm = false;
onConfirm();
delay(2);
}
} else if (c == char(MSG_CONFIRM)) {
read_confirm = true;
} else {
if (read_name == true) {
sub_name += c;
} else if (read_confirm == true) {
sub_name += c;
} else if (read_msg == true) {
sub_msg += c;
}
@ -220,6 +266,43 @@ void SpacebrewYun::monitor() {
}
}
}
if (publishers != NULL) {
struct Publisher *curr = publishers;
while((curr != NULL)){
if ( (curr->confirmed == 0) && ((millis() - curr->time) > 50) ) {
if (_verbose) {
Serial.print(F("resending msg: "));
Serial.println(curr->name);
}
send(curr->name, curr->lastMsg);
}
curr = curr->next;
}
}
}
void SpacebrewYun::onConfirm() {
if (publishers != NULL) {
struct Publisher *curr = publishers;
while((curr != NULL)){
if (sub_name.equals(curr->name) == true) {
curr->confirmed = true;
// if (_verbose) {
// Serial.print(F("confirmed "));
// Serial.println(curr->name);
// }
break;
}
curr = curr->next;
}
}
sub_name = "";
sub_msg = "";
sub_type = "";
}
boolean SpacebrewYun::connected() {
@ -232,13 +315,12 @@ void SpacebrewYun::verbose(boolean verbose = true) {
void SpacebrewYun::onMessage() {
if (subscribers != NULL) {
Subscriber *curr = subscribers;
struct Subscriber *curr = subscribers;
while((curr != NULL) && (sub_type == "")){
if (sub_name.equals(curr->name) == true) {
sub_type = curr->type;
}
if (curr->next == NULL) curr = NULL;
else curr = curr->next;
curr = curr->next;
}
}
@ -275,14 +357,34 @@ void SpacebrewYun::onMessage() {
void SpacebrewYun::send(const String& name, const String& value){
Console.print(char(29));
Console.print(name);
Console.print(char(30));
Console.print(value);
Console.print(char(31));
Console.flush();
if (publishers != NULL) {
true;
Console.print(char(29));
Console.print(name);
Console.print(char(30));
Console.print(value);
Console.print(char(31));
Console.flush();
struct Publisher *curr = publishers;
while(curr != NULL){
if (name.equals(curr->name) == true) {
int msg_len = 0;
if (curr->type == "range") msg_len = sub_msg_int_max;
else if (curr->type == "boolean") msg_len = sub_msg_bool_max;
else msg_len = sub_msg_str_max;
if (value.length() < msg_len) msg_len = value.length() + 1;
value.toCharArray(curr->lastMsg, msg_len);
curr->confirmed = false;
curr->time = millis();
}
curr = curr->next;
}
}
}
@ -292,8 +394,9 @@ void SpacebrewYun::send(const String& name, const String& value){
void SpacebrewYun::getPids() {
// request the pid of all python processes
// brew.begin("run-getsbpids"); // Process should launch the "curl" command
pids.begin("python");
pids.addParameter("/usr/lib/python2.7/spacebrew/getProcPid.py"); // Process should launch the "curl" command
pids.addParameter("/usr/lib/python2.7/spacebrew/getprocpid.py"); // Process should launch the "curl" command
pids.run();
if (_verbose) {

View File

@ -11,6 +11,7 @@ enum SBmsg {
CONNECTION_START = char(28),
CONNECTION_END = char(27),
CONNECTION_ERROR = char(26),
MSG_CONFIRM = char(7),
MSG_START = char(29),
MSG_DIV = char(30),
MSG_END = char(31)
@ -19,14 +20,16 @@ enum SBmsg {
struct Publisher {
char *name;
char *type;
char *defaultValue;
Publisher * next;
char *lastMsg;
Publisher *next;
int confirmed;
long time;
};
struct Subscriber{
char *name;
char *type;
Subscriber * next;
Subscriber *next;
};
int const pidLength = 6;
@ -46,12 +49,13 @@ class SpacebrewYun {
void monitor();
void onMessage();
void onConfirm();
boolean connected();
void send(const String&, const String&);
void send(const String& name, char * value) { send(name, String(value)); }
void send(const String& name, bool value){ send(name, (value ? "true" : "false")); };
void send(const String& name, bool value){ send(name, (value ? String("true") : String("false"))); };
void send(const String& name, int value) { send(name, String(value)); };
void send(const String& name, long value) { send(name, String(value)); };
void send(const String& name, float value) { send(name, String(value)); };
@ -102,8 +106,13 @@ class SpacebrewYun {
boolean read_name;
boolean read_msg;
int sub_name_max;
int sub_msg_max;
boolean read_confirm;
static int sub_name_max;
static int sub_msg_str_max;
static int sub_msg_int_max;
static int sub_msg_bool_max;
// int sub_name_max;
// int sub_msg_str_max;
Process pids;
char pid [6];
@ -113,10 +122,16 @@ class SpacebrewYun {
void getPids();
static char * createString(int len){
char * out = ( char * )malloc( len + 1 );
char * out = ( char * ) malloc ( len + 1 );
return out;
}
static void emptyString(char * str, int len){
for (int i = 0; i < len; i++) {
str[i] = '\0';
}
}
};
#endif