/*
* SD card attached to SPI bus as follows:
** MOSI - pin 11
** MISO - pin 12
** CLK - pin 13
** CS - pin 4
*/
#include <SD.h>
#include <OneWire.h>
#include <SPI.h>
#include <Ethernet.h>
/*********** SD Stuff ****************/
// On the Ethernet Shield, CS is pin 4. Note that even if it's not
// used as the CS pin, the hardware CS pin (10 on most Arduino boards,
// 53 on the Mega) must be left as an output or the SD library
// functions will not work.
const int chipSelect = 4;
/*********** ETHERNET STUFF ***********/
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192, 168, 1, 177 };
EthernetServer server(80);
#define BUFSIZ 100
/********** OneWire Stuff ************/
OneWire ds(9); // OneWire bus on pin 9
float celsius[10], fahrenheit[10];
int cnt=0, maxCnt;
/********** Radial Stuff ************/
char *bcname[]={"HLT","MLT","RIMS","BOIL","TBD"};
char *bcrfn[]={"bcr100.htm","bcr150.htm","bcr200.htm","bcr250.htm","bcr300.htm","bcr350.htm"};
int bcrsize[]={100,150,200,250,300,350};
void setup()
{
// Open serial communications and wait for port to open:
Serial.begin(9600);
// Serial.print("Initializing SD card...");
// make sure that the default chip select pin is set to
// output, even if you don't use it:
pinMode(10, OUTPUT);
// see if the card is present and can be initialized:
if (!SD.begin(chipSelect)) {
Serial.println(F("Card failed, or not present"));
// don't do anything more:
return;
}
// Serial.println(F("SD card initialized."));
// set up bcradial.htm
byte addr[8];
while ( ds.search(addr)) {
cnt++;
delay(500);
}
ds.reset_search();
// Serial.println("No more addresses.");
// Serial.println();
maxCnt = cnt;
cnt=0;
// Serial.print(F("maxCnt = "));
// Serial.println(maxCnt);
// create radial canvas files
//Serial.println(sizeof(bcrsize)/sizeof(int));
for(int cnta = 0; cnta < (sizeof(bcrsize)/sizeof(int)); cnta++)
{
SD.remove(bcrfn[cnta]);
writeBCRfile(bcrfn[cnta], bcrsize[cnta]);
}
// now start up the webserver
Ethernet.begin(mac, ip);
server.begin();
// Serial.print(F("Ethernet server is at "));
// Serial.println(Ethernet.localIP());
}
void getOneWire(void)
{
byte i;
byte present = 0;
byte type_s;
byte data[12];
byte addr[8];
if ( !ds.search(addr)) {
// Serial.println("No more addresses.");
// Serial.println();
maxCnt = cnt;
cnt=0;
ds.reset_search();
delay(500);
return;
}
/*
Serial.print("ROM ");
Serial.print(cnt);
Serial.print(" = ");
for( i = 0; i < 8; i++)
{
Serial.write(' ');
Serial.print(addr[i], HEX);
}
if (OneWire::crc8(addr, 7) != addr[7]) {
Serial.println("CRC is not valid!");
return;
}
Serial.println();
*/
// the first ROM byte indicates which chip
switch (addr[0]) {
case 0x10:
// Serial.println(" Chip = DS18S20"); // or old DS1820
type_s = 1;
break;
case 0x28:
// Serial.println(" Chip = DS18B20");
type_s = 0;
break;
case 0x22:
// Serial.println(" Chip = DS1822");
type_s = 0;
break;
default:
Serial.println(F("Not a DS18x20"));
return;
}
ds.reset();
ds.select(addr);
ds.write(0x44,1); // start conversion, with parasite power on at the end
delay(750); // 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
// Serial.print(" Data = ");
// Serial.print(present,HEX);
// Serial.print(" ");
for ( i = 0; i < 9; i++) { // we need 9 bytes
data[i] = ds.read();
// Serial.print(data[i], HEX);
// Serial.print(" ");
}
// Serial.print(" CRC=");
// Serial.print(OneWire::crc8(data, 8), HEX);
// Serial.println();
// convert the data to actual temperature
unsigned int raw = (data[1] << 8) | data[0];
if (type_s) {
raw = raw << 3; // 9 bit resolution default
if (data[7] == 0x10) {
// count remain gives full 12 bit resolution
raw = (raw & 0xFFF0) + 12 - data[6];
}
} else {
byte cfg = (data[4] & 0x60);
if (cfg == 0x00) raw = raw << 3; // 9 bit resolution, 93.75 ms
else if (cfg == 0x20) raw = raw << 2; // 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[cnt] = (float)raw / 16.0;
fahrenheit[cnt] = ((celsius[cnt] * 1.8) + 31.0);
// degC = (int)(celsius + 0.5);
// degF = (int)(((celsius * 1.8) + 32.0) + 0.5);
// Serial.print(" Temperature = ");
// Serial.print(celsius[cnt]);
// Serial.print(" Celsius, ");
// Serial.print(fahrenheit[cnt]);
// Serial.println(" Fahrenheit");
cnt++;
}
void writeBCRfile(char *filename, int size)
{
int cntz;
File bcrWriteFile = SD.open(filename, FILE_WRITE);
if (bcrWriteFile)
{
bcrWriteFile.println(F("<!DOCTYPE html>"));
bcrWriteFile.println(F("<html lang=\"en\">"));
bcrWriteFile.println(F("<head>"));
bcrWriteFile.println(F(" <meta charset=\"utf-8\" />"));
bcrWriteFile.println(F(" <title>ButtCrack Brewery</title>"));
bcrWriteFile.println(F(" <script type='text/javascript' src='http://www.buttcrackbrewery.com/js/Arduino/tween.js'></script>"));
bcrWriteFile.println(F(" <script type='text/javascript' src='http://www.buttcrackbrewery.com/js/Arduino/sslib1.js'></script>"));
bcrWriteFile.println(F(""));
bcrWriteFile.println(F(" <script type=\"application/javascript\">"));
bcrWriteFile.println(F(""));
bcrWriteFile.println(F("// Ajax request for xml data generated by Arduino"));
bcrWriteFile.println(F(" function ajaxUpdateValues()"));
bcrWriteFile.println(F(" {"));
bcrWriteFile.println(F(""));
bcrWriteFile.println(F(" var httpRequest;"));
bcrWriteFile.println(F(" var xmlDoc;"));
bcrWriteFile.println(F(""));
bcrWriteFile.println(F("// get the xml document via Ajax/http"));
bcrWriteFile.println(F(" httpRequest = new XMLHttpRequest();"));
bcrWriteFile.println(F(" httpRequest.onreadystatechange=function() {"));
bcrWriteFile.println(F(" if(httpRequest.readyState == 4) {"));
bcrWriteFile.println(F(" steamPress = Number(httpRequest.responseText);"));
bcrWriteFile.println(F(" }"));
bcrWriteFile.println(F(" }"));
bcrWriteFile.println(F(" httpRequest.open(\"GET\",\"http://192.168.1.177/butcrack.xml\",false);"));
bcrWriteFile.println(F(" httpRequest.send(null);"));
bcrWriteFile.println(F(" xmlDoc=httpRequest.responseXML;"));
bcrWriteFile.println(F("\n// update the global variables by parsing the xml document"));
for(cntz = 0; cntz < maxCnt; cntz++)
{
bcrWriteFile.print(F(" Temp"));
bcrWriteFile.print(cntz);
bcrWriteFile.print(F("=Number(xmlDoc.getElementsByTagName(\"Temp"));
bcrWriteFile.print(cntz);
bcrWriteFile.println(F("\")[0].childNodes[0].nodeValue);"));
}
bcrWriteFile.println(F(""));
bcrWriteFile.println(F(" }"));
bcrWriteFile.println(F(""));
bcrWriteFile.println(F(" function init()"));
bcrWriteFile.println(F(" {"));
bcrWriteFile.println(F(""));
bcrWriteFile.println(F("// Define section(s)"));
bcrWriteFile.print(F(" sections = Array(steelseries.Section(68, 80,\"rgba(0, 0, 254, 0.9)\"),\n\t steelseries.Section(140, 160,\"rgba(0, 254, 0, 0.9)\"),\n\t steelseries.Section(160, 180,\"rgba(254, 254, 0, 0.9)\"),\n\t steelseries.Section(180, 220, \"rgba(254, 0, 0, 0.9)\"));\n"));
bcrWriteFile.println(F(""));
bcrWriteFile.println(F("// Define area(s)"));
bcrWriteFile.print(F(" areas = Array(steelseries.Section(68, 80,\"rgba(0, 0, 254, 0.9)\"),\n\tsteelseries.Section(140, 160,\"rgba(0, 254, 0, 0.9)\"),\n\tsteelseries.Section(160, 180,\"rgba(254, 254, 0, 0.9)\"),\n\tsteelseries.Section(180, 220, \"rgba(254, 0, 0, 0.9)\"));\n"));
bcrWriteFile.println(F(""));
bcrWriteFile.println(F("// Initialize gauge"));
for(cntz = 0; cntz < maxCnt; cntz++)
{
bcrWriteFile.print(F(" radial"));
bcrWriteFile.print(cntz);
bcrWriteFile.print(F(" = new steelseries.Radial(\"Temp"));
bcrWriteFile.print(cntz);
bcrWriteFile.println(F("\", "));
bcrWriteFile.println(F(" {"));
// bcrWriteFile.println(F("// gaugeType: steelseries.GaugeType.TYPE3,"));
bcrWriteFile.print(F("\tsize: "));
bcrWriteFile.print(size);
bcrWriteFile.print(F(",\n\tminValue: 0,\n\tmaxValue: 220,\n\tthreshold: 152,\n\tsection: sections,\n\tarea: areas,\n\ttitleString: \""));
bcrWriteFile.print(bcname[cntz]);
bcrWriteFile.println(F("\",\n\tunitString: \"°F\",\n\tpointerType: steelseries.PointerType.TYPE2,\n\tframeDesign: steelseries.FrameDesign.BLACK_METAL,\n\tforegroundType: steelseries.ForegroundType.TYPE3,\n\tbackgroundColor: steelseries.BackgroundColor.CARBON,\n\tledVisible: true"));
bcrWriteFile.println(F(" });"));
bcrWriteFile.println(F(""));
}
bcrWriteFile.println(F(""));
bcrWriteFile.println(F("// Start the random update"));
bcrWriteFile.println(F(" setInterval(function(){ ajaxUpdateValues(); }, 5000); "));
for(cntz = 0; cntz < maxCnt; cntz++)
{
bcrWriteFile.print(F(" setInterval(function(){ setValue(radial"));
bcrWriteFile.print(cntz);
bcrWriteFile.print(F(", Temp"));
bcrWriteFile.print(cntz);
bcrWriteFile.println(F("); }, 10000);"));
}
// bcrWriteFile.println(F(""));
bcrWriteFile.println(F("\n }"));
bcrWriteFile.println(F(""));
bcrWriteFile.println(F(" function setValue(gauge, range)"));
bcrWriteFile.println(F(" {"));
bcrWriteFile.println(F(" gauge.setValueAnimated(range);"));
bcrWriteFile.println(F(" }"));
bcrWriteFile.println(F(""));
bcrWriteFile.println(F(""));
bcrWriteFile.println(F("</script>"));
bcrWriteFile.println(F("<style>body {background: url(\"http://www.buttcrackbrewery.com/images/Arduino/bc.png\");}</style>"));
bcrWriteFile.println(F("</head>"));
bcrWriteFile.println(F("<body onload=\"init()\"> "));
for(cntz = 0; cntz < maxCnt; cntz++)
{
bcrWriteFile.print(F("\t<canvas id=\"Temp"));
bcrWriteFile.print(cntz);
bcrWriteFile.println(F("\">\n\tNo canvas in your browser...sorry...\n\t</canvas>"));
}
bcrWriteFile.println(F("</body>"));
bcrWriteFile.println(F("</html>"));
bcrWriteFile.close();
Serial.print(filename);
Serial.println(F(" written"));
} else {
// if the file didn't open, print an error:
Serial.println(F("error opening bcradial.htm"));
}
}
void writeXMLfile(void)
{
int cnty;
// open the file. note that only one file can be open at a time,
// so you have to close this one before opening another.
File xmlWriteFile = SD.open("butcrack.xml", FILE_WRITE);
// if the file opened okay, write to it:
if (xmlWriteFile) {
// Serial.print("Writing to butcrack.xml...");
xmlWriteFile.print(F("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>"));
xmlWriteFile.print(F("<!-- Created by Arduino Buttcrack sketch -->"));
xmlWriteFile.print(F("<buttcrack>"));
for (cnty = 0; cnty < maxCnt; cnty++)
{
xmlWriteFile.print(F("<Temp"));
xmlWriteFile.print(cnty);
xmlWriteFile.print(F(">"));
xmlWriteFile.print(fahrenheit[cnty],1);
xmlWriteFile.print(F("</Temp"));
xmlWriteFile.print(cnty);
xmlWriteFile.print(F(">"));
}
xmlWriteFile.print(F("</buttcrack>"));
// close the file:
xmlWriteFile.close();
// Serial.println("done.");
} else {
// if the file didn't open, print an error:
Serial.println(F("error opening butcrack.xml"));
}
}
/*
void readXMLfile(void)
{
// open the file. note that only one file can be open at a time,
// so you have to close this one before opening another.
File xmlReadFile = SD.open("butcrack.xml");
// if the file is available, write to it:
if (xmlReadFile)
{
while (xmlReadFile.available())
{
Serial.write(xmlReadFile.read());
}
xmlReadFile.close();
} else {
// if the file isn't open, pop up an error:
Serial.println("error opening butcrack.xml");
}
}
*/
void writeTemperatureFile(void)
{
int cntx;
// open the file. note that only one file can be open at a time,
// so you have to close this one before opening another.
File tempWriteFile = SD.open("thermo.htm", FILE_WRITE);
// if the file opened okay, write to it:
if (tempWriteFile)
{
// Serial.print(F("Writing to thermo.htm..."));
tempWriteFile.println(F("HTTP/1.1 200 OK"));
tempWriteFile.println(F("Content-Type: text/html"));
tempWriteFile.println(F("Connnection: close"));
tempWriteFile.println();
tempWriteFile.println(F("<!DOCTYPE HTML>"));
tempWriteFile.println(F("<html>"));
// add a meta refresh tag, so the browser pulls again every 60 seconds:
tempWriteFile.println(F("<meta http-equiv=\"refresh\" content=\"60\">"));
// output the value of each analog input pin
tempWriteFile.println(F("<table><tr>"));
for(cntx=0 ; cntx < maxCnt ; cntx++)
{
tempWriteFile.print(F("<td Align=\"center\" valign=\"top\">"));
tempWriteFile.print(F("    Ambient Temperature "));
tempWriteFile.print(cntx);
tempWriteFile.print(F(":    <br /><br /><font size=\"10\">"));
tempWriteFile.print(fahrenheit[cntx], 1);
tempWriteFile.println(F("°</font>F"));
tempWriteFile.print(F("<br /><font size=\"8\">"));
tempWriteFile.print(celsius[cntx], 1);
tempWriteFile.print(F("°</font>C"));
tempWriteFile.println(F("</td>"));
}
tempWriteFile.println(F("</tr></table>"));
tempWriteFile.println(F("</html>"));
// close the file:
tempWriteFile.close();
// Serial.println("done.");
} else {
// if the file didn't open, print an error:
Serial.println(F("error opening thermo.htm"));
}
}
/*
void readTemperaturefile(void)
{
// open the file. note that only one file can be open at a time,
// so you have to close this one before opening another.
File tempReadFile = SD.open("thermo.htm");
// if the file is available, write to it:
if (tempReadFile)
{
while (tempReadFile.available())
{
Serial.write(tempReadFile.read());
}
tempReadFile.close();
} else {
// if the file isn't open, pop up an error:
Serial.println("error opening thermo.htm");
}
}
*/
void checkForInternetRequest(void)
{
char clientline[BUFSIZ];
char *filename;
int index = 0;
int image = 0;
EthernetClient client = server.available();
if (client) {
// an http request ends with a blank line
boolean current_line_is_blank = true;
// reset the input buffer
index = 0;
while (client.connected()) {
if (client.available()) {
char c = client.read();
// If it isn't a new line, add the character to the buffer
if (c != '\n' && c != '\r') {
clientline[index] = c;
index++;
// are we too big for the buffer? start tossing out data
if (index >= BUFSIZ)
index = BUFSIZ -1;
// continue to read more data!
continue;
}
// got a \n or \r new line, which means the string is done
clientline[index] = 0;
filename = 0;
// Print it out for debugging
// Serial.println(clientline);
/*
// Look for substring such as a request to get the root file
if (strstr(clientline, "GET / ") != 0)
{
filename = rootFileName;
}
*/
if (strstr(clientline, "GET /") != 0) {
// this time no space after the /, so a sub-file
if (!filename) filename = clientline + 5; // look after the "GET /" (5 chars)
// a little trick, look for the " HTTP/1.1" string and
// turn the first character of the substring into a 0 to clear it out.
(strstr(clientline, " HTTP"))[0] = 0;
// print the file we want
if (
(strstr(filename, ".htm") != 0) |
(strstr(filename, ".xml") != 0) |
(strstr(filename, ".js") != 0)
)
{
Serial.print(filename);
File webReadFile = SD.open(filename);
if (webReadFile)
{
Serial.println(F(" - Opened!"));
while (webReadFile.available())
{
client.write(webReadFile.read());
}
webReadFile.close();
} else {
// if the file isn't open, pop up an error:
Serial.print(" - error");
// Serial.println(filename);
client.println(F("HTTP/1.1 404 Not Found"));
client.println(F("Content-Type: text/html"));
client.println();
client.println(F("<h2>File Not Found!</h2>"));
break;
}
webReadFile.close();
} else {
// everything else is a 404
client.println(F("HTTP/1.1 404 Not Found"));
client.println(F("Content-Type: text/html"));
client.println();
client.println(F("<h2>File Not Found</h2>"));
}
break;
}
}
}
// give the web browser time to receive the data
delay(1);
client.stop();
}
}
void loop()
{
// readXMLfile();
// readTemperaturefile();
SD.remove("butcrack.xml");
SD.remove("thermo.htm");
getOneWire();
writeXMLfile();
writeTemperatureFile();
checkForInternetRequest();
// delay(2000);
}