Skip to content

Instantly share code, notes, and snippets.

Created December 23, 2012 13:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/4363344 to your computer and use it in GitHub Desktop.
Save anonymous/4363344 to your computer and use it in GitHub Desktop.
temperature logger arduino + enc28J60
#include <SPI.h>
#include "etherShield.h"
#include <LiquidCrystal.h>
#include "Sensirion.h"
#include <OneWire.h>
#include <DallasTemperature.h>
// please modify the following two lines. mac and ip have to be unique
// in your local area network. You can not have the same numbers in
// two devices:
static uint8_t mymac[6] = {0x54,0x55,0x58,0x10,0x04,0x05};
static uint8_t myip[4] = {192,168,1,16};
static char baseurl[]="http://192.168.1.16/";
static uint16_t mywwwport =80; // listen port for tcp/www (max range 1-254)
// or on a different port:
//static char baseurl[]="http://10.0.0.24:88/";
//static uint16_t mywwwport =88; // listen port for tcp/www (max range 1-254)
//
// Default gateway. The ip address of your DSL/Cable router.
static uint8_t gwip[4] = {192,168,1,1};
// ** pachube.com setup **
// IP address of the www.pachube.com server to contact (IP of the first portion of the URL):
static uint8_t pachubeip[4] = {216,52,233,122};
// The name of the virtual host which you want to contact at pachubeip (hostname of the first portion of the URL):
#define PACHUBE_VHOST "api.cosm.com"
// setup yor feed url and API keys here.
#define PACHUBEAPIURL "/v2/feeds/35832/datastreams/4.csv"
#define PACHUBEAPIKEY "X-PachubeApiKey: sj1H0f8qiJocfUu-ajZl6lpX28hzlG14WWxxOPsYDkE"
#define BUFFER_SIZE 500
static uint8_t buf[BUFFER_SIZE+1];
#define STR_BUFFER_SIZE 22
static char strbuf[STR_BUFFER_SIZE+1];
EtherShield es=EtherShield();
// initialize the library with the numbers of the interface pins
// RS 8
// Enable 9
LiquidCrystal lcd(1, 0, 4, 5, 6, 7);
#define SHTdataPin 4
#define SHTclockPin 3
#define LDRpin 0
// Data wire is plugged into port 2 on the Arduino
#define ONE_WIRE_BUS 9
float insideTemp, outsideTemp;
float humidity;
float dewPoint;
unsigned int measureresult;
int LDRval;
// Str version
char insideTempStr[10];
char outsideTempStr[10];
char dewPointStr[10];
char humidityStr[10];
char LDRvalStr[10];
Sensirion tempSensor = Sensirion(SHTdataPin, SHTclockPin);
// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
static volatile uint8_t start_web_client=0; // 0=off but enabled, 1=send update, 2=sending initiated, 3=update was sent OK, 4=diable updates
static uint8_t web_client_attempts=0;
static uint8_t web_client_sendok=0;
static uint8_t resend=0;
// prepare the webpage by writing the data to the tcp send buffer
uint16_t print_webpage(uint8_t *buf);
int8_t analyse_cmd(char *str);
//char * floatToString(char * outstr, float value, int places, int minwidth=, bool rightjustify) {
char * floatToString(char * outstr, float value, int places, int minwidth=0, bool rightjustify=false) {
// this is used to write a float value to string, outstr. oustr is also the return value.
int digit;
float tens = 0.1;
int tenscount = 0;
int i;
float tempfloat = value;
int c = 0;
int charcount = 1;
int extra = 0;
// make sure we round properly. this could use pow from <math.h>, but doesn't seem worth the import
// if this rounding step isn't here, the value 54.321 prints as 54.3209
// calculate rounding term d: 0.5/pow(10,places)
float d = 0.5;
if (value < 0)
d *= -1.0;
// divide by ten for each decimal place
for (i = 0; i < places; i++)
d/= 10.0;
// this small addition, combined with truncation will round our values properly
tempfloat += d;
// first get value tens to be the large power of ten less than value
if (value < 0)
tempfloat *= -1.0;
while ((tens * 10.0) <= tempfloat) {
tens *= 10.0;
tenscount += 1;
}
if (tenscount > 0)
charcount += tenscount;
else
charcount += 1;
if (value < 0)
charcount += 1;
charcount += 1 + places;
minwidth += 1; // both count the null final character
if (minwidth > charcount){
extra = minwidth - charcount;
charcount = minwidth;
}
if (extra > 0 and rightjustify) {
for (int i = 0; i< extra; i++) {
outstr[c++] = ' ';
}
}
// write out the negative if needed
if (value < 0)
outstr[c++] = '-';
if (tenscount == 0)
outstr[c++] = '0';
for (i=0; i< tenscount; i++) {
digit = (int) (tempfloat/tens);
itoa(digit, &outstr[c++], 10);
tempfloat = tempfloat - ((float)digit * tens);
tens /= 10.0;
}
// if no places after decimal, stop now and return
// otherwise, write the point and continue on
if (places > 0)
outstr[c++] = '.';
// now write out each decimal place by shifting digits one by one into the ones place and writing the truncated value
for (i = 0; i < places; i++) {
tempfloat *= 10.0;
digit = (int) tempfloat;
itoa(digit, &outstr[c++], 10);
// once written, subtract off that digit
tempfloat = tempfloat - (float) digit;
}
if (extra > 0 and not rightjustify) {
for (int i = 0; i< extra; i++) {
outstr[c++] = ' ';
}
}
outstr[c++] = '\0';
return outstr;
}
// Browser callback, where we get to after receiving a reply to an update, should really
// do somthing here to check all was OK.
void browserresult_callback(uint8_t statuscode,uint16_t datapos){
if (statuscode==0){
web_client_sendok++;
Serial.println("Pachube Ok");
}
else
{
Serial.print("Pachube error: ");
Serial.println(statuscode);
}
// clear pending state at sucessful contact with the
// web server even if account is expired:
if (start_web_client==2) start_web_client=3;
}
// prepare the webpage by writing the data to the tcp send buffer
uint16_t print_webpage(uint8_t *buf)
{
uint16_t plen;
char buffer[25]; // just give it plenty to write out any values you want to test
plen = es.ES_fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\nPragma: no-cache\r\n\r\n"));
// Display full info
plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("<h1>Arduino Monitoring</h1><pre>\n"));
plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("Inside Temp: "));
plen=es.ES_fill_tcp_data(buf,plen,insideTempStr);
plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("C\nRel Humidity: "));
plen=es.ES_fill_tcp_data(buf,plen,humidityStr);
plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("%RH\nDew Point: "));
plen=es.ES_fill_tcp_data(buf,plen,dewPointStr);
plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("C\nOutside Temp: "));
plen=es.ES_fill_tcp_data(buf,plen,outsideTempStr);
plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("C\nLight Level: "));
plen=es.ES_fill_tcp_data(buf,plen,LDRvalStr);
plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("%\n</pre>"));
plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("<a href=\"http://www.pachube.com/feeds/35832/\">Pachube Feed</a>"));
return(plen);
}
#define STATUS_BUFFER_SIZE 200
// global string buffer for twitter message:
static char statusstr[STATUS_BUFFER_SIZE];
//from http://www.arduino.cc/playground/Code/AvailableMemory
int availableMemory() {
uint8_t * heapptr, * stackptr;
stackptr = (uint8_t *)malloc(4);
heapptr = stackptr;
free(stackptr);
stackptr = (uint8_t *)(SP);
return stackptr - heapptr;
}
void setup(){
Serial.begin(57600);
// initialize enc28j60
es.ES_enc28j60Init(mymac);
//init the ethernet/ip layer:
es.ES_init_ip_arp_udp_tcp(mymac,myip, mywwwport);
// init the web client:
es.ES_client_set_gwip(gwip); // e.g internal IP of dsl router
// Start up the library
sensors.begin();
lcd.begin(16, 2);
lcd.print("Starting ...");
Serial.print("Free memory: ");
Serial.println(availableMemory());
}
void loop(){
uint16_t dat_p;
int8_t cmd;
start_web_client=1;
unsigned long lastSend = millis();
unsigned long time;
while(1){
// handle ping and wait for a tcp packet
dat_p=es.ES_packetloop_icmp_tcp(buf,es.ES_enc28j60PacketReceive(BUFFER_SIZE, buf));
if(dat_p==0){
// Nothing received, jus see if there is anythng to do
time = millis();
if( time > (lastSend + 30000) ) {
resend=1; // resend once if it failed
start_web_client=1;
lastSend = time;
Serial.println("Timer > 30 sec");
}
if (start_web_client==1) {
Serial.println("Start ...");
start_web_client=2;
web_client_attempts++;
Serial.print("Free memory: ");
Serial.println(availableMemory());
// Actualisation des sensors
// SHT11
measureresult = tempSensor.measure(&insideTemp, &humidity, &dewPoint);
Serial.print("Result: ");
Serial.println(measureresult);
insideTemp=insideTemp; // correction de la temperature de l'air
// Dallas
sensors.requestTemperatures(); // Send the command to get temperatures
outsideTemp = sensors.getTempCByIndex(0);
outsideTemp=outsideTemp-0.7; // correction de la temperature de l'eau
// LDR
LDRval = analogRead(LDRpin);
LDRval = map(LDRval, 0, 1023, 0, 100);
floatToString(outsideTempStr, outsideTemp, 2);
floatToString(insideTempStr, insideTemp, 2);
floatToString(humidityStr, humidity, 2);
floatToString(dewPointStr, dewPoint, 2);
itoa(LDRval,LDRvalStr,10);
lcd.setCursor(0, 0);
lcd.print("O");
lcd.print(outsideTempStr);
lcd.print("C I");
lcd.print(insideTempStr);
lcd.print("C");
lcd.setCursor(0, 1);
lcd.print("H");
lcd.print(humidityStr);
lcd.print("% L");
lcd.print(LDRvalStr);
Serial.print("LDRval: ");
Serial.println(LDRvalStr);
// Decide to update pachube or tweet
// Pachube update
sprintf( statusstr, "%s", insideTempStr );
Serial.println(statusstr);
es.ES_client_set_wwwip(pachubeip);
es.ES_client_http_post(PSTR("/v2/feeds/35832/datastreams/4.csv"),PSTR(PACHUBE_VHOST),PSTR(PACHUBEAPIKEY), PSTR("PUT "), insideTempStr ,&browserresult_callback);
// }
// continue;
dat_p=print_webpage(buf);
es.ES_www_server_reply(buf,dat_p); // send data
// }
//delay(1000); //attendre une seconde
sprintf( statusstr, "%s", outsideTempStr );
Serial.println(statusstr);
es.ES_client_set_wwwip(pachubeip);
es.ES_client_http_post(PSTR("/v2/feeds/35832/datastreams/5.csv"),PSTR(PACHUBE_VHOST),PSTR(PACHUBEAPIKEY), PSTR("PUT "), outsideTempStr ,&browserresult_callback);
}
continue;
}
dat_p=print_webpage(buf);
es.ES_www_server_reply(buf,dat_p); // send data
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment