Pages: [1]   Go Down
Author Topic: Online Thermometer with Pachube feed, HELP!  (Read 1574 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 16
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi all,

Quite the noob with Adruino programming but learning little bits as I go.  Hoping to get a little more help here.

I've got this set up working a treat (http://www.freetronics.com/pages/online-thermometer) and use it in another webpage of mine which has other home automation on it.  I want to continue to do this but also have a feed to Pachube.

I have added all the relevant code from the working online thermometer sketch to the example Pachube sketch I got here: http://community.pachube.com/node/112#inputoutput

I have verified and uploaded the sketch to my Adruidno and it continues to perform the online thermometer function which is printing the correct degrees celcius to a webpage served by the Arduino.  The only problem is I have no idea what to put after the pachube_in_out(); function.

See my sketch below, hopefully you might be able to help me out.  I figure I'm already getting the correct temp reading printing to the webpage so there can't be much more I need to send it to Pachube on a regular basis.  I've already added all the Pachube feed details.

Code:
/* ==============================
 * This code, which assumes you're using the official Arduino Ethernet shield,
 * updates a Pachube feed with your analog-in values and grabs values from a Pachube
 * feed - basically it enables you to have both "local" and "remote" sensors.
 *
 * Tested with Arduino 14
 *
 * Pachube is www.pachube.com - connect, tag and share real time sensor data
 * code by usman (www.haque.co.uk), may 2009
 * copy, distribute, whatever, as you like.
 *
 * v1.1 - added User-Agent & fixed HTTP parser for new Pachube headers
 * and check millis() for when it wraps around
 *
 * =============================== */


#include <SPI.h>
#include <Ethernet.h>
#include <WebServer.h>
#include <string.h>

#undef int() // needed by arduino 0011 to allow use of stdio
#include <stdio.h> // for function sprintf

// No-cost stream operator as described at
// http://sundial.org/arduino/?page_id=119
template<class T>
inline Print &operator <<(Print &obj, T arg)
{ obj.print(arg); return obj; }

#define SHARE_FEED_ID              14512     // this is your Pachube feed ID that you want to share to
#define REMOTE_FEED_ID             13743      // this is the ID of the remote Pachube feed that you want to connect to
#define REMOTE_FEED_DATASTREAMS    2        // make sure that remoteSensor array is big enough to fit all the remote data streams
#define UPDATE_INTERVAL            10000    // if the connection is good wait 10 seconds before updating again - should not be less than 5
#define RESET_INTERVAL             10000    // if connection fails/resets wait 10 seconds before trying again - should not be less than 5

#define PACHUBE_API_KEY            "842fdd1657c26c8f3bdc680cb9fdcdefe4ebc74c509f12085ed35f64beb54fd2" // fill in your API key

static uint8_t mac[] = { 0xDE, 0xAD, 0xBE, 0xEE, 0xEE, 0xEF };
static uint8_t ip[] = { 192, 168, 1, 2 };
static uint8_t myPort = 80; // Listen port for tcp/www (range 1-254)
byte remoteServer[] = { 209,40,205,190 };            // pachube.com

float remoteSensor[REMOTE_FEED_DATASTREAMS];        // we know that feed 256 has floats - this might need changing for feeds without floats

/* This creates an instance of the webserver.  By specifying a prefix
 * of "/", all pages will be at the root of the server. */
#define PREFIX "/"
WebServer webserver( PREFIX, myPort );

// Specify data pins for connected DS18B20 temperature sensors
#define SENSOR_A  14
#define SENSOR_B  15
#define SENSOR_C  16
#define SENSOR_D  17
#define SENSOR_E  18
#define SENSOR_F  19

// Function prototypes to trick the Arduino pre-processor into
// allowing call-by-reference
void sendTemperatureValues( WebServer &server);
void sendAboutPage( WebServer &server);
void sendFormButtons( WebServer &server);

/**
 * Default page to return to browser
 */
void valuesCmd(WebServer &server, WebServer::ConnectionType type, char *url_tail, bool tail_complete)
{
  server.httpSuccess();
  sendTemperatureValues( server );
  sendFormButtons( server );
}

/**
 * Default page to return to browser
 */
void aboutCmd(WebServer &server, WebServer::ConnectionType type, char *url_tail, bool tail_complete)
{
  server.httpSuccess();
  sendAboutPage( server );
  sendFormButtons( server );
}

/**
 * Configure Ethernet shield
 */
void setup(){
  Serial.begin(38400);

  Ethernet.begin(mac, ip);
  webserver.begin();
  
  pinMode(3, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  
  webserver.setDefaultCommand( &valuesCmd );
  webserver.addCommand( "values", &valuesCmd );
  webserver.addCommand( "about", &aboutCmd );

  // Set up the data pins for communication with DS18B20 sensors
  digitalWrite(SENSOR_A, LOW);
  pinMode(SENSOR_A, INPUT);
  digitalWrite(SENSOR_B, LOW);
  pinMode(SENSOR_B, INPUT);
  digitalWrite(SENSOR_C, LOW);
  pinMode(SENSOR_C, INPUT);
  digitalWrite(SENSOR_D, LOW);
  pinMode(SENSOR_D, INPUT);
  digitalWrite(SENSOR_E, LOW);
  pinMode(SENSOR_E, INPUT);
}

void loop()
{
    webserver.processConnection();
  
  // call 'pachube_in_out' at the beginning of the loop, handles timing, requesting
  // and reading. use serial monitor to view debug messages

  pachube_in_out();

  // then put your code here, you can access remote sensor values
  // by using the remoteSensor float array, e.g.:

What do I put here?

  // you can have code that is time sensitive (e.g. using 'delay'), but
  // be aware that it will be affected by a short pause during connecting
  // to and reading from ethernet (approx. 0.5 to 1 sec).
  // e.g. this code should carry on flashing regularly, with brief pauses
  // every few seconds during Pachube update.

And here?

}

Continued in the next post.

Edit: spelling, more info.
« Last Edit: January 05, 2011, 02:58:54 am by benthomas » Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 16
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code continued:

Code:
/**
 * Send the HTML for the "about" page
 */
void sendAboutPage( WebServer &server )
{
  server.print("<h1>Online Thermometer v1.0 (Wiznet version)</h1>");
  server.print("As featured in Practical Arduino.<br />");
  server.print("See <a href=\"http://practicalarduino.com\">practicalarduino.com</a> for more info.");
}

/**
 * Send the HTML for the navigation buttons
 */
void sendFormButtons( WebServer &server )
{
  // Display a form button to update the display
  server << "<p><form METHOD='POST' action='" PREFIX "'>";
  server.println("<input type=submit value=\"Update\">");
  server.println("</form></p>");
}  
  // Display a form button to access the "about" page
/*
  server << "<p><form METHOD=POST action='" PREFIX "/about'>";
  server.println("<input type=submit value=\"About\">");
  server.println("</form>");
}
*/
/**
 * Get temperature values from connected sensors and generate the HTML
 */
void sendTemperatureValues( WebServer &server )
{
  char temp_string_a[10];
  char temp_string_b[10];
  char temp_string_c[10];
  char temp_string_d[10];
  char temp_string_e[10];
  char temp_string_f[10];
  
  getCurrentTemp(SENSOR_A, temp_string_a);
  getCurrentTemp(SENSOR_B, temp_string_b);
  getCurrentTemp(SENSOR_C, temp_string_c);
  getCurrentTemp(SENSOR_D, temp_string_d);
  getCurrentTemp(SENSOR_E, temp_string_e);
  getCurrentTemp(SENSOR_F, temp_string_f);
  
  server.print("Current Apartment Temperature: ");
  server.print(temp_string_a);
  server.print("<br />");
/* server.print("Sensor B:");
  server.print(temp_string_b);
  server.print("<br />");
  server.print("Sensor C:");
  server.print(temp_string_c);
  server.print("<br />");
  server.print("Sensor D:");
  server.print(temp_string_d);
  server.print("<br />");
  server.print("Sensor E:");
  server.print(temp_string_e);
  server.print("<br />");
  server.print("Sensor F:");
  server.print(temp_string_f);
  server.print("<br />");
*/
}

/**
 * Reset the 1-wire bus
 */
void OneWireReset (int Pin) // reset.  Should improve to act as a presence pulse
{
  digitalWrite (Pin, LOW);
  pinMode (Pin, OUTPUT);        // bring low for 500 us
  delayMicroseconds (500);
  pinMode (Pin, INPUT);
  delayMicroseconds (500);
}

/**
 * Send data to a 1-wire device
 */
void OneWireOutByte (int Pin, byte d) // output byte d (least sig bit first).
{
  byte n;

  for (n=8; n!=0; n--)
  {
    if ((d & 0x01) == 1)  // test least sig bit
    {
      digitalWrite (Pin, LOW);
      pinMode (Pin, OUTPUT);
      delayMicroseconds (5);
      pinMode (Pin, INPUT);
      delayMicroseconds (60);
    }
    else
    {
      digitalWrite (Pin, LOW);
      pinMode (Pin, OUTPUT);
      delayMicroseconds (60);
      pinMode (Pin, INPUT);
    }

    d = d>>1; // now the next bit is in the least sig bit position.
  }
}

/**
 * Read data from a 1-wire device
 */
byte OneWireInByte (int Pin) // read byte, least sig byte first
{
  byte d, n, b;

  for (n=0; n<8; n++)
  {
    digitalWrite (Pin, LOW);
    pinMode (Pin, OUTPUT);
    delayMicroseconds (5);
    pinMode (Pin, INPUT);
    delayMicroseconds (5);
    b = digitalRead (Pin);
    delayMicroseconds (50);
    d = (d >> 1) | (b<<7); // shift d to right and insert b in most sig bit position
  }
  return (d);
}


/**
 * Read temperature from a DS18B20.
 * int sensorPin: Arduino digital I/O pin connected to sensor
 * char *temp: global array to be populated with current reading
 */
void getCurrentTemp (int sensorPin, char *temp)
{
  int HighByte, LowByte, TReading, Tc_100, sign, whole, fract;

  OneWireReset (sensorPin);
  OneWireOutByte (sensorPin, 0xcc);
  OneWireOutByte (sensorPin, 0x44); // Perform temperature conversion, strong pullup for one sec

  OneWireReset (sensorPin);
  OneWireOutByte (sensorPin, 0xcc);
  OneWireOutByte (sensorPin, 0xbe);

  LowByte = OneWireInByte (sensorPin);
  HighByte = OneWireInByte (sensorPin);
  TReading = (HighByte << 8) + LowByte;
  sign = TReading & 0x8000;  // test most sig bit
  if (sign) // negative
  {
    TReading = (TReading ^ 0xffff) + 1; // 2's complement
  }
  Tc_100 = (6 * TReading) + TReading / 4;    // multiply by (100 * 0.0625) or 6.25

  whole = Tc_100 / 100;  // separate off the whole and fractional portions
  fract = Tc_100 % 100;

  if (sign) {
    temp[0] = '-';
  } else {
    temp[0] = '+';
  }

  if (whole/100 == 0) {
    temp[1] = ' ';
  } else {
    temp[1] = whole/100+'0';
  }

  temp[2] = (whole-(whole/100)*100)/10 +'0' ;
  temp[3] = whole-(whole/10)*10 +'0';
  temp[4] = '.';
  temp[5] = fract/10 +'0';
  temp[6] = fract-(fract/10)*10 +'0';
  temp[7] = '\0';
}

Any help is appreciated!

Thanks, BT.
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 16
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I've tried troubleshooting it again today but cannot for the life of me figure this out.  Anyone able to lend a hand?

Thanks.
Logged

Oxford, UK
Offline Offline
Newbie
*
Karma: 0
Posts: 41
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Basically the pachube_in_out() function handles sending and receiving feed data. You need to build a string from your sensor data and reference this within the function. If you have a look at this thread http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1293217061/4#4 you can see how I did it - I pass each sensor reading in like this
Code:
pachube_data = String(convertReading(temp_0));
I'm not receiving any data in this code

Hope it helps you
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 16
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi there, thanks heaps for your reply.

Unfortunately I'm a noob with programming so it's still a bit complex for me to work out.  That sketch I had was from a tutorial and I haven't changed it at all.  I wouldn't know how to create a string and include it in my existing sketch.

I've definitely still got a lot to learn!  I actually thought it would be a bit easier than that.

Thanks again for your contribution thought!

Cheers
Ben
Logged

Pages: [1]   Go Up
Jump to: