Hola! Os comento por partes para que todo se pueda entender de forma sencilla.
Paso 1:
Le he montado a mi Arduino UNO R3 una shield para Ethernet y va fenomenal. Tras eso he cargado un programa para conectarme al web service de Pachube (ahora llamado COSM) y dar información de sensores (por ahora el valor de los sensores es una variable interna que voy cambiando de valor para simplificar un poco las cosas).
Hasta aquí todo correcto.
Paso 2:
A continuación he instalado un módulo de hora basado en el RTC DS1307 a través de interfaz I2C (lo conecto a los pines analógicos 4 y 5 de Arduino). Una vez puesto el reloj en hora he intentando hacer un programa que guarde la información de un sensor, junto a la marca de tiempo suministrada por el RTC DS1307, en una tarjeta micro SD (la shield Ethernet incorpora un slot para este tipo de tarjetas). Esto también funciona sin problema.
PROBLEMA: al intentar unir Paso 1 con Paso 2: o sea que en el mismo programa, teniendo conectada la shield Ethernet y el RTC DS1307 a través de I2C (pines A4 y A5), se actualice el valor del sensor en Pachube y también se guarde dicha lectura, junto a la hora actual del reloj, en la tarjeta micro SD.
Os paso el código a ver si alguien con conocimientos, tiempo y que se apiade de mi puede orientarme.
//******************************************____ LIBRERÍAS ____*******************************************
#include <SPI.h>
#include <Ethernet.h>
#include <SD.h>
#include <Wire.h>
//********************************************************************************************************
//******************************************____ CONSTANTES ____******************************************
#define APIKEY // your cosm api key
#define FEEDID // your feed ID
#define USERAGENT // user agent is the project name
#define maxLength 100
#define maxLength2 500
//********************************************************************************************************
//******************************************____ VARIABLES ____*******************************************
uint8_t hora,minuto,segundo;
int hora_int, minuto_int, segundo_int, contador_SD = 0;
double sensorReading;
boolean subir = true;
byte mac[] = { 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF };
byte ip[] = { 192, 168, 1, 180 };
byte gateway[] = { 192, 168, 1, 1 };
byte subnet[] = { 255, 255, 255, 0 };
File archivo;
Sd2Card card;
SdVolume volume;
SdFile root;
EthernetClient client;
IPAddress server(216,52,233,121); // numeric IP for api.cosm.com
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 Cosm.com
String fecha = String("11/08/2012 -- Sábado");
String texto = String(maxLength);
String ls = String(maxLength2);
char fechaChar[] = "11/08/2012 -- Sábado";
char* textoChar[2];
//********************************************************************************************************
void setup()
{
Serial.begin(9600);
// 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);
}
pinMode(10, OUTPUT);
sensorReading = 30;
Serial.println("************_ Sketch 'RELOJ 4' _************");
Serial.println("Inicializando tarjeta SD...");
SD.begin(4);
card.init(SPI_HALF_SPEED, 4);
volume.init(card);
root.openRoot(volume);
archivo = SD.open("hora.txt", FILE_WRITE);
Wire.begin();
}
void loop()
{
if (client.available()) {
char c = client.read();
}
if (!client.connected() && lastConnected) {
Serial.println();
Serial.println("disconnecting.");
client.stop();
}
if(!client.connected() && (millis() - lastConnectionTime > postingInterval)) {
sendData(sensorReading);
sensorReading = modificacionValor(sensorReading);
contador_SD++;
}
if(contador_SD >= 3){
archivo.close();
archivo = SD.open("hora.txt", FILE_WRITE);
contador_SD = 0;
}
lastConnected = client.connected();
}
void sendData(double sensor) {
char aux[20];
// if there's a successful connection:
if (client.connect(server, 80)) {
Serial.println("connecting...");
// send the HTTP PUT request:
//SI COMENTO DESDE AQUÍ (con un comentario de bloque)...
client.print("PUT /v2/feeds/");
client.print(FEEDID);
client.println(".csv HTTP/1.1");
client.println("Host: api.cosm.com");
client.print("X-ApiKey: ");
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(sensor);
//int thisLength = 2 + getLength(sensor);
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("sensor1,");
client.println(sensor);
//...HASTA AQUÍ EL CÓDIGO se ejecuta pero obviamente no actualiza datos en el servicio Pachube...
// Si no lo comento no parece que que funcione ya que la salida serie no muestra nada...
leehora();
char* textoChar[]= {fechaChar , " || Temperatura: " , " || Hora: " ,":"};
Serial.print("Datos para escribir en la tarjeta SD: '");
Serial.print(textoChar[0]);
Serial.print(textoChar[1]);
Serial.print(sensorReading);
Serial.print(textoChar[2]);
Serial.print(hora);
Serial.print(textoChar[3]);
Serial.print(minuto);
Serial.print(textoChar[3]);
Serial.print(segundo);
Serial.print("'");
archivo.print(textoChar[0]);
archivo.print(textoChar[1]);
archivo.print(sensorReading);
archivo.print(textoChar[2]);
archivo.print(hora);
archivo.print(textoChar[3]);
archivo.print(minuto);
archivo.print(textoChar[3]);
archivo.print(segundo);
}
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();
}
void leehora() {
Wire.beginTransmission(0x68);
Wire.write((byte)0);
Wire.endTransmission();
Wire.requestFrom(0x68, 3);
byte cadena[3];
int i;
for(i=0; i<3; i++) {
cadena[i] = Wire.read();
//Serial.print(cadena[i]);
}
segundo = bcd2bin(cadena[0] & 0x7F);
minuto = bcd2bin(cadena[1]);
hora = bcd2bin(cadena[2]);
}
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;
}
double modificacionValor(double sensorReading){
double res;
if(sensorReading<40 && subir){
res = sensorReading + 0.1;// = analogRead(A0);
}else if(sensorReading>=40){
res = sensorReading - 0.1;
subir = false;
}else if(sensorReading<=30){
res = sensorReading + 0.1;
subir = true;
}else {
res = sensorReading - 0.1;
}
return res;
}
static uint8_t bcd2bin (uint8_t val) {
return val - 6 * (val >> 4);
}
static int bin2bcd (int val) {
return val + 6 * (val / 10);
}
Como se puede ver en el código que hay arriba (he omitido los valores APIKEY, FEEDID y USERAGENT que para poder probarlo debereis emplear los vuestros) en la función ‘sendData’ es donde, según active/desactive una parte de código funciona (pero no me hace lo que necesito) o no me funciona…
Si alguna parte no la explico bien por favor preguntarme y os doy más detalles…
¡Muchas gracias por adelantado!
Saludos.