Reputation: 517
I am building an arduino-powered Air Conditioner Remote. I have the actual IR remote trigger working with pusher.com, but now want to add xively feeds for the temperature in the room and the current status of the AC unit (on or off, read from the power LED using a photoresistor)
When I add in Xively code to the sketch and upload it, the arduino freezes. I've narrowed it down to int ret = xivelyclient.put(feed, xivelyKey); which calls the put function from the xively library. If you comment this line out, the pusher stuff runs as usual.
How do I make pusher and xively coexist? Are they competing for connections on the ethernet shield? (I thought I read that the ethernet shield could handle 4 simultaneous connections)
Code below:
#include <SPI.h>
#include <Ethernet.h>
#include <PusherClient.h>
#include <HttpClient.h>
#include <Xively.h>
byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xEE };
PusherClient client;
char xivelyKey[] = "myxivelykeyhere";
#define xivelyFeed 1454201282
int IRledPin = 8;
int sensorPin = 0;
// Define the strings for our datastream IDs
char sensorId[] = "temp";
XivelyDatastream datastreams[] = {
XivelyDatastream(sensorId, strlen(sensorId), DATASTREAM_FLOAT),
};
// Finally, wrap the datastreams into a feed
XivelyFeed feed(15552, datastreams, 1 /* number of datastreams */);
EthernetClient Eclient;
XivelyClient xivelyclient(Eclient);
void setup() {
pinMode(IRledPin,OUTPUT);
Serial.begin(9600);
Serial.println("I'm Alive");
if (Ethernet.begin(mac) == 0) {
Serial.println("Init Ethernet failed");
for(;;)
;
}
if(client.connect("336b1e021d66c95fad49")) {
client.bind("togglePower", togglePower);
client.subscribe("ac");
Serial.println("Connected!");
}
else {
while(1) {
}
Serial.println("Can't connect!!");
}
}
void loop() {
if (client.connected()) {
client.monitor();
}
int reading = analogRead(sensorPin);
float voltage = reading * 5.0;
voltage /= 1024.0;
float temperatureC = (voltage - 0.5) * 100 ;
float temperatureF = (temperatureC * 9.0 / 5.0) + 32.0;
Serial.print(temperatureF); Serial.println(" degrees F");
datastreams[0].setFloat(temperatureF);
Serial.println("Uploading it to Xively");
int ret = xivelyclient.put(feed, xivelyKey);
Serial.print("xivelyclient.put returned ");
// Serial.println(ret);
delay(8000);
}
void togglePower(String data) {
Serial.println("togglePower() was triggered");
pulseIR(8860);
delayMicroseconds(4360);
pulseIR(600);
delayMicroseconds(1580);
pulseIR(600);
delayMicroseconds(500);
pulseIR(600);
delayMicroseconds(480);
pulseIR(600);
delayMicroseconds(500);
pulseIR(600);
delayMicroseconds(480);
pulseIR(600);
delayMicroseconds(500);
pulseIR(600);
delayMicroseconds(500);
pulseIR(580);
delayMicroseconds(1600);
pulseIR(600);
delayMicroseconds(480);
pulseIR(600);
delayMicroseconds(1600);
pulseIR(600);
delayMicroseconds(1580);
pulseIR(600);
delayMicroseconds(500);
pulseIR(580);
delayMicroseconds(520);
pulseIR(580);
delayMicroseconds(1600);
pulseIR(600);
delayMicroseconds(1580);
pulseIR(600);
delayMicroseconds(500);
pulseIR(600);
delayMicroseconds(1580);
pulseIR(600);
delayMicroseconds(500);
pulseIR(580);
delayMicroseconds(500);
pulseIR(600);
delayMicroseconds(500);
pulseIR(600);
delayMicroseconds(500);
pulseIR(580);
delayMicroseconds(500);
pulseIR(600);
delayMicroseconds(500);
pulseIR(580);
delayMicroseconds(1600);
pulseIR(580);
delayMicroseconds(520);
pulseIR(580);
delayMicroseconds(1600);
pulseIR(600);
delayMicroseconds(1600);
pulseIR(520);
delayMicroseconds(1660);
pulseIR(520);
delayMicroseconds(1660);
pulseIR(520);
delayMicroseconds(1680);
pulseIR(580);
delayMicroseconds(1600);
pulseIR(520);
delayMicroseconds(580);
pulseIR(520);
delayMicroseconds(41480);
pulseIR(8840);
delayMicroseconds(2200);
pulseIR(540);
delayMicroseconds(28564);
pulseIR(8880);
delayMicroseconds(2140);
pulseIR(560);
}
void pulseIR(long microsecs) {
// we'll count down from the number of microseconds we are told to wait
cli(); // this turns off any background interrupts
while (microsecs > 0) {
// 38 kHz is about 13 microseconds high and 13 microseconds low
digitalWrite(IRledPin, HIGH); // this takes about 3 microseconds to happen
delayMicroseconds(10); // hang out for 10 microseconds
digitalWrite(IRledPin, LOW); // this also takes about 3 microseconds
delayMicroseconds(10); // hang out for 10 microseconds
// so 26 microseconds altogether
microsecs -= 26;
}
sei(); // this turns them back on
}
Upvotes: 0
Views: 1040
Reputation: 1
You should also consider using http://devicehub.net, they have a really simple HTTP api right now http://devicehub.net/about/api#api-guide and the platform is opensource as opposed to xively
Upvotes: 0
Reputation: 6912
Most likely your Arduino just runs out of RAM, you should measure it.
Alternatively you could:
send data to Xively without using the library (examples can be found in the Arduino IDE
under File –» Examples –» Ethernet –» (CosmClient, CosmClientString)
those are rather outdated but should still work okay, you might want to replace Cosm with Xively
stop using pusher and just use ws://api.xively.com:8080/
which should give you very
similar publish/subcribe functionality for channels or the entire device feeds
The 2nd solution will need a bit more work and a JSON parser. However, there is another option to use MQTT, for which you can use PubSub library that is shipped with Arduino IDE since at least v1.0. Unlike WebSoket endpoint, Xively's MQTT bridge doesn't require a JSON parser and CSV data format can be used with it. You can then use the WebSocket in a JavaScript app very easily, unless you have implemented a whole lot of stuff on Pusher alredy, I'd recommend to just use the MQTT for Xively/Arduino.
If you are still hitting some memory problem, you should measure the usage with the most basic example for each library you have included. For a quick and easy solution you could aways try using the Arduino Due, hopefully it would have more room for growth too.
Upvotes: 1