This is my formal write-up for
RiderNet; an Arduino-managed all-weather WiFi network that I'm building for Misty Brae Farm.
This project would never have happened were it not for Lady Ada and the fantastic tutorials she has created for the many
projects that Adafruit Industries creates and sells. She is an inspiration to the DIY community, for which I am deeply grateful!
Starting Requirements:I always like to start a project with a set of requirements to work from, otherwise I have been known to get lost in the weeds.

The business need is to carry an IP network out to several barns that have no network connectivity, so that several
Arduino projects can work from within the barns. The second business need was to create a Wifi network for customers
of Misty Brae Farm to use, adding a perk that few other large horse farms will have! The initial plans for the RiderNet
network are projects called RiderScan (WIP)
http://forums.adafruit.com/viewtopic.php?f=25&t=22139&p=118096&hilit=RiderScan,
RiderTrack (WIP) and RiderCam (Planned)
* RiderScan uses RFID reader systems to allow riders to badge-in for lessons or work time, to quickly identify
tack with the horse that it belongs to and to allow instructors to see who is riding or who rode on a given day.
* RiderCam is an Arduino-managed set of outdoor wireless video cameras positioned around the farm. Each camera will
sit on small servo platform managed by an Arduino and Adafruit Motor Shield, so the cameras can pan-around.
* RiderTrack is an all-weather Linux server that will sit at the main barn and manage a host of systems, provide
web-sites for RiderScan and video-management software for RiderCam.
These were the requirements I started with in March 2011. I decided on the functional following design:
Structure: A. I decided to use a mineral-oil cooled/heated system to provide stable temperature control
for the electronics without the need for any air-flow for exposure to the elements.
B. I decided to use a small 15 Watt aquarium heater to heat the mineral oil on cold winter nights.
C. I'm using a Sunterra aquarium pump to circulate the mineral oil around the router.
D. I chose 3/8" inch thick Acrylic for the exterior case, mainly for astetics. Using Acrylic and
bright blue LEDs allows me to add a blue-glow that looks great at night. The Acrylic also
allows me to see what's going on inside. A wooden deck with wood pedistals will provide mounting.
E. Based on the lessons learned from the V1 prototype of RiderNet, the new strategy is to mount
-Nothing- to walls/base of the mineral oil tank itself. Rather the tanks are just like fish
tanks and thus will never leak. My new idea was to mount all the tronics onto a single piece
of Acrylic that is slightly smaller than the dimentions of the tanks. Then the router/tronics
are immersed in the tank without any exterior holes to worry about. Second great advantage of
this method is that it allows me to remove all of the tronics to maintenance/work/replace them
very easily without moving the router tank or dealing with a huge mess. I call them router "slips"
and each is attached to the Top of the tank, meaning I just pull off the top of the tank and
the router/arduino/tronics comes out with it. All of the rubber/weather-stripping is applied
to the inside of the top of the tank, so all waterproofing is done at one point making it much
easier to build. I recommend this to anyone doing mineral oil projects.
Router:F. I settled on Netgear WNDR-3300 wireless routers because they are inexpensive,
readily available and compatible with the DD-WRT Linux OS.
G. I using DD-WRT for the operating system to run on the wireless routers, because Linux is king
and DD-WRT is an extremely capable WiFi router management system.
H. I decided to build a Wireless Distribution System (WDS) for the wireless network configuration.
This will allow the same Class-C network to span across all routers, so someone can move to
anywhere on the farm and keep the same IP and connectivity.
I. I'm using WPA2 Personal with AES encryption as the security, because I want the bad guys to stay out!
Arduino:J. I decided on using an Arduino Mega as the controller, because I need the SRAM for my phat code.
The UNO would have enough digital/analog PINs, but I have big plans for the future and want
the expansion room to grow as the project evolves.
K. I decided on using an Ethernet Shield to connect it to the network. This was not my first choice,
I would have MUCH rather used a Wifi network adapter instead of a hard-wire, but the Arduino
Wifi shields were not out yet and the Async Labs shields were gone.

This still works well,
The Mega connects to the Wifi router it's mounted with using a hard-line cable.
L. I'm using the TMP36 Analog Temperature sensor for measuring the temperature inside the router
enclosure, and an Adafruit 10k precision epoxy thermistor for exterior/outside temperature.
M. I'm using Flex sensor to measure the oil-level inside the routers. The float is a small piece
of styrofoam with a small plastic horse attached, giving it the right weight/float charateristics.
N. I'm using a Photo cell to detect the router power status (sensor sits above the router power LED).
O. I will using a seris of status LED's that will allow me to make a quick determination of a router
status even when mounted high on trees or in the barns.
P. I went with a small web server on each Arduino that reports it's current status, future version
will have the Arduino send heart-beat signals to the RiderTrack server.
Q. I added 7 total LEDs to each setup (5 stand-alone, 2 tri-color RGB) to show power status, temp status,
fluid status, etc (I love blinky LEDs, now is my chance to go wild!).
R. I used the NHK Arduino Mega Protoshield to join the pins for each sensor and LED into groups which I
created/used wire-sets to make the wiring much more net.
Sketch / Code:The Arduino sketch for managing the routers I call, "RiderNet", and it's purposes are to:
A. Monitor the oil temperature to ensure the router is not too-hot or too-cold. If temperature gets critical,
I use the power-switch tail to disconnect power to the router and equipment (so only the Arduino remains on).
B. Monitor the power-status of the wireless router by watching the power-led with a photo-cell positioned ocer it,
and issue warnings if the router looses power.
C. Monitor the oil-level in the router with a flex sensor, and sound an alarm and shut-down power to the the
router if it looses oil pressure.
D. Provides a small web-server that prints the stats of the router every minute.
E. Provide an SNMP agent so that each router can be polled, and the stats tracked using Zymon/MRTG.
F. Provide a diagnostic capability so that the routers can be tested on/off the bench.
- Code: Select all
/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
RaiderNet Showcase version 1.3 - Octoboer 2011
Original Code Examples by Lady Ada of Adafruit Industries
Customization by Kris Kortright of Sojourn Studio
This code released under Creative Commons and is free to all
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
#include <SPI.h>
#include <Ethernet.h>
#include <SPI_VFD.h>
#include "DHT.h"
// Uncomment whatever type you're using!
//#define DHTTYPE DHT11 // DHT 11
#define DHTTYPE DHT22 // DHT 22 (AM2302)
//#define DHTTYPE DHT21 // DHT 21 (AM2301)
// resistance at 25 degrees C
#define THERMISTORNOMINAL 10000
// temp. for nominal resistance (almost always 25 C)
#define TEMPERATURENOMINAL 25
// how many samples to take and average, more takes longer
// but is more 'smooth'
#define NUMSAMPLES 5
// The beta coefficient of the thermistor (usually 3000-4000)
#define BCOEFFICIENT 3950
// the value of the 'other' resistor
#define SERIESRESISTOR 10000
// Set IDENTITY; 0=KortrightHaus, 1=Garage, 2=BoardersTack, 3=RiderTrack, 4=FeedRoom, 5=ClubHouse, 6=HutchisonHaus, 7=Backup
// int IDENTITY = 0;
// byte mac[] = { 0x90, 0xA2, 0xDA, 0x00, 0x3F, 0x40 };
// byte ip[] = { 192, 168, 1, 180 };
// int IDENTITY = 1;
// byte mac[] = { 0x90, 0xA2, 0xDA, 0x00, 0x3F, 0x41 };
// byte ip[] = { 192, 168, 1, 181 };
// int IDENTITY = 2;
// byte mac[] = { 0x90, 0xA2, 0xDA, 0x00, 0x3F, 0x42 };
// byte ip[] = { 192, 168, 1, 182 };
// int IDENTITY = 3;
// byte mac[] = { 0x90, 0xA2, 0xDA, 0x00, 0x3F, 0x43 };
// byte ip[] = { 192, 168, 1, 183 };
int IDENTITY = 4;
byte mac[] = { 0x90, 0xA2, 0xDA, 0x00, 0x3F, 0x44 };
byte ip[] = { 192, 168, 1, 184 };
// int IDENTITY = 5;
// byte mac[] = { 0x90, 0xA2, 0xDA, 0x00, 0x3F, 0x45 };
// byte ip[] = { 192, 168, 1, 185 };
// int IDENTITY = 6;
// byte mac[] = { 0x90, 0xA2, 0xDA, 0x00, 0x3F, 0x46 };
// byte ip[] = { 192, 168, 1, banned };
// int IDENTITY = 7;
// byte mac[] = { 0x90, 0xA2, 0xDA, 0x00, 0x3F, 0x47 };
// byte ip[] = { 192, 168, 1, 187 };
// int IDENTITY = 8;
// byte mac[] = { 0x90, 0xA2, 0xDA, 0x00, 0x3F, 0x48 };
// byte ip[] = { 192, 168, 1, 188 };
#define aref_voltage 3.3 // we tie 3.3V to ARef and measure it with a multimeter!
int VERSION = 1.2;
int POWER_INTERRUPT = 1;
int MAX_TEMP_ALARMS = 10;
int MAX_TILT_ALARMS = 10;
int ThermistorOffset = 15;
int TMP36offset = 0;
int samples[NUMSAMPLES];
int AdminState = 0;
int FluidState = 0;
int TempState = 0;
int RouterState = 0;
int RouterPowerState = 0;
int SystemState = 0;
int InternTempF = 0;
int ExternTempF = 0;
int SeriesDelay = (IDENTITY * 60);
int Tilts = 0;
int pinReadDelay = 10; // ms delay to stabilize reading on Arduino ADC when switching pin-to-pin?
unsigned int Loopy = 0;
int TempAlarms = 0;
int ReverseTiltMode = 0;
int FlexBaseline = 0;
int FlexAlarmLevel = 0;
int DigitalDHTSensor = 2;
int AnalogPhotoCellRouter = 67;
int AnalogInternalTemp = 62;
int AnalogThermistorSensor = 69;
int AnalogFlexSensor = 68;
int AnalogVibrationSensor = 65;
int DigitalRouterPower = 22;
int DigitalArduinoPowerLED = 28;
int DigitalRouterStatusLEDRed = 34;
int DigitalRouterStatusLEDGreen = 32;
int DigitalRouterStatusLEDYellow = 30;
int DigitalRouterPowerLED = 26;
int DigitalInternalTempLEDred = 48;
int DigitalInternalTempLEDblue = 44;
int DigitalInternalTempLEDgreen = 46;
int DigitalExternalTempLED = 42;
int DigitalOilLevelLED = 40;
int DigitalVibrationLED = 38;
// Start the VFD.
SPI_VFD vfd(23, 31, 27);
// Start the DHT sensor.
DHT dht(DigitalDHTSensor, DHTTYPE);
// Start the action
Server server(80);
void setup()
{
int i, k;
int Spinner = 0;
int SleepTime = 0;
int FluidStateRaw = 0;
int FlexTest1 = 0;
int FlexTest2 = 0;
int FlexTest3 = 0;
char buf[128];
// If you want to set the aref to something other than 5v
analogReference(EXTERNAL);
sprintf(buf, "RiderNet Router #%d", IDENTITY);
// set up the VFD's number of columns and rows:
vfd.begin(20, 2);
// Print a message to the VFD.
vfd.print(buf);
vfd.setCursor(0, 1);
vfd.print("Router starting up!");
pinMode(AnalogPhotoCellRouter, INPUT);
pinMode(AnalogInternalTemp, INPUT);
pinMode(AnalogThermistorSensor, INPUT);
pinMode(AnalogFlexSensor, INPUT);
pinMode(AnalogVibrationSensor, INPUT);
pinMode(DigitalDHTSensor, INPUT);
pinMode(DigitalExternalTempLED, OUTPUT);
pinMode(DigitalOilLevelLED, OUTPUT);
pinMode(DigitalVibrationLED, OUTPUT);
pinMode(DigitalArduinoPowerLED, OUTPUT);
pinMode(DigitalRouterPowerLED, OUTPUT);
pinMode(DigitalInternalTempLEDred, OUTPUT);
pinMode(DigitalInternalTempLEDgreen, OUTPUT);
pinMode(DigitalInternalTempLEDblue, OUTPUT);
pinMode(DigitalRouterPower, OUTPUT);
pinMode(DigitalRouterStatusLEDYellow, OUTPUT);
pinMode(DigitalRouterStatusLEDGreen, OUTPUT);
pinMode(DigitalRouterStatusLEDRed, OUTPUT);
digitalWrite(DigitalArduinoPowerLED, HIGH);
Serial.begin(9600);
// start the SPI library:
SPI.begin();
dht.begin();
// Valid Admin States are: 0 = Normal (ON), 1 = Reboot, 2 = Shut-off, 3 = Series Reboot
AdminState = 0;
if(AdminState == 0) {
digitalWrite(DigitalRouterPower, HIGH);
digitalWrite(DigitalRouterStatusLEDYellow, LOW);
digitalWrite(DigitalRouterStatusLEDGreen, HIGH);
digitalWrite(DigitalRouterStatusLEDRed, LOW);
SleepTime = 10000;
digitalWrite(DigitalRouterPower, HIGH);
for(i = 0; i < SleepTime; i = i + 1000) {
if(Spinner == 0) {
digitalWrite(DigitalRouterPowerLED, HIGH);
Spinner = 1;
} else {
digitalWrite(DigitalRouterPowerLED, LOW);
Spinner = 0;
}
delay(1000);
}
} else if(AdminState == 1) {
SleepTime = 30000;
digitalWrite(DigitalRouterPower, LOW);
for(i = 0; i < SleepTime; i = i + 1000) {
if(Spinner == 0) {
digitalWrite(DigitalRouterPowerLED, HIGH);
Spinner = 1;
} else {
digitalWrite(DigitalRouterPowerLED, LOW);
Spinner = 0;
}
delay(1000);
}
digitalWrite(DigitalRouterPower, HIGH);
digitalWrite(DigitalRouterStatusLEDYellow, HIGH);
digitalWrite(DigitalRouterStatusLEDGreen, LOW);
digitalWrite(DigitalRouterStatusLEDRed, LOW);
AdminState = 0;
} else if(AdminState == 2) {
if(POWER_INTERRUPT == 1) {
digitalWrite(DigitalRouterPower, LOW);
}
digitalWrite(DigitalRouterStatusLEDYellow, LOW);
digitalWrite(DigitalRouterStatusLEDGreen, LOW);
digitalWrite(DigitalRouterStatusLEDRed, HIGH);
} else if(AdminState == 3) {
if(POWER_INTERRUPT == 1) {
digitalWrite(DigitalRouterPower, LOW);
}
for(i = 0; i < SeriesDelay; i = i + 1000) {
if(Spinner == 0) {
digitalWrite(DigitalRouterPowerLED, HIGH);
Spinner = 1;
} else {
digitalWrite(DigitalRouterPowerLED, LOW);
Spinner = 0;
}
delay(100);
}
digitalWrite(DigitalRouterPowerLED, HIGH);
digitalWrite(DigitalRouterStatusLEDYellow, HIGH);
digitalWrite(DigitalRouterStatusLEDGreen, LOW);
digitalWrite(DigitalRouterStatusLEDRed, LOW);
delay(SeriesDelay);
digitalWrite(DigitalRouterPower, HIGH);
AdminState = 0;
} else {
digitalWrite(DigitalRouterPower, HIGH);
}
// start the Ethernet connection and the server:
Ethernet.begin(mac, ip);
server.begin();
digitalWrite(DigitalRouterStatusLEDRed, HIGH);
digitalWrite(DigitalRouterStatusLEDGreen, HIGH);
digitalWrite(DigitalRouterStatusLEDYellow, HIGH);
digitalWrite(DigitalInternalTempLEDgreen, HIGH);
digitalWrite(DigitalInternalTempLEDred, HIGH);
digitalWrite(DigitalInternalTempLEDblue, HIGH);
// Now set the Flex sensor baseline
digitalWrite(DigitalOilLevelLED, LOW);
FlexTest1 = analogRead(AnalogFlexSensor);
delay(pinReadDelay);
SleepTime = 1000;
for(k = 0; k < SleepTime; k = k + 100) {
if(Spinner == 0) {
digitalWrite(DigitalOilLevelLED, HIGH);
Spinner = 1;
} else {
digitalWrite(DigitalOilLevelLED, LOW);
Spinner = 0;
}
delay(100);
}
sprintf(buf, "Flex Baseline Test #1: %d", FlexTest1);
Serial.println(buf);
FlexTest2 = analogRead(AnalogFlexSensor);
delay(pinReadDelay);
SleepTime = 1000;
for(k = 0; k < SleepTime; k = k + 100) {
if(Spinner == 0) {
digitalWrite(DigitalOilLevelLED, HIGH);
Spinner = 1;
} else {
digitalWrite(DigitalOilLevelLED, LOW);
Spinner = 0;
}
delay(100);
}
sprintf(buf, "Flex Baseline Test #2: %d", FlexTest2);
Serial.println(buf);
FlexTest3 = analogRead(AnalogFlexSensor);
delay(pinReadDelay);
SleepTime = 1000;
for(k = 0; k < SleepTime; k = k + 100) {
if(Spinner == 0) {
digitalWrite(DigitalOilLevelLED, HIGH);
Spinner = 1;
} else {
digitalWrite(DigitalOilLevelLED, LOW);
Spinner = 0;
}
delay(100);
}
sprintf(buf, "Flex Baseline Test #3: %d", FlexTest3);
Serial.println(buf);
FlexBaseline = ((FlexTest1 + FlexTest2 + FlexTest3) / 3);
FlexAlarmLevel = (FlexBaseline + 25);
sprintf(buf, "Flex Baseline set to: %d, Alarm Level set to: %d", FlexBaseline, FlexAlarmLevel);
Serial.println(buf);
}
void ListenForClients(void)
{
// listen for incoming clients
Client client = server.available();
if (client) {
Serial.println("Got a client");
// an http request ends with a blank line
boolean currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
// if you've gotten to the end of the line (received a newline
// character) and the line is blank, the http request has ended,
// so you can send a reply
if (c == '\n' && currentLineIsBlank) {
// send a standard http response header
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println();
client.println("<meta http-equiv=\"refresh\" content=\"30\">");
// print the current readings, in HTML format:
client.print("" + String());
client.println("RiderTrack Network Version: \n" + String(VERSION));
client.println("<br />");
client.println("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n");
client.println("<br />");
if(IDENTITY == 0) {
client.println("Current Status for Node: mbf-wan-core (Kortrights)");
} else if (IDENTITY == 1) {
client.println("Current Status for Node: mbf-wan-edge1 (Garage)");
} else if (IDENTITY == 2) {
client.println("Current Status for Node: mbf-wan-edge2 (Boarders Tackroom)");
} else if (IDENTITY == 3) {
client.println("Current Status for Node: mbf-wan-barn (Main Barn)");
} else if (IDENTITY == 4) {
client.println("Current Status for Node: mbf-wan-edge3 (Feed Room)");
} else if (IDENTITY == 5) {
client.println("Current Status for Node: mbf-wan-edge4 (Barn Office)");
} else if (IDENTITY == 6) {
client.println("Current Status for Node: mbf-wan-edge5 (Hutchesons)");
} else if (IDENTITY == 7) {
client.println("Current Status for Node: mbf-wan-backup (Any Location)");
} else {
client.println("Current Status for Node: mbf-wan-backup (Any Location)");
}
client.println("<br />");
client.print("Loop Count: " + String(Loopy));
client.println("<br />");
client.print("Series Delay: " + String(SeriesDelay));
client.println("<br />");
client.println("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=");
client.println("<br />");
if(AdminState == 0) {
client.println("Admin Status: OK");
} else if(AdminState == 1) {
client.println("Admin Status: Rebooting");
} else if(AdminState == 2) {
client.println("Admin Status: Shut-Down");
} else if(AdminState == 3) {
client.println("Admin Status: Series-Rebooting");
} else {
client.println("Admin Status: Unknown");
}
client.println("<br />");
if(SystemState == 0) {
client.println("System Status: ON");
} else if(SystemState == 1) {
client.println("System Status: OFF");
}
client.println("<br />");
if(RouterState == 0) {
client.println("Router Status: ON");
} else if(RouterState == 1) {
client.println("Router Status: OFF");
}
client.println("<br />");
if(FluidState == 0) {
client.println("Fluid Status: OK");
} else if(FluidState == 1) {
client.println("Fluid Status: ALARM");
}
client.println("<br />");
if(TempState == 0) {
client.println("Temp Status: Normal");
} else if(TempState == 1) {
if(InternTempF < 32) {
client.println("Temp Status: COLD");
} else if(InternTempF > 100) {
client.println("Temp Status: HOT");
} else {
client.println("Temp Status: Normal");
}
} else if(TempState == 2) {
if(InternTempF < 0) {
client.println("Temp Status: FROZEN");
} else {
client.println("Temp Status: BOILING");
}
}
client.println("<br />");
client.print("Air Temperature: " + String(ExternTempF));
client.println("<br />");
client.print("Oil Temperature: " + String(InternTempF));
client.println("<br />");
break;
}
if (c == '\n') {
// you're starting a new line
currentLineIsBlank = true;
}
else if (c != '\r') {
// you've gotten a character on the current line
currentLineIsBlank = false;
}
}
}
// give the web browser time to receive the data
delay(1000);
// close the connection:
client.stop();
}
}
/* xyzzy */
void loop()
{
uint8_t i;
float average;
float ExternTemp;
float DHTtemp, DHTtempRaw, DHThumidity;
float ThermistorTempC, ExternTempF;
int DHTtempF, InternTempC, InternTemp;
int SleepTime = 0;
int Spinner = 0;
int LightLevelFlag = 0;
int TiltSensor = 0;
int TiltSensorRaw = 0;
int TempCount = 0;
int SetTempRecovery = 0;
int x, k, d;
int AverageTemp;
int VibrationRaw = 0;
char buf[128];
int tf;
SetTempRecovery = 0;
sprintf(buf, " ");
Serial.println(buf);
Loopy = Loopy + 1;
sprintf(buf, "Loop: %d", Loopy);
Serial.println(buf);
if(AdminState == 2) {
digitalWrite(DigitalRouterStatusLEDYellow, LOW);
digitalWrite(DigitalRouterStatusLEDGreen, LOW);
digitalWrite(DigitalRouterStatusLEDRed, HIGH);
digitalWrite(DigitalInternalTempLEDblue, LOW);
digitalWrite(DigitalInternalTempLEDgreen, LOW);
SleepTime = 2500;
Spinner = 0;
for(k = 0; k < SleepTime; k = k + 100) {
if(Spinner == 0) {
digitalWrite(DigitalRouterStatusLEDRed, HIGH);
if(FluidState == 1) {
analogWrite(DigitalOilLevelLED, 255);
}
Spinner = 1;
} else {
digitalWrite(DigitalRouterStatusLEDRed, LOW);
if(FluidState == 1) {
digitalWrite(DigitalOilLevelLED, 0);
}
Spinner = 0;
}
delay(100);
}
}
// =-=-= DHT Temp/Humidity Sensor =-=-=
// Reading temperature or humidity takes about 250 milliseconds!
// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
DHThumidity = dht.readHumidity();
DHTtempRaw = dht.readTemperature();
// check if returns are valid, if they are NaN (not a number) then something went wrong!
if (isnan(DHTtemp) || isnan(DHThumidity)) {
Serial.println("Failed to read from DHT");
} else {
// DHTtemp = (((DHTtempRaw - .5) * 100) * 1.8) + 32;
DHTtemp = ((1.8 * DHTtempRaw) + 32);
DHTtempF = int(DHTtemp);
Serial.print("Humidity: ");
Serial.print(DHThumidity);
Serial.print(" %\t");
Serial.print("Temperature: ");
Serial.print(DHTtempF);
Serial.println(" *F");
}
// =-=-= Internal Temp Sensor =-=-=
// =-=-= Thermistor Sensor =-=-=
// take N samples in a row, with a slight delay
for (d=0; d< NUMSAMPLES; d++) {
samples[d] = analogRead(AnalogThermistorSensor);
delay(pinReadDelay);
}
// average all the samples out
average = 0;
for (d=0; d< NUMSAMPLES; d++) {
average += samples[d];
}
average /= NUMSAMPLES;
Serial.print("Average thermistor analog reading: ");
Serial.println(average);
// convert the value to resistance
average = 1023 / average - 1;
average = SERIESRESISTOR / average;
Serial.print("Thermistor resistance: ");
Serial.println(average);
float steinhart;
steinhart = average / THERMISTORNOMINAL; // (R/Ro)
steinhart = log(steinhart); // ln(R/Ro)
steinhart /= BCOEFFICIENT; // 1/B * ln(R/Ro)
steinhart += 1.0 / (TEMPERATURENOMINAL + 273.15); // + (1/To)
steinhart = 1.0 / steinhart; // Invert
steinhart -= 273.15; // convert to C
// steinhart -= ThermistorOffset;
/*
if((steinhart < 20) && (steinhart > 15)) {
steinhart -= 2;
} else if((steinhart < 16) && (steinhart > 10)) {
steinhart -= 4;
} else if((steinhart < 11) && (steinhart > 5)) {
steinhart -= 6;
} else if((steinhart < 6) && (steinhart > 0)) {
steinhart -= 8;
} else if((steinhart > 30) && (steinhart < 35)) {
steinhart += 1;
} else if((steinhart > 34) && (steinhart < 40)) {
steinhart += 2;
} else if((steinhart < 39) && (steinhart > 45)) {
steinhart += 3;
} else if((steinhart < 44) && (steinhart > 50)) {
steinhart += 4;
}
*/
float temperatureF = (steinhart * 1.8) + 32.0;
Serial.print("Thermistor Temperature in C: ");
Serial.print(steinhart);
Serial.println(" *C");
Serial.print("Thermistor Temperature in F: ");
Serial.print(temperatureF);
Serial.println(" *F");
InternTempF = int(temperatureF);
if (InternTempF < -10) {
digitalWrite(DigitalInternalTempLEDblue, LOW);
digitalWrite(DigitalInternalTempLEDgreen, HIGH);
digitalWrite(DigitalInternalTempLEDred, HIGH);
TempAlarms = TempAlarms + 1;
if((TempAlarms > MAX_TEMP_ALARMS) && (TempState < 2)) {
// XYZZY: need to send an alarm to Netcool HERE, Too COLD!! O_O
sprintf(buf, "Cold Temperature Critical! System freezing up!");
Serial.println(buf);
sprintf(buf, "Disconnecting power to router/pump/heater!");
Serial.println(buf);
digitalWrite(DigitalRouterStatusLEDYellow, HIGH);
digitalWrite(DigitalRouterStatusLEDGreen, HIGH);
digitalWrite(DigitalRouterStatusLEDRed, LOW);
digitalWrite(DigitalInternalTempLEDblue, LOW);
if(POWER_INTERRUPT == 1) {
digitalWrite(DigitalRouterPower, LOW);
}
SystemState = 1;
AdminState = 2;
TempState = 2;
} else {
sprintf(buf, "Oil Temperature too Cold!");
Serial.println(buf);
Spinner = 0;
for(k = 0; k < 1000; k = k + 100) {
if(Spinner == 0) {
digitalWrite(DigitalInternalTempLEDblue, HIGH);
Spinner = 1;
} else {
digitalWrite(DigitalInternalTempLEDblue, LOW);
Spinner = 0;
}
delay(100);
}
digitalWrite(DigitalInternalTempLEDblue, HIGH);
}
} else if (InternTempF > 140) {
digitalWrite(DigitalInternalTempLEDblue, HIGH);
digitalWrite(DigitalInternalTempLEDgreen, HIGH);
digitalWrite(DigitalInternalTempLEDred, LOW);
digitalWrite(DigitalExternalTempLED, HIGH);
TempAlarms = TempAlarms + 1;
if((TempAlarms > MAX_TEMP_ALARMS) && (TempState < 2)) {
// XYZZY: need to send an alarm to Netcool HERE, Too HOT!! O_O
sprintf(buf, "Hot Temperature Critical! System is burning up!");
Serial.println(buf);
digitalWrite(DigitalRouterStatusLEDYellow, HIGH);
digitalWrite(DigitalRouterStatusLEDGreen, HIGH);
digitalWrite(DigitalRouterStatusLEDRed, LOW);
digitalWrite(DigitalInternalTempLEDred, LOW);
if(POWER_INTERRUPT == 1) {
digitalWrite(DigitalRouterPower, LOW);
}
SystemState = 1;
AdminState = 2;
TempState = 2;
} else {
sprintf(buf, "Oil Temperature too Hot!");
Serial.println(buf);
Spinner = 0;
for(k = 0; k < 1000; k = k + 100) {
if(Spinner == 0) {
digitalWrite(DigitalRouterStatusLEDRed, HIGH);
Spinner = 1;
} else {
digitalWrite(DigitalRouterStatusLEDRed, LOW);
Spinner = 0;
}
delay(100);
}
digitalWrite(DigitalRouterStatusLEDRed, HIGH);
}
} else if(InternTempF < 40) {
if(TempState == 2) {
if(AdminState == 2) {
if(SystemState == 1) {
SetTempRecovery = 1;
}
}
}
digitalWrite(DigitalInternalTempLEDblue, LOW);
digitalWrite(DigitalInternalTempLEDgreen, HIGH);
digitalWrite(DigitalInternalTempLEDred, HIGH);
digitalWrite(DigitalRouterStatusLEDYellow, HIGH);
TempState = 1;
sprintf(buf, "Its too damn Cold in here! Temp < 40!");
Serial.println(buf);
} else if (InternTempF > 100.0) {
if(TempState == 2) {
if(AdminState == 2) {
if(SystemState == 1) {
SetTempRecovery = 1;
}
}
}
digitalWrite(DigitalInternalTempLEDblue, HIGH);
digitalWrite(DigitalInternalTempLEDgreen, HIGH);
digitalWrite(DigitalInternalTempLEDred, LOW);
digitalWrite(DigitalRouterStatusLEDYellow, LOW);
TempState = 1;
sprintf(buf, "Its too banned Hot in here man! Temp > 100!");
Serial.println(buf);
} else {
if(TempState == 2) {
if(AdminState == 2) {
if(SystemState == 1) {
SetTempRecovery = 1;
}
}
}
if(TempState == 1) {
sprintf(buf, "Exterior tempeature returned to normal range (%d)", ExternTempF);
digitalWrite(DigitalRouterStatusLEDYellow, LOW);
digitalWrite(DigitalInternalTempLEDblue, HIGH);
digitalWrite(DigitalInternalTempLEDgreen, LOW);
digitalWrite(DigitalInternalTempLEDred, HIGH);
TempState = 0;
}
}
if(SetTempRecovery == 1) {
sprintf(buf, "Internal Oil tempeature returned to normal range!");
Serial.println(buf);
sprintf(buf, "Starting router/pump/heater power!");
Serial.println(buf);
TempState = 0;
TempAlarms = 0;
AdminState = 0;
if(SystemState == 1) {
sprintf(buf, "Tempeature returned to normal range, re-activating power!", TiltSensorRaw);
Serial.println(buf);
digitalWrite(DigitalRouterPower, HIGH);
SystemState = 0;
}
SetTempRecovery = 0;
digitalWrite(DigitalRouterStatusLEDYellow, HIGH);
digitalWrite(DigitalRouterStatusLEDGreen, LOW);
if(RouterState == 0) {
digitalWrite(DigitalRouterStatusLEDRed, HIGH);
}
}
// =-=-= Light (power) Sensor =-=-=
int LightLevel = analogRead(AnalogPhotoCellRouter);
delay(pinReadDelay);
LightLevel = map(LightLevel, 0, 900, 0, 10);
LightLevel = constrain(LightLevel, 0, 10);
if(LightLevel > 4) {
if(RouterState == 0) {
if(RouterPowerState == 0) {
digitalWrite(DigitalRouterPowerLED, HIGH);
}
RouterPowerState = 1;
sprintf(buf, "Router power is ON (sensor: %d)", LightLevel);
Serial.println(buf);
} else {
digitalWrite(DigitalRouterPowerLED, HIGH);
RouterPowerState = 1;
sprintf(buf, "Router power is ON, it must have recovered! (sensor: %d)", LightLevel);
Serial.println(buf);
// XYZZY: Send an Recovery alarm to Netcool HERE.
RouterState = 0;
digitalWrite(DigitalRouterStatusLEDYellow, LOW);
digitalWrite(DigitalRouterStatusLEDGreen, LOW);
digitalWrite(DigitalRouterStatusLEDRed, LOW);
}
} else {
if(AdminState == 0) {
digitalWrite(DigitalRouterPowerLED, LOW);
sprintf(buf, "Router power is OFF and should be ON!(sensor: %d)", LightLevel);
Serial.println(buf);
// XYZZY: Send an alarm to Netcool HERE.
RouterState = 1;
RouterPowerState = 0;
digitalWrite(DigitalRouterStatusLEDYellow, LOW);
digitalWrite(DigitalRouterStatusLEDGreen, LOW);
digitalWrite(DigitalRouterStatusLEDRed, HIGH);
} else {
digitalWrite(DigitalRouterPowerLED, LOW);
sprintf(buf, "Router power is OFF (sensor: %d)", LightLevel);
Serial.println(buf);
}
}
// =-=-= Tilt Sensor =-=-=
TiltSensorRaw = analogRead(AnalogFlexSensor);
delay(pinReadDelay);
sprintf(buf, "Raw Flex Resistance: %d, Alarm Level is: %d, Delta = %d", TiltSensorRaw, FlexAlarmLevel, (FlexAlarmLevel - TiltSensorRaw));
Serial.println(buf);
if((TiltSensorRaw > FlexAlarmLevel) || (ReverseTiltMode == 1)) {
TiltSensor = 1;
} else {
TiltSensor = 0;
}
if(TiltSensor == 0) {
analogWrite(DigitalOilLevelLED, 0);
Tilts = 0;
if(FluidState == 1) {
sprintf(buf, "Fluid Level Test: PASS! (raw: %d)", TiltSensorRaw);
Serial.println(buf);
FluidState = 0;
if(AdminState == 2) {
AdminState = 0;
if(SystemState == 1) {
// XYZZY - Send tilt Recovery trap to Netcool.
sprintf(buf, "Fluid levels Restored!, re-activating Power!", TiltSensorRaw);
Serial.println(buf);
digitalWrite(DigitalRouterPower, HIGH);
SystemState = 0;
} else {
// XYZZY - Send tilt Recovery trap to Netcool.
}
} else {
// XYZZY - Send tilt Recovery trap to Netcool.
}
digitalWrite(DigitalRouterStatusLEDYellow, LOW);
digitalWrite(DigitalRouterStatusLEDGreen, HIGH);
if(RouterState == 0) {
digitalWrite(DigitalRouterStatusLEDRed, LOW);
}
} else {
// XYZZY - Send tilt Recovery trap to Netcool.
sprintf(buf, "Fluid Level Test: PASS");
Serial.println(buf);
Tilts = 0;
}
} else {
analogWrite(DigitalOilLevelLED, 255);
Tilts = Tilts + 1;
if(Tilts >= MAX_TILT_ALARMS) {
// XYZZY: need to send an alarm to Netcool HERE, were out of fluid!! O_O
sprintf(buf, "Fluid Level Alarm!! Router is out of Oil!");
Serial.println(buf);
sprintf(buf, "Disconnecting power to router, pump and heater!");
Serial.println(buf);
analogWrite(DigitalOilLevelLED, 255);
digitalWrite(DigitalRouterStatusLEDYellow, LOW);
digitalWrite(DigitalRouterStatusLEDGreen, LOW);
digitalWrite(DigitalRouterStatusLEDRed, HIGH);
Spinner = 0;
for(k = 0; k < 1000; k = k + 100) {
if(Spinner == 0) {
analogWrite(DigitalOilLevelLED, 255);
Spinner = 1;
} else {
analogWrite(DigitalOilLevelLED, 0);
Spinner = 0;
}
delay(100);
}
analogWrite(DigitalOilLevelLED, 255);
if(POWER_INTERRUPT == 1) {
digitalWrite(DigitalRouterPower, LOW);
}
SystemState = 1;
AdminState = 2;
FluidState = 1;
} else if((Tilts > 4) && (Tilts < MAX_TILT_ALARMS)) {
// XYZZY: need to send an alarm to Netcool HERE, were out of fluid!! O_O
sprintf(buf, "Fluid Level Alarm! (Tilts: %d)", Tilts);
Serial.println(buf);
analogWrite(DigitalOilLevelLED, 255);
} else {
// XYZZY: need to send an alarm to Netcool HERE, were out of fluid!! O_O
sprintf(buf, "Fluid Sensor has moved! (Tilts: %d), Raw: %d", Tilts, TiltSensorRaw);
Serial.println(buf);
Spinner = 0;
for(k = 0; k < 1000; k = k + 100) {
if(Spinner == 0) {
analogWrite(DigitalOilLevelLED, 255);
Spinner = 1;
} else {
analogWrite(DigitalOilLevelLED, 0);
Spinner = 0;
}
delay(100);
}
analogWrite(DigitalOilLevelLED, 0);
}
}
// =-=-= Vibration Sensor =-=-=
/*
VibrationRaw = analogRead(AnalogVibrationSensor);
delay(pinReadDelay);
Serial.print("Raw Vibration Sensor Reading: ");
Serial.print(VibrationRaw);
Serial.println(".");
*/
vfd.clear();
int temp = int(DHTtempF);
int humidity = int(DHThumidity);
sprintf(buf, "Temp: %dF Hum: %d%%", temp, humidity);
vfd.setCursor(0, 0);
vfd.print(buf);
if(AdminState == 2) {
sprintf(buf, "Emergency Shutdown!");
} else if(FluidState == 1) {
sprintf(buf, "Oil Level Low/Out!");
} else if(TempState == 1) {
if(InternTempF > 0) {
sprintf(buf, "Alarm: Oil Temp High");
} else {
sprintf(buf, "Alarm: Oil Temp Low");
}
} else if(TempState == 2) {
if(InternTempF > 0) {
sprintf(buf, "PANIC! Oil Temp High");
} else {
sprintf(buf, "PANIC! Oil Temp Low");
}
} else if(RouterState == 1) {
sprintf(buf, "Router Power Off?!");
} else {
sprintf(buf, "All is Good at MBF!");
}
vfd.setCursor(0, 1);
vfd.print(buf);
// Now determine final LED state
if(AdminState == 0) {
if(RouterState == 0) {
digitalWrite(DigitalRouterStatusLEDYellow, HIGH);
digitalWrite(DigitalRouterStatusLEDRed, HIGH);
digitalWrite(DigitalRouterStatusLEDGreen, LOW);
delay(100);
digitalWrite(DigitalRouterStatusLEDGreen, HIGH);
digitalWrite(DigitalArduinoPowerLED, HIGH);
delay(100);
digitalWrite(DigitalArduinoPowerLED, LOW);
digitalWrite(DigitalRouterPowerLED, HIGH);
delay(100);
digitalWrite(DigitalRouterPowerLED, LOW);
digitalWrite(DigitalInternalTempLEDgreen, LOW);
digitalWrite(DigitalInternalTempLEDred, LOW);
delay(100);
digitalWrite(DigitalInternalTempLEDgreen, HIGH);
digitalWrite(DigitalInternalTempLEDred, HIGH);
digitalWrite(DigitalExternalTempLED, HIGH);
delay(100);
digitalWrite(DigitalExternalTempLED, LOW);
delay(100);
digitalWrite(DigitalOilLevelLED, HIGH);
delay(100);
digitalWrite(DigitalOilLevelLED, LOW);
delay(100);
digitalWrite(DigitalVibrationLED, HIGH);
delay(100);
digitalWrite(DigitalVibrationLED, LOW);
delay(100);
} else {
digitalWrite(DigitalRouterStatusLEDGreen, HIGH);
digitalWrite(DigitalRouterStatusLEDRed, LOW);
digitalWrite(DigitalRouterStatusLEDYellow, HIGH);
SleepTime = 1000;
for(k = 0; k < SleepTime; k = k + 100) {
if(Spinner == 0) {
digitalWrite(DigitalRouterPowerLED, HIGH);
digitalWrite(DigitalRouterStatusLEDRed, HIGH);
Spinner = 1;
} else {
digitalWrite(DigitalRouterPowerLED, LOW);
digitalWrite(DigitalRouterStatusLEDRed, LOW);
Spinner = 0;
}
delay(100);
}
digitalWrite(DigitalRouterStatusLEDRed, HIGH);
}
}
sprintf(buf, "SystemState: %d, AdminState: %d, FluidState: %d, TempState: %d", SystemState, AdminState, FluidState, TempState);
Serial.println(buf);
for(d=0;d<=100;d++) {
ListenForClients();
delay(10);
}
}
float getVoltage(int pin) {
return (analogRead(pin) * .004882814);
}
This concludes the gory details.

If there is anything I've left off that your interested in, don't hesitate to ask!
Kris