Pachube Client Problem

All,

I downloaded and slightly modified a Pachube Client sketch. It works fine, but when I add in another sensor, it starts printing the “client.print” sections of the code 1 character at a time in the serial window. It’s like it only stays in the sendData subfunction to print 1 character, then it jumps back into the loop.

/*
  Pachube sensor client
 
 This sketch connects an analog sensor to Pachube (http://www.pachube.com)
 using a Wiznet Ethernet shield. You can use the Arduino Ethernet shield, or
 the Adafruit Ethernet shield, either one will work, as long as it's got
 a Wiznet Ethernet module on board.
 
 This example has been updated to use version 2.0 of the Pachube.com API. 
 To make it work, create a feed with a datastream, and give it the ID
 sensor1. Or change the code below to match your feed.
 
 
 Circuit:
 * Analog sensor attached to analog in 0
 * Ethernet shield attached to pins 10, 11, 12, 13
 
 created 15 March 2010
 modified 9 Apr 2012
 by Tom Igoe with input from Usman Haque and Joe Saavedra
 
http://arduino.cc/en/Tutorial/PachubeClient
 This code is in the public domain.
 
 */

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

#define APIKEY         "???" // replace your pachube api key here
#define FEEDID         ???? // replace your feed ID
#define USERAGENT      "Aquarium Data" // user agent is the project name
#define ato_dist_in 2       // Pin to receive echo pulse
#define ato_dist 3     // Pin to send trigger pulse
#define kalk_dist 47  // kalk US level

// assign a MAC address for the ethernet controller.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
// fill in your address here:
byte mac[] = { 
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
  
char SRF04_US = 'S'; //SRF04 ultra sonic rangefinder
char Parallax = 'P'; // Parallax ultra sonic rangefinder

// fill in an available IP address on your network here,
// for manual configuration:
IPAddress ip(10,0,1,20);
// initialize the library instance:
EthernetClient client;

// if you don't want to use DNS (and reduce your sketch size)
// use the numeric IP instead of the name for the server:
IPAddress server(216,52,233,122);      // numeric IP for api.pachube.com
//char server[] = "api.pachube.com";   // name address for pachube API

unsigned long lastConnectionTime = 0;          // last time you connected to the server, in milliseconds
boolean lastConnected = false;                 // state of the connection last time through the main loop
const unsigned long postingInterval = 10*1000; //delay between updates to Pachube.com

void setup() {
 // Open serial communications and wait for port to open:
  Serial.begin(9600);
  delay(1000);
//   while (!Serial) {
//    ; // wait for serial port to connect. Needed for Leonardo only
//  }


 // start the Ethernet connection:
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    // DHCP failed, so use a fixed IP address:
    Ethernet.begin(mac, ip);
  }
}

void loop() {
  // read the analog sensor:
//  int ato_level = rangefinderDist(SRF04_US);
  int kalk_level = rangefinderDist(Parallax);
  int sensorReading = analogRead(A0);  
//  Serial.println(sensorReading); 

  // if there's incoming data from the net connection.
  // send it out the serial port.  This is for debugging
  // purposes only:
  if (client.available()) {
    char c = client.read();
    Serial.print(c);
  }

  // if there's no net connection, but there was one last time
  // through the loop, then stop the client:
  if (!client.connected() && lastConnected) {
    Serial.println();
    Serial.println("disconnecting.");
    client.stop();
  }

  // if you're not connected, and ten seconds have passed since
  // your last connection, then connect again and send data:
  if(!client.connected() && (millis() - lastConnectionTime > postingInterval)) {
    sendData(sensorReading, "sensor3,");
  }
  // store the state of the connection for next time through
  // the loop:
  lastConnected = client.connected();
}

// this method makes a HTTP connection to the server:
void sendData(int thisData, char* dataName) {
  // if there's a successful connection:
  if (client.connect(server, 80)) {
    Serial.println("connecting...");
    // send the HTTP PUT request:
    client.print("PUT /v2/feeds/");
    client.print(FEEDID);
    client.println(".csv HTTP/1.1");
    client.println("Host: api.pachube.com");
    client.print("X-PachubeApiKey: ");
    client.println(APIKEY);
    client.print("User-Agent: ");
    client.println(USERAGENT);
    client.print("Content-Length: ");

    // calculate the length of the sensor reading in bytes:
    // 8 bytes for "sensor1," + number of digits of the data:
    int thisLength = 8 + getLength(thisData);
    client.println(thisLength);

    // last pieces of the HTTP PUT request:
    client.println("Content-Type: text/csv");
    client.println("Connection: close");
    client.println();

    // here's the actual content of the PUT request:
    client.print(dataName);
    client.println(thisData);
  
  } 
  else {
    // if you couldn't make a connection:
    Serial.println("connection failed");
    Serial.println();
    Serial.println("disconnecting.");
    client.stop();
  }
   // note the time that the connection was made or attempted:
  lastConnectionTime = millis();
}


// This method calculates the number of digits in the
// sensor reading.  Since each digit of the ASCII decimal
// representation is a byte, the number of digits equals
// the number of bytes:

int getLength(int someValue) {
  // there's at least one byte:
  int digits = 1;
  // continually divide the value by ten, 
  // adding one to the digit count for each
  // time you divide, until you're at 0:
  int dividend = someValue /10;
  while (dividend > 0) {
    dividend = dividend /10;
    digits++;
  }
  // return the number of digits:
  return digits;
}


int rangefinderDist(char US_type) {
  int distance=0;
  int distance2 = 0;
  int USPin;
  int USPin_in;
  if (US_type=='S'){ 
    USPin = ato_dist;
    USPin_in = ato_dist_in;
  }
  if (US_type=='P'){ 
    USPin = kalk_dist;  
    USPin_in = kalk_dist;
  }
  for(int counter = 0; counter<50; counter++)  {
    if (US_type=='S'){
      digitalWrite(USPin, LOW);                   // Set the trigger pin to low for 2uS
      delayMicroseconds(2);
      digitalWrite(USPin, HIGH);                  // Send a 10uS high to trigger ranging
      delayMicroseconds(10);
      digitalWrite(USPin, LOW);                   // Send pin low again
      int distance2 = pulseIn(USPin_in, HIGH);  // Read in times pulse
      distance2 = distance2/54;
      distance = distance2 + distance;
      delay(20);
    }
    if (US_type=='P'){
      pinMode(USPin, OUTPUT);
      digitalWrite(USPin, LOW);
      delayMicroseconds(2);
      digitalWrite(USPin, HIGH);
      delayMicroseconds(5);
      digitalWrite(USPin, LOW);
      pinMode(USPin_in, INPUT);
      int distance2 = pulseIn(USPin_in, HIGH);
//      Serial.println(distance2);
      distance2 = distance2/74/2;
      distance = distance2 + distance;
      delay(20);
//      Serial.println(distance);
    }
  }
  distance = distance/50;
//  Serial.print("Average dist ");
//  Serial.println(distance);
  return distance;
}

Where in your code did you "add another sensor"?

parker21: All,

I downloaded and slightly modified a Pachube Client sketch. It works fine, but when I add in another sensor, it starts printing the "client.print" sections of the code 1 character at a time in the serial window. It's like it only stays in the sendData subfunction to print 1 character, then it jumps back into the loop.

If I'm looking at the right bit of code, the client output should appear on the serial output at all. Have you tried putting another Serial.println at the end of sendData() to confirm that you've left that function?

[quote author=James C4S link=topic=123086.msg925553#msg925553 date=1347821511] Where in your code did you "add another sensor"? [/quote] int kalk_level = rangefinderDist(Parallax);

It is a parallax US rangefinder.

PeterH:

parker21: All,

I downloaded and slightly modified a Pachube Client sketch. It works fine, but when I add in another sensor, it starts printing the "client.print" sections of the code 1 character at a time in the serial window. It's like it only stays in the sendData subfunction to print 1 character, then it jumps back into the loop.

If I'm looking at the right bit of code, the client output should appear on the serial output at all. Have you tried putting another Serial.println at the end of sendData() to confirm that you've left that function?

So I added the serial.print and this is what I got. I think pachube might be sending the arduino a serial stream back. This is what I got in the terminal: disconnecting. connecting... Testing.................... HTTP/1.1 200 OK Date: Fri, 05 Oct 2012 11:03:08 GMT Content-Type: text/plain; charset=utf-8 Connection: close X-PachubePurgeCache: t:feeds/48961,web:feed:48961 X-Runtime: 212 Content-Length: 1 X-Pachube-Logging-Key: logging.dcsUN2sofumFGHfurn1n X-PachubeRequestId: 3ba70f54de845bcba009fba24cfcf4af2bfac35f Set-Cookie: _pachcore_app_session=BAh7BjoPc2Vzc2lvbl9pZCIlZTlmNzJhNDc5ZmExMGZiMmNjY2E3YmQ5ZTBhNWNkYjU%3D--a3220a61208086635fe78b68a041074d145df1fc; domain=.cosm.com; path=/; expires=Fri, 19-Oct-2012 11:03:08 GMT; HttpOnly Cache-Control: max-age=0 Vary: Accept-Encoding

void sendData(int thisData, char* dataName) {
  // if there's a successful connection:
  if (client.connect(server, 80)) {
    Serial.println("connecting...");
    // send the HTTP PUT request:
    client.print("PUT /v2/feeds/");
    client.print(FEEDID);
    client.println(".csv HTTP/1.1");
    client.println("Host: api.pachube.com");
    client.print("X-PachubeApiKey: ");
    client.println(APIKEY);
    client.print("User-Agent: ");
    client.println(USERAGENT);
    client.print("Content-Length: ");

    // calculate the length of the sensor reading in bytes:
    // 8 bytes for "sensor1," + number of digits of the data:
    int thisLength = 8 + getLength(thisData);
    client.println(thisLength);

    // last pieces of the HTTP PUT request:
    client.println("Content-Type: text/csv");
    client.println("Connection: close");
    client.println();

    // here's the actual content of the PUT request:
    client.print(dataName);
    client.println(thisData);
  Serial.println("Testing....................");
  } 
  else {
    // if you couldn't make a connection:
    Serial.println("connection failed");
    Serial.println();
    Serial.println("disconnecting.");
    client.stop();
  }
   // note the time that the connection was made or attempted:
  lastConnectionTime = millis();
}

For clarification, this is what I get when I uncomment the US sensor at the beginning of the loop. It keeps printing 1 letter at a time about a second apart starting after the "Testing....." line. Connecting... Testing.................... HTTP/1.1 200 OK Date: Fri, 05 Oct 2012 11:05:35 GMT Conten

Bump

For clarification, this is what I get when I uncomment the US sensor at the beginning of the loop. It keeps printing 1 letter at a time about a second apart starting after the "Testing....." line.

Bump

Snippets are us is down the road a ways. You can bump there without posting complete code. Not here, though. Here, we expect to see all of your code.

For anybody else who may be having similar problems, I switched to using this library and it works great. Only downside is that the name of the data stream must me an integer.

http://code.google.com/p/pachubelibrary/