Pachube and WiShield

Discussion about any of the included sketches (i.e. WebServer), or user-generated applications.

Re: Pachube and WiShield

Postby GregEigsti » Fri Sep 04, 2009 6:28 pm

Threw the code that I wrote last night into the Win32 service that gathers the home power usage data so that it now also logs to Pachube. Not quite WiShield logging directly to Pachube but a WiShield and Pachube are involved ;)

http://www.pachube.com/feeds/2557

Also just got my outside WX feeds hooked up (outside temp, air pressure)

http://www.pachube.com/feeds/2555

Greg
Check out the wiki!
uIP Stack Docs
Compatible Access Point List
WiShield user contrib branch - DNS, DHCP, AP Scanning, bug fixes, etc.
SlackLab.org - My geek projects blog.
User avatar
GregEigsti
 
Posts: 955
Joined: Sun Aug 02, 2009 5:23 pm
Location: Sammamish WA USA (near Seattle)

Re: Pachube and WiShield

Postby GregEigsti » Sun Sep 06, 2009 1:03 pm

mbdtsmo (or anyone else who is interested), if you have a chance give the following sketch a try. I am unable to try it myself right now and it is a bit of a hack - but it requires no changes to the WiShield / WiServer code. Of course there are some things that you'll have to change to get this working in your environment. ;)

The "magic" occurs when setting the hostName and url strings; basically I am overloading hostName to fill in the "extra" stuff that Pachube wants in the POST header - I also added ?_method=put to the end of the url string to make Pachube accept the POST as a PUT. I have no idea if this will work but its worth a try. I did muck about with the Mac code that I previously wrote and found that Pachube is not sensitive to the order of the items in the header so it may just work (unless the WiShield / WiServer code does not like such overloading).

Things you will need to change
- The WiShield header apps-conf.h - make sure that #define APP_WISERVER is uncommented (and the others are commented)
- WiShield net settings in the sketch below to match your particular wireless settings
- Change YOUR_PACHUBE_API_KEY to your actual Pachube API key in hostName
- Change the feed number to your feed number in url; currently set to 2556 (one of mine)
- Finally the feedData() function should be made dynamic; currently just has hardcoded value(s)

Code: Select all
/*
* A simple sketch that uses WiServer to PUT (via POST) to Pachube
*/

#include <WiServer.h>

#define WIRELESS_MODE_INFRA   1
#define WIRELESS_MODE_ADHOC   2

// Wireless configuration parameters ----------------------------------------
unsigned char local_ip[] = {192,168,1,2};   // IP address of WiShield
unsigned char gateway_ip[] = {192,168,1,1};   // router or gateway IP address
unsigned char subnet_mask[] = {255,255,255,0};   // subnet mask for the local network
const prog_char ssid[] PROGMEM = {"ASYNCLABS"};      // max 32 bytes

unsigned char security_type = 0;   // 0 - open; 1 - WEP; 2 - WPA; 3 - WPA2

// WPA/WPA2 passphrase
const prog_char security_passphrase[] PROGMEM = {"12345678"};   // max 64 characters

// WEP 128-bit keys
// sample HEX keys
prog_uchar wep_keys[] PROGMEM = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,   // Key 0
              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,   // Key 1
              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,   // Key 2
              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00   // Key 3
            };

// setup the wireless mode
// infrastructure - connect to AP
// adhoc - connect to another WiFi device
unsigned char wireless_mode = WIRELESS_MODE_INFRA;
unsigned char ssid_len;
unsigned char security_passphrase_len;
// End of wireless configuration parameters ----------------------------------------


// Function that prints data from the server
void printData(char* data, int len) {
 
  // Print the data returned by the server
  // Note that the data is not null-terminated, may be broken up into smaller packets, and
  // includes the HTTP header.
  while (len-- > 0) {
    Serial.print(*(data++));
  }
}

//body data function, provides data for the POST command in comma separated values (CSV)
//currently POSTs one value but more can be added by separating with commas (no spaces)
//Your program will not want to use the hardcoded values below, rather it would read the
//sensor(s) and build the data string shown below.
void feedData()
{
   //e.g. a single value
   WiServer.print("21");
   //e.g. two values
   //WiServer.print("21,42");
}

// IP Address for Pachube.com 
uint8 ip[] = {209,40,205,190};
char hostName[] = "www.pachube.com\nX-PachubeApiKey: YOUR_PACHUBE_API_KEY\nConnection: close";
char url[] = "/api/2556.csv?_method=put";

// A request that POSTS data to Pachube
POSTrequest postPachube(ip, 80, hostName, url, feedData);


void setup() {
    // Initialize WiServer (we'll pass NULL for the page serving function since we don't need to serve web pages)
  WiServer.init(NULL);
 
  // Enable Serial output and ask WiServer to generate log messages (optional)
  Serial.begin(9600);
  WiServer.enableVerboseMode(true);

  // Have the printData function called when data is returned by the server
  postPachube.setReturnFunc(printData);
}


// Time (in millis) when the data should be retrieved
long updateTime = 0;

void loop(){

  // Check if it's time to get an update
  if (millis() >= updateTime) {
    postPachube.submit();   
    // Get another update one minute from now
    updateTime += 1000 * 60;
  }
 
  // Run WiServer
  WiServer.server_task();
  delay(10);
}
Check out the wiki!
uIP Stack Docs
Compatible Access Point List
WiShield user contrib branch - DNS, DHCP, AP Scanning, bug fixes, etc.
SlackLab.org - My geek projects blog.
User avatar
GregEigsti
 
Posts: 955
Joined: Sun Aug 02, 2009 5:23 pm
Location: Sammamish WA USA (near Seattle)

Re: Pachube and WiShield

Postby GregEigsti » Fri Sep 18, 2009 4:02 pm

Had a new WiShield and Arduino waiting for me when I got home - so I tried this Pachube sketch out and it works! Am working on an update to the sketch which uses a light sensor, thermistor and is based upon a timer. Will post it when I am happy with it; but the above sketch basically works!

Greg
Check out the wiki!
uIP Stack Docs
Compatible Access Point List
WiShield user contrib branch - DNS, DHCP, AP Scanning, bug fixes, etc.
SlackLab.org - My geek projects blog.
User avatar
GregEigsti
 
Posts: 955
Joined: Sun Aug 02, 2009 5:23 pm
Location: Sammamish WA USA (near Seattle)

Re: Pachube and WiShield

Postby GregEigsti » Sun Sep 20, 2009 9:39 pm

Here is the updated Pachube sketch; cleaned up a bit and now grabbing values from two analog pins (0, 5) connected to a light sensor and a temperature sensor (thermistor). Its all sitting down in the TV room running and posting once a minute via the WiShield. The same notes above for the original sketch apply.

I noticed that the light sensor (my first time playing with one) gives less resistance in a darker room (higher AD value) and more resistance in a lighter room (lower AD value). This seems counterintuitive as I would like to see lower values for less light and greater values for more light; this is easily corrected by subtracting the "light" value from 1024 (max AD value).

My Pachube feed page that is being fed by this sketch
http://www.pachube.com/feeds/2556

Code: Select all
/*
* A simple sketch that uses WiServer to PUT (via POST) to Pachube
*/

#include <WiServer.h>
#include <MsTimer2.h> 
#include <math.h>

//Wireless configuration defines ----------------------------------------
#define WIRELESS_MODE_INFRA   1
#define WIRELESS_MODE_ADHOC   2

//Wireless configuration parameters ----------------------------------------
unsigned char local_ip[]       = {192,168,1,2};  // IP address of WiShield
unsigned char gateway_ip[]     = {192,168,1,1};     // router or gateway IP address
unsigned char subnet_mask[]    = {255,255,255,0}; // subnet mask for the local network
const prog_char ssid[] PROGMEM = {"SSID"};    // max 32 bytes
unsigned char security_type    = 0;               // 0 - open; 1 - WEP; 2 - WPA; 3 - WPA2
// WPA/WPA2 passphrase
const prog_char security_passphrase[] PROGMEM = {"12345678"};   // max 64 characters
// WEP 128-bit keys
prog_uchar wep_keys[] PROGMEM = {
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Key 0
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Key 1
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Key 2
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; // Key 3
// setup the wireless mode
// infrastructure - connect to AP
// adhoc - connect to another WiFi device
unsigned char wireless_mode = WIRELESS_MODE_INFRA;
unsigned char ssid_len;
unsigned char security_passphrase_len;
// End of wireless configuration parameters ----------------------------------------

//non WiShield defines
//#define DEBUG_PRINT
#define TEMPERATURE_PIN 5
#define LIGHT_PIN       0

//global state data
boolean intTimer;
int temperature;
int light;
// IP Address for Pachube.com 
uint8 ip[] = {209,40,205,190};
char hostName[] = "www.pachube.com\nX-PachubeApiKey: YOUR_PACHUBE_API_KEY\nConnection: close";
char url[] = "/api/YOUR_PACHUBE_FEED.csv?_method=put";
// A request that POSTS data to Pachube
POSTrequest postPachube(ip, 80, hostName, url, feedData);


//MsTimer2 one minute timer ISR
void timerISR() {
   intTimer = true;
}

// Function that prints data from the server
void printData(char* data, int len) {
   // Print the data returned by the server
   // Note that the data is not null-terminated, may be broken up into smaller packets, and
   // includes the HTTP header.
#ifdef DEBUG_PRINT
   while (len-- > 0) {
      Serial.print(*(data++));
   }
#endif //DEBUG_PRINT
}

//body data function, provides data for the POST command in comma separated values (CSV)
//currently POSTs one value but more can be added by separating with comma (no spaces)
//Your program will not want to use the hardcoded values below, rather it would read the
//sensor(s) and build the data string shown below.
void feedData()
{
   char buf[16];
   sprintf(buf, "%d,%d", temperature, light);
   WiServer.print(buf);
}

void setup()
{   
   temperature = 0;
   light = 0;

   //setup the analog pins as input, probly redundant
   pinMode(TEMPERATURE_PIN, INPUT);
   pinMode(LIGHT_PIN, INPUT);

   // Initialize WiServer (we'll pass NULL for the page serving function since we don't need to serve web pages)
   WiServer.init(NULL);

   // Enable Serial output and ask WiServer to generate log messages (optional)
#ifdef DEBUG_PRINT
   Serial.begin(9600);
   //WiServer.enableVerboseMode(true);
#endif //DEBUG_PRINT

   // Have the processData function called when data is returned by the server
   postPachube.setReturnFunc(printData);

   //set up global state data
   intTimer = false;

   //setup the timerISR to be called every minute
   MsTimer2::set(60000, timerISR); // 60000ms/1min period
   MsTimer2::start();
}


void loop()
{
   //--------------------------------------------------------------------------------------------
   //handle the timer overflow
   //--------------------------------------------------------------------------------------------
   if(true == intTimer) {
      //one minute has passed
      intTimer = false;
      temperature = convertTemp(analogRead(TEMPERATURE_PIN));
      light = 1024 - analogRead(LIGHT_PIN);
#ifdef DEBUG_PRINT
      Serial.print("===== intTimer fired: temperature ");
      Serial.print(temperature, DEC);
      Serial.print("F, light ");
      Serial.println(light, DEC);
#endif //DEBUG_PRINT
      postPachube.submit();   
   }

   // Run WiServer
   WiServer.server_task();

   delay(10);
}

/*
http://www.arduino.cc/playground/ComponentLib/Thermistor2

(Ground) ---- (10k-Resistor) -------|------- (Thermistor) ---- (+5v)
                                     |
                                Analog Pin 0
*/

int convertTemp(int value)
{
   double temp;
   temp = log(((10240000 / value) - 10000));
   temp = 1 / (0.001129148 + (0.000234125 * temp) + (0.0000000876741 * temp * temp * temp));
   temp = temp - 273.15;            // Convert Kelvin to Celcius
   temp = (temp * 9.0) / 5.0 + 32.0; // Convert Celcius to Fahrenheit
   return (int)temp;
}

/*
http://www.libelium.com/squidbee/index.php?title=Adding_a_light_sensor

(Ground) ---- (Light Sensor) -------|------- (1k-Resistor) ---- (+5v)
                                     |
                                Analog Pin 0
*/


Greg
Check out the wiki!
uIP Stack Docs
Compatible Access Point List
WiShield user contrib branch - DNS, DHCP, AP Scanning, bug fixes, etc.
SlackLab.org - My geek projects blog.
User avatar
GregEigsti
 
Posts: 955
Joined: Sun Aug 02, 2009 5:23 pm
Location: Sammamish WA USA (near Seattle)

Re: Pachube and WiShield

Postby Chief Robot » Sat Oct 17, 2009 11:11 am

Nice work Greg. I decided to try Pachube as well and have got it running, but it needs a little tweaking.
I'm not familiar with sprintf. Can you explain this in your code:
void feedData()
{
char buf[16];
sprintf(buf, "%d,%d", temperature, light);
WiServer.print(buf);
}

I have my temperature already in variable x.

Can I just use WiServer.print(x); ?

Thanks!
User avatar
Chief Robot
 
Posts: 36
Joined: Thu May 07, 2009 10:47 am

Re: Pachube and WiShield

Postby GregEigsti » Sat Oct 17, 2009 11:31 am

Can I just use WiServer.print(x); ?

For a single value you sure can. sprintf is like printf except that it puts the "new string" into the buffer that you supply (rather than printing it out). In my case I am sending two values to Pachube each time and they must be sent as comma separated values.

Code: Select all
//this is just a storage buffer, somewhere where we can stick some bytes...
char buf[16];
//in this sprintf use the following "happens" - think of it as kind of a search and replace
//1 - the results end up in buf
//2 - the "%d,%d" gets turned into an array of characters; two numbers separated by a comma (and ends up in buf)
//3 - %d tells sprintf to replace me with the string equivalent of a decimal value
//4 - the first %d is replaced with the first "data variable", in this case "temperature", the second with "light"
sprintf(buf, "%d,%d", temperature, light);
//now use WiServer to send our string
WiServer.print(buf);

//so if you did the following (assuming buf is big enough to hold it all)
sprintf(buf, "My favorite numbers are %d and %d", 100, 200);
Serial.println(buf)
//you would get this printed
My favorite numbers are 100 and 200


sprintf is a very useful function, you can read more about it at:
http://www.nongnu.org/avr-libc/user-manual/group__avr__stdio.html#g6017094d9fd800fa02600d35399f2a2a

Greg
Check out the wiki!
uIP Stack Docs
Compatible Access Point List
WiShield user contrib branch - DNS, DHCP, AP Scanning, bug fixes, etc.
SlackLab.org - My geek projects blog.
User avatar
GregEigsti
 
Posts: 955
Joined: Sun Aug 02, 2009 5:23 pm
Location: Sammamish WA USA (near Seattle)

Re: Pachube and WiShield

Postby mylesleadbeatter » Mon Feb 22, 2010 3:08 pm

Ahoy there Gregg!
Ive just tried uploading your sketch for pachube using an LDR, set up my account ( Pachube is a rather exciting service i must say) put in my details for the network etc and the sketch is compiling but for some reason my feed is not being updated and the serial monitor on the arduino is empty :( . Ive commented out the temperature things in the sketch because i dont have a thermistor to hand. Just wondering if you knew what could be going on.
When i set up my feed in pachube i chose manual and NOT automatic so that i push using put - is that the correct practice?
Your not running processing alongside on a computer i take it?
In short i need a spot of help.



Code: Select all
/*
* A simple sketch that uses WiServer to PUT (via POST) to Pachube
*/

#include <WiServer.h>
#include <MsTimer2.h> 
#include <math.h>

//Wireless configuration defines ----------------------------------------
#define WIRELESS_MODE_INFRA   1
#define WIRELESS_MODE_ADHOC   2

// Wireless configuration parameters ----------------------------------------
unsigned char local_ip[] = {192,168,1,20};   // IP address of WiShield
unsigned char gateway_ip[] = {192,168,1,1};   // router or gateway IP address
unsigned char subnet_mask[] = {255,255,255,0};   // subnet mask for the local network
const prog_char ssid[] PROGMEM = {"lolathon"};      // max 32 bytes

unsigned char security_type = 0;   // 0 - open; 1 - WEP; 2 - WPA; 3 - WPA2

// WPA/WPA2 passphrase
const prog_char security_passphrase[] PROGMEM = {"12345678"};   // max 64 characters
// WEP 128-bit keys
prog_uchar wep_keys[] PROGMEM = {
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Key 0
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Key 1
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Key 2
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; // Key 3
// setup the wireless mode
// infrastructure - connect to AP
// adhoc - connect to another WiFi device
unsigned char wireless_mode = WIRELESS_MODE_ADHOC;
unsigned char ssid_len;
unsigned char security_passphrase_len;
// End of wireless configuration parameters ----------------------------------------

//non WiShield defines
//#define DEBUG_PRINT
//#define TEMPERATURE_PIN 5
#define LIGHT_PIN       0

//global state data
boolean intTimer;
//int temperature;
int light;
// IP Address for Pachube.com 
uint8 ip[] = {209,40,205,190};
char hostName[] = "www.pachube.com\nX-PachubeApiKey: a1ee945349e1ecd25d745ca8d03306e7396053be***********************\nConnection: close";
char url[] = "/api/5860.csv?_method=put";
// A request that POSTS data to Pachube
POSTrequest postPachube(ip, 80, hostName, url, feedData);


//MsTimer2 one minute timer ISR
void timerISR() {
   intTimer = true;
}

// Function that prints data from the server
void printData(char* data, int len) {
   // Print the data returned by the server
   // Note that the data is not null-terminated, may be broken up into smaller packets, and
   // includes the HTTP header.
#ifdef DEBUG_PRINT
   while (len-- > 0) {
      Serial.print(*(data++));
   }
#endif //DEBUG_PRINT
}

//body data function, provides data for the POST command in comma separated values (CSV)
//currently POSTs one value but more can be added by separating with comma (no spaces)
//Your program will not want to use the hardcoded values below, rather it would read the
//sensor(s) and build the data string shown below.
void feedData()
{
   char buf[16];
   sprintf(buf, "%d", light);
   WiServer.print(buf);
}

void setup()
{   
  // temperature = 0;
   light = 0;

   //setup the analog pins as input, probly redundant
  // pinMode(TEMPERATURE_PIN, INPUT);
   pinMode(LIGHT_PIN, INPUT);

   // Initialize WiServer (we'll pass NULL for the page serving function since we don't need to serve web pages)
   WiServer.init(NULL);

   // Enable Serial output and ask WiServer to generate log messages (optional)
#ifdef DEBUG_PRINT
   Serial.begin(9600);
   //WiServer.enableVerboseMode(true);
#endif //DEBUG_PRINT

   // Have the processData function called when data is returned by the server
   postPachube.setReturnFunc(printData);

   //set up global state data
   intTimer = false;

   //setup the timerISR to be called every minute
   MsTimer2::set(60000, timerISR); // 60000ms/1min period
   MsTimer2::start();
}


void loop()
{
   //--------------------------------------------------------------------------------------------
   //handle the timer overflow
   //--------------------------------------------------------------------------------------------
   if(true == intTimer) {
      //one minute has passed
      intTimer = false;
     // temperature = convertTemp(analogRead(TEMPERATURE_PIN));
      light = 1024 - analogRead(LIGHT_PIN);
#ifdef DEBUG_PRINT
     // Serial.print("===== intTimer fired: temperature ");
     // Serial.print(temperature, DEC);
      Serial.print("F, light ");
      //Serial.println(light, DEC);
#endif //DEBUG_PRINT
      postPachube.submit();   
   }

   // Run WiServer
   WiServer.server_task();

   delay(10);
}

/*
http://www.arduino.cc/playground/ComponentLib/Thermistor2

(Ground) ---- (10k-Resistor) -------|------- (Thermistor) ---- (+5v)
                                     |
                                Analog Pin 0
*/

//int convertTemp(int value)
//{
  // double temp;
//  temp = log(((10240000 / value) - 10000));
  // temp = 1 / (0.001129148 + (0.000234125 * temp) + (0.0000000876741 * temp * temp * temp));
//  temp = temp - 273.15;            // Convert Kelvin to Celcius
//  temp = (temp * 9.0) / 5.0 + 32.0; // Convert Celcius to Fahrenheit
  // return (int)temp;
//}

/*
http://www.libelium.com/squidbee/index.php?title=Adding_a_light_sensor

(Ground) ---- (Light Sensor) -------|------- (1k-Resistor) ---- (+5v)
                                     |
                                Analog Pin 0
*/


Kind regards
Myles.
mylesleadbeatter
 
Posts: 4
Joined: Thu Feb 18, 2010 4:45 pm

Re: Pachube and WiShield

Postby GregEigsti » Mon Feb 22, 2010 11:11 pm

You are not getting out of the serial monitor because DEBUG_PRINT is not defined (try uncommenting the #define DEBUG_PRINT line). Take a look at how all uses of Serial are "wrapped" with #ifdef DEBUG_PRINT and #endif //DEBUG_PRINT.

Try defining DEBUG_PRINT and seeing if you now get serial output and if that is helpful. Try searching the forums for "pachube" and you will find a post from someone who said pachube had broken the method used by this sketch to post, pachube said they were looking into it and it was not a problem for my stuff (at the time anyway).

Greg
Check out the wiki!
uIP Stack Docs
Compatible Access Point List
WiShield user contrib branch - DNS, DHCP, AP Scanning, bug fixes, etc.
SlackLab.org - My geek projects blog.
User avatar
GregEigsti
 
Posts: 955
Joined: Sun Aug 02, 2009 5:23 pm
Location: Sammamish WA USA (near Seattle)

Re: Pachube and WiShield

Postby mylesleadbeatter » Tue Feb 23, 2010 2:52 am

Ive tried commenting the debug stuff but still no dice. Searching pachube on these forums bares the result " too many people have spoken about pachube" but i shall persevere. Thanks for the heads up anywho. :shock:
mylesleadbeatter
 
Posts: 4
Joined: Thu Feb 18, 2010 4:45 pm

Re: Pachube and WiShield

Postby GregEigsti » Mon Mar 01, 2010 9:45 pm

Here's the thread that covers Pachube service changes that were causing consternation...
http://asynclabs.com/forums/viewtopic.php?f=15&t=194&p=1183#p1183

Ive tried commenting the debug stuff but still no dice.

Hmmm, can you get _any_ simple serial logging to work?

Greg
Check out the wiki!
uIP Stack Docs
Compatible Access Point List
WiShield user contrib branch - DNS, DHCP, AP Scanning, bug fixes, etc.
SlackLab.org - My geek projects blog.
User avatar
GregEigsti
 
Posts: 955
Joined: Sun Aug 02, 2009 5:23 pm
Location: Sammamish WA USA (near Seattle)

PreviousNext

Return to Sketches and Applications

Who is online

Users browsing this forum: DrStu, Yahoo [Bot] and 0 guests