Created
December 31, 2017 19:10
-
-
Save NonaSuomy/eaaedb4e99228fbdcae541b71e3fb717 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Project: WOOF | |
Date: 20171228 | |
Hardware | |
FTDI for Pro Mini | |
https://www.banggood.com/FT232RL-FTDI-USB-To-TTL-Serial-Converter-Adapter-Module-For-Arduino-p-917226.html?rmmds=search&cur_warehouse=CN | |
Arduino Pro Mini or Micro | |
https://www.banggood.com/Wholesale-New-Ver-Pro-Mini-ATMEGA328-328p-5V-16MHz-Arduino-Compatible-Nano-Size-p-68534.html?rmmds=search&cur_warehouse=CN | |
https://www.banggood.com/Pro-Micro-5V-16M-Mini-Leonardo-Microcontroller-Development-Board-For-Arduino-p-1077675.html?rmmds=search&cur_warehouse=CN | |
W5500 Ethernet Network Module | |
http://wiznetmuseum.com/portfolio-items/w5500-ethernet-network-module-tcpip-interface-51stm32-program/ | |
https://www.banggood.com/W5500-Ethernet-Network-Module-TCPIP-Interface-51STM32-Program-p-982668.html?cur_warehouse=CN | |
Libraries | |
ICMPPing | |
https://github.com/NonaSuomy/Arduino-Ping-W5500 | |
Ethernet2 | |
Use the library manager to get ethernet2 library. | |
https://github.com/adafruit/Ethernet2 | |
Pinouts | |
Arduino W5500 Wire Colours | |
10 SCS Grey | |
11 MOSI Orange | |
12 MISO Brown | |
13 SCLK White | |
RST RST Purple | |
5V 5V White | |
N/C 3.3V N/C | |
GND GND Black | |
N/C INT N/C | |
N/C NC N/C | |
Tips | |
Look in the Serial Monitor for your DHCP IP or Static set it. | |
Connect to IP of Arduino in your web browser example: http://192.168.1.50 | |
Use ' instead of " in the html. | |
*/ | |
#include <string.h> | |
#include <EEPROM.h> | |
#include "EEPROMAnything.h" | |
#include <SPI.h> | |
#include <Ethernet2.h> | |
#include <ICMPPing.h> | |
IPAddress pingAddr(255, 255, 255, 255); // ip address to ping | |
// PING_REQUEST_TIMEOUT_MS -- Timeout in ms. between 1 and 65000 or so | |
// Save values: 1000 to 5000, say. | |
//#define PING_REQUEST_TIMEOUT_MS 2500 | |
//#ifndef ICMPPING_ASYNCH_ENABLE | |
//#error "Asynchronous functions only available if ICMPPING_ASYNCH_ENABLE is defined -- see ICMPPing.h" | |
//#endif | |
SOCKET pingSocket = 0; | |
char buffer [256]; | |
ICMPPing ping(pingSocket, (uint16_t)random(0, 255)); | |
#define MINPIN 2 // Pin 0 and 1 are RX/TX. | |
#define MAXPIN 9 // Stick to digital for now. | |
#define SHORT 250 // Short keypress, in 'ms'. | |
#define LONG 4500 // Long keypress, in 'ms'. | |
#define INPUTLEN 50 // Length of input string we parse. | |
#define NAMELEN 10 // Length of a host/config name. | |
#define IPLEN 256 // Length of IP. | |
#define CONFIGS 7 // Amount of configs to store. | |
#define PROMPT "\n> " | |
// Function declarations | |
void processString(); | |
char * inputstring = (char *) malloc(INPUTLEN+1); | |
char * isbegin = inputstring; | |
byte islen = 0; | |
bool inputdone = false; | |
struct configdata | |
{ | |
bool used; | |
byte resetpin; | |
byte powerpin; | |
char name[NAMELEN]; | |
byte pip1; | |
byte pip2; | |
byte pip3; | |
byte pip4; | |
} config[CONFIGS]; | |
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // Physical MAC Address | |
byte ip[] = { 10, 20, 30, 33 }; // IP Address | |
byte gateway[] = { 10, 20, 30, 40 }; // Router Gateway | |
byte subnet[] = { 255, 255, 255, 0 }; // Network Subnet MaskEthernetServer server(80); // Server Port | |
EthernetServer server(80); // Server Port | |
String readString; | |
// Arduino PINS default to 'input' and 'LOW', but set them anyway | |
// so we can call reset later to revert to defaults if needed. | |
void setup() | |
{ | |
for( int i = MINPIN; i <= MAXPIN; i++) | |
{ | |
pinMode(i, INPUT); | |
digitalWrite(i, LOW); | |
} | |
// Start Ethernet | |
Ethernet.begin(mac, ip, gateway, subnet); // Static | |
//Ethernet.begin(mac); // DHCP | |
server.begin(); | |
// initialize serial communication at 9600 bits per second: | |
Serial.begin(115200); | |
Serial.print(F( "WOOF!\n\r" )); | |
/* | |
int i = sizeof(config); | |
Serial.print( "Configuration is " ); | |
Serial.print( i, DEC ); | |
Serial.print( " bytes\n\r\n\r" ); | |
*/ | |
Serial.print(F("Server is at: ")); | |
Serial.println(Ethernet.localIP()); | |
// increase the default time-out, if needed, assuming a bad | |
// connection or whatever. | |
ICMPPing::setTimeout(PING_REQUEST_TIMEOUT_MS); | |
inputstring[0] = '\0'; // Initialize to empty | |
inputstring[INPUTLEN+1] = '\0'; // Should never be overwritten | |
Serial.print( PROMPT ); | |
EEPROM_readAnything(0, config); | |
} | |
// the loop routine runs over and over again forever: | |
void loop() | |
{ | |
// Create a client connection | |
EthernetClient client = server.available(); | |
if (client) { | |
while (client.connected()) { | |
if (client.available()) { | |
pong(10,13,37,173); | |
char c = client.read(); | |
//read char by char HTTP request | |
if (readString.length() < 100) { | |
//store characters to string | |
readString += c; | |
//Serial.print(c); | |
} | |
// If HTTP request has ended. | |
if (c == '\n') { | |
Serial.println(readString); // Print to serial monitor for debuging. | |
client.println(F("HTTP/1.1 200 OK")); // Send new page. | |
client.println(F("Content-Type: text/html")); | |
client.println(); | |
client.println(F("<HTML>")); | |
client.println(F("<HEAD>")); | |
client.println(F("<TITLE>WOOF!</TITLE>")); | |
client.println(F("</HEAD>")); | |
client.println(F("<BODY>")); | |
client.println(F("<H1>Watchdog Overseer Open Farm</H1>")); | |
// Custom Buttons | |
client.print(F("Sys0 ")); | |
//client.print("<input type=submit value=ON style=width:100px;height:45px onClick=location.href='/?on2;'>"); | |
//client.print("<input type=submit value=OFF style=width:100px;height:45px onClick=location.href='/?off3;'><br><br>"); | |
client.println(F("<a href=/?p0 >POW</a>")); | |
client.println(F("<a href=/?r0 >RST</a>")); | |
client.println(F("<a href=/?f0 >FRC</a><br>")); | |
client.print(F("Sys1 ")); | |
client.println(F("<a href=/?p1 >POW</a>")); | |
client.println(F("<a href=/?r1 >RST</a>")); | |
client.println(F("<a href=/?f1 >FRC</a><br>")); | |
client.print(F("Sys2 ")); | |
client.println(F("<a href=/?p2 >POW</a>")); | |
client.println(F("<a href=/?r2 >RST</a>")); | |
client.println(F("<a href=/?f2 >FRC</a><br>")); | |
client.print(F("Sys3 ")); | |
client.println(F("<a href=/?p3 >POW</a>")); | |
client.println(F("<a href=/?r3 >RST</a>")); | |
client.println(F("<a href=/?f3 >FRC</a><br>")); | |
client.print(F("Sys All ")); | |
//client.print(" <input type=submit value='ALL OFF' style=width:100px;height:45px onClick=location.href='/?off3579;'>"); | |
client.println(F("<a href=/?pall >POW All</a><br>")); | |
client.println(F("</BODY>")); | |
client.println(F("</HTML>")); | |
delay(1); | |
// Stopping client | |
client.stop(); | |
// Change pin states from web url. | |
if(readString.indexOf("p0") >0) // Checks for p1 | |
{ | |
do_power( 0 ); | |
//digitalWrite(2, HIGH); // Set pin 2 high | |
//Serial.println(F("P2P")); | |
} | |
else if(readString.indexOf("r0") >0) // Checks for 3 | |
{ | |
do_reset( 0 ); | |
//digitalWrite(2, LOW); // Set pin 2 low | |
//Serial.println("P2R"); | |
} | |
else if(readString.indexOf("f0") >0) // Checks for 3 | |
{ | |
do_force( 0 ); | |
//digitalWrite(2, LOW); // Set pin 2 low | |
//Serial.println("P2R"); | |
} | |
else if(readString.indexOf("p1") >0) // Checks for 4 | |
{ | |
do_power( 1 ); | |
//digitalWrite(4, HIGH); // Set pin 4 high | |
//Serial.println("Led 4 On"); | |
} | |
else if(readString.indexOf("r1") >0) // Checks for 5 | |
{ | |
do_reset( 1 ); | |
//digitalWrite(4, LOW); // Set pin 4 low | |
//Serial.println("Led 4 Off"); | |
} | |
else if(readString.indexOf("f1") >0) // Checks for 3 | |
{ | |
do_force( 1 ); | |
//digitalWrite(2, LOW); // Set pin 2 low | |
//Serial.println("P2R"); | |
} | |
else if(readString.indexOf("p2") >0) // Checks for 6 | |
{ | |
do_power( 2 ); | |
//digitalWrite(6, HIGH); // Set pin 6 high | |
//Serial.println("Led 6 On"); | |
} | |
else if(readString.indexOf("r2") >0) // Checks for 7 | |
{ | |
do_reset( 2 ); | |
//digitalWrite(6, LOW); // Set pin 6 low | |
//Serial.println("Led 6 Off"); | |
} | |
else if(readString.indexOf("f2") >0) // Checks for 3 | |
{ | |
do_force( 2 ); | |
//digitalWrite(2, LOW); // Set pin 2 low | |
//Serial.println("P2R"); | |
} | |
else if(readString.indexOf("p3") >0) // Checks for 8 | |
{ | |
do_power( 3 ); | |
//digitalWrite(8, HIGH); // Set pin 8 high | |
//Serial.println("Led 8 On"); | |
} | |
else if(readString.indexOf("r3") >0) // Checks for 9 | |
{ | |
do_reset( 3 ); | |
//digitalWrite(8, LOW); // Set pin 8 low | |
//Serial.println("Led 8 Off"); | |
} | |
else if(readString.indexOf("f3") >0) // Checks for 3 | |
{ | |
do_force( 3 ); | |
//digitalWrite(2, LOW); // Set pin 2 low | |
//Serial.println("P2R"); | |
} | |
else if(readString.indexOf("pall") >0) // Checks for 9 | |
{ | |
do_power( 0 ); | |
do_power( 1 ); | |
do_power( 2 ); | |
do_power( 3 ); | |
//digitalWrite(8, LOW); // Set pin 8 low | |
//Serial.println("Led 8 Off"); | |
} | |
//clearing string for next read | |
readString=""; | |
} | |
} | |
} | |
} | |
// If we have a input to process, do so | |
if (inputdone) { | |
processString(); | |
// clear the string: | |
inputstring[0] = '\0'; | |
islen=0; | |
inputdone = false; | |
Serial.print( PROMPT ); | |
} | |
if( Serial.available() > 0) | |
{ | |
char input = Serial.read(); | |
Serial.print(input); | |
// Newline / Carriage return close the input | |
if( ( input == '\n' ) || ( input == '\r' ) ) | |
{ | |
// Close input with \0 | |
inputstring[islen++] = '\0'; | |
inputdone=true; | |
Serial.print(F( "\n\r\n\r" )); | |
} | |
else if( input == 127 ) | |
{ | |
// Backspace | |
if ( islen >= 1 ) | |
{ | |
Serial.print(F( "\b \b" )); | |
inputstring[islen--] = '\0'; | |
} | |
} | |
else if( ( input >= ' ' ) && ( input <= 'z' ) ) | |
{ | |
// Add valid character, increment islen | |
inputstring[islen++] = input; | |
} | |
else | |
{ | |
Serial.print(F( "Illegal character: '" )); | |
Serial.print( input, HEX ); | |
Serial.print(F( "'\n" )); | |
} | |
// Have we reached max length, also close input and flush remainder | |
if( islen >= INPUTLEN ) | |
{ | |
inputstring[islen] = '\0'; | |
inputdone=true; | |
// Flush remaining characters in input to /dev/zero | |
while( Serial.available() > 0 ) | |
{ | |
// This doesn't seem to flush all input | |
Serial.read(); | |
} | |
} | |
} | |
} | |
// Toggle pin state. | |
void toggle_pin( byte pin, int ms ) | |
{ | |
pinMode( pin, OUTPUT ); | |
digitalWrite(pin, LOW); | |
delay( ms ); | |
pinMode(pin, INPUT); | |
digitalWrite(pin, LOW); | |
} | |
// Send reset signal to pin. | |
void do_reset( byte cnum ) | |
{ | |
if( config[cnum].used ) | |
{ | |
Serial.print(F( "Sending reset signal to pin: " )); | |
Serial.println( config[cnum].resetpin ); | |
toggle_pin( config[cnum].resetpin, SHORT ); | |
} | |
else | |
{ | |
Serial.print(F( "Config invalid" )); | |
} | |
} | |
// Trigger Computer Power Button. | |
void do_power( byte cnum ) | |
{ | |
if( config[cnum].used ) | |
{ | |
Serial.print(F( "Sending power signal to pin: " )); | |
Serial.println( config[cnum].powerpin ); | |
toggle_pin( config[cnum].powerpin, SHORT ); | |
} | |
else | |
{ | |
Serial.print(F( "Config invalid" )); | |
} | |
} | |
void do_force( byte cnum ) | |
{ | |
if( config[cnum].used ) | |
{ | |
Serial.print(F( "Sending long power signal to pin: " )); | |
Serial.println( config[cnum].powerpin ); | |
toggle_pin( config[cnum].powerpin, LONG ); | |
} | |
else | |
{ | |
Serial.print(F( "Config invalid" )); | |
} | |
} | |
void do_state( byte cnum ) | |
{ | |
if( config[cnum].used ) | |
{ | |
bool power, state; | |
power = digitalRead( config[cnum].powerpin ); | |
state = digitalRead( config[cnum].resetpin ); | |
Serial.print(F( "System " )); | |
Serial.print( config[cnum].name ); | |
Serial.print(F( " has " )); | |
if ( ! power ) | |
{ | |
Serial.print(F( "NO " )); | |
} | |
Serial.print(F( "ATX power." )); | |
if ( state ) | |
{ | |
Serial.println(F( " It seems to be powered on." )); | |
} | |
else | |
{ | |
Serial.println(F( " It seems to be off." )); | |
} | |
} | |
else | |
{ | |
Serial.print(F( "Config invalid" )); | |
} | |
} | |
void do_load() | |
{ | |
EEPROM_readAnything(0, config); | |
} | |
void do_save() | |
{ | |
EEPROM_writeAnything(0, config); | |
} | |
void do_erase( byte confignum ) | |
{ | |
config[confignum].used = false; | |
config[confignum].resetpin = 255; | |
config[confignum].powerpin = 255; | |
strncpy( config[confignum].name, "unused", NAMELEN ); | |
config[confignum].pip1 = 255; | |
config[confignum].pip2 = 255; | |
config[confignum].pip3 = 255; | |
config[confignum].pip4 = 255; | |
} | |
void do_dump() | |
{ | |
Serial.print(F( "\rConfig\n\r" )); | |
for( byte i = 0; i < CONFIGS; i++ ) | |
{ | |
Serial.print(F( "Config: " )); | |
Serial.print( i ); | |
Serial.print(F( " Data: " )); | |
Serial.print( config[i].used ); | |
Serial.print(F( " / " )); | |
Serial.print( config[i].resetpin ); | |
Serial.print(F( " / " )); | |
Serial.print( config[i].powerpin ); | |
Serial.print(F( " / " )); | |
Serial.print( config[i].name ); | |
Serial.print(F( " / " )); | |
Serial.print( config[i].pip1 ); | |
Serial.print(F( "." )); | |
Serial.print( config[i].pip2 ); | |
Serial.print(F( "." )); | |
Serial.print( config[i].pip3 ); | |
Serial.print(F( "." )); | |
Serial.println( config[i].pip4 ); | |
} | |
} | |
void do_wipe() | |
{ | |
for( byte i = 0; i < CONFIGS; i++ ) | |
{ | |
do_erase( i ); | |
} | |
do_save(); | |
} | |
void do_help() | |
{ | |
Serial.print(F( "Help: \n\r\ | |
config Edit configuration\n\r\ | |
config [0-7] resetpin pwrpin name 192 168 1 100\n\r\ | |
reset # Toggle reset switch on config #\n\r\ | |
power # Toggle power switch on config #\n\r\ | |
force # Long-Press power switch on pc number #\n\r\ | |
erase # Erase config number #\n\r\ | |
state Check power state\n\r\ | |
dump Dump configuration to serial\n\r\ | |
save Save configuration to EEPROM\n\r\ | |
load Load configuration from EEPROM\n\r\ | |
wipe Wipe onfiguration and update EEPROM\n\r\ | |
\n\r\n\r" )); | |
} | |
bool do_config( byte cnum, byte rspin, byte ppin, char * name, byte pipl1, byte pipl2, byte pipl3, byte pipl4) | |
{ | |
byte namelen = strnlen( name, NAMELEN +2 ); | |
if( ( cnum >= 0 ) && ( cnum < CONFIGS ) && ( rspin != ppin ) && | |
( rspin >= MINPIN ) && ( rspin <= MAXPIN ) && | |
( ppin >= MINPIN ) && ( ppin <= MAXPIN ) && | |
( namelen < NAMELEN ) && ( pipl1 < IPLEN ) && | |
( pipl2 < IPLEN ) && ( pipl3 < IPLEN ) && | |
( pipl4 < IPLEN ) ) | |
{ | |
Serial.print(F( "Do_CONFIG\n\r" )); | |
config[cnum].used = true; | |
config[cnum].resetpin = rspin; | |
config[cnum].powerpin = ppin; | |
strncpy( config[cnum].name, name, NAMELEN ); | |
config[cnum].pip1 = pipl1; | |
config[cnum].pip2 = pipl2; | |
config[cnum].pip3 = pipl3; | |
config[cnum].pip4 = pipl4; | |
return true; | |
} | |
else | |
{ | |
Serial.print(F( "Illegal config. Try: config 0 3 2 Sys0 192 168 1 100\n\r" )); | |
return false; | |
} | |
}; | |
void pong(byte ip0, byte ip1, byte ip2, byte ip3) | |
{ | |
pingAddr[0] = ip0; | |
pingAddr[1] = ip1; | |
pingAddr[2] = ip2; | |
pingAddr[3] = ip3; | |
Serial.print(ip0); | |
Serial.print("."); | |
Serial.print(ip1); | |
Serial.print("."); | |
Serial.print(ip2); | |
Serial.print("."); | |
Serial.println(ip3); | |
ICMPEchoReply echoReply = ping(pingAddr, 4); | |
if (echoReply.status == SUCCESS) | |
{ | |
sprintf(buffer, | |
"Reply[%d] from: %d.%d.%d.%d: bytes=%d time=%ldms TTL=%d", | |
echoReply.data.seq, | |
echoReply.addr[0], | |
echoReply.addr[1], | |
echoReply.addr[2], | |
echoReply.addr[3], | |
REQ_DATASIZE, | |
millis() - echoReply.data.time, | |
echoReply.ttl); | |
} | |
else | |
{ | |
sprintf(buffer, "Echo request failed; %d", echoReply.status); | |
} | |
Serial.println(buffer); | |
delay(500); | |
} | |
void processString() | |
{ | |
char *cmd, *save; | |
cmd = strtok_r(inputstring," ",&save); | |
//Serial.print(cmd); | |
// Simple commands without arguments | |
if( ( strncmp( cmd, "help", 4 ) == 0 ) ) | |
{ | |
do_help(); | |
} | |
else if( ( strncmp( cmd, "save", 4 ) == 0 ) ) | |
{ | |
do_save(); | |
} | |
else if( ( strncmp( cmd, "load", 4 ) == 0 ) ) | |
{ | |
do_load(); | |
} | |
else if( ( strncmp( cmd, "dump", 4 ) == 0 ) ) | |
{ | |
do_dump(); | |
} | |
else if( ( strncmp( cmd, "wipe", 4 ) == 0 ) ) | |
{ | |
do_wipe(); | |
} | |
else | |
{ | |
// Commands with at least 1 argument | |
char * confignum; | |
byte cnum; | |
confignum = strtok_r( NULL, " ", &save ); | |
cnum = (byte) atoi(confignum); | |
if( ! ( cnum >= 0 ) && ( cnum < CONFIGS ) ) | |
{ | |
Serial.println(F( "Invalid config number\n\r" )); | |
} | |
else | |
{ | |
if( ( strncmp( cmd, "reset", 5 ) == 0 ) ) | |
{ | |
//Serial.println( cnum ); | |
do_reset( cnum ); | |
} | |
else if( ( strncmp( cmd, "power", 5 ) == 0 ) ) | |
{ | |
do_power( cnum ); | |
} | |
else if( ( strncmp( cmd, "force", 5 ) == 0 ) ) | |
{ | |
do_force( cnum ); | |
} | |
else if( ( strncmp( cmd, "erase", 5 ) == 0 ) ) | |
{ | |
do_erase( cnum ); | |
} | |
else if( ( strncmp( cmd, "state", 5 ) == 0 ) ) | |
{ | |
do_state( cnum ); | |
} | |
// config 0 3 2 Sys0 10 13 37 173 | |
// config 1 5 4 Sys1 10 13 37 173 | |
// config 2 7 6 Sys2 10 13 37 173 | |
// config 3 9 8 Sys3 10 13 37 173 | |
// config 0 3 2 Sys0 192 168 1 100 | |
// config 1 5 4 Sys1 192 168 1 101 | |
// config 2 7 6 Sys2 192 168 1 102 | |
// config 3 9 8 Sys3 192 168 1 103 | |
else if( ( strncmp( cmd, "config", 6 ) == 0 ) ) | |
{ | |
char *resetpin, *pwrpin, *name, *pips0, *pips1, *pips2, *pips3; | |
resetpin = strtok_r( NULL, " ", &save ); | |
pwrpin = strtok_r( NULL, " ", &save ); | |
name = strtok_r( NULL, " ", &save ); | |
pips0 = strtok_r( NULL, " ", &save ); | |
pips1 = strtok_r( NULL, " ", &save ); | |
pips2 = strtok_r( NULL, " ", &save ); | |
pips3 = strtok_r( NULL, " ", &save ); | |
if ( resetpin && pwrpin && name && pips0 && pips1 && pips2 && pips3 ) | |
{ | |
byte rspin, ppin, pip0, pip1, pip2, pip3; | |
rspin = atoi( resetpin ); | |
ppin = atoi( pwrpin ); | |
pip0 = atoi( pips0 ); | |
pip1 = atoi( pips1 ); | |
pip2 = atoi( pips2 ); | |
pip3 = atoi( pips3 ); | |
do_config( cnum, rspin, ppin, name, pip0, pip1, pip2, pip3); | |
} | |
else | |
{ | |
Serial.print(F( "ERROR: Please specify configuration number, resetpin, pwrpin, name, 192 168 1 100\n\r\n\r" )); | |
} | |
} | |
else | |
{ | |
Serial.print(F( "Unknown command: " )); | |
Serial.print( cmd ); | |
Serial.print(F( "\n\r\n\r" )); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment