Skip to content

Instantly share code, notes, and snippets.

@analogic
Last active August 29, 2015 14:16
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 analogic/88b41891b4279e8ba67b to your computer and use it in GitHub Desktop.
Save analogic/88b41891b4279e8ba67b to your computer and use it in GitHub Desktop.
#include <OneWire.h>
#include <EtherCard.h>
#include <avr/wdt.h>
// milliseconds to wait for data send
#define REQUEST_RATE 60000
// ethernet module RST pin
#define ETHERNET_RST 6
// arduino RST pin
#define ARDUINO_RST 4
// do you want debug through Serial?
#define SERIAL true
// ethernet interface mac address, must be unique on the LAN
static byte mymac[] = { 0x74,0x69,0x69,0x2D,0x30,0x31 };
static byte myip[] = { 192,168,88,111 };
static byte mygw[] = { 192,168,88,1 };
static byte mydns[] = { 8,8,8,8 };
static byte mask[] = { 255,255,255,0 };
// we will test every minut DNS(restart if unavailable)
// and send data to that host
const char website[] PROGMEM = "your.server.com";
// we need to send request right after start
static long timer = -REQUEST_RATE;
OneWire ds(3);
byte Ethernet::buffer[500];
BufferFiller bfill;
char zxc[7];
byte addr[8]; // temp sensor address
uint8_t errata;
void setup () {
// http://weblog.jos.ph/development/arduino-reset-hack/
digitalWrite(ARDUINO_RST, HIGH); //We need to set it HIGH immediately on boot
pinMode(ARDUINO_RST,OUTPUT); //We can declare it an output ONLY AFTER it's HIGH
// if there is watchdog running stop it!
wdt_disable();
// Starting watchdog with 8s timeout
wdt_enable(WDTO_8S);
#if SERIAL
// starting Serial debug
Serial.begin(9600);
debugln('Hello world!');
#endif
// Starting ethernet
// will keep restarting whole arduino while it got started properly
while(restartEthernet()) {
digitalWrite(ARDUINO_RST, LOW); // Force restart
}
// Find temp sensor, some attempts can fail so we will run it until
// address with proper CRC is found
while(restartDS18B20()) {
digitalWrite(ARDUINO_RST, LOW); // Force restart
}
}
bool restartEthernet() {
debugln(F("Restarting ethernet"));
pinMode(ETHERNET_RST, OUTPUT);
digitalWrite(ETHERNET_RST, HIGH);
delay(200);
// ENC28J60 resets on holding RST pin LOW
digitalWrite(ETHERNET_RST, LOW);
delay(200);
digitalWrite(ETHERNET_RST, HIGH);
delay(200);
ether.doBIST();
debugln(F("...done"));
errata = ether.begin(sizeof Ethernet::buffer, mymac);
if (errata == 0) {
debugln(F("Failed to access Ethernet controller"));
return 1;
}
Serial.println(errata);
debugln(F("Ethernet begin() success"));
debugln(F("Setting static IP"));
ether.staticSetup(myip, mygw, mydns, mask);
// dynamic/static setup can sometimes take long time
// so we rather get another 8s to DNS resolve test
wdt_reset();
#if SERIAL
debugln(F("...done"));
ether.printIp("IP: ", ether.myip);
ether.printIp("GW: ", ether.gwip);
ether.printIp("DNS: ", ether.dnsip);
#endif
if (!ether.dnsLookup(website)) {
debugln(F("Failed to resolve domain name via DNS"));
return 1;
}
#if SERIAL
ether.printIp("SRV: ", ether.hisip);
#endif
wdt_reset();
debugln(F("...OK"));
return 0;
}
bool restartDS18B20() {
debugln(F("Searching temp sensor"));
byte i;
ds.reset_search();
if ( !ds.search(addr)) {
debugln(F("No more addresses."));
ds.reset_search();
return 1;
}
debug(F("ROM ="));
for( i = 0; i < 8; i++) {
debug(F(" "));
debug(addr[i], HEX);
}
debugln();
debugln(F("CRC check"));
if (OneWire::crc8(addr, 7) != addr[7]) {
debugln(F("CRC is not valid!"));
return 1;
}
debugln(F("...OK"));
return 0;
}
static void response (byte status, word off, word len)
{
debugln(F(">>>"));
Ethernet::buffer[off+300] = 0;
debugln((const char*) Ethernet::buffer + off);
debugln(F("..."));
}
void loop ()
{
ether.packetLoop(ether.packetReceive());
if (millis() > timer + REQUEST_RATE) {
timer = millis();
delay(500);
if (!ether.dnsLookup(website)) {
debugln(F("Failed to resolve domain name via DNS, forcing restart"));
digitalWrite(ARDUINO_RST, LOW); // Force restart
}
char data[50];
sprintf(data, "?temp=%s&uptime=%ld", dtostrf(temperature(),3,2,zxc), timer/1000);
debug(F("<<< REQ "));
debugln(data);
wdt_reset();
ether.browseUrl(PSTR("/therm.php"), data, website, response);
}
if(timer > 86400000) {
digitalWrite(ARDUINO_RST, LOW); // Force restart
}
wdt_reset();
}
float temperature()
{
byte i;
byte present = 0;
byte data[12];
float celsius, fahrenheit;
ds.reset();
ds.select(addr);
ds.write(0x44, 1); // start conversion, with parasite power on at the end
delay(1000); // maybe 750ms is enough, maybe not
// we might do a ds.depower() here, but the reset will take care of it.
present = ds.reset();
ds.select(addr);
ds.write(0xBE); // Read Scratchpad
debug(F(" Data = "));
debug(present, HEX);
debug(F(" "));
for ( i = 0; i < 9; i++) { // we need 9 bytes
data[i] = ds.read();
debug(data[i], HEX);
debug(F(" "));
}
debug(F(" CRC="));
debug(OneWire::crc8(data, 8), HEX);
debugln();
// Convert the data to actual temperature
// because the result is a 16 bit signed integer, it should
// be stored to an "int16_t" type, which is always 16 bits
// even when compiled on a 32 bit processor.
int16_t raw = (data[1] << 8) | data[0];
byte cfg = (data[4] & 0x60);
// at lower res, the low bits are undefined, so let's zero them
if (cfg == 0x00) raw = raw & ~7; // 9 bit resolution, 93.75 ms
else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
//// default is 12 bit resolution, 750 ms conversion time
celsius = (float)raw / 16.0;
fahrenheit = celsius * 1.8 + 32.0;
debug(F(" Temperature = "));
debug(celsius);
debugln(F(" Celsius"));
return celsius;
}
/********************* DEBUG SUGAR ****************************/
void debug(const __FlashStringHelper *ifsh) {
#if SERIAL
Serial.print(ifsh);
#endif
}
void debug(const char *message) {
#if SERIAL
Serial.print(message);
#endif
}
void debug(int num) {
#if SERIAL
Serial.print(num);
#endif
}
void debug(uint8_t b, int s) {
#if SERIAL
Serial.print(b, s);
#endif
}
void debugln(const __FlashStringHelper *ifsh) {
#if SERIAL
Serial.println(ifsh);
#endif
}
void debugln(const char *message) {
#if SERIAL
Serial.println(message);
#endif
}
void debugln(int num) {
#if SERIAL
Serial.println(num);
#endif
}
void debugln() {
#if SERIAL
Serial.println();
#endif
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment