Arduino & Pachube’s API V2

Oggi vorrei parlarvi di pachube.com e della mia ethernet shield.
In questi giorni mi è arrivata l’ethernet shield: una figata pazzesca.
Ancora devo approfondire il funzionamento ma ho già smanettato e fatta funzionare.

La preparazione dell’hardware è avvenuta in questo modo:

Per questo progetto ho collegato all’ethernet shield un sensore di temperatura LM35 al pin A2.
Più precisamente il pin centrale su A2, quello a sinistra a 5V e quello destro a GND:

tmp36pinout

Non ho usato i pin A0 o A1 in quanto sono usati dall’ethernet shield per la protezione in scrittura di un eventuale SD sulla board… per recuperare tali pin, basterebbe tagliare la traccia sulla pcb.

L’ethernet shield poi è stata collegata tramite cavo ethernet ad una fonera moddata con firmware dd-wrt e usabile come un normalissimo router… ma in mancanza di una fonera si può attacchare la shield ad un qualsiasi router.

Preparazione softare:
Nell’IDE di arduino già è fruibile un esempio (PachubeClient) che permette di sfruttare le API V1 di pachube.com per inviare il valore di un sensore collegato ad A0.
Una volta registrato al sito pachube.com, aver creato un feed, un datastream e una chiave di utilizzo; ho impostato tutti i valori nello sketch presente nell’ide.
Compile&upload e tutto funziona alla perfezione.

Unico problema è che lo sketch presente sull’ide utilizza le vecchie API di pachube.com: le V1
Il sito consiglia di utilizzare le nuove V2 lasciando, però, ancora fruibili le vecchie V1.

Ho modificato un pò il codice e in particolare la put scrivendola così come indica la documentazione V2: PUT V2
Update datastream: PUT /v2/feeds/<feed_id>/datastreams/<datastream_id>

Dove:
Feed_id: è l’inidentificativo univoco del proprio feed assegnato in automatico alla creazione da pachube.com
Datastream_id: è l’identificativo univoco di uno dei proprio stream assegnato manualmente dall’utente all’interno di un feed.

Il tutto funziona con le API V2… in giro non ho trovato molta documentazione a proposito delle V2.

Et voilà:

captureby
immagineoia
img20111008123820
img20111008124023

 

 

 

 

/*
  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.
 
 Circuit:
 * Analog sensor attached to analog in 2
 * Ethernet shield attached to pins 10, 11, 12, 13
 
 created 15 March 2010
 updated 4 Sep 2010
 by Tom Igoe
 
 http://www.tigoe.net/pcomp/code/category/arduinowiring/873
 This code is in the public domain.
 
 UPDATE:
 *Using Pachube's V2 API
 *Analog sensor attached to analog in 2
 *New pachube.com IP
  
 08/10/2011
 by Andrea Esposito
 www.blackstufflabs.com
 
 */

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

// assign a MAC address for the ethernet controller.
// fill in your address here:
byte mac[] = {
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
// assign an IP address for the controller:
byte ip[] = {
  192,168,1,20 };
byte gateway[] = {
  192,168,1,1};
byte subnet[] = {
  255, 255, 255, 0 };

//  The address of the server you want to connect to (pachube.com):
byte server[] = {
  173,203,98,29 }; 

// initialize the library instance:
Client client(server, 80);

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 int postingInterval = 12000;  //delay between updates to Pachube.com

void setup() {
  // start the ethernet connection and serial port:
  Ethernet.begin(mac, ip);
  Serial.begin(9600);
  // give the ethernet module time to boot up:
  delay(1000);
}

void loop() {
  // read the analog sensor:

  //LM35 on A2
  int sensorCelsius = analogRead(2);
  // voltage=5v but on my board is 4.91v 
  float voltage=4.91;
  sensorCelsius = (voltage * sensorCelsius * 100.0)/1024.0;

  // 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(sensorCelsius);
  }
  // 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) {
  // if there's a successful connection:
  if (client.connect()) {
    Serial.print("Temperature: ");
    Serial.println(thisData);
    Serial.println("connecting...");
    // send the HTTP PUT request. 
    // fill in your feed address here   
    // example: client.print("PUT /v2/feeds/37040/datastreams/due HTTP/1.1n");    
    client.print("PUT /v2/feeds/YOUR_FEED_HERE/datastreams/YOUR_ID_STREAM_HERE HTTP/1.1n");
    client.print("Host: api.pachube.comn");
    // fill in your Pachube API key here:
    client.print("X-PachubeApiKey: YOUR_API_KEY_HEREn");
    client.print("Content-Length: ");

    // calculate the length of the sensor reading in bytes:
    int thisLength = getLength(thisData);
    client.println(thisLength, DEC);

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

    // here's the actual content of the PUT request:
    client.println(thisData, DEC);

    // note the time that the connection was made:
    lastConnectionTime = millis();
  } 
  else {
    // if you couldn't make a connection:
    Serial.println("connection failed");
  }
}

// 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;
}

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.