Mega with wiznet shield (wire hack)+thingspeak+sd problem

Tim,

thank you! I will put this ( with modifications) to my sketch to send data to thingspeak and inform you!

I would work on the sending data to the server and read a response until it works flawlessly. Then add the SD code to save the data.

I am in the throes of converting to Mega 2560 at the moment and modifying my proto boards. The cosm feed I have at the moment does not use the SD or a clock since it only needs them for backup when in a remote location.

Here is what I'm working on - untested. This is for Uno and is simply the cosm stuff I had added to a previous sketch that worked fine.

Note that I don't use strings for the serial and SD feeds, hence the slightly bloated code, but it works.

Mega pins are different but it should not affect the code.

I have had serial print stuff looking like yours and it was down to sending it too fast but the code you sent me had the serial at 9600 so maybe you need a couple of delays in it. The 85 could be the DS18B20s being read too soon.

/*
From cosm library example and lifts from a lot of others
 particularly from Stanley in Kuala Lumpur.
 Use your own DS18B20 addresses, keys etc.
 
 */
//#include <LiquidCrystal.h>
#include <SD.h>
#include <string.h>
#include "RTClib.h"

RTC_DS1307 RTC;
File myFile;
char filename[] = "00000000.CSV";
#include "Wire.h"
#define DS1307_ADDRESS 0x68

#include <OneWire.h>
#include <DallasTemperature.h>
#include <SPI.h>
#include <Ethernet.h>
#include <HttpClient.h>
#include <Cosm.h>

byte InThermo[8] =  {
  0x28, 0x69, 0xC2, 0xB0, 0x03, 0x00, 0x00, 0X9F};
byte OutThermo[8] = {
  0x28, 0x7A, 0x8B, 0xC0, 0x03, 0x00, 0x00, 0x2F};
#define ONE_WIRE_BUS 3
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

byte mac[] = { 
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

char cosmKey[] = "l6absmJ.................U0t0Zz0g";

int sensorPin = 3;
int  second, minute, hour, weekDay, monthDay, month, year;
float InTemp, OutTemp;

// Define the strings for our datastream IDs
char sensorId0[] = "InThermo";
char sensorId1[] = "OutThermo";
//char sensorId2{} = "DrainThermo"

const int bufferSize = 100;
char bufferValue[bufferSize]; // enough space to store the string we're going to send

CosmDatastream datastreams[] = {
  CosmDatastream(sensorId0, strlen(sensorId0), DATASTREAM_FLOAT),
  CosmDatastream(sensorId1, strlen(sensorId1), DATASTREAM_FLOAT),
  //    CosmDatastream(sensorId2, strlen(sensorId2), DATASTREAM_FLOAT),
};

// Finally, wrap the datastreams into a feed
CosmFeed feed(83153, datastreams, 2 /*put your number here */);

EthernetClient client;
CosmClient cosmclient(client);

//LiquidCrystal lcd(8,9,56,5,6,7);

void setup() {

  Wire.begin();
  Serial.begin(9600);
  delay(300);//Wait for newly restarted system to stabilize
  Serial.print("Temperature measurement");
  Serial.print("Initializing SD card...");

  pinMode(10, OUTPUT);

  if (!SD.begin(4)) {
    Serial.println("initialization failed!");
    return;
  }

  Serial.println("initialization done.");

  sensors.setResolution(InThermo, 12);
  sensors.setResolution(OutThermo, 12);

  Serial.println("Starting multiple datastream upload to Cosm...");
  Serial.println();

  while (Ethernet.begin(mac) != 1)
  {
    Serial.println("Error getting IP address via DHCP, trying again...");
    delay(10000);
  }
}

void loop() {

  GetClock();
  PrintDate;

  sensors.requestTemperatures();
  Serial.println("Read sensor value ");

  InTemp = (sensorValue(InThermo));
  OutTemp = (sensorValue(OutThermo));  
  // float Drain = (sensorValue(DrainThermo));  

  datastreams[0].setFloat(InTemp);
  datastreams[1].setFloat(OutTemp);

  Serial.println(datastreams[0]);
  Serial.println(datastreams[1]);
  /*
  datastreams[2].setFloat(DrainTemp);
   Serial.println(datastreams[2].getFloat(DrainTemp));
   */
  // LCD stuff will go here

  if (second == 0 || second == 10 || second == 20 || second == 30 || second == 40 || second == 50) 
  {
    myFile = SD.open("data.csv", FILE_WRITE);//<<<<<<<<<<<<< OPEN
    WriteSD;
    int ret=0;
    delay(200);// Delay... must not be too short.
    Serial.println("Uploading it to Cosm");
    ret = cosmclient.put(feed, cosmKey);    // SEND FEED TO COSM
    Serial.print("cosmclient.put returned "); // tell us about it
    Serial.println(ret);                      // pray to God it says 200
    myFile.println();
    myFile.close();//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>CLOSE
  }
    delay(200);// Delay... must not be too short.
    Serial.println();
    delay(800);
}

//sensorValue function
float sensorValue (byte deviceAddress[])
{
  float tempC = sensors.getTempC (deviceAddress);
  return tempC;
}


byte bcdToDec(byte val)  {
  // Convert binary coded decimal to normal decimal numbers
  return ( (val/16*10) + (val%16) );
}

void GetClock(){
  // Reset the register pointer
  Wire.beginTransmission(DS1307_ADDRESS);
  byte zero = 0x00;
  Wire.write(zero);
  Wire.endTransmission();
  Wire.requestFrom(DS1307_ADDRESS, 7);

  second = bcdToDec(Wire.read());
  minute = bcdToDec(Wire.read());
  hour = bcdToDec(Wire.read() & 0b111111); //24 hour time
  weekDay = bcdToDec(Wire.read()); //0-6 -> sunday - Saturday
  monthDay = bcdToDec(Wire.read());
  month = bcdToDec(Wire.read());
  year = bcdToDec(Wire.read());
}

void PrintDate () {
  Serial.print(monthDay);
  Serial.print("/");
  Serial.print(month);
  Serial.print("/");
  Serial.print(year);
  Serial.print("     ");
  Serial.print(hour);
  Serial.print(":");
  Serial.print(minute);
  Serial.print(":");

  if (second < 10)
  {
    Serial.print("0");
  };

  Serial.print(second);
  Serial.print("         ");
}

void WriteSD () {

  myFile.print(monthDay);
  myFile.print("/");
  myFile.print(month);
  myFile.print("/");
  myFile.print(year);
  myFile.print(",  ");
  myFile.print(hour);
  myFile.print(":");
  myFile.print(minute);
  myFile.print(":");
  myFile.print(second);
  myFile.print(",         ");

  myFile.print(InTemp);
  myFile.print(",    ");
  myFile.print(OutTemp);
  myFile.print(",    ");
}

Thanks for your replies, I will take a deep breath and create the new sketches.

seems that I'm newbie...
I have checked the example method of post...

How can I put that to your code Tim?

is this the sending to the server?:

sprintf(pageAdd,"/",totalCount);
// sprintf(pageAdd,"/arduino.php?test=%u",totalCount);

if(!getPage(server,pageAdd)) Serial.print("Fail ");
else Serial.print("Pass ");

Should I use strcpy to put the lines to pageAdd and then sprintf(pageAdd); ?

Sorry for the question...

The API says it will take GET or POST requests, so this should work. In loop() change the sprintf line.

 sprintf(pageAdd,"/update?key=MyKey&test=%u",totalCount);

Change MyKey to your key. Change "test" to "Field", "Channel", etc. Change totalCount to the parameter you want to pass.

Insure there are no illegal characters in the parameters, like spaces.

Tim,

seems your code is working. Exactly did what you wrote. Serial monitor said:

Starting ethernet...
192.168.9.110
Starting SD...ok Ready
connecting...connected
HTTP/1.1 200 OK
Server: nginx/0.8.53
Date: Wed, 21 Nov 2012 19:01:40 GMT
Content-Type: text/html; charset=utf-8
Connection: close
Vary: Accept-Encoding
Status: 200
ETag: "b4fd1d2cb085390fbbadae65e07876a7"
Cache-Control: max-age=0, private, must-revalidate

2809
disconnecting.
Pass 1

I have just add manually temp values.

Of all the things I enjoy seeing in the serial monitor, this is my favorite:

Pass 1

I have defined the temp0, temp1 ... values as "int". How can put them to sprintf(...)? Manual send was : &field1=200&field2=200 ....
instead of 200 i have to put the temp0, temp1 ....

That sounds like this:

sprintf(pageAdd,"/update?key=MyKey&field1=%u&field2=%u",temp0,temp1);

edit: Insure the character array pageAdd has enough storage for the string.

I'm going to be happy :slight_smile:
current code is here:
SKETCH

answer is:
Starting ethernet...
192.168.9.110
Starting SD...ok Ready
Locating devices...Found 1 devices.
Parasite power is: OFF
Found device 0 with address: 1092942902080056
Getting temperatures...

Temperatures are 85 Celsius, 0 Celsius, 0 Celsius,

connecting...connected
HTTP/1.1 200 OK
Server: nginx/0.8.53
Date: Wed, 21 Nov 2012 19:36:14 GMT
Content-Type: text/html; charset=utf-8
Connection: close
Vary: Accept-Encoding
Status: 200
ETag: "d53697441ef12a45422f6660202f9840"
Cache-Control: max-age=0, private, must-revalidate

2818
disconnecting.
Pass 1

85 degrees is maybe some kind of delay I guess...
we are almost at the start of writing to SD :slight_smile:

edit: I have modified the char array to 140. As API documentation said that is the maximum. Can I modify later the temp as float?

Watch out for type float. If you try to use that type in sprintf, the result will be "?" where you expected the value to be. You need to convert that float to a string first.

Is the value returned from the temperature sensor a float type? Or integer?

edit: Some devices return the temperature in fractions of a degree, like half or quarter of a degree. 85 may be in quarter degrees. That would be 21.25 degrees Celsius.

I have tried that, I will stay at integer ( i gues return value can be a float)...I hope it will show negative values.
Facing to SD writing...I have put the SD code what you wrote to the setup().
Can you help how should I go ahaed?

it was my original SD code:

#include <Wire.h>
#include <OneWire.h>
#include <Rtc_Pcf8563.h>
#include <SD.h>

//init the real time clock
Rtc_Pcf8563 rtc;

// Global variables
const int period = 30000;
const int chipSelect = 8;

//**************************SETUP*****************************
void setup()
{
  String message="";
  Serial.begin(9600);
  Wire.begin();
  pinMode(8, OUTPUT);
   if (!SD.begin(chipSelect)) 
    {
    Serial.println("Card failed");
    return;
    }
  Serial.println("Card init");
  File logFile = SD.open("errorlog.txt", FILE_WRITE);
  if (logFile) 
  { 
    message = String(rtc.formatDate(RTCC_DATE_ASIA)) + " " + String(rtc.formatTime());
    logFile.println("Progstart: " + message);
    logFile.close();
    Serial.println("Progrstart: "  + message);
  }  
// if the file isn't open, pop up an error:
  else 
  {
    Serial.println("cannot open errorlog.txt");
  } 
}

//********************LOOP**********************************
void loop()
{
  delay(period);  
// make a string for assembling the data to log:
  String dataString = "";
  String sDate = "";
  String sTime ="";
//-------------------------------------------------------------  
    sTime=rtc.formatTime();               //read formatted time from i2C RTC
    sDate=rtc.formatDate(RTCC_DATE_ASIA); //read formatted date from 12C RTC

  Serial.print(sTime);
  Serial.print(" ");
  Serial.print(sDate);
  Serial.println();
   dataString += String(sDate + ";" + sTime + ";");
    delay(100);
  File dataFile = SD.open("datalog.txt", FILE_WRITE);
  if (dataFile) 
  {
    dataFile.println(dataString);
    dataFile.close();
// print to the serial port too:
    Serial.println(dataString);
  }  
  // if the file isn't open, pop up an error:
  else 
  {
    Serial.println("cannot open datalog.txt");
  } 
}
// END LOOP

or should I use your ftp code?? Seems I will need your further help :blush:

Did you see my edit to my last post? The value returned may be in 1/4 degrees Celsius.
85 / 4 = 21.25 degrees.
Is that about right?

oh yes...I will double check the DS18b20...now I'm excited about the SD :slight_smile:

SurferTim:
Did you see my edit to my last post? The value returned may be in 1/4 degrees Celsius.
85 / 4 = 21.25 degrees.
Is that about right?

85 is the value the DS18B20 returns when it hasn't read the temperature. Discussed again recently in this thread:

wildbill:
85 is the value the DS18B20 returns when it hasn't read the temperature. Discussed again recently in this thread:
Boot time and DS18B20 problem - #3 by wildbill - Programming Questions - Arduino Forum

And this seems to be the final piece of the puzzle for you.
Thanks, wildbill! :slight_smile:

Thanks wildbill, I will put initial sensor readings to setup.

Tim,

can you help me out of this SD code? What and where should I put? Should I stay at my code or better to use your ftp like?

edit: after initial reading of sensors in setup() 85 degrees at the start disappeared, thanks again!

Since you have the values in the loop() function, I would put the SD routine immediately after the getPage() call. Like this:

if(!logFile(temp0,temp1)) Serial.println("Log failed");
else Serial.println("Log ok");

Here is logFile:

int logFile(int temp0, int temp1) {
  File fh = SD.open("test.txt",FILE_WRITE);

  if(!fh) {
    Serial.println("Open fail");
    return 0;
  }

  // Use the same character array here to send stuff to the file.
  // pageAdd array is global
  sprintf(pageAdd,"Field1=%u Field2=%u",temp0,temp1);
  fh.println(pageAdd);
  fh.close();
  return 1;
}

problems coming... test.txt created manually, but have errors.

Temperatures are 29 Celsius, 0 Celsius, 0 Celsius,

connecting...failed
Fail Open fail
Log failed
1