Web-сервер для MEGA+5100+DHT+DS18B20
- Войдите на сайт для отправки комментариев
Web-сервер для MEGA+5100+DHT+DS18B20. Сборка! сам не прогер не чуть-чуть! Особо умных которые будут тыкать RFC по HTTP прошу обходить стороной. Делалось для себя. на вопросы с удовольствие отвечу.
Долго бился с формой ввода желаемой температуры, сделал отдельными кнопками, в итоге так оказалось гораздо удобнее управлять с телефона, отпала необходимость набивать на клавиатуре желаемое значение.
В ближайшее время будет установлено на даче в замен честно отпахавшему без сбоев пол года NANO+ENC28J60, для удаленного управления инфракрасными обогревателями.
источники:
1. http://forum.arduino.cc/index.php?topic=114436.msg1008272#msg1008272
2. http://bildr.org/2011/06/arduino-ethernet-pin-control/

скейтч
#include <Ethernet.h>
#include <SPI.h>
#include <EEPROM.h>
#include <DHT.h>
#include <OneWire.h>
////////////////////////////////////////////////////////////////////////
//CONFIGURATION
////////////////////////////////////////////////////////////////////////
//IP manual settings
byte ip[] = {
10, 16, 30, 2 }; //Manual setup only
byte gateway[] = {
10, 16, 30, 3 }; //Manual setup only
byte subnet[] = {
255, 255, 255, 0 }; //Manual setup only
// if need to change the MAC address (Very Rare)
byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
//Ethernet Port
EthernetServer server = EthernetServer(80); //default html port 80
//The number of outputs going to be switched.
int outputQuantity = 10; //should not exceed 10
//Invert the output of the leds
boolean outputInverted = false; //true or false
// This is done in case the relay board triggers the relay on negative, rather then on positive supply
//Html page refresh
int refreshPage = 15; //default is 10sec.
//Beware that if you make it refresh too fast, the page could become inacessable.
//Display or hide the "Switch on all Pins" buttons at the bottom of page
int switchOnAllPinsButton = true; //true or false
//Button Array
//Just for a note, varables start from 0 to 9, as 0 is counted as well, thus 10 outputs.
// Select the pinout address
int outputAddress[10] = { 3,5,6,7,8,9,14,15,16,17}; //Allocate 10 spaces and name the output pin address.
//PS pin addresses 10, 11, 12 and 13 on the Duemilanove are used for the ethernet shield, therefore cannot be used.
//PS pin addresses 10, 50, 51 and 52 and 53 on the Mega are used for the ethernet shield, therefore cannot be used.
//PS pin addresses 4, are used for the SD card, therefore cannot be used.
//PS. pin address 2 is used for interrupt-driven notification, therefore could not be used.
// Write the text description of the output channel
String buttonText[10] = {
"01. Канал","02. Канал","03. Канал","04. Канал","05. Канал","06. Канал","07. Канал","08. Канал","09. Канал","10. Канал"};
////////////////////////////////////////////////////////////////////////
int ten[10] = { 1,2,3,4,5,6,7,8,9};
////////////////////////////////////////////////////////////////////////
//VARIABLES DECLARATION
////////////////////////////////////////////////////////////////////////
int outp = 0;
boolean printLastCommandOnce = false;
boolean printButtonMenuOnce = false;
boolean initialPrint = true;
String allOn = "";
String allOff = "";
boolean reading = false;
boolean outputStatus[10]; //Create a boolean array for the maximum ammount.
String rev = "V1.2";
unsigned long timeConnectedAt;
boolean writeToEeprom = false;
//EthernetClient client;
//////////////переменные упрвавления температурой
const byte PinSSR1 = 18; // Реле Pin for SSR 1
const byte PinSSR2 = 19; // Реле Pin for SSR 2
const byte PinSSR3 = 20; // Реле Pin for SSR 3
char chartemp1[10];
char chartemp2[10];
char chartemp3[10];
char chartemp4[10];
int TargetTemp1;
int TargetTemp2;
int TargetTemp3;
float temp1;
float temp2;
OneWire ds(23);
DHT dht1(21, DHT11);
DHT dht2(22, DHT11);
////////////////////////////////
////////////////////////////////////////////////////////////////////////
//RUN ONCE
////////////////////////////////////////////////////////////////////////
//Beginning of Program
void setup(){
Serial.begin(9600);
initEepromValues();
readEepromValues();
//Set pins as Outputs
boolean currentState = false;
for (int var = 0; var < outputQuantity; var++){
pinMode(outputAddress[var], OUTPUT);
//Switch all outputs to either on or off on Startup
if(outputInverted == true) {
//digitalWrite(outputAddress[var], HIGH);
if(outputStatus[var] == 0){currentState = true;}else{currentState = false;} //check outputStatus if off, switch output accordingly
digitalWrite(outputAddress[var], currentState);
}
else{
//digitalWrite(outputAddress[var], LOW);
if(outputStatus[var] == 0){currentState = false;}else{currentState = true;}//check outputStatus if off, switch output accordingly
digitalWrite(outputAddress[var], currentState);
}
}
//Setting up the IP address. Comment out the one you dont need.
//Ethernet.begin(mac); //for DHCP address. (Address will be printed to serial.)
Ethernet.begin(mac, ip, gateway, subnet); //for manual setup. (Address is the one configured above.)
server.begin();
Serial.print("Server started at ");
Serial.println(Ethernet.localIP());
////////////////управление температурой
pinMode(PinSSR1, OUTPUT);
pinMode(PinSSR2, OUTPUT);
pinMode(PinSSR3, OUTPUT);
TargetTemp1 = EEPROM.read(100);
TargetTemp2 = EEPROM.read(102);
TargetTemp3 = EEPROM.read(104);
dht1.begin();
dht2.begin();
/////////////////////////////////////
}
////////////////////////////////////////////////////////////////////////
//LOOP
////////////////////////////////////////////////////////////////////////
//Run once
void loop(){
// listen for incoming clients, and process requests.
checkForClient();
///////////////////////управление температурой
float temp3;
float temp4;
byte sensor1[8] = {0x28, 0xFF, 0x34, 0x2C, 0x50, 0x15, 0x01, 0x87}; // Адрес сенсора
byte sensor2[8] = {0x28, 0xDF, 0x7E, 0xDC, 0x06, 0x00, 0x00, 0xF3}; // Адрес сенсора
//DHT
temp1 = dht1.readTemperature();
dtostrf(temp1, 3, 1, chartemp1);
temp2 = dht2.readTemperature();
dtostrf(temp2, 3, 1, chartemp2);
//DS18B20
temp3 = tempread(sensor1);
dtostrf(temp3, 3, 1, chartemp3);
temp4 = tempread(sensor2);
dtostrf(temp4, 3, 1, chartemp4);
if (temp1<TargetTemp1-1)
{
digitalWrite(PinSSR1, LOW);
}
else if (temp1>TargetTemp1+1)
{
digitalWrite(PinSSR1, HIGH);
}
if (temp2<TargetTemp2-1)
{
digitalWrite(PinSSR2, LOW);
}
else if (temp2>TargetTemp2+1)
{
digitalWrite(PinSSR2, HIGH);
}
if (temp3<TargetTemp3-1)
{
digitalWrite(PinSSR3, LOW);
}
else if (temp3>TargetTemp3+1)
{
digitalWrite(PinSSR3, HIGH);
}
}
////////////////////////////////////////////////////////////////////////
//checkForClient Function
////////////////////////////////////////////////////////////////////////
//
void checkForClient(){
EthernetClient client = server.available();
if (client) {
// an http request ends with a blank line
boolean currentLineIsBlank = true;
boolean sentHeader = false;
while (client.connected()) {
if (client.available()) {
//if header was not set send it
//read user input
char c = client.read();
if(c == '*'){
printHtmlHeader(client); //call for html header and css
printLoginTitle(client);
printHtmlFooter(client);
//sentHeader = true;
break;
}
if(!sentHeader){
printHtmlHeader(client); //call for html header and css
printHtmlButtonTitle(client); //print the button title
//This is for the arduino to construct the page on the fly.
sentHeader = true;
}
//read user input
// char c = client.read();
//if there was reading but is blank there was no reading
if(reading && c == ' '){
reading = false;
}
//if there is a ? there was user input
if(c == '?') {
reading = true; //found the ?, begin reading the info
}
// if there was user input switch the relevant output
if(reading){
//if user input is H set output to 1
if(c == 'H') {
outp = 1;
}
//if user input is L set output to 0
if(c == 'L') {
outp = 0;
}
if(c == 'q') {TargetTemp1 = 0; EEPROM.write(100, 0);}
if(c == 'w') {TargetTemp1 = 5; EEPROM.write(100, 5);}
if(c == 'e') {TargetTemp1 = 10; EEPROM.write(100, 10);}
if(c == 'r') {TargetTemp1 = 20; EEPROM.write(100, 20);}
if(c == 't') {TargetTemp1 = 22; EEPROM.write(100, 22);}
if(c == 'y') {TargetTemp1 = 24; EEPROM.write(100, 24);}
if(c == 'a') {TargetTemp2 = 0; EEPROM.write(102, 0);}
if(c == 's') {TargetTemp2 = 5; EEPROM.write(102, 5);}
if(c == 'd') {TargetTemp2 = 10; EEPROM.write(102, 10);}
if(c == 'f') {TargetTemp2 = 20; EEPROM.write(102, 20);}
if(c == 'g') {TargetTemp2 = 22; EEPROM.write(102, 22);}
if(c == 'h') {TargetTemp2 = 24; EEPROM.write(102, 24);}
if(c == 'z') {TargetTemp3 = 0; EEPROM.write(104, 0);}
if(c == 'x') {TargetTemp3 = 5; EEPROM.write(104, 5);}
if(c == 'c') {TargetTemp3 = 10; EEPROM.write(104, 10);}
if(c == 'v') {TargetTemp3 = 20; EEPROM.write(104, 20);}
if(c == 'b') {TargetTemp3 = 22; EEPROM.write(104, 22);}
if(c == 'n') {TargetTemp3 = 24; EEPROM.write(104, 24);}
Serial.print(c); //print the value of c to serial communication
//Serial.print(outp);
//Serial.print('\n');
switch (c) {
case '0':
//add code here to trigger on 0
triggerPin(outputAddress[0], client, outp);
break;
case '1':
//add code here to trigger on 1
triggerPin(outputAddress[1], client, outp);
break;
case '2':
//add code here to trigger on 2
triggerPin(outputAddress[2], client, outp);
break;
case '3':
//add code here to trigger on 3
triggerPin(outputAddress[3], client, outp);
break;
case '4':
//add code here to trigger on 4
triggerPin(outputAddress[4], client, outp);
break;
case '5':
//add code here to trigger on 5
triggerPin(outputAddress[5], client, outp);
//printHtml(client);
break;
case '6':
//add code here to trigger on 6
triggerPin(outputAddress[6], client, outp);
break;
case '7':
//add code here to trigger on 7
triggerPin(outputAddress[7], client, outp);
break;
case '8':
//add code here to trigger on 8
triggerPin(outputAddress[8], client, outp);
break;
case '9':
//add code here to trigger on 9
triggerPin(outputAddress[9], client, outp);
break;
} //end of switch case
}//end of switch switch the relevant output
//if user input was blank
if (c == '\n' && currentLineIsBlank){
printLastCommandOnce = true;
printButtonMenuOnce = true;
triggerPin(777, client, outp); //Call to read input and print menu. 777 is used not to update any outputs
break;
}
}
}
printHtmlFooter(client); //Prints the html footer
}
else
{ //if there is no client
//And time of last page was served is more then a minute.
if (millis() > (timeConnectedAt + 5000)){
if (writeToEeprom == true){
writeEepromValues(); //write to EEprom the current output statuses
Serial.println("No Clients for more then a 5 sec. - Writing statuses to Eeprom.");
writeToEeprom = false;
}
}
}
}
////////////////////////////////////////////////////////////////////////
//triggerPin Function
////////////////////////////////////////////////////////////////////////
//
void triggerPin(int pin, EthernetClient client, int outp){
//Switching on or off outputs, reads the outputs and prints the buttons
//Setting Outputs
if (pin != 777){
if(outp == 1) {
if (outputInverted ==false){
digitalWrite(pin, HIGH);
}
else{
digitalWrite(pin, LOW);
}
}
if(outp == 0){
if (outputInverted ==false){
digitalWrite(pin, LOW);
}
else{
digitalWrite(pin, HIGH);
}
}
}
//Refresh the reading of outputs
readOutputStatuses();
//Prints the buttons
if (printButtonMenuOnce == true){
printHtmlButtons(client);
printButtonMenuOnce = false;
}
}
////////////////////////////////////////////////////////////////////////
//printHtmlButtons Function
////////////////////////////////////////////////////////////////////////
//print the html buttons to switch on/off channels
void printHtmlButtons(EthernetClient client){
//Start to create the html table
client.println("");
//client.println("<p>");
client.println("<FORM>");
//вывод таблицы управления температурой
client.println("<table border=\"0\" align=\"center\">");
client.print("<tr>");
client.print("<td></td>");
client.print("<td><h3>текущая</h3></td>");
client.print("<td><h3>обогрев</h3</td>");
client.print("<td><h3>желаемая</h3</td>");
client.print("</tr>");
client.print("<tr>");
client.print("<td><h4>");
client.print("Первый этаж:");
client.print("</h4></td>");
client.print("<td align=\"center\">");
client.println(chartemp1); //текущая температура
client.print(" °C</td>");
if ( digitalRead(PinSSR1) == LOW ) {
client.println("<td align=\"center\"><font color=green><b>ВКЛ</b></font></td>"); } // вкл или выкл
else {
client.println("<td align=\"center\"><font color=red><b>ВЫКЛ</b></font></td>"); }
client.println("<td align=\"center\">");
client.println(TargetTemp1); //отображение желаемой температуры
client.println(" °C</td>");
client.print("</tr>");
client.print("<tr>");
client.print("<td><h4>");
client.print("Установить:"); //выбор желаемой температуры
client.print("</h4></td>");
client.print(" <td colspan=3><table border=\"0\"><tr><td><INPUT TYPE=\"button\" VALUE=\"0" "\" onClick=\"parent.location='/?q""'\"></td>");
client.print(" <td><INPUT TYPE=\"button\" VALUE=\"5" "\" onClick=\"parent.location='/?w""'\"></td>");
client.print(" <td><INPUT TYPE=\"button\" VALUE=\"10" "\" onClick=\"parent.location='/?e""'\"></td>");
client.print(" <td><INPUT TYPE=\"button\" VALUE=\"20" "\" onClick=\"parent.location='/?r""'\"></td>");
client.print(" <td><INPUT TYPE=\"button\" VALUE=\"22" "\" onClick=\"parent.location='/?t""'\"></td>");
client.print(" <td><INPUT TYPE=\"button\" VALUE=\"24" "\" onClick=\"parent.location='/?y""'\"></td></tr></table></td>");
client.print("</tr>");
client.println("</table>");
client.println("<table border=\"0\" align=\"center\">");
client.print("<tr>");
client.print("<td></td>");
client.print("<td><h3>текущая</h3></td>");
client.print("<td><h3>обогрев</h3</td>");
client.print("<td><h3>желаемая</h3</td>");
client.print("</tr>");
client.print("<tr>");
client.print("<td><h4>");
client.print("Второй этаж:");
client.print("</h4></td>");
client.print("<td align=\"center\">");
client.println(chartemp2); //текущая температура
client.print(" °C</td>");
if ( digitalRead(PinSSR2) == LOW ) {
client.println("<td align=\"center\"><font color=green><b>ВКЛ</b></font></td>"); } // вкл или выкл
else {
client.println("<td align=\"center\"><font color=red><b>ВЫКЛ</b></font></td>"); }
client.println("<td align=\"center\">");
client.println(TargetTemp2); //отображение желаемой температуры
client.println(" °C</td>");
client.print("</tr>");
client.print("<tr>");
client.print("<td><h4>");
client.print("Установить:"); //выбор желаемой температуры
client.print("</h4></td>");
client.print(" <td colspan=3><table border=\"0\"><tr><td><INPUT TYPE=\"button\" VALUE=\"0" "\" onClick=\"parent.location='/?a""'\"></td>");
client.print(" <td><INPUT TYPE=\"button\" VALUE=\"5" "\" onClick=\"parent.location='/?s""'\"></td>");
client.print(" <td><INPUT TYPE=\"button\" VALUE=\"10" "\" onClick=\"parent.location='/?d""'\"></td>");
client.print(" <td><INPUT TYPE=\"button\" VALUE=\"20" "\" onClick=\"parent.location='/?f""'\"></td>");
client.print(" <td><INPUT TYPE=\"button\" VALUE=\"22" "\" onClick=\"parent.location='/?g""'\"></td>");
client.print(" <td><INPUT TYPE=\"button\" VALUE=\"24" "\" onClick=\"parent.location='/?h""'\"></td></tr></table></td>");
client.print("</tr>");
client.println("</table>");
client.println("<table border=\"0\" align=\"center\">");
client.print("<tr>");
client.print("<td></td>");
client.print("<td><h3>текущая</h3></td>");
client.print("<td><h3>обогрев</h3</td>");
client.print("<td><h3>желаемая</h3</td>");
client.print("</tr>");
client.print("<tr>");
client.print("<td><h4>");
client.print("Кухня:");
client.print("</h4></td>");
client.print("<td align=\"center\">");
client.println(chartemp3); //текущая температура
client.print(" °C</td>");
if ( digitalRead(PinSSR3) == LOW ) {
client.println("<td align=\"center\"><font color=green><b>ВКЛ</b></font></td>"); } // вкл или выкл
else {
client.println("<td align=\"center\"><font color=red><b>ВЫКЛ</b></font></td>"); }
client.println("<td align=\"center\">");
client.println(TargetTemp3); //отображение желаемой температуры
client.println(" °C</td>");
client.print("</tr>");
client.print("<tr>");
client.print("<td><h4>");
client.print("Установить:"); //выбор желаемой температуры
client.print("</h4></td>");
client.print(" <td colspan=3><table border=\"0\"><tr><td><INPUT TYPE=\"button\" VALUE=\"0" "\" onClick=\"parent.location='/?z""'\"></td>");
client.print(" <td><INPUT TYPE=\"button\" VALUE=\"5" "\" onClick=\"parent.location='/?x""'\"></td>");
client.print(" <td><INPUT TYPE=\"button\" VALUE=\"10" "\" onClick=\"parent.location='/?c""'\"></td>");
client.print(" <td><INPUT TYPE=\"button\" VALUE=\"20" "\" onClick=\"parent.location='/?v""'\"></td>");
client.print(" <td><INPUT TYPE=\"button\" VALUE=\"22" "\" onClick=\"parent.location='/?b""'\"></td>");
client.print(" <td><INPUT TYPE=\"button\" VALUE=\"24" "\" onClick=\"parent.location='/?n""'\"></td></tr></table></td>");
client.print("</tr>");
client.println("</table>");
//вывод текста, кнопок ON и OFF и лампочек состояния
client.println("<table border=\"0\" align=\"center\">");
for (int var = 0; var < outputQuantity; var++) {
//set command for all on/off
allOn += "H";
allOn += ten[var]; //ten - массив 1..9
allOff += "L";
allOff += ten[var];
//Print begining of row
client.print("<tr>\n");
//Prints the button Text
client.print("<td><h4>");
client.print(buttonText[var]);
client.print("</h4></td>\n");
//Prints the ON Buttons
client.print("<td>");
client.print("<INPUT TYPE=\"button\" VALUE=\"ВКЛ ");
client.print("\" onClick=\"parent.location='/?H");
client.print(var);
client.print("'\"></td>\n");
//Prints the OFF Buttons
client.print(" <td><INPUT TYPE=\"button\" VALUE=\"ВЫКЛ");
client.print("\" onClick=\"parent.location='/?L");
client.print(var);
client.print("'\"></td>\n");
//Print first part of the Circles or the LEDs
//Invert the LED display if output is inverted.
if (outputStatus[var] == true ){ //If Output is ON
if (outputInverted == false){ //and if output is not inverted
client.print(" <td><div class='green-circle'><div class='glare'></div></div></td>\n"); //Print html for ON LED
}
else{ //else output is inverted then
client.print(" <td><div class='black-circle'><div class='glare'></div></div></td>\n"); //Print html for OFF LED
}
}
else //If Output is Off
{
if (outputInverted == false){ //and if output is not inverted
client.print(" <td><div class='black-circle'><div class='glare'></div></div></td>\n"); //Print html for OFF LED
}
else{ //else output is inverted then
client.print(" <td><div class='green-circle'><div class='glare'></div></div></td>\n"); //Print html for ON LED
}
}
//Print end of row
client.print("</tr>\n");
}
//Вывод кнопок вкл всё и выкл всё
if (switchOnAllPinsButton == true ){
//Prints the ON All Pins Button
client.print("<tr>\n<td colspan=2><INPUT TYPE=\"button\" VALUE=\"Включить ВСЁ");
client.print("\" onClick=\"parent.location='/?");
client.print(allOn);
client.print("'\"></td>\n");
//Prints the OFF All Pins Button
client.print("<td colspan=2><INPUT TYPE=\"button\" VALUE=\"Выключить ВСЁ");
client.print("\" onClick=\"parent.location='/?");
client.print(allOff);
client.print("'\"></td>\n<td></td>\n<td></td>\n</tr>\n");
}
//Closing the table and form
client.println("</table>");
client.println("</FORM>");
//client.println("</p>");
}
////////////////////////////////////////////////////////////////////////
//readOutputStatuses Function
////////////////////////////////////////////////////////////////////////
//Reading the Output Statuses
void readOutputStatuses(){
for (int var = 0; var < outputQuantity; var++) {
outputStatus[var] = digitalRead(outputAddress[var]);
//Serial.print(outputStatus[var]);
}
}
////////////////////////////////////////////////////////////////////////
//readEepromValues Function
////////////////////////////////////////////////////////////////////////
//Read EEprom values and save to outputStatus
void readEepromValues(){
for (int adr = 0; adr < outputQuantity; adr++) {
outputStatus[adr] = EEPROM.read(adr);
}
}
////////////////////////////////////////////////////////////////////////
//writeEepromValues Function
////////////////////////////////////////////////////////////////////////
//Write EEprom values
void writeEepromValues(){
for (int adr = 0; adr < outputQuantity; adr++) {
EEPROM.write(adr, outputStatus[adr]);
}
}
////////////////////////////////////////////////////////////////////////
//initEepromValues Function
////////////////////////////////////////////////////////////////////////
//Initialiaze EEprom values
//if eeprom values are not the correct format ie not euqual to 0 or 1 (thus greater then 1) initialize by putting 0
void initEepromValues(){
for (int adr = 0; adr < outputQuantity; adr++){
if (EEPROM.read(adr) > 1){
EEPROM.write(adr, 0);
}
}
}
////////////////////////////////////////////////////////////////////////
//htmlHeader Function
////////////////////////////////////////////////////////////////////////
//Prints html header
void printHtmlHeader(EthernetClient client){
Serial.print("Serving html Headers at ms -");
timeConnectedAt = millis(); //Record the time when last page was served.
Serial.print(timeConnectedAt); // Print time for debbugging purposes
writeToEeprom = true; // page loaded so set to action the write to eeprom
// send a standard http response header
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html; charset=utf-8");
client.println("Connnection: close");
client.println();
client.println("<!DOCTYPE HTML>");
client.println("<head>");
// Добавить заголовок страницы
client.println("<title>Контроль и управление домом</title>");
client.println("<meta name=\"description\" content=\"Контроль и управление домом\"/>");
// Добавить мета-тег обновления, так что браузер тянет снова каждые х секунд:
client.print("<meta http-equiv=\"refresh\" content=\"");
client.print(refreshPage);
client.println("; url=/\">");
// Добавить другую конфигурацию браузера
client.println("<meta name=\"apple-mobile-web-app-capable\" content=\"yes\">");
client.println("<meta name=\"apple-mobile-web-app-status-bar-style\" content=\"default\">");
client.println("<meta name=\"viewport\" content=\"width=device-width, user-scalable=no\">");
// вставка данных стилей, как правило, найти в CSS файлов.
client.println("<style type=\"text/css\">");
client.println("");
// Это позволит установить, как будет выглядеть страница графически
client.println("html { height:100%; }");
client.println(" body {");
client.println(" height: 100%;");
client.println(" margin: 0;");
client.println(" font-family: helvetica, sans-serif;");
client.println(" -webkit-text-size-adjust: none;");
client.println(" }");
client.println("");
client.println("body {");
client.println(" -webkit-background-size: 100% 21px;");
client.println(" background-color: #c5ccd3;");
client.println(" background-image:");
client.println(" -webkit-gradient(linear, left top, right top,");
client.println(" color-stop(.75, transparent),");
client.println(" color-stop(.75, rgba(255,255,255,.1)) );");
client.println(" -webkit-background-size: 7px;");
client.println(" }");
client.println("");
client.println(".view {");
client.println(" min-height: 100%;");
client.println(" overflow: auto;");
client.println(" }");
client.println("");
client.println(".header-wrapper {");
client.println(" height: 44px;");
client.println(" font-weight: bold;");
client.println(" text-shadow: rgba(0,0,0,0.7) 0 -1px 0;");
client.println(" border-top: solid 1px rgba(255,255,255,0.6);");
client.println(" border-bottom: solid 1px rgba(0,0,0,0.6);");
client.println(" color: #fff;");
client.println(" background-color: #8195af;");
client.println(" background-image:");
client.println(" -webkit-gradient(linear, left top, left bottom,");
client.println(" from(rgba(255,255,255,.4)),");
client.println(" to(rgba(255,255,255,.05)) ),");
client.println(" -webkit-gradient(linear, left top, left bottom,");
client.println(" from(transparent),");
client.println(" to(rgba(0,0,64,.1)) );");
client.println(" background-repeat: no-repeat;");
client.println(" background-position: top left, bottom left;");
client.println(" -webkit-background-size: 100% 21px, 100% 22px;");
client.println(" -webkit-box-sizing: border-box;");
client.println(" }");
client.println("");
client.println(".header-wrapper h1 {");
client.println(" text-align: center;");
client.println(" font-size: 20px;");
client.println(" line-height: 44px;");
client.println(" margin: 0;");
client.println(" }");
client.println("");
client.println(".group-wrapper {");
client.println(" margin: 9px;");
client.println(" aling: center;");
client.println(" }");
client.println("");
client.println(".group-wrapper h2 {");
client.println(" color: #4c566c;");
client.println(" font-size: 17px;");
client.println(" line-height: 0.8;");
client.println(" font-weight: bold;");
client.println(" text-shadow: #fff 0 1px 0;");
client.println(" margin: 20px 10px 12px;");
client.println(" }");
client.println("");
client.println(".group-wrapper h3 {");
client.println(" color: #4c566c;");
client.println(" font-size: 12px;");
client.println(" line-height: 1;");
client.println(" font-weight: bold;");
client.println(" text-shadow: #fff 0 1px 0;");
client.println(" margin: 20px 10px 12px;");
client.println(" }");
client.println("");
client.println(".group-wrapper h4 {"); //Text for description
client.println(" color: #212121;");
client.println(" font-size: 14px;");
client.println(" line-height: 1;");
client.println(" font-weight: bold;");
client.println(" text-shadow: #aaa 1px 1px 3px;");
client.println(" margin: 5px 5px 5px;");
client.println(" }");
client.println("");
client.println(".group-wrapper table {");
client.println(" background-color: #fff;");
client.println(" -webkit-border-radius: 10px;");
client.println(" -moz-border-radius: 10px;");
client.println(" -khtml-border-radius: 10px;");
client.println(" border-radius: 10px;");
client.println(" font-size: 17px;");
client.println(" line-height: 20px;");
client.println(" margin: 9px 0 20px;");
client.println(" border: solid 1px #a9abae;");
client.println(" padding: 11px 3px 12px 3px;");
client.println(" margin-left:auto;");
client.println(" margin-right:auto;");
client.println(" -moz-transform :scale(1);"); //Code for Mozilla Firefox
client.println(" -moz-transform-origin: 0 0;");
client.println(" }");
client.println("");
//how the green (ON) LED will look
client.println(".green-circle {");
client.println(" display: block;");
client.println(" height: 23px;");
client.println(" width: 23px;");
client.println(" background-color: #0f0;");
//client.println(" background-color: rgba(60, 132, 198, 0.8);");
client.println(" -moz-border-radius: 11px;");
client.println(" -webkit-border-radius: 11px;");
client.println(" -khtml-border-radius: 11px;");
client.println(" border-radius: 11px;");
client.println(" margin-left: 1px;");
client.println(" background-image: -webkit-gradient(linear, 0% 0%, 0% 90%, from(rgba(46, 184, 0, 0.8)), to(rgba(148, 255, 112, .9)));@");
client.println(" border: 2px solid #ccc;");
client.println(" -webkit-box-shadow: rgba(11, 140, 27, 0.5) 0px 10px 16px;");
client.println(" -moz-box-shadow: rgba(11, 140, 27, 0.5) 0px 10px 16px; /* FF 3.5+ */");
client.println(" box-shadow: rgba(11, 140, 27, 0.5) 0px 10px 16px; /* FF 3.5+ */");
client.println(" }");
client.println("");
//how the black (off)LED will look
client.println(".black-circle {");
client.println(" display: block;");
client.println(" height: 23px;");
client.println(" width: 23px;");
client.println(" background-color: #040;");
client.println(" -moz-border-radius: 11px;");
client.println(" -webkit-border-radius: 11px;");
client.println(" -khtml-border-radius: 11px;");
client.println(" border-radius: 11px;");
client.println(" margin-left: 1px;");
client.println(" -webkit-box-shadow: rgba(11, 140, 27, 0.5) 0px 10px 16px;");
client.println(" -moz-box-shadow: rgba(11, 140, 27, 0.5) 0px 10px 16px; /* FF 3.5+ */");
client.println(" box-shadow: rgba(11, 140, 27, 0.5) 0px 10px 16px; /* FF 3.5+ */");
client.println(" }");
client.println("");
//this will add the glare to both of the LEDs
client.println(" .glare {");
client.println(" position: relative;");
client.println(" top: 1;");
client.println(" left: 5px;");
client.println(" -webkit-border-radius: 10px;");
client.println(" -moz-border-radius: 10px;");
client.println(" -khtml-border-radius: 10px;");
client.println(" border-radius: 10px;");
client.println(" height: 1px;");
client.println(" width: 13px;");
client.println(" padding: 5px 0;");
client.println(" background-color: rgba(200, 200, 200, 0.25);");
client.println(" background-image: -webkit-gradient(linear, 0% 0%, 0% 95%, from(rgba(255, 255, 255, 0.7)), to(rgba(255, 255, 255, 0)));");
client.println(" }");
client.println("");
//and finally this is the end of the style data and header
client.println("</style>");
client.println("</head>");
//now printing the page itself
client.println("<body>");
client.println("<div class=\"view\">");
client.println(" <div class=\"header-wrapper\">");
client.println(" <h1>СМАРТ ДАЧА</h1>");
client.println(" </div>");
} //end of htmlHeader
////////////////////////////////////////////////////////////////////////
//htmlFooter Function
////////////////////////////////////////////////////////////////////////
//Prints html footer
void printHtmlFooter(EthernetClient client){
//Set Variables Before Exiting
printLastCommandOnce = false;
printButtonMenuOnce = false;
allOn = "";
allOff = "";
//printing last part of the html
client.println("\n<h3 align=\"center\">© Plagiary - 2016 - ");
client.println(rev);
client.println("</h3></div>\n</div>\n</body>\n</html>");
delay(1); // give the web browser time to receive the data
client.stop(); // close the connection:
Serial.println(" - Done, Closing Connection.");
delay (2); //delay so that it will give time for client buffer to clear and does not repeat multiple pages.
} //end of htmlFooter
////////////////////////////////////////////////////////////////////////
//printHtmlButtonTitle Function
////////////////////////////////////////////////////////////////////////
//Prints html button title
void printHtmlButtonTitle(EthernetClient client){
client.println("<div class=\"group-wrapper\">");
client.println("<h2 align=\"center\" >Температура на улице");
client.println(chartemp4);
client.print(" °C </h2>");
client.println();
}
////////////////////////////////////////////////////////////////////////
//printLoginTitle Function
////////////////////////////////////////////////////////////////////////
//Prints html button title
void printLoginTitle(EthernetClient client){
// client.println("<div class=\"group-wrapper\">");
client.println(" <h2>Please enter the user data to login.</h2>");
client.println();
}
/////////////////управление температурой
float tempread(byte sensoraddr[])
// error codes:
// -1 no sensors found
// -2 invalid CRC
// -3 not a DS1820
{
byte i;
byte present = 0;
byte data[12];
byte addr[8];
//int HighByte, LowByte, TReading, SignBit, Tc_100, Tf_100, Whole, Fract;
for ( i = 0; i < 8; i++) {
addr[i]=sensoraddr[i];
}
ds.reset(); // pulse the pins and wait for a response to reset the DS1820
ds.select(addr); // 0x55 (MATCH_ROM) followed by the address of the 1820 to talk to.
// ds.write(0x44,1); // start conversion, with parasite power on at the end
ds.write(0x44,0); //PARASITE POWER OFF
// delay(800);
present = ds.reset();
ds.select(addr);
ds.write(0xBE); // Read Scratchpad
for ( i = 0; i < 9; i++) { // we need 9 bytes
data[i] = ds.read();
}
int16_t raw = (data[1] << 8) | data[0];
float temp = (float)raw / 16.0;
return temp;
}
Особо умный: это же ни разу не веб-сервер, давайте не путать понятия. Это просто девайс, который выдаёт жёстко захардкоженную страницу по HTTP, всё (причём - никак не анализируя запрос, но про RFC вы просили не говорить, поэтому не буду, так и быть).
Никакого отношения к понятию WEB-сервер написанный код не имеет.
Долго бился с формой ввода желаемой температуры, сделал отдельными кнопками
Скажи проще, и всем будет понятней: просто по-другому - не получилось, потому что там, оказывается, учиться надо :)
Особо умный: это же ни разу не веб-сервер, давайте не путать понятия. Это просто девайс, который выдаёт жёстко захардкоженную страницу по HTTP, всё (причём - никак не анализируя запрос, но про RFC вы просили не говорить, поэтому не буду, так и быть).
Никакого отношения к понятию WEB-сервер написанный код не имеет.
ну вот просил же пройти мимо, но нет нужно в каждую бочку залезть)
Долго бился с формой ввода желаемой температуры, сделал отдельными кнопками
Скажи проще, и всем будет понятней: просто по-другому - не получилось, потому что там, оказывается, учиться надо :)
для меня эти два высказывания синонимы, для Вашего понимания возможно Ваш вариант проще )
ЗЫ. Вы уж определитесь на Вы или на ты обращаться.
ЗЫЫ. ru.wikipedia.org›Веб-сервер
поздравляю!смотрю на скетч и понимаю,какой труд вы пережили,сам таким был год назад=)
ну а вообще больно смотреть на такой код...кощунство вшивать жестко в оперативку столько текста в виде html =)
для этого дам вам малюсенький совет: везде где используется жесткий текст в выводе(не переменные) используйте встроенный макрос,например ваша строчка
client.println("HTTP/1.1 200 OK");пишите такclient.println(F("HTTP/1.1 200 OK"));таким образом текст вшивается во влеш,а не в оперативку...
учите ajax для динамического обновления данных на странице,чтоб не использовать мета-теги,это кака...примеров хватает...да и веб странички лучше читать с карты памяти,так их проще редактировать и отлаживать...это так,на будущее,если будете расширять свой проект,пока для этих задач само-собой меги вам хватает...но ой как не рационально вы ресурс ее используете..
спору нет,главное что работает,но вам есть куда еще расти=)база у ва есть,теперь совершенствуйте потихоньку...
ЗЫЫ. ru.wikipedia.org›Веб-сервер
Ну ведь клиника же, клиника - вы даже справочную документацию читать не умеете. Сказано ведь: "принимающий HTTP-запросы". Где в вашем коде приём HTTP-запроса, анализ того, что вообще HTTP-запрос пришёл, что он - валидный, и пр. необходимый минимум? Именно поэтому ещё раз повторюсь: то, что вы написали - это не веб-сервер. Это просто кусок говнокода, выдающий что-то там в браузер. Веб-сервером это называть - огромная наглость и безграмотность.
Не берите близко к сердцу, но это - не веб-сервер. Да, код работает, что-то там делает - пусть его, мне от этого ни тепло, ни холодно. Но "это" - не веб-сервер.
Продолжим :) Более того - вы пока не сталкивались с кодированием символов как в URL, так и в теле POST-запроса, и кода, который это разбирает - не видно ничуть. Я не говорю, что вы с этим столкнётесь, оно вам и не надо, но: раз учитесь, пусть и на плохих примерах - давайте не хватать вершков, а хотя бы понимать основные принципы взаимодействия HTTP-клиент - HTTP-сервер. без этого, рано или поздно - не взлететь.
Хотя, конечно, сейчас браузеры какой только каки не принимают - и всё равно честно пытаются разобрать это на атомы, чтобы таки отрисовать страницу. В этом их, безусловно, плюс, и, одновременно - огромный минус, т.к. расхолаживает разработчиков прикладного софта любого уровня. Если вы действительно хотите понять, о чём я, проведите простой эксперимент: добавьте перед <html в отсылаемом коде вот такую строку:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
И посмотрите в инструментах веб-разработки в браузере - сколько вам посыпется ошибок разметки - я, например, сходу вижу, что они есть.
Проект, к слову, нормальный, но - работать, работать, работать. И не называть веб-сервером.
поздравляю!смотрю на скетч и понимаю,какой труд вы пережили,сам таким был год назад=)
для этого дам вам малюсенький совет:
Спасибо, и за совет огромный респект, на этом форуме это редкость для меня, как правило люди могут только в душу срать, показывая какие они умные(не факт, это их мнение, всем известно что здоровый и мудрый человек не будет себя называть умным, даже если он себя таким считает) =)
Это просто кусок говнокода, выдающий что-то там в браузер....
....Проект, к слову, нормальный, но - работать, работать, работать.
Вы назвали этот говнокод нормальным проектом? =) что с Вами?
Это просто кусок говнокода, выдающий что-то там в браузер....
....Проект, к слову, нормальный, но - работать, работать, работать.
Вы назвали этот говнокод нормальным проектом? =) что с Вами?
Проект - нормальный, код - гавно, о чём я честно сказал. Не нравится выслушивать чужое мнение - не выкладывайте своё.
З.Ы. Дабы пресечь возможные инсинуации: код, который пишу я - тоже гавно. Но я - стремлюсь.
Объясните мне пожалуйста почему переменная "с" не может быть двухзначным? Т.е.
case '9': //add code here to trigger on 9 triggerPin(outputAddress[9], client, outp); break; /* case '10': //add code here to trigger on 10 triggerPin(outputAddress[10], client, outp); break;void checkForClient(){ EthernetClient client = server.available(); if (client) { // an http request ends with a blank line boolean currentLineIsBlank = true; boolean sentHeader = false; while (client.connected()) { if (client.available()) { //if header was not set send it //read user input char c = client.read(); if(c == '*'){ printHtmlHeader(client); //call for html header and css printHtmlFooter(client); //sentHeader = true; break; } if(!sentHeader){ printHtmlHeader(client); //call for html header and css printHtmlButtonTitle(client); //print the button title //This is for the arduino to construct the page on the fly. sentHeader = true; } //read user input // char c = client.read(); //if there was reading but is blank there was no reading if(reading && c == ' '){ reading = false; } //if there is a ? there was user input if(c == '?') { reading = true; //found the ?, begin reading the info } // if there was user input switch the relevant output if(reading){ //if user input is H set output to 1 if(c == 'H') { outp = 1; } //if user input is L set output to 0 if(c == 'L') { outp = 0; } Serial.print(c); //print the value of c to serial communication //Serial.print(outp); //Serial.print('\n'); switch (c) { case '0': //add code here to trigger on 0 triggerPin(outputAddress[0], client, outp); break; case '1': //add code here to trigger on 1 triggerPin(outputAddress[1], client, outp); break; case '2': //add code here to trigger on 2 triggerPin(outputAddress[2], client, outp); break; case '3': //add code here to trigger on 3 triggerPin(outputAddress[3], client, outp); break; case '4': //add code here to trigger on 4 triggerPin(outputAddress[4], client, outp); break; case '5': //add code here to trigger on 5 triggerPin(outputAddress[5], client, outp); //printHtml(client); break; case '6': //add code here to trigger on 6 triggerPin(outputAddress[6], client, outp); break; case '7': //add code here to trigger on 7 triggerPin(outputAddress[7], client, outp); break; case '8': //add code here to trigger on 8 triggerPin(outputAddress[8], client, outp); break; case '9': //add code here to trigger on 9 triggerPin(outputAddress[9], client, outp); break; /* case '10': //add code here to trigger on 10 triggerPin(outputAddress[10], client, outp); break;Объясните мне пожалуйста почему переменная "с" не может быть двухзначным? Т.е. case '10';
Void checkForClient(){ EthernetClient client = server.available(); if (client) { // an http request ends with a blank line boolean currentLineIsBlank = true; boolean sentHeader = false; while (client.connected()) { if (client.available()) { //if header was not set send it //read user input char c = client.read(); if(c == '*'){ printHtmlHeader(client); //call for html header and css printHtmlFooter(client); //sentHeader = true; break; } if(!sentHeader){ printHtmlHeader(client); //call for html header and css printHtmlButtonTitle(client); //print the button title //This is for the arduino to construct the page on the fly. sentHeader = true; } //read user input // char c = client.read(); //if there was reading but is blank there was no reading if(reading && c == ' '){ reading = false; } //if there is a ? there was user input if(c == '?') { reading = true; //found the ?, begin reading the info } // if there was user input switch the relevant output if(reading){ //if user input is H set output to 1 if(c == 'H') { outp = 1; } //if user input is L set output to 0 if(c == 'L') { outp = 0; } Serial.print(c); //print the value of c to serial communication //Serial.print(outp); //Serial.print('\n'); switch (c) { case '0': //add code here to trigger on 0 triggerPin(outputAddress[0], client, outp); break; case '1': //add code here to trigger on 1 triggerPin(outputAddress[1], client, outp); break; case '2': //add code here to trigger on 2 triggerPin(outputAddress[2], client, outp); break; case '3': //add code here to trigger on 3 triggerPin(outputAddress[3], client, outp); break; case '4': //add code here to trigger on 4 triggerPin(outputAddress[4], client, outp); break; case '5': //add code here to trigger on 5 triggerPin(outputAddress[5], client, outp); //printHtml(client); break; case '6': //add code here to trigger on 6 triggerPin(outputAddress[6], client, outp); break; case '7': //add code here to trigger on 7 triggerPin(outputAddress[7], client, outp); break; case '8': //add code here to trigger on 8 triggerPin(outputAddress[8], client, outp); break; case '9': //add code here to trigger on 9 triggerPin(outputAddress[9], client, outp); break; /* case '10': //add code here to trigger on 10 triggerPin(outputAddress[10], client, outp); break;почему же не может,очень даже может...
а вот outputAddress[10] не может быть...вы плохо усвоили вчерашний урок и ссылки =)))
чтоб понять в чем проблема изначально,ставьте так сказать "маркеры" вывода в сериал порт для отладки,чтоб вам самим было яснее что происходит в вашей программе,например:
сase'10':Serial.println("OK");triggerPin(outputAddress[10], client, outp);
break;увидели бы в мониторе порта ОК,стало бы понятно,что в блок 10 мы попали,значит ошибка в чем-то другом и тд...когда все заработает,тогда уже удалите или закоментируйте маркеры
почему же не может,очень даже может...
а вот outputAddress[10] не может быть...
если Вы про короткий массив, то я его увеличил
int outputAddress[20] = { 3,5,6,7,8,9,14,15,16,17,18,19,20,21,22,23,24,25,26,27};
и что за урок с ссылками был вчера?)))
Ну, в приведенном коде этого объявления я не увидел, поэтому так и решил... Тогда ставьте маркер и напишите, что получилось.ссылки на описание объявления массива..
Сижу с телефона, тяжело код смотреть... Чуть выше по коду поставьте маркер, что б вообще посмотреть кой case мы получаем перед обработкой, а то может он и не 10 вообще...а, увидел, вы так и делаете... Десятка приходит? Тяжко с телефона сидеть)
Вы меня извините, но ссылки у меня не оттображаются похоже=)
#include <Ethernet.h> #include <SPI.h> #include <EEPROM.h> #include <DHT.h> #include <OneWire.h> //////////////////////////////////////////////////////////////////////// //CONFIGURATION //////////////////////////////////////////////////////////////////////// //IP manual settings byte ip[] = { 10, 16, 30, 2 }; //Manual setup only byte gateway[] = { 10, 16, 30, 3 }; //Manual setup only byte subnet[] = { 255, 255, 255, 0 }; //Manual setup only // if need to change the MAC address (Very Rare) byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //Ethernet Port EthernetServer server = EthernetServer(80); //default html port 80 //The number of outputs going to be switched. int outputQuantity = 11; //should not exceed 10 //Invert the output of the leds boolean outputInverted = false; //true or false // This is done in case the relay board triggers the relay on negative, rather then on positive supply //Html page refresh int refreshPage = 15; //default is 10sec. //Beware that if you make it refresh too fast, the page could become inacessable. //Display or hide the "Switch on all Pins" buttons at the bottom of page int switchOnAllPinsButton = true; //true or false //Button Array //Just for a note, varables start from 0 to 9, as 0 is counted as well, thus 10 outputs. // Select the pinout address int outputAddress[20] = { 3,5,6,7,8,9,14,15,16,17,18,19,20,21,22,23,24,25,26,27}; //Allocate 10 spaces and name the output pin address. //PS pin addresses 10, 11, 12 and 13 on the Duemilanove are used for the ethernet shield, therefore cannot be used. //PS pin addresses 10, 50, 51 and 52 and 53 on the Mega are used for the ethernet shield, therefore cannot be used. //PS pin addresses 4, are used for the SD card, therefore cannot be used. //PS. pin address 2 is used for interrupt-driven notification, therefore could not be used. // Write the text description of the output channel String buttonText[20] = { "01. Канал","02. Канал","03. Канал","04. Канал","05. Канал","06. Канал","07. Канал","08. Канал","09. Канал","10. Канал","11. Канал","12. Канал","13. Канал","14. Канал","15. Канал","16. Канал","17. Канал","18. Канал","19. Канал","20. Канал"}; //////////////////////////////////////////////////////////////////////// int ten[11] = {0,1,2,3,4,5,6,7,8,9,10}; int twenty[20] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19}; //int twenty[20] = {00,01,02,03,04,05,06,07,8,9,10,11,12,13,14,15,16,17,18,19}; //////////////////////////////////////////////////////////////////////// //VARIABLES DECLARATION //////////////////////////////////////////////////////////////////////// int outp = 0; boolean printLastCommandOnce = false; boolean printButtonMenuOnce = false; boolean initialPrint = true; String allOn = ""; String allOff = ""; boolean reading = false; boolean outputStatus[10]; //Create a boolean array for the maximum ammount. String rev = "V1.3"; unsigned long timeConnectedAt; boolean writeToEeprom = false; //////////////переменные упрвавления температурой const byte PinSSR1 = 44; // Реле Pin for SSR 1 const byte PinSSR2 = 45; // Реле Pin for SSR 2 const byte PinSSR3 = 46; // Реле Pin for SSR 3 char chartemp1[10]; char chartemp2[10]; char chartemp3[10]; char chartemp4[10]; int TargetTemp1; int TargetTemp2; int TargetTemp3; float temp1; float temp2; OneWire ds(47); DHT dht1(48, DHT11); DHT dht2(49, DHT11); //////////////////////////////// //////////////////////////////////////////////////////////////////////// //RUN ONCE //////////////////////////////////////////////////////////////////////// //Beginning of Program void setup(){ Serial.begin(9600); initEepromValues(); readEepromValues(); //Set pins as Outputs boolean currentState = false; for (int var = 0; var < outputQuantity; var++){ pinMode(outputAddress[var], OUTPUT); //Switch all outputs to either on or off on Startup if(outputInverted == true) { //digitalWrite(outputAddress[var], HIGH); if(outputStatus[var] == 0){currentState = true;}else{currentState = false;} //check outputStatus if off, switch output accordingly digitalWrite(outputAddress[var], currentState); } else{ //digitalWrite(outputAddress[var], LOW); if(outputStatus[var] == 0){currentState = false;}else{currentState = true;}//check outputStatus if off, switch output accordingly digitalWrite(outputAddress[var], currentState); } } //Setting up the IP address. Comment out the one you dont need. //Ethernet.begin(mac); //for DHCP address. (Address will be printed to serial.) Ethernet.begin(mac, ip, gateway, subnet); //for manual setup. (Address is the one configured above.) server.begin(); Serial.print("Server started at "); Serial.println(Ethernet.localIP()); ////////////////управление температурой pinMode(PinSSR1, OUTPUT); pinMode(PinSSR2, OUTPUT); pinMode(PinSSR3, OUTPUT); TargetTemp1 = EEPROM.read(100); TargetTemp2 = EEPROM.read(102); TargetTemp3 = EEPROM.read(104); dht1.begin(); dht2.begin(); } //////////////////////////////////////////////////////////////////////// //LOOP //////////////////////////////////////////////////////////////////////// //Run once void loop(){ // listen for incoming clients, and process requests. checkForClient(); ///////////////////////управление температурой float temp3; float temp4; byte sensor1[8] = {0x28, 0xFF, 0x34, 0x2C, 0x50, 0x15, 0x01, 0x87}; // Адрес сенсора byte sensor2[8] = {0x28, 0xDF, 0x7E, 0xDC, 0x06, 0x00, 0x00, 0xF3}; // Адрес сенсора //DHT temp1 = dht1.readTemperature(); dtostrf(temp1, 3, 1, chartemp1); temp2 = dht2.readTemperature(); dtostrf(temp2, 3, 1, chartemp2); //DS18B20 temp3 = tempread(sensor1); dtostrf(temp3, 3, 1, chartemp3); temp4 = tempread(sensor2); dtostrf(temp4, 3, 1, chartemp4); if (temp1<TargetTemp1-1) { digitalWrite(PinSSR1, LOW); } else if (temp1>TargetTemp1+1) { digitalWrite(PinSSR1, HIGH); } if (temp2<TargetTemp2-1) { digitalWrite(PinSSR2, LOW); } else if (temp2>TargetTemp2+1) { digitalWrite(PinSSR2, HIGH); } if (temp3<TargetTemp3-1) { digitalWrite(PinSSR3, LOW); } else if (temp3>TargetTemp3+1) { digitalWrite(PinSSR3, HIGH); } } //////////////////////////////////////////////////////////////////////// //checkForClient Function //////////////////////////////////////////////////////////////////////// // void checkForClient(){ EthernetClient client = server.available(); if (client) { // an http request ends with a blank line boolean currentLineIsBlank = true; boolean sentHeader = false; while (client.connected()) { if (client.available()) { //if header was not set send it //read user input char c = client.read(); if(c == '*'){ printHtmlHeader(client); //call for html header and css printHtmlFooter(client); //sentHeader = true; break; } if(!sentHeader){ printHtmlHeader(client); //call for html header and css printHtmlButtonTitle(client); //print the button title //This is for the arduino to construct the page on the fly. sentHeader = true; } //read user input // char c = client.read(); //if there was reading but is blank there was no reading if(reading && c == ' '){ reading = false; } //if there is a ? there was user input if(c == '?') { reading = true; //found the ?, begin reading the info } // if there was user input switch the relevant output if(reading){ //if user input is H set output to 1 if(c == 'H') { outp = 1; } //if user input is L set output to 0 if(c == 'L') { outp = 0; } Serial.print(c); //print the value of c to serial communication //Serial.print(outp); //Serial.print('\n'); switch (c) { case '0': //add code here to trigger on 0 triggerPin(outputAddress[0], client, outp); Serial.println("case '0': OK"); break; case '1': //add code here to trigger on 1 triggerPin(outputAddress[1], client, outp); break; case '2': //add code here to trigger on 2 triggerPin(outputAddress[2], client, outp); break; case '3': //add code here to trigger on 3 triggerPin(outputAddress[3], client, outp); break; case '4': //add code here to trigger on 4 triggerPin(outputAddress[4], client, outp); break; case '5': //add code here to trigger on 5 triggerPin(outputAddress[5], client, outp); //printHtml(client); break; case '6': //add code here to trigger on 6 triggerPin(outputAddress[6], client, outp); break; case '7': //add code here to trigger on 7 triggerPin(outputAddress[7], client, outp); break; case '8': //add code here to trigger on 8 triggerPin(outputAddress[8], client, outp); break; case '9': //add code here to trigger on 9 triggerPin(outputAddress[9], client, outp); Serial.println("case '9': OK"); break; case '10': //add code here to trigger on 10 triggerPin(outputAddress[10], client, outp); Serial.println("case '10': OK"); break; /* case '11': //add code here to trigger on 11 triggerPin(outputAddress[11], client, outp); break; case '12': //add code here to trigger on 12 triggerPin(outputAddress[12], client, outp); break; case '13': //add code here to trigger on 13 triggerPin(outputAddress[13], client, outp); break; case '14': //add code here to trigger on 14 triggerPin(outputAddress[14], client, outp); break; case '15': //add code here to trigger on 15 triggerPin(outputAddress[15], client, outp); //printHtml(client); break; case '16': //add code here to trigger on 16 triggerPin(outputAddress[16], client, outp); break; case '17': //add code here to trigger on 17 triggerPin(outputAddress[17], client, outp); break; case '18': //add code here to trigger on 18 triggerPin(outputAddress[18], client, outp); break; case '19': //add code here to trigger on 19 triggerPin(outputAddress[19], client, outp); break; */ } //end of switch case if(c == 'q1') {TargetTemp1 = 0; EEPROM.write(100, 0);} if(c == 'w1') {TargetTemp1 = 5; EEPROM.write(100, 5);} if(c == 'e') {TargetTemp1 = 10; EEPROM.write(100, 10);} if(c == 'r') {TargetTemp1 = 20; EEPROM.write(100, 20);} if(c == 't') {TargetTemp1 = 22; EEPROM.write(100, 22);} if(c == 'y') {TargetTemp1 = 24; EEPROM.write(100, 24);} if(c == 'a') {TargetTemp2 = 0; EEPROM.write(102, 0);} if(c == 's') {TargetTemp2 = 5; EEPROM.write(102, 5);} if(c == 'd') {TargetTemp2 = 10; EEPROM.write(102, 10);} if(c == 'f') {TargetTemp2 = 20; EEPROM.write(102, 20);} if(c == 'g') {TargetTemp2 = 22; EEPROM.write(102, 22);} if(c == 'h') {TargetTemp2 = 24; EEPROM.write(102, 24);} if(c == 'z') {TargetTemp3 = 0; EEPROM.write(104, 0);} if(c == 'x') {TargetTemp3 = 5; EEPROM.write(104, 5);} if(c == 'c') {TargetTemp3 = 10; EEPROM.write(104, 10);} if(c == 'v') {TargetTemp3 = 20; EEPROM.write(104, 20);} if(c == 'b') {TargetTemp3 = 22; EEPROM.write(104, 22);} if(c == 'n') {TargetTemp3 = 24; EEPROM.write(104, 24);} }//end of switch switch the relevant output //if user input was blank if (c == '\n' && currentLineIsBlank){ printLastCommandOnce = true; printButtonMenuOnce = true; triggerPin(777, client, outp); //Call to read input and print menu. 777 is used not to update any outputs break; } } } printHtmlFooter(client); //Prints the html footer } else { //if there is no client // таймаут простоя, для записи данных состояния переключателей в кэш if (millis() > (timeConnectedAt + 50000)){ if (writeToEeprom == true){ writeEepromValues(); //write to EEprom the current output statuses Serial.println("No Clients for more then a 50 sec. - Writing statuses to Eeprom."); writeToEeprom = false; } } } } /////////////////////////////////////////////////////////////////////// //triggerPin Function //////////////////////////////////////////////////////////////////////// void triggerPin(int pin, EthernetClient client, int outp){ //Switching on or off outputs, reads the outputs and prints the buttons //Setting Outputs if (pin != 777){ if(outp == 1) { if (outputInverted ==false){ digitalWrite(pin, HIGH); } else{ digitalWrite(pin, LOW); } } if(outp == 0){ if (outputInverted ==false){ digitalWrite(pin, LOW); } else{ digitalWrite(pin, HIGH); } } } //Refresh the reading of outputs readOutputStatuses(); //Prints the buttons if (printButtonMenuOnce == true){ printHtmlButtons(client); printButtonMenuOnce = false; } } //////////////////////////////////////////////////////////////////////// //printHtmlButtons Function //////////////////////////////////////////////////////////////////////// void printHtmlButtons(EthernetClient client){ client.println(""); client.println("<FORM>"); //вывод таблиц управления температурой client.println("<table border=\"0\" align=\"center\">"); client.print("<tr>"); client.print("<td></td>"); client.print("<td><h3>текущая</h3></td>"); client.print("<td><h3>обогрев</h3</td>"); client.print("<td><h3>желаемая</h3</td>"); client.print("</tr>"); client.print("<tr>"); client.print("<td><h4>"); client.print("Первый этаж:"); client.print("</h4></td>"); client.print("<td align=\"center\">"); client.println(chartemp1); //текущая температура client.print(" °C</td>"); if ( digitalRead(PinSSR1) == LOW ) { client.println("<td align=\"center\"><font color=green><b>ВКЛ</b></font></td>"); } // вкл или выкл else { client.println("<td align=\"center\"><font color=red><b>ВЫКЛ</b></font></td>"); } client.println("<td align=\"center\">"); client.println(TargetTemp1); //отображение желаемой температуры client.println(" °C</td>"); client.print("</tr>"); client.print("<tr>"); client.print("<td><h4>"); client.print("Установить:"); //выбор желаемой температуры client.print("</h4></td>"); client.print(" <td colspan=3><table border=\"0\"><tr><td><INPUT TYPE=\"button\" VALUE=\"0" "\" onClick=\"parent.location='/?q1""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"5" "\" onClick=\"parent.location='/?w1""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"10" "\" onClick=\"parent.location='/?e""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"20" "\" onClick=\"parent.location='/?r""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"22" "\" onClick=\"parent.location='/?t""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"24" "\" onClick=\"parent.location='/?y""'\"></td></tr></table></td>"); client.print("</tr>"); client.println("</table>"); client.println("<table border=\"0\" align=\"center\">"); client.print("<tr>"); client.print("<td></td>"); client.print("<td><h3>текущая</h3></td>"); client.print("<td><h3>обогрев</h3</td>"); client.print("<td><h3>желаемая</h3</td>"); client.print("</tr>"); client.print("<tr>"); client.print("<td><h4>"); client.print("Второй этаж:"); client.print("</h4></td>"); client.print("<td align=\"center\">"); client.println(chartemp2); //текущая температура client.print(" °C</td>"); if ( digitalRead(PinSSR2) == LOW ) { client.println("<td align=\"center\"><font color=green><b>ВКЛ</b></font></td>"); } // вкл или выкл else { client.println("<td align=\"center\"><font color=red><b>ВЫКЛ</b></font></td>"); } client.println("<td align=\"center\">"); client.println(TargetTemp2); //отображение желаемой температуры client.println(" °C</td>"); client.print("</tr>"); client.print("<tr>"); client.print("<td><h4>"); client.print("Установить:"); //выбор желаемой температуры client.print("</h4></td>"); client.print(" <td colspan=3><table border=\"0\"><tr><td><INPUT TYPE=\"button\" VALUE=\"0" "\" onClick=\"parent.location='/?a""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"5" "\" onClick=\"parent.location='/?s""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"10" "\" onClick=\"parent.location='/?d""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"20" "\" onClick=\"parent.location='/?f""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"22" "\" onClick=\"parent.location='/?g""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"24" "\" onClick=\"parent.location='/?h""'\"></td></tr></table></td>"); client.print("</tr>"); client.println("</table>"); client.println("<table border=\"0\" align=\"center\">"); client.print("<tr>"); client.print("<td></td>"); client.print("<td><h3>текущая</h3></td>"); client.print("<td><h3>обогрев</h3</td>"); client.print("<td><h3>желаемая</h3</td>"); client.print("</tr>"); client.print("<tr>"); client.print("<td><h4>"); client.print("Кухня:"); client.print("</h4></td>"); client.print("<td align=\"center\">"); client.println(chartemp3); //текущая температура client.print(" °C</td>"); if ( digitalRead(PinSSR3) == LOW ) { client.println("<td align=\"center\"><font color=green><b>ВКЛ</b></font></td>"); } // вкл или выкл else { client.println("<td align=\"center\"><font color=red><b>ВЫКЛ</b></font></td>"); } client.println("<td align=\"center\">"); client.println(TargetTemp3); //отображение желаемой температуры client.println(" °C</td>"); client.print("</tr>"); client.print("<tr>"); client.print("<td><h4>"); client.print("Установить:"); //выбор желаемой температуры client.print("</h4></td>"); client.print(" <td colspan=3><table border=\"0\"><tr><td><INPUT TYPE=\"button\" VALUE=\"0" "\" onClick=\"parent.location='/?z""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"5" "\" onClick=\"parent.location='/?x""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"10" "\" onClick=\"parent.location='/?c""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"20" "\" onClick=\"parent.location='/?v""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"22" "\" onClick=\"parent.location='/?b""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"24" "\" onClick=\"parent.location='/?n""'\"></td></tr></table></td>"); client.print("</tr>"); client.println("</table>"); //вывод текста, кнопок ON и OFF и лампочек состояния client.println("<table border=\"0\" align=\"center\">"); for (int var = 0; var < outputQuantity; var++) { //set command for all on/off allOn += "H"; allOn += twenty[var]; //ten - массив 1..19 allOff += "L"; allOff += twenty[var]; //Print begining of row client.print("<tr>\n"); //Prints the button Text client.print("<td><h4>"); client.print(buttonText[var]); client.print("</h4></td>\n"); //Prints the ON Buttons client.print("<td>"); client.print("<INPUT TYPE=\"button\" VALUE=\"ВКЛ "); client.print("\" onClick=\"parent.location='/?H"); client.print(var); client.print("'\"></td>\n"); //Prints the OFF Buttons client.print(" <td><INPUT TYPE=\"button\" VALUE=\"ВЫКЛ"); client.print("\" onClick=\"parent.location='/?L"); client.print(var); client.print("'\"></td>\n"); //Print first part of the Circles or the LEDs //Invert the LED display if output is inverted. if (outputStatus[var] == true ){ //If Output is ON if (outputInverted == false){ //and if output is not inverted client.print(" <td><div class='green-circle'><div class='glare'></div></div></td>\n"); //Print html for ON LED } else{ //else output is inverted then client.print(" <td><div class='black-circle'><div class='glare'></div></div></td>\n"); //Print html for OFF LED } } else //If Output is Off { if (outputInverted == false){ //and if output is not inverted client.print(" <td><div class='black-circle'><div class='glare'></div></div></td>\n"); //Print html for OFF LED } else{ //else output is inverted then client.print(" <td><div class='green-circle'><div class='glare'></div></div></td>\n"); //Print html for ON LED } } client.print("</tr>\n"); } // end for //Вывод кнопок вкл всё и выкл всё if (switchOnAllPinsButton == true ){ //Prints the ON All Pins Button client.print("<tr>\n<td colspan=2><INPUT TYPE=\"button\" VALUE=\"Включить ВСЁ"); client.print("\" onClick=\"parent.location='/?"); client.print(allOn); client.print("'\"></td>\n"); //Prints the OFF All Pins Button client.print("<td colspan=2><INPUT TYPE=\"button\" VALUE=\"Выключить ВСЁ"); client.print("\" onClick=\"parent.location='/?"); client.print(allOff); client.print("'\"></td>\n<td></td>\n<td></td>\n</tr>\n"); } client.println("</table>"); client.println("</FORM>"); } //////////////////////////////////////////////////////////////////////// //readOutputStatuses Function //////////////////////////////////////////////////////////////////////// //Reading the Output Statuses void readOutputStatuses(){ for (int var = 0; var < outputQuantity; var++) { outputStatus[var] = digitalRead(outputAddress[var]); //Serial.print(outputStatus[var]); } } //////////////////////////////////////////////////////////////////////// //readEepromValues Function //////////////////////////////////////////////////////////////////////// //Read EEprom values and save to outputStatus void readEepromValues(){ for (int adr = 0; adr < outputQuantity; adr++) { outputStatus[adr] = EEPROM.read(adr); } } //////////////////////////////////////////////////////////////////////// //writeEepromValues Function //////////////////////////////////////////////////////////////////////// void writeEepromValues(){ for (int adr = 0; adr < outputQuantity; adr++) { EEPROM.write(adr, outputStatus[adr]); } } //////////////////////////////////////////////////////////////////////// //initEepromValues Function //////////////////////////////////////////////////////////////////////// //Initialiaze EEprom values //if eeprom values are not the correct format ie not euqual to 0 or 1 (thus greater then 1) initialize by putting 0 void initEepromValues(){ for (int adr = 0; adr < outputQuantity; adr++){ if (EEPROM.read(adr) > 1){ EEPROM.write(adr, 0); } } } //////////////////////////////////////////////////////////////////////// //htmlHeader Function //////////////////////////////////////////////////////////////////////// void printHtmlHeader(EthernetClient client){ Serial.print("Serving html Headers at ms -"); timeConnectedAt = millis(); //Record the time when last page was served. Serial.print(timeConnectedAt); // Print time for debbugging purposes writeToEeprom = true; // page loaded so set to action the write to eeprom // send a standard http response header client.println(F("HTTP/1.1 200 OK")); client.println(F("Content-Type: text/html; charset=utf-8")); client.println(F("Connnection: close")); client.println(); client.println(F("<!DOCTYPE HTML>")); client.println(F("<head>")); // заголовок страницы client.println(F("<title>Контроль и управление домом</title>")); client.println(F("<meta name=\"description\" content=\"Контроль и управление домом\"/>")); // время обновления страницы client.print(F("<meta http-equiv=\"refresh\" content=\"")); client.print(refreshPage); client.println(F("; url=/\">")); // конфигурация браузера client.println(F("<meta name=\"apple-mobile-web-app-capable\" content=\"yes\">")); client.println(F("<meta name=\"apple-mobile-web-app-status-bar-style\" content=\"default\">")); client.println(F("<meta name=\"viewport\" content=\"width=device-width, user-scalable=no\">")); // вставка данных стилей CSS client.println(F("<style type=\"text/css\">")); client.println(F("")); // как будет выглядеть страница графически client.println(F("html { height:100%; }")); client.println(F(" body {")); client.println(F(" height: 100%;")); client.println(F(" margin: 0;")); client.println(F(" font-family: helvetica, sans-serif;")); client.println(F(" -webkit-text-size-adjust: none;")); client.println(F(" }")); client.println(F("")); client.println(F("body {")); client.println(F(" -webkit-background-size: 100% 21px;")); client.println(F(" background-color: #c5ccd3;")); client.println(F(" background-image:")); client.println(F(" -webkit-gradient(linear, left top, right top,")); client.println(F(" color-stop(.75, transparent),")); client.println(F(" color-stop(.75, rgba(255,255,255,.1)) );")); client.println(F(" -webkit-background-size: 7px;")); client.println(F(" }")); client.println(F("")); client.println(F(".view {")); client.println(F(" min-height: 100%;")); client.println(F(" overflow: auto;")); client.println(F(" }")); client.println(F("")); client.println(F(".header-wrapper {")); client.println(F(" height: 44px;")); client.println(F(" font-weight: bold;")); client.println(F(" text-shadow: rgba(0,0,0,0.7) 0 -1px 0;")); client.println(F(" border-top: solid 1px rgba(255,255,255,0.6);")); client.println(F(" border-bottom: solid 1px rgba(0,0,0,0.6);")); client.println(F(" color: #fff;")); client.println(F(" background-color: #8195af;")); client.println(F(" background-image:")); client.println(F(" -webkit-gradient(linear, left top, left bottom,")); client.println(F(" from(rgba(255,255,255,.4)),")); client.println(F(" to(rgba(255,255,255,.05)) ),")); client.println(F(" -webkit-gradient(linear, left top, left bottom,")); client.println(F(" from(transparent),")); client.println(F(" to(rgba(0,0,64,.1)) );")); client.println(F(" background-repeat: no-repeat;")); client.println(F(" background-position: top left, bottom left;")); client.println(F(" -webkit-background-size: 100% 21px, 100% 22px;")); client.println(F(" -webkit-box-sizing: border-box;")); client.println(F(" }")); client.println(F("")); client.println(F(".header-wrapper h1 {")); client.println(F(" text-align: center;")); client.println(F(" font-size: 20px;")); client.println(F(" line-height: 44px;")); client.println(F(" margin: 0;")); client.println(F(" }")); client.println(F("")); client.println(F(".group-wrapper {")); client.println(F(" margin: 9px;")); client.println(F(" aling: center;")); client.println(F(" }")); client.println(F("")); client.println(F(".group-wrapper h2 {")); client.println(F(" color: #4c566c;")); client.println(F(" font-size: 17px;")); client.println(F(" line-height: 0.8;")); client.println(F(" font-weight: bold;")); client.println(F(" text-shadow: #fff 0 1px 0;")); client.println(F(" margin: 20px 10px 12px;")); client.println(F(" }")); client.println(F("")); client.println(F(".group-wrapper h3 {")); client.println(F(" color: #4c566c;")); client.println(F(" font-size: 12px;")); client.println(F(" line-height: 1;")); client.println(F(" font-weight: bold;")); client.println(F(" text-shadow: #fff 0 1px 0;")); client.println(F(" margin: 20px 10px 12px;")); client.println(F(" }")); client.println(F("")); client.println(F(".group-wrapper h4 {")); //Text for description client.println(F(" color: #212121;")); client.println(F(" font-size: 14px;")); client.println(F(" line-height: 1;")); client.println(F(" font-weight: bold;")); client.println(F(" text-shadow: #aaa 1px 1px 3px;")); client.println(F(" margin: 5px 5px 5px;")); client.println(F(" }")); client.println(F("")); client.println(F(".group-wrapper table {")); client.println(F(" background-color: #fff;")); client.println(F(" -webkit-border-radius: 10px;")); client.println(F(" -moz-border-radius: 10px;")); client.println(F(" -khtml-border-radius: 10px;")); client.println(F(" border-radius: 10px;")); client.println(F(" font-size: 17px;")); client.println(F(" line-height: 20px;")); client.println(F(" margin: 9px 0 20px;")); client.println(F(" border: solid 1px #a9abae;")); client.println(F(" padding: 11px 3px 12px 3px;")); client.println(F(" margin-left:auto;")); client.println(F(" margin-right:auto;")); client.println(F(" -moz-transform :scale(1);")); //Code for Mozilla Firefox client.println(F(" -moz-transform-origin: 0 0;")); client.println(F(" }")); //how the green (ON) LED will look client.println(F(".green-circle {")); client.println(F(" display: block;")); client.println(F(" height: 23px;")); client.println(F(" width: 23px;")); client.println(F(" background-color: #0f0;")); client.println(F(" -moz-border-radius: 11px;")); client.println(F(" -webkit-border-radius: 11px;")); client.println(F(" -khtml-border-radius: 11px;")); client.println(F(" border-radius: 11px;")); client.println(F(" margin-left: 1px;")); client.println(F(" background-image: -webkit-gradient(linear, 0% 0%, 0% 90%, from(rgba(46, 184, 0, 0.8)), to(rgba(148, 255, 112, .9)));@")); client.println(F(" border: 2px solid #ccc;")); client.println(F(" -webkit-box-shadow: rgba(11, 140, 27, 0.5) 0px 10px 16px;")); client.println(F(" -moz-box-shadow: rgba(11, 140, 27, 0.5) 0px 10px 16px; /* FF 3.5+ */")); client.println(F(" box-shadow: rgba(11, 140, 27, 0.5) 0px 10px 16px; /* FF 3.5+ */")); client.println(F(" }")); client.println(F("")); //how the black (off)LED will look client.println(F(".black-circle {")); client.println(F(" display: block;")); client.println(F(" height: 23px;")); client.println(F(" width: 23px;")); client.println(F(" background-color: #040;")); client.println(F(" -moz-border-radius: 11px;")); client.println(F(" -webkit-border-radius: 11px;")); client.println(F(" -khtml-border-radius: 11px;")); client.println(F(" border-radius: 11px;")); client.println(F(" margin-left: 1px;")); client.println(F(" -webkit-box-shadow: rgba(11, 140, 27, 0.5) 0px 10px 16px;")); client.println(F(" -moz-box-shadow: rgba(11, 140, 27, 0.5) 0px 10px 16px; /* FF 3.5+ */")); client.println(F(" box-shadow: rgba(11, 140, 27, 0.5) 0px 10px 16px; /* FF 3.5+ */")); client.println(F(" }")); client.println(F("")); //this will add the glare to both of the LEDs client.println(F(" .glare {")); client.println(F(" position: relative;")); client.println(F(" top: 1;")); client.println(F(" left: 5px;")); client.println(F(" -webkit-border-radius: 10px;")); client.println(F(" -moz-border-radius: 10px;")); client.println(F(" -khtml-border-radius: 10px;")); client.println(F(" border-radius: 10px;")); client.println(F(" height: 1px;")); client.println(F(" width: 13px;")); client.println(F(" padding: 5px 0;")); client.println(F(" background-color: rgba(200, 200, 200, 0.25);")); client.println(F(" background-image: -webkit-gradient(linear, 0% 0%, 0% 95%, from(rgba(255, 255, 255, 0.7)), to(rgba(255, 255, 255, 0)));")); client.println(F(" }")); client.println(F("")); //and finally this is the end of the style data and header client.println(F("</style>")); client.println(F("</head>")); //now printing the page itself client.println(F("<body>")); client.println(F("<div class=\"view\">")); client.println(F(" <div class=\"header-wrapper\">")); client.println(F(" <h1>СМАРТ ДАЧА</h1>")); client.println(F(" </div>")); } //end of htmlHeader //////////////////////////////////////////////////////////////////////// //htmlFooter Function //////////////////////////////////////////////////////////////////////// void printHtmlFooter(EthernetClient client){ //Set Variables Before Exiting printLastCommandOnce = false; printButtonMenuOnce = false; allOn = ""; allOff = ""; client.println(F("\n<h3 align=\"center\">©- Plagiary - <br> 774 KM - 2016 - ")); client.println(rev); client.println(F("</h3></div>\n</div>\n</body>\n</html>")); delay(1); // give the web browser time to receive the data client.stop(); // close the connection: Serial.println(" - Done, Closing Connection."); delay (2); //delay so that it will give time for client buffer to clear and does not repeat multiple pages. } //end of htmlFooter //////////////////////////////////////////////////////////////////////// //printHtmlButtonTitle Function //////////////////////////////////////////////////////////////////////// void printHtmlButtonTitle(EthernetClient client){ client.println(F("<div class=\"group-wrapper\">")); client.println(F("<h2 align=\"center\" >Температура на улице")); client.println(chartemp4); client.print(F(" °C </h2>")); client.println(); } ///////////////// DS18B20 float tempread(byte sensoraddr[]) // error codes: // -1 no sensors found // -2 invalid CRC // -3 not a DS1820 { byte i; byte present = 0; byte data[12]; byte addr[8]; //int HighByte, LowByte, TReading, SignBit, Tc_100, Tf_100, Whole, Fract; for ( i = 0; i < 8; i++) { addr[i]=sensoraddr[i]; } ds.reset(); // pulse the pins and wait for a response to reset the DS1820 ds.select(addr); // 0x55 (MATCH_ROM) followed by the address of the 1820 to talk to. // ds.write(0x44,1); // start conversion, with parasite power on at the end ds.write(0x44,0); //PARASITE POWER OFF // delay(800); present = ds.reset(); ds.select(addr); ds.write(0xBE); // Read Scratchpad for ( i = 0; i < 9; i++) { // we need 9 bytes data[i] = ds.read(); } int16_t raw = (data[1] << 8) | data[0]; float temp = (float)raw / 16.0; return temp; }меняю в строке 551 onClick=\"parent.location='/?q" на onClick=\"parent.location='/?q1"
и поправляю строку 399 if(c == 'q1') {TargetTemp1 = 0; EEPROM.write(100, 0); Serial.println("temp 0 OK");}
код не работает, маркер не вылезает
сейчас заметил когда отправляю
onClick=\"parent.location='/?H10 т.е case 10
высвечиваются маркера case 1 и case 0 по очереди как будто сначало отправляю
onClick=\"parent.location='/?H1
а потом
onClick=\"parent.location='/?H0
uservasil, case '10' не будет работать по определению, потому что '10' это два символа, а переменная у тебя объявлена как char с.
сейчас заметил когда отправляю
onClick=\"parent.location='/?H10 т.е case 10
высвечиваются маркера case 1 и case 0 по очереди как будто сначало отправляю
onClick=\"parent.location='/?H1
а потом
onClick=\"parent.location='/?H0
Всё просто: вычитываем в char, а хотим сравнить со строкой. Смотри: когда ты получаешь данные из порта, они идут в виде набора символов, т.е. приходит, допустим, '1', потом - '0' (я имею в виду, когда ты разбираешь, чего там пришло после "?H"). Чтобы быстро в лоб получить число 10 из двух символов - надо их вычитать в String и потом сделать String.toInt, и уже с этим числом сравнивать.
Надеюсь, понятно объяснил.
Что касаемо реализации, то:
перед строкой 249
вставляешь
Далее, строка 284, добавляешь после неё:
reading = true; //found the ?, begin reading the info command = F(""); // clear current commandПосле строки 288:
if(reading){проверяешь - если вычитал H или L, то дальше все символы складываешь в command. Как только встретишь пробел, символ '\r' или символ '\n' - не сохраняешь этот символ в command, а смотришь, что у тебя там внутри, в твоём случае - вызываешь command.toInt() и проверяешь, что за число пришло.
Но, строго говоря, лучше делать это по-другому, смотри: каждый GET-запрос имеет параметры вида ключ=значение, эти параметры разделены символом '&'. Можно написать простенький класс, который выщемляет все параметры в массив, и потом уже работать с отдельными параметрами будет удобно очень. Вот кусок моего говнокода на этот случай:
void HTTPRequestParser::AddParam(const String& param) { if(req.ParamsCount >= MAX_HTTP_PARAMS) // всё, некуда писать параметры! return; String pname, pdata; int8_t idx = param.indexOf(F("=")); if(idx == -1) // ничего не нашли return; pname = param.substring(0,idx); pdata = param.substring(idx+1); req.Params[req.ParamsCount].Name = pname; req.Params[req.ParamsCount].Value = pdata; req.ParamsCount++; } void HTTPRequestParser::ParseParams(const String& uri, int16_t paramsStartIdx) { String params = uri.substring(paramsStartIdx); req.URIOnly = uri.substring(0,paramsStartIdx-1); // разбираем параметры while(1) { int16_t idx = params.indexOf(F("&")); if(idx != -1) { String param = params.substring(0,idx); params = params.substring(idx+1); AddParam(param); } // if else { AddParam(params); // добавляем последний параметр, и выходим break; } } // while }Что касаемо реализации, то:
Благодарю! После праздников конечно было тяжело, но что то получилось)
#include <Ethernet.h> #include <SPI.h> #include <EEPROM.h> #include <DHT.h> #include <OneWire.h> //////////////////////////////////////////////////////////////////////// //CONFIGURATION //////////////////////////////////////////////////////////////////////// //IP manual settings byte ip[] = { 10, 16, 30, 2 }; //Manual setup only byte gateway[] = { 10, 16, 30, 3 }; //Manual setup only byte subnet[] = { 255, 255, 255, 0 }; //Manual setup only // if need to change the MAC address (Very Rare) byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //Ethernet Port EthernetServer server = EthernetServer(80); //default html port 80 //The number of outputs going to be switched. int outputQuantity = 20; //should not exceed 10 //Invert the output of the leds boolean outputInverted = false; //true or false // This is done in case the relay board triggers the relay on negative, rather then on positive supply //Html page refresh int refreshPage = 15; //default is 10sec. //Beware that if you make it refresh too fast, the page could become inacessable. //Display or hide the "Switch on all Pins" buttons at the bottom of page int switchOnAllPinsButton = true; //true or false //Button Array //Just for a note, varables start from 0 to 9, as 0 is counted as well, thus 10 outputs. // Select the pinout address int outputAddress[20] = { 3,5,6,7,8,9,14,15,16,17,18,19,20,21,22,23,24,25,26,27}; //Allocate 10 spaces and name the output pin address. //PS pin addresses 10, 11, 12 and 13 on the Duemilanove are used for the ethernet shield, therefore cannot be used. //PS pin addresses 10, 50, 51 and 52 and 53 on the Mega are used for the ethernet shield, therefore cannot be used. //PS pin addresses 4, are used for the SD card, therefore cannot be used. //PS. pin address 2 is used for interrupt-driven notification, therefore could not be used. // Write the text description of the output channel String buttonText[20] = { "01. Канал","02. Канал","03. Канал","04. Канал","05. Канал","06. Канал","07. Канал","08. Канал","09. Канал","10. Канал","11. Канал","12. Канал","13. Канал","14. Канал","15. Канал","16. Канал","17. Канал","18. Канал","19. Канал","20. Канал"}; //////////////////////////////////////////////////////////////////////// int twenty[] = {11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30}; //char twentyTEXT[] = {'d1','d2','d3','d4','d5','d6','d7','d8','d9','d10','d11','d12','d13','d14','d15','d16','d17','d18','d19','d20'}; //////////////////////////////////////////////////////////////////////// //VARIABLES DECLARATION //////////////////////////////////////////////////////////////////////// int outp = 0; boolean printLastCommandOnce = false; boolean printButtonMenuOnce = false; boolean initialPrint = true; boolean reading = false; boolean outputStatus[20]; //Create a boolean array for the maximum ammount. String rev = "V1.3"; unsigned long timeConnectedAt; boolean writeToEeprom = false; int page=1; int intCommand=0; //////////////переменные упрвавления температурой const byte PinSSR1 = 44; // Реле Pin for SSR 1 const byte PinSSR2 = 45; // Реле Pin for SSR 2 const byte PinSSR3 = 46; // Реле Pin for SSR 3 char chartemp1[10]; char chartemp2[10]; char chartemp3[10]; char chartemp4[10]; int TargetTemp1; int TargetTemp2; int TargetTemp3; float temp1; float temp2; OneWire ds(47); DHT dht1(48, DHT11); DHT dht2(49, DHT11); //////////////////////////////// //////////////////////////////////////////////////////////////////////// //RUN ONCE //////////////////////////////////////////////////////////////////////// //Beginning of Program void setup(){ Serial.begin(9600); initEepromValues(); readEepromValues(); //Set pins as Outputs boolean currentState = false; for (int var = 0; var < outputQuantity; var++){ pinMode(outputAddress[var], OUTPUT); //Switch all outputs to either on or off on Startup if(outputInverted == true) { //digitalWrite(outputAddress[var], HIGH); if(outputStatus[var] == 0){currentState = true;}else{currentState = false;} //check outputStatus if off, switch output accordingly digitalWrite(outputAddress[var], currentState); } else{ //digitalWrite(outputAddress[var], LOW); if(outputStatus[var] == 0){currentState = false;}else{currentState = true;}//check outputStatus if off, switch output accordingly digitalWrite(outputAddress[var], currentState); } } //Setting up the IP address. Comment out the one you dont need. //Ethernet.begin(mac); //for DHCP address. (Address will be printed to serial.) Ethernet.begin(mac, ip, gateway, subnet); //for manual setup. (Address is the one configured above.) server.begin(); Serial.print("Server started at "); Serial.println(Ethernet.localIP()); ////////////////управление температурой pinMode(PinSSR1, OUTPUT); pinMode(PinSSR2, OUTPUT); pinMode(PinSSR3, OUTPUT); TargetTemp1 = EEPROM.read(100); TargetTemp2 = EEPROM.read(102); TargetTemp3 = EEPROM.read(104); dht1.begin(); dht2.begin(); } //////////////////////////////////////////////////////////////////////// //LOOP //////////////////////////////////////////////////////////////////////// //Run once void loop(){ // listen for incoming clients, and process requests. checkForClient(); ///////////////////////управление температурой float temp3; float temp4; byte sensor1[8] = {0x28, 0xFF, 0x34, 0x2C, 0x50, 0x15, 0x01, 0x87}; // Адрес сенсора byte sensor2[8] = {0x28, 0xDF, 0x7E, 0xDC, 0x06, 0x00, 0x00, 0xF3}; // Адрес сенсора //DHT temp1 = dht1.readTemperature(); dtostrf(temp1, 3, 1, chartemp1); temp2 = dht2.readTemperature(); dtostrf(temp2, 3, 1, chartemp2); //DS18B20 temp3 = tempread(sensor1); dtostrf(temp3, 3, 1, chartemp3); temp4 = tempread(sensor2); dtostrf(temp4, 3, 1, chartemp4); if (temp1<TargetTemp1-1) { digitalWrite(PinSSR1, LOW); } else if (temp1>TargetTemp1+1) { digitalWrite(PinSSR1, HIGH); } if (temp2<TargetTemp2-1) { digitalWrite(PinSSR2, LOW); } else if (temp2>TargetTemp2+1) { digitalWrite(PinSSR2, HIGH); } if (temp3<TargetTemp3-1) { digitalWrite(PinSSR3, LOW); } else if (temp3>TargetTemp3+1) { digitalWrite(PinSSR3, HIGH); } } //////////////////////////////////////////////////////////////////////// //checkForClient Function //////////////////////////////////////////////////////////////////////// // void checkForClient(){ EthernetClient client = server.available(); if (client) { // an http request ends with a blank line boolean currentLineIsBlank = true; boolean sentHeader = false; String command; while (client.connected()) { if (client.available()) { //read user input char c = client.read(); if(c == '*'){ printHtmlHeader(client); //call for html header and css printHtmlFooter(client); //sentHeader = true; break; } if(!sentHeader){ printHtmlHeader(client); //call for html header and css printHtmlButtonTitle(client); //print the button title //This is for the arduino to construct the page on the fly. sentHeader = true; } //if there was reading but is blank there was no reading if(reading && c == ' '){ reading = false; } //if there is a ? there was user input if(c == '?') { reading = true; //found the ?, begin reading the info command = F(""); // clear current command } // if there was user input switch the relevant output if(reading){ //if user input is H set output to 1 if(c == 'H') { outp = 1; } //if user input is L set output to 0 if(c == 'L') { outp = 0; } if(c!='?'&&c!='H'&&c!='L') {command +=c;} if(command == "t1-00") {TargetTemp1 = 0; EEPROM.write(100, 0); Serial.println(" "); Serial.println("temp 0 OK");} if(command == "t1-05") {TargetTemp1 = 5; EEPROM.write(100, 5); Serial.println(" "); Serial.println("temp 5 OK");} if(command == "t1-10") {TargetTemp1 = 10; EEPROM.write(100, 10); Serial.println(" "); Serial.println("temp 10 OK");} if(command == "t1-20") {TargetTemp1 = 20; EEPROM.write(100, 20);} if(command == "t1-22") {TargetTemp1 = 22; EEPROM.write(100, 22);} if(command == "t1-24") {TargetTemp1 = 24; EEPROM.write(100, 24);} if(command == "t2-00") {TargetTemp2 = 0; EEPROM.write(102, 0);} if(command == "t2-05") {TargetTemp2 = 5; EEPROM.write(102, 5);} if(command == "t2-10") {TargetTemp2 = 10; EEPROM.write(102, 10);} if(command == "t2-20") {TargetTemp2 = 20; EEPROM.write(102, 20);} if(command == "t2-22") {TargetTemp2 = 22; EEPROM.write(102, 22);} if(command == "t2-24") {TargetTemp2 = 24; EEPROM.write(102, 24);} if(command == "t3-00") {TargetTemp3 = 0; EEPROM.write(104, 0);} if(command == "t3-05") {TargetTemp3 = 5; EEPROM.write(104, 5);} if(command == "t3-10") {TargetTemp3 = 10; EEPROM.write(104, 10);} if(command == "t3-20") {TargetTemp3 = 20; EEPROM.write(104, 20);} if(command == "t3-22") {TargetTemp3 = 22; EEPROM.write(104, 22);} if(command == "t3-24") {TargetTemp3 = 24; EEPROM.write(104, 24);} if(command == "d11") {triggerPin(outputAddress[0], client, outp); Serial.println(" "); Serial.println("case 1 OK"); } if(command == "d12") {triggerPin(outputAddress[1], client, outp); Serial.println(" "); Serial.println("case 2 OK"); } if(command == "d13") {triggerPin(outputAddress[2], client, outp); Serial.println(" "); Serial.println("case 3 OK"); } if(command == "d14") {triggerPin(outputAddress[3], client, outp); Serial.println(" "); Serial.println("case 4 OK"); } if(command == "d15") {triggerPin(outputAddress[4], client, outp); Serial.println(" "); Serial.println("case 5 OK"); } if(command == "d16") {triggerPin(outputAddress[5], client, outp); Serial.println(" "); Serial.println("case 6 OK"); } if(command == "d17") {triggerPin(outputAddress[6], client, outp); Serial.println(" "); Serial.println("case 7 OK"); } if(command == "d18") {triggerPin(outputAddress[7], client, outp); Serial.println(" "); Serial.println("case 8 OK"); } if(command == "d19") {triggerPin(outputAddress[8], client, outp); Serial.println(" "); Serial.println("case 9 OK"); } if(command == "d20") {triggerPin(outputAddress[9], client, outp); Serial.println(" "); Serial.println("case 10 OK"); } if(command == "d21") {triggerPin(outputAddress[10], client, outp); Serial.println(" "); Serial.println("case 11 OK"); } if(command == "d22") {triggerPin(outputAddress[11], client, outp); Serial.println(" "); Serial.println("case 12 OK"); } if(command == "d23") {triggerPin(outputAddress[12], client, outp); Serial.println(" "); Serial.println("case 13 OK"); } if(command == "d24") {triggerPin(outputAddress[13], client, outp); Serial.println(" "); Serial.println("case 14 OK"); } if(command == "d25") {triggerPin(outputAddress[14], client, outp); Serial.println(" "); Serial.println("case 15 OK"); } if(command == "d26") {triggerPin(outputAddress[15], client, outp); Serial.println(" "); Serial.println("case 16 OK"); } if(command == "d27") {triggerPin(outputAddress[16], client, outp); Serial.println(" "); Serial.println("case 17 OK"); } if(command == "d28") {triggerPin(outputAddress[17], client, outp); Serial.println(" "); Serial.println("case 18 OK"); } if(command == "d29") {triggerPin(outputAddress[18], client, outp); Serial.println(" "); Serial.println("case 19 OK"); } if(command == "d30") {triggerPin(outputAddress[19], client, outp); Serial.println(" "); Serial.println("case 20 OK"); } if(command == "100"){ for (int var = 0; var < outputQuantity; var++) { triggerPin(outputAddress[var], client, outp); } } if(command == "page1") {page=1; Serial.println(" "); Serial.println("page 1 OK"); } if(command == "page0") {page=0; Serial.println(" "); Serial.println("page 0 OK"); } }//end of switch switch the relevant output //if user input was blank if (c == '\n' && currentLineIsBlank){ printLastCommandOnce = true; printButtonMenuOnce = true; triggerPin(777, client, outp); //Call to read input and print menu. 777 is used not to update any outputs break; } } } Serial.println(" "); Serial.print("command:"); Serial.print(command); Serial.println(" "); /* intCommand=command.toInt(); Serial.println(" "); Serial.print("intCommand:"); Serial.println(intCommand); Serial.println(" "); switch (intCommand) { case 1: //add code here to trigger on 0 triggerPin(outputAddress[0], client, outp); Serial.println(" "); Serial.println("case 1 OK"); break; case 2: //add code here to trigger on 1 triggerPin(outputAddress[1], client, outp); Serial.println(" "); Serial.println("case 2 OK"); break; case 3: //add code here to trigger on 2 triggerPin(outputAddress[2], client, outp); break; case 4: //add code here to trigger on 3 triggerPin(outputAddress[3], client, outp); break; case 5: //add code here to trigger on 4 triggerPin(outputAddress[4], client, outp); break; case 6: //add code here to trigger on 5 triggerPin(outputAddress[5], client, outp); //printHtml(client); break; case 7: //add code here to trigger on 6 triggerPin(outputAddress[6], client, outp); break; case 8: //add code here to trigger on 7 triggerPin(outputAddress[7], client, outp); break; case 9: //add code here to trigger on 8 triggerPin(outputAddress[8], client, outp); break; case 10: //add code here to trigger on 9 triggerPin(outputAddress[9], client, outp); Serial.println(" "); Serial.println("case 10 OK"); break; case 11: //add code here to trigger on 10 triggerPin(outputAddress[10], client, outp); Serial.println(" "); Serial.println("case 11 OK"); break; case 12: //add code here to trigger on 11 triggerPin(outputAddress[11], client, outp); break; case 13: //add code here to trigger on 12 triggerPin(outputAddress[12], client, outp); break; case 14: //add code here to trigger on 13 triggerPin(outputAddress[13], client, outp); break; case 15: //add code here to trigger on 14 triggerPin(outputAddress[14], client, outp); break; case 16: //add code here to trigger on 15 triggerPin(outputAddress[15], client, outp); //printHtml(client); break; case 17: //add code here to trigger on 16 triggerPin(outputAddress[16], client, outp); break; case 18: //add code here to trigger on 17 triggerPin(outputAddress[17], client, outp); break; case 19: //add code here to trigger on 18 triggerPin(outputAddress[18], client, outp); break; case 20: //add code here to trigger on 19 triggerPin(outputAddress[19], client, outp); break; case 100: //add code here to trigger on 19 for (int var = 0; var < outputQuantity; var++) { triggerPin(outputAddress[var], client, outp); } break; } //end of switch case */ Serial.println("----------"); printHtmlFooter(client); //Prints the html footer } else { //if there is no client // таймаут простоя, для записи данных состояния переключателей в кэш if (millis() > (timeConnectedAt + 10000)){ if (writeToEeprom == true){ writeEepromValues(); //write to EEprom the current output statuses Serial.println("No Clients for more then a 10 sec. - Writing statuses to Eeprom."); writeToEeprom = false; } } } } /////////////////////////////////////////////////////////////////////// //triggerPin Function //////////////////////////////////////////////////////////////////////// void triggerPin(int pin, EthernetClient client, int outp){ //Switching on or off outputs, reads the outputs and prints the buttons //Setting Outputs if (pin != 777){ if(outp == 1) { if (outputInverted ==false){ digitalWrite(pin, HIGH); } else{ digitalWrite(pin, LOW); } } if(outp == 0){ if (outputInverted ==false){ digitalWrite(pin, LOW); } else{ digitalWrite(pin, HIGH); } } Serial.println(" "); Serial.print("triggerPin:"); Serial.print(pin); Serial.println(" OK"); } //Refresh the reading of outputs readOutputStatuses(); //Prints the buttons if (printButtonMenuOnce == true){ printHtmlButtons(client); printButtonMenuOnce = false; } } //////////////////////////////////////////////////////////////////////// //printHtmlButtons Function //////////////////////////////////////////////////////////////////////// void printHtmlButtons(EthernetClient client){ client.println(""); client.println("<FORM>"); //вывод таблиц управления температурой if (page == 1){ client.println("<table border=\"0\" align=\"center\">"); client.print("<tr>"); client.print("<td rowspan=3>"); } //вывод текста, кнопок ON и OFF и лампочек состояния client.println("<table border=\"0\" align=\"center\">"); for (int var = 0; var < outputQuantity; var++) { //Print begining of row client.print("<tr>\n"); //Prints the button Text client.print("<td><h4>"); client.print(buttonText[var]); client.print("</h4></td>\n"); //Prints the ON Buttons client.print("<td>"); client.print("<INPUT TYPE=\"button\" VALUE=\"ВКЛ "); client.print("\" onClick=\"parent.location='/?H"); client.print("d"); client.print(twenty[var]); client.print("'\"></td>\n"); //Prints the OFF Buttons client.print(" <td><INPUT TYPE=\"button\" VALUE=\"ВЫКЛ"); client.print("\" onClick=\"parent.location='/?L"); client.print("d"); client.print(twenty[var]); client.print("'\"></td>\n"); //Print first part of the Circles or the LEDs //Invert the LED display if output is inverted. if (outputStatus[var] == true ){ //If Output is ON if (outputInverted == false){ //and if output is not inverted client.print(" <td><div class='green-circle'><div class='glare'></div></div></td>\n"); //Print html for ON LED } else{ //else output is inverted then client.print(" <td><div class='black-circle'><div class='glare'></div></div></td>\n"); //Print html for OFF LED } } else //If Output is Off { if (outputInverted == false){ //and if output is not inverted client.print(" <td><div class='black-circle'><div class='glare'></div></div></td>\n"); //Print html for OFF LED } else{ //else output is inverted then client.print(" <td><div class='green-circle'><div class='glare'></div></div></td>\n"); //Print html for ON LED } } client.print("</tr>\n"); } // end for //Вывод кнопок вкл всё и выкл всё if (switchOnAllPinsButton == true ){ //Prints the ON All Pins Button client.print("<tr>\n<td colspan=2><INPUT TYPE=\"button\" VALUE=\"Включить ВСЁ"); client.print("\" onClick=\"parent.location='/?H100"); // client.print(allOn); client.print("'\"></td>\n"); //Prints the OFF All Pins Button client.print("<td colspan=2><INPUT TYPE=\"button\" VALUE=\"Выключить ВСЁ"); client.print("\" onClick=\"parent.location='/?L100"); // client.print(allOff); client.print("'\"></td>\n<td></td>\n<td></td>\n</tr>\n"); } client.println("</table>"); if (page == 1){ client.print("</td>"); client.print("<td>"); } client.println("<table border=\"0\" align=\"center\">"); client.print("<tr>"); client.print("<td></td>"); client.print("<td><h3>текущая</h3></td>"); client.print("<td><h3>обогрев</h3</td>"); client.print("<td><h3>желаемая</h3</td>"); client.print("</tr>"); client.print("<tr>"); client.print("<td><h4>"); client.print("Первый этаж:"); client.print("</h4></td>"); client.print("<td align=\"center\">"); client.println(chartemp1); //текущая температура client.print(" °C</td>"); if ( digitalRead(PinSSR1) == LOW ) { client.println("<td align=\"center\"><font color=green><b>ВКЛ</b></font></td>"); } // вкл или выкл else { client.println("<td align=\"center\"><font color=red><b>ВЫКЛ</b></font></td>"); } client.println("<td align=\"center\">"); client.println(TargetTemp1); //отображение желаемой температуры client.println(" °C</td>"); client.print("</tr>"); client.print("<tr>"); client.print("<td><h4>"); client.print("Установить:"); //выбор желаемой температуры client.print("</h4></td>"); client.print(" <td colspan=3><table border=\"0\"><tr><td><INPUT TYPE=\"button\" VALUE=\"0" "\" onClick=\"parent.location='/?t1-00""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"5" "\" onClick=\"parent.location='/?t1-05""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"10" "\" onClick=\"parent.location='/?t1-10""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"20" "\" onClick=\"parent.location='/?t1-20""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"22" "\" onClick=\"parent.location='/?t1-22""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"24" "\" onClick=\"parent.location='/?t1-24""'\"></td></tr></table></td>"); client.print("</tr>"); client.println("</table>"); if (page == 1){ client.print("</td>"); client.print("</tr>"); client.print("<tr>"); client.print("<td>"); } client.println("<table border=\"0\" align=\"center\">"); client.print("<tr>"); client.print("<td></td>"); client.print("<td><h3>текущая</h3></td>"); client.print("<td><h3>обогрев</h3</td>"); client.print("<td><h3>желаемая</h3</td>"); client.print("</tr>"); client.print("<tr>"); client.print("<td><h4>"); client.print("Второй этаж:"); client.print("</h4></td>"); client.print("<td align=\"center\">"); client.println(chartemp2); //текущая температура client.print(" °C</td>"); if ( digitalRead(PinSSR2) == LOW ) { client.println("<td align=\"center\"><font color=green><b>ВКЛ</b></font></td>"); } // вкл или выкл else { client.println("<td align=\"center\"><font color=red><b>ВЫКЛ</b></font></td>"); } client.println("<td align=\"center\">"); client.println(TargetTemp2); //отображение желаемой температуры client.println(" °C</td>"); client.print("</tr>"); client.print("<tr>"); client.print("<td><h4>"); client.print("Установить:"); //выбор желаемой температуры client.print("</h4></td>"); client.print(" <td colspan=3><table border=\"0\"><tr><td><INPUT TYPE=\"button\" VALUE=\"0" "\" onClick=\"parent.location='/?t2-00""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"5" "\" onClick=\"parent.location='/?t2-05""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"10" "\" onClick=\"parent.location='/?t2-10""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"20" "\" onClick=\"parent.location='/?t2-20""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"22" "\" onClick=\"parent.location='/?t2-22""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"24" "\" onClick=\"parent.location='/?t2-24""'\"></td></tr></table></td>"); client.print("</tr>"); client.println("</table>"); if (page == 1){ client.print("</td>"); client.print("</tr>"); client.print("<tr>"); client.print("<td>"); } client.println("<table border=\"0\" align=\"center\">"); client.print("<tr>"); client.print("<td></td>"); client.print("<td><h3>текущая</h3></td>"); client.print("<td><h3>обогрев</h3</td>"); client.print("<td><h3>желаемая</h3</td>"); client.print("</tr>"); client.print("<tr>"); client.print("<td><h4>"); client.print("Кухня:"); client.print("</h4></td>"); client.print("<td align=\"center\">"); client.println(chartemp3); //текущая температура client.print(" °C</td>"); if ( digitalRead(PinSSR3) == LOW ) { client.println("<td align=\"center\"><font color=green><b>ВКЛ</b></font></td>"); } // вкл или выкл else { client.println("<td align=\"center\"><font color=red><b>ВЫКЛ</b></font></td>"); } client.println("<td align=\"center\">"); client.println(TargetTemp3); //отображение желаемой температуры client.println(" °C</td>"); client.print("</tr>"); client.print("<tr>"); client.print("<td><h4>"); client.print("Установить:"); //выбор желаемой температуры client.print("</h4></td>"); client.print(" <td colspan=3><table border=\"0\"><tr><td><INPUT TYPE=\"button\" VALUE=\"0" "\" onClick=\"parent.location='/?t3-00""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"5" "\" onClick=\"parent.location='/?t3-05""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"10" "\" onClick=\"parent.location='/?t3-10""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"20" "\" onClick=\"parent.location='/?t3-20""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"22" "\" onClick=\"parent.location='/?t3-22""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"24" "\" onClick=\"parent.location='/?t3-24""'\"></td></tr></table></td>"); client.print("</tr>"); client.println("</table>"); if (page == 1){ client.print("</td>"); client.print("</tr>"); client.println("</table>"); } client.println("</FORM>"); } //////////////////////////////////////////////////////////////////////// //readOutputStatuses Function //////////////////////////////////////////////////////////////////////// //Reading the Output Statuses void readOutputStatuses(){ for (int var = 0; var < outputQuantity; var++) { outputStatus[var] = digitalRead(outputAddress[var]); // Serial.print(outputStatus[var]); } } //////////////////////////////////////////////////////////////////////// //readEepromValues Function //////////////////////////////////////////////////////////////////////// //Read EEprom values and save to outputStatus void readEepromValues(){ for (int adr = 0; adr < outputQuantity; adr++) { outputStatus[adr] = EEPROM.read(adr); } } //////////////////////////////////////////////////////////////////////// //writeEepromValues Function //////////////////////////////////////////////////////////////////////// void writeEepromValues(){ for (int adr = 0; adr < outputQuantity; adr++) { EEPROM.write(adr, outputStatus[adr]); } } //////////////////////////////////////////////////////////////////////// //initEepromValues Function //////////////////////////////////////////////////////////////////////// //Initialiaze EEprom values //if eeprom values are not the correct format ie not euqual to 0 or 1 (thus greater then 1) initialize by putting 0 void initEepromValues(){ for (int adr = 0; adr < outputQuantity; adr++){ if (EEPROM.read(adr) > 1){ EEPROM.write(adr, 0); } } } //////////////////////////////////////////////////////////////////////// //htmlHeader Function //////////////////////////////////////////////////////////////////////// void printHtmlHeader(EthernetClient client){ Serial.print("Serving html Headers at ms -"); timeConnectedAt = millis(); //Record the time when last page was served. Serial.println(timeConnectedAt); // Print time for debbugging purposes writeToEeprom = true; // page loaded so set to action the write to eeprom // send a standard http response header client.println(F("HTTP/1.1 200 OK")); client.println(F("Content-Type: text/html; charset=utf-8")); client.println(F("Connnection: close")); client.println(); client.println(F("<!DOCTYPE HTML>")); client.println(F("<head>")); // заголовок страницы client.println(F("<title>Контроль и управление домом</title>")); client.println(F("<meta name=\"description\" content=\"Контроль и управление домом\"/>")); // время обновления страницы client.print(F("<meta http-equiv=\"refresh\" content=\"")); client.print(refreshPage); client.println(F("; url=/\">")); // конфигурация браузера client.println(F("<meta name=\"apple-mobile-web-app-capable\" content=\"yes\">")); client.println(F("<meta name=\"apple-mobile-web-app-status-bar-style\" content=\"default\">")); client.println(F("<meta name=\"viewport\" content=\"width=device-width, user-scalable=no\">")); // вставка данных стилей CSS client.println(F("<style type=\"text/css\">")); client.println(F("")); // как будет выглядеть страница графически client.println(F("html { height:100%; }")); client.println(F(" body {")); client.println(F(" height: 100%;")); client.println(F(" margin: 0;")); client.println(F(" font-family: helvetica, sans-serif;")); client.println(F(" -webkit-text-size-adjust: none;")); client.println(F(" }")); client.println(F("")); client.println(F("body {")); client.println(F(" -webkit-background-size: 100% 21px;")); client.println(F(" background-color: #c5ccd3;")); client.println(F(" background-image:")); client.println(F(" -webkit-gradient(linear, left top, right top,")); client.println(F(" color-stop(.75, transparent),")); client.println(F(" color-stop(.75, rgba(255,255,255,.1)) );")); client.println(F(" -webkit-background-size: 7px;")); client.println(F(" }")); client.println(F("")); client.println(F(".view {")); client.println(F(" min-height: 100%;")); client.println(F(" overflow: auto;")); client.println(F(" }")); client.println(F("")); client.println(F(".header-wrapper {")); client.println(F(" height: 64px;")); client.println(F(" font-weight: bold;")); client.println(F(" text-shadow: rgba(0,0,0,0.7) 0 -1px 0;")); client.println(F(" border-top: solid 1px rgba(255,255,255,0.6);")); client.println(F(" border-bottom: solid 1px rgba(0,0,0,0.6);")); client.println(F(" color: #fff;")); client.println(F(" background-color: #8195af;")); client.println(F(" background-image:")); client.println(F(" -webkit-gradient(linear, left top, left bottom,")); client.println(F(" from(rgba(255,255,255,.4)),")); client.println(F(" to(rgba(255,255,255,.05)) ),")); client.println(F(" -webkit-gradient(linear, left top, left bottom,")); client.println(F(" from(transparent),")); client.println(F(" to(rgba(0,0,64,.1)) );")); client.println(F(" background-repeat: no-repeat;")); client.println(F(" background-position: top left, bottom left;")); client.println(F(" -webkit-background-size: 100% 21px, 100% 22px;")); client.println(F(" -webkit-box-sizing: border-box;")); client.println(F(" }")); client.println(F("")); client.println(F(".header-wrapper h1 {")); client.println(F(" text-align: center;")); client.println(F(" font-size: 20px;")); client.println(F(" line-height: 44px;")); client.println(F(" margin: 0;")); client.println(F(" }")); client.println(F("")); client.println(F(".group-wrapper {")); client.println(F(" margin: 9px;")); client.println(F(" aling: center;")); client.println(F(" }")); client.println(F("")); client.println(F(".group-wrapper h2 {")); client.println(F(" color: #4c566c;")); client.println(F(" font-size: 17px;")); client.println(F(" line-height: 0.8;")); client.println(F(" font-weight: bold;")); client.println(F(" text-shadow: #fff 0 1px 0;")); client.println(F(" margin: 20px 10px 12px;")); client.println(F(" }")); client.println(F("")); client.println(F(".group-wrapper h3 {")); client.println(F(" color: #4c566c;")); client.println(F(" font-size: 12px;")); client.println(F(" line-height: 1;")); client.println(F(" font-weight: bold;")); client.println(F(" text-shadow: #fff 0 1px 0;")); client.println(F(" margin: 20px 10px 12px;")); client.println(F(" }")); client.println(F("")); client.println(F(".group-wrapper h4 {")); //Text for description client.println(F(" color: #212121;")); client.println(F(" font-size: 14px;")); client.println(F(" line-height: 1;")); client.println(F(" font-weight: bold;")); client.println(F(" text-shadow: #aaa 1px 1px 3px;")); client.println(F(" margin: 5px 5px 5px;")); client.println(F(" }")); client.println(F("")); client.println(F(".group-wrapper table {")); client.println(F(" background-color: #fff;")); client.println(F(" -webkit-border-radius: 10px;")); client.println(F(" -moz-border-radius: 10px;")); client.println(F(" -khtml-border-radius: 10px;")); client.println(F(" border-radius: 10px;")); client.println(F(" font-size: 17px;")); client.println(F(" line-height: 20px;")); client.println(F(" margin: 9px 0 20px;")); client.println(F(" border: solid 1px #a9abae;")); client.println(F(" padding: 11px 3px 12px 3px;")); client.println(F(" margin-left:auto;")); client.println(F(" margin-right:auto;")); client.println(F(" -moz-transform :scale(1);")); //Code for Mozilla Firefox client.println(F(" -moz-transform-origin: 0 0;")); client.println(F(" }")); //how the green (ON) LED will look client.println(F(".green-circle {")); client.println(F(" display: block;")); client.println(F(" height: 23px;")); client.println(F(" width: 23px;")); client.println(F(" background-color: #0f0;")); client.println(F(" -moz-border-radius: 11px;")); client.println(F(" -webkit-border-radius: 11px;")); client.println(F(" -khtml-border-radius: 11px;")); client.println(F(" border-radius: 11px;")); client.println(F(" margin-left: 1px;")); client.println(F(" background-image: -webkit-gradient(linear, 0% 0%, 0% 90%, from(rgba(46, 184, 0, 0.8)), to(rgba(148, 255, 112, .9)));@")); client.println(F(" border: 2px solid #ccc;")); client.println(F(" -webkit-box-shadow: rgba(11, 140, 27, 0.5) 0px 10px 16px;")); client.println(F(" -moz-box-shadow: rgba(11, 140, 27, 0.5) 0px 10px 16px; /* FF 3.5+ */")); client.println(F(" box-shadow: rgba(11, 140, 27, 0.5) 0px 10px 16px; /* FF 3.5+ */")); client.println(F(" }")); client.println(F("")); //how the black (off)LED will look client.println(F(".black-circle {")); client.println(F(" display: block;")); client.println(F(" height: 23px;")); client.println(F(" width: 23px;")); client.println(F(" background-color: #040;")); client.println(F(" -moz-border-radius: 11px;")); client.println(F(" -webkit-border-radius: 11px;")); client.println(F(" -khtml-border-radius: 11px;")); client.println(F(" border-radius: 11px;")); client.println(F(" margin-left: 1px;")); client.println(F(" -webkit-box-shadow: rgba(11, 140, 27, 0.5) 0px 10px 16px;")); client.println(F(" -moz-box-shadow: rgba(11, 140, 27, 0.5) 0px 10px 16px; /* FF 3.5+ */")); client.println(F(" box-shadow: rgba(11, 140, 27, 0.5) 0px 10px 16px; /* FF 3.5+ */")); client.println(F(" }")); client.println(F("")); //this will add the glare to both of the LEDs client.println(F(" .glare {")); client.println(F(" position: relative;")); client.println(F(" top: 1;")); client.println(F(" left: 5px;")); client.println(F(" -webkit-border-radius: 10px;")); client.println(F(" -moz-border-radius: 10px;")); client.println(F(" -khtml-border-radius: 10px;")); client.println(F(" border-radius: 10px;")); client.println(F(" height: 1px;")); client.println(F(" width: 13px;")); client.println(F(" padding: 5px 0;")); client.println(F(" background-color: rgba(200, 200, 200, 0.25);")); client.println(F(" background-image: -webkit-gradient(linear, 0% 0%, 0% 95%, from(rgba(255, 255, 255, 0.7)), to(rgba(255, 255, 255, 0)));")); client.println(F(" }")); client.println(F("")); //and finally this is the end of the style data and header client.println(F("</style>")); client.println(F("</head>")); //now printing the page itself client.println(F("<body>")); client.println(F("<div class=\"view\">")); client.println(F(" <div class=\"header-wrapper\">")); // client.println(F(" <h1>СМАРТ ДАЧА</h1>")); client.print(F("<table border=\"0\" align=\"center\"><tr><td><h4>Стиль страницы:</h4></td><td><INPUT TYPE=\"button\" VALUE=\"широкая" "\" onClick=\"parent.location='/?page1""'\"></td>")); client.print(F("<td><INPUT TYPE=\"button\" VALUE=\" узкая " "\" onClick=\"parent.location='/?page0""'\"></td></tr></table>")); client.println(F(" </div>")); } //end of htmlHeader //////////////////////////////////////////////////////////////////////// //htmlFooter Function //////////////////////////////////////////////////////////////////////// void printHtmlFooter(EthernetClient client){ //Set Variables Before Exiting printLastCommandOnce = false; printButtonMenuOnce = false; client.println(F("\n<h3 align=\"center\">©- Plagiary - <br> 774 KM - 2016 - ")); client.println(rev); client.println(F("</h3></div>\n</div>\n</body>\n</html>")); delay(1); // give the web browser time to receive the data client.stop(); // close the connection: Serial.println(" - Done, Closing Connection."); delay (2); //delay so that it will give time for client buffer to clear and does not repeat multiple pages. } //end of htmlFooter //////////////////////////////////////////////////////////////////////// //printHtmlButtonTitle Function //////////////////////////////////////////////////////////////////////// void printHtmlButtonTitle(EthernetClient client){ client.println(F("<div class=\"group-wrapper\">")); client.println(F("<h2 align=\"center\" >Температура на улице")); client.println(chartemp4); client.print(F(" °C </h2>")); client.println(); } ///////////////// DS18B20 float tempread(byte sensoraddr[]) // error codes: // -1 no sensors found // -2 invalid CRC // -3 not a DS1820 { byte i; byte present = 0; byte data[12]; byte addr[8]; //int HighByte, LowByte, TReading, SignBit, Tc_100, Tf_100, Whole, Fract; for ( i = 0; i < 8; i++) { addr[i]=sensoraddr[i]; } ds.reset(); // pulse the pins and wait for a response to reset the DS1820 ds.select(addr); // 0x55 (MATCH_ROM) followed by the address of the 1820 to talk to. // ds.write(0x44,1); // start conversion, with parasite power on at the end ds.write(0x44,0); //PARASITE POWER OFF // delay(800); present = ds.reset(); ds.select(addr); ds.write(0xBE); // Read Scratchpad for ( i = 0; i < 9; i++) { // we need 9 bytes data[i] = ds.read(); } int16_t raw = (data[1] << 8) | data[0]; float temp = (float)raw / 16.0; return temp; }и конечно есть вопрос =)
почему во время загрузки при чтении из флеш сохраненых состоянии пинов, 0, 2, и 4 байты всегда "1" с остальными все впорядке, пишутся и считываюся нормально
подпишусь. может и я когда нибудь страничку смогу сделать
хотя выглядит так просто. но это наверно первое неверное впечатление
и конечно есть вопрос =)
почему во время загрузки при чтении из флеш сохраненых состоянии пинов, 0, 2, и 4 байты всегда "1" с остальными все впорядке, пишутся и считываюся нормально
Сходу не нашёл проблемы с EEPROM, но код тяжело читать и сопровождать, поэтому так вот сразу и не скажу, к тому же цифры какие-то магические - 0, 2, 4.
Сходу не нашёл проблемы с EEPROM, но код тяжело читать и сопровождать, поэтому так вот сразу и не скажу, к тому же цифры какие-то магические - 0, 2, 4.
решил проблему увеличив начальный адрес байта флеш памяти в двух строках:
измененный скейтч:
#include <Ethernet.h> #include <SPI.h> #include <EEPROM.h> #include <DHT.h> #include <OneWire.h> //////////////////////////////////////////////////////////////////////// //CONFIGURATION //////////////////////////////////////////////////////////////////////// //IP manual settings byte ip[] = { 10, 16, 30, 2 }; //Manual setup only byte gateway[] = { 10, 16, 30, 3 }; //Manual setup only byte subnet[] = { 255, 255, 255, 0 }; //Manual setup only // if need to change the MAC address (Very Rare) byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //Ethernet Port EthernetServer server = EthernetServer(80); //default html port 80 //The number of outputs going to be switched. int outputQuantity = 20; //should not exceed 10 //Invert the output of the leds boolean outputInverted = false; //true or false // This is done in case the relay board triggers the relay on negative, rather then on positive supply //Html page refresh int refreshPage = 15; //default is 10sec. //Beware that if you make it refresh too fast, the page could become inacessable. //Display or hide the "Switch on all Pins" buttons at the bottom of page int switchOnAllPinsButton = true; //true or false //Button Array //Just for a note, varables start from 0 to 9, as 0 is counted as well, thus 10 outputs. // Select the pinout address int outputAddress[20] = { 3,5,6,7,8,9,14,15,16,17,18,19,20,21,22,23,24,25,26,27}; //Allocate 10 spaces and name the output pin address. //PS pin addresses 10, 11, 12 and 13 on the Duemilanove are used for the ethernet shield, therefore cannot be used. //PS pin addresses 10, 50, 51 and 52 and 53 on the Mega are used for the ethernet shield, therefore cannot be used. //PS pin addresses 4, are used for the SD card, therefore cannot be used. //PS. pin address 2 is used for interrupt-driven notification, therefore could not be used. // Write the text description of the output channel String buttonText[20] = { "01. Канал","02. Канал","03. Канал","04. Канал","05. Канал","06. Канал","07. Канал","08. Канал","09. Канал","10. Канал","11. Канал","12. Канал","13. Канал","14. Канал","15. Канал","16. Канал","17. Канал","18. Канал","19. Канал","20. Канал"}; //////////////////////////////////////////////////////////////////////// int twenty[] = {11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30}; //char twentyTEXT[] = {'d1','d2','d3','d4','d5','d6','d7','d8','d9','d10','d11','d12','d13','d14','d15','d16','d17','d18','d19','d20'}; //////////////////////////////////////////////////////////////////////// //VARIABLES DECLARATION //////////////////////////////////////////////////////////////////////// int outp = 0; boolean printLastCommandOnce = false; boolean printButtonMenuOnce = false; boolean initialPrint = true; boolean reading = false; boolean outputStatus[20]; //Create a boolean array for the maximum ammount. String rev = "V1.3"; unsigned long timeConnectedAt; boolean writeToEeprom = false; int page=1; int intCommand=0; //////////////переменные упрвавления температурой const byte PinSSR1 = 44; // Реле Pin for SSR 1 const byte PinSSR2 = 45; // Реле Pin for SSR 2 const byte PinSSR3 = 46; // Реле Pin for SSR 3 char chartemp1[10]; char chartemp2[10]; char chartemp3[10]; char chartemp4[10]; int TargetTemp1; int TargetTemp2; int TargetTemp3; float temp1; float temp2; OneWire ds(47); DHT dht1(48, DHT11); DHT dht2(49, DHT11); //////////////////////////////// //////////////////////////////////////////////////////////////////////// //RUN ONCE //////////////////////////////////////////////////////////////////////// //Beginning of Program void setup(){ Serial.begin(9600); initEepromValues(); readEepromValues(); //Set pins as Outputs boolean currentState = false; for (int var = 0; var < outputQuantity; var++){ pinMode(outputAddress[var], OUTPUT); //Switch all outputs to either on or off on Startup if(outputInverted == true) { //digitalWrite(outputAddress[var], HIGH); if(outputStatus[var] == 0){currentState = true;}else{currentState = false;} //check outputStatus if off, switch output accordingly digitalWrite(outputAddress[var], currentState); } else{ //digitalWrite(outputAddress[var], LOW); if(outputStatus[var] == 0){currentState = false;}else{currentState = true;}//check outputStatus if off, switch output accordingly digitalWrite(outputAddress[var], currentState); } } //Setting up the IP address. Comment out the one you dont need. //Ethernet.begin(mac); //for DHCP address. (Address will be printed to serial.) Ethernet.begin(mac, ip, gateway, subnet); //for manual setup. (Address is the one configured above.) server.begin(); Serial.print("Server started at "); Serial.println(Ethernet.localIP()); ////////////////управление температурой pinMode(PinSSR1, OUTPUT); pinMode(PinSSR2, OUTPUT); pinMode(PinSSR3, OUTPUT); TargetTemp1 = EEPROM.read(1000); TargetTemp2 = EEPROM.read(1002); TargetTemp3 = EEPROM.read(1004); dht1.begin(); dht2.begin(); } //////////////////////////////////////////////////////////////////////// //LOOP //////////////////////////////////////////////////////////////////////// //Run once void loop(){ // listen for incoming clients, and process requests. checkForClient(); ///////////////////////управление температурой float temp3; float temp4; byte sensor1[8] = {0x28, 0xFF, 0x34, 0x2C, 0x50, 0x15, 0x01, 0x87}; // Адрес сенсора byte sensor2[8] = {0x28, 0xDF, 0x7E, 0xDC, 0x06, 0x00, 0x00, 0xF3}; // Адрес сенсора //DHT temp1 = dht1.readTemperature(); dtostrf(temp1, 3, 1, chartemp1); temp2 = dht2.readTemperature(); dtostrf(temp2, 3, 1, chartemp2); //DS18B20 temp3 = tempread(sensor1); dtostrf(temp3, 3, 1, chartemp3); temp4 = tempread(sensor2); dtostrf(temp4, 3, 1, chartemp4); if (temp1<TargetTemp1-1) { digitalWrite(PinSSR1, LOW); } else if (temp1>TargetTemp1+1) { digitalWrite(PinSSR1, HIGH); } if (temp2<TargetTemp2-1) { digitalWrite(PinSSR2, LOW); } else if (temp2>TargetTemp2+1) { digitalWrite(PinSSR2, HIGH); } if (temp3<TargetTemp3-1) { digitalWrite(PinSSR3, LOW); } else if (temp3>TargetTemp3+1) { digitalWrite(PinSSR3, HIGH); } } //////////////////////////////////////////////////////////////////////// //checkForClient Function //////////////////////////////////////////////////////////////////////// // void checkForClient(){ EthernetClient client = server.available(); if (client) { // an http request ends with a blank line boolean currentLineIsBlank = true; boolean sentHeader = false; String command; while (client.connected()) { if (client.available()) { //read user input char c = client.read(); if(c == '*'){ printHtmlHeader(client); //call for html header and css printHtmlFooter(client); //sentHeader = true; break; } if(!sentHeader){ printHtmlHeader(client); //call for html header and css printHtmlButtonTitle(client); //print the button title //This is for the arduino to construct the page on the fly. sentHeader = true; } //if there was reading but is blank there was no reading if(reading && c == ' '){ reading = false; } //if there is a ? there was user input if(c == '?') { reading = true; //found the ?, begin reading the info command = F(""); // clear current command } // if there was user input switch the relevant output if(reading){ //if user input is H set output to 1 if(c == 'H') { outp = 1; } //if user input is L set output to 0 if(c == 'L') { outp = 0; } if(c!='?'&&c!='H'&&c!='L') {command +=c;} if(command == "t1-00") {TargetTemp1 = 0; EEPROM.write(1000, 0); Serial.println(" "); Serial.println("temp 0 OK");} if(command == "t1-05") {TargetTemp1 = 5; EEPROM.write(1000, 5); Serial.println(" "); Serial.println("temp 5 OK");} if(command == "t1-10") {TargetTemp1 = 10; EEPROM.write(1000, 10); Serial.println(" "); Serial.println("temp 10 OK");} if(command == "t1-20") {TargetTemp1 = 20; EEPROM.write(1000, 20);} if(command == "t1-22") {TargetTemp1 = 22; EEPROM.write(1000, 22);} if(command == "t1-24") {TargetTemp1 = 24; EEPROM.write(1000, 24);} if(command == "t2-00") {TargetTemp2 = 0; EEPROM.write(1002, 0);} if(command == "t2-05") {TargetTemp2 = 5; EEPROM.write(1002, 5);} if(command == "t2-10") {TargetTemp2 = 10; EEPROM.write(1002, 10);} if(command == "t2-20") {TargetTemp2 = 20; EEPROM.write(1002, 20);} if(command == "t2-22") {TargetTemp2 = 22; EEPROM.write(1002, 22);} if(command == "t2-24") {TargetTemp2 = 24; EEPROM.write(1002, 24);} if(command == "t3-00") {TargetTemp3 = 0; EEPROM.write(1004, 0);} if(command == "t3-05") {TargetTemp3 = 5; EEPROM.write(1004, 5);} if(command == "t3-10") {TargetTemp3 = 10; EEPROM.write(1004, 10);} if(command == "t3-20") {TargetTemp3 = 20; EEPROM.write(1004, 20);} if(command == "t3-22") {TargetTemp3 = 22; EEPROM.write(1004, 22);} if(command == "t3-24") {TargetTemp3 = 24; EEPROM.write(1004, 24);} if(command == "d11") {triggerPin(outputAddress[0], client, outp); Serial.println(" "); Serial.println("case 1 OK"); } if(command == "d12") {triggerPin(outputAddress[1], client, outp); Serial.println(" "); Serial.println("case 2 OK"); } if(command == "d13") {triggerPin(outputAddress[2], client, outp); Serial.println(" "); Serial.println("case 3 OK"); } if(command == "d14") {triggerPin(outputAddress[3], client, outp); Serial.println(" "); Serial.println("case 4 OK"); } if(command == "d15") {triggerPin(outputAddress[4], client, outp); Serial.println(" "); Serial.println("case 5 OK"); } if(command == "d16") {triggerPin(outputAddress[5], client, outp); Serial.println(" "); Serial.println("case 6 OK"); } if(command == "d17") {triggerPin(outputAddress[6], client, outp); Serial.println(" "); Serial.println("case 7 OK"); } if(command == "d18") {triggerPin(outputAddress[7], client, outp); Serial.println(" "); Serial.println("case 8 OK"); } if(command == "d19") {triggerPin(outputAddress[8], client, outp); Serial.println(" "); Serial.println("case 9 OK"); } if(command == "d20") {triggerPin(outputAddress[9], client, outp); Serial.println(" "); Serial.println("case 10 OK"); } if(command == "d21") {triggerPin(outputAddress[10], client, outp); Serial.println(" "); Serial.println("case 11 OK"); } if(command == "d22") {triggerPin(outputAddress[11], client, outp); Serial.println(" "); Serial.println("case 12 OK"); } if(command == "d23") {triggerPin(outputAddress[12], client, outp); Serial.println(" "); Serial.println("case 13 OK"); } if(command == "d24") {triggerPin(outputAddress[13], client, outp); Serial.println(" "); Serial.println("case 14 OK"); } if(command == "d25") {triggerPin(outputAddress[14], client, outp); Serial.println(" "); Serial.println("case 15 OK"); } if(command == "d26") {triggerPin(outputAddress[15], client, outp); Serial.println(" "); Serial.println("case 16 OK"); } if(command == "d27") {triggerPin(outputAddress[16], client, outp); Serial.println(" "); Serial.println("case 17 OK"); } if(command == "d28") {triggerPin(outputAddress[17], client, outp); Serial.println(" "); Serial.println("case 18 OK"); } if(command == "d29") {triggerPin(outputAddress[18], client, outp); Serial.println(" "); Serial.println("case 19 OK"); } if(command == "d30") {triggerPin(outputAddress[19], client, outp); Serial.println(" "); Serial.println("case 20 OK"); } if(command == "100"){ for (int var = 0; var < outputQuantity; var++) { triggerPin(outputAddress[var], client, outp); } } if(command == "page1") {page=1; Serial.println(" "); Serial.println("page 1 OK"); } if(command == "page0") {page=0; Serial.println(" "); Serial.println("page 0 OK"); } }//end of switch switch the relevant output //if user input was blank if (c == '\n' && currentLineIsBlank){ printLastCommandOnce = true; printButtonMenuOnce = true; triggerPin(777, client, outp); //Call to read input and print menu. 777 is used not to update any outputs break; } } } Serial.println(" "); Serial.print("command:"); Serial.print(command); Serial.println(" "); /* intCommand=command.toInt(); Serial.println(" "); Serial.print("intCommand:"); Serial.println(intCommand); Serial.println(" "); switch (intCommand) { case 1: //add code here to trigger on 0 triggerPin(outputAddress[0], client, outp); Serial.println(" "); Serial.println("case 1 OK"); break; case 2: //add code here to trigger on 1 triggerPin(outputAddress[1], client, outp); Serial.println(" "); Serial.println("case 2 OK"); break; case 3: //add code here to trigger on 2 triggerPin(outputAddress[2], client, outp); break; case 4: //add code here to trigger on 3 triggerPin(outputAddress[3], client, outp); break; case 5: //add code here to trigger on 4 triggerPin(outputAddress[4], client, outp); break; case 6: //add code here to trigger on 5 triggerPin(outputAddress[5], client, outp); //printHtml(client); break; case 7: //add code here to trigger on 6 triggerPin(outputAddress[6], client, outp); break; case 8: //add code here to trigger on 7 triggerPin(outputAddress[7], client, outp); break; case 9: //add code here to trigger on 8 triggerPin(outputAddress[8], client, outp); break; case 10: //add code here to trigger on 9 triggerPin(outputAddress[9], client, outp); Serial.println(" "); Serial.println("case 10 OK"); break; case 11: //add code here to trigger on 10 triggerPin(outputAddress[10], client, outp); Serial.println(" "); Serial.println("case 11 OK"); break; case 12: //add code here to trigger on 11 triggerPin(outputAddress[11], client, outp); break; case 13: //add code here to trigger on 12 triggerPin(outputAddress[12], client, outp); break; case 14: //add code here to trigger on 13 triggerPin(outputAddress[13], client, outp); break; case 15: //add code here to trigger on 14 triggerPin(outputAddress[14], client, outp); break; case 16: //add code here to trigger on 15 triggerPin(outputAddress[15], client, outp); //printHtml(client); break; case 17: //add code here to trigger on 16 triggerPin(outputAddress[16], client, outp); break; case 18: //add code here to trigger on 17 triggerPin(outputAddress[17], client, outp); break; case 19: //add code here to trigger on 18 triggerPin(outputAddress[18], client, outp); break; case 20: //add code here to trigger on 19 triggerPin(outputAddress[19], client, outp); break; case 100: //add code here to trigger on 19 for (int var = 0; var < outputQuantity; var++) { triggerPin(outputAddress[var], client, outp); } break; } //end of switch case */ Serial.println("----------"); printHtmlFooter(client); //Prints the html footer } else { //if there is no client // таймаут простоя, для записи данных состояния переключателей в кэш if (millis() > (timeConnectedAt + 10000)){ if (writeToEeprom == true){ writeEepromValues(); //write to EEprom the current output statuses Serial.println("No Clients for more then a 10 sec. - Writing statuses to Eeprom."); writeToEeprom = false; } } } } /////////////////////////////////////////////////////////////////////// //triggerPin Function //////////////////////////////////////////////////////////////////////// void triggerPin(int pin, EthernetClient client, int outp){ //Switching on or off outputs, reads the outputs and prints the buttons //Setting Outputs if (pin != 777){ if(outp == 1) { if (outputInverted ==false){ digitalWrite(pin, HIGH); } else{ digitalWrite(pin, LOW); } } if(outp == 0){ if (outputInverted ==false){ digitalWrite(pin, LOW); } else{ digitalWrite(pin, HIGH); } } Serial.println(" "); Serial.print("triggerPin:"); Serial.print(pin); Serial.println(" OK"); } //Refresh the reading of outputs readOutputStatuses(); //Prints the buttons if (printButtonMenuOnce == true){ printHtmlButtons(client); printButtonMenuOnce = false; } } //////////////////////////////////////////////////////////////////////// //printHtmlButtons Function //////////////////////////////////////////////////////////////////////// void printHtmlButtons(EthernetClient client){ client.println(""); client.println("<FORM>"); //вывод таблиц управления температурой if (page == 1){ client.println("<table border=\"0\" align=\"center\">"); client.print("<tr>"); client.print("<td rowspan=3>"); } //вывод текста, кнопок ON и OFF и лампочек состояния client.println("<table border=\"0\" align=\"center\">"); for (int var = 0; var < outputQuantity; var++) { //Print begining of row client.print("<tr>\n"); //Prints the button Text client.print("<td><h4>"); client.print(buttonText[var]); client.print("</h4></td>\n"); //Prints the ON Buttons client.print("<td>"); client.print("<INPUT TYPE=\"button\" VALUE=\"ВКЛ "); client.print("\" onClick=\"parent.location='/?H"); client.print("d"); client.print(twenty[var]); client.print("'\"></td>\n"); //Prints the OFF Buttons client.print(" <td><INPUT TYPE=\"button\" VALUE=\"ВЫКЛ"); client.print("\" onClick=\"parent.location='/?L"); client.print("d"); client.print(twenty[var]); client.print("'\"></td>\n"); //Print first part of the Circles or the LEDs //Invert the LED display if output is inverted. if (outputStatus[var] == true ){ //If Output is ON if (outputInverted == false){ //and if output is not inverted client.print(" <td><div class='green-circle'><div class='glare'></div></div></td>\n"); //Print html for ON LED } else{ //else output is inverted then client.print(" <td><div class='black-circle'><div class='glare'></div></div></td>\n"); //Print html for OFF LED } } else //If Output is Off { if (outputInverted == false){ //and if output is not inverted client.print(" <td><div class='black-circle'><div class='glare'></div></div></td>\n"); //Print html for OFF LED } else{ //else output is inverted then client.print(" <td><div class='green-circle'><div class='glare'></div></div></td>\n"); //Print html for ON LED } } client.print("</tr>\n"); } // end for //Вывод кнопок вкл всё и выкл всё if (switchOnAllPinsButton == true ){ //Prints the ON All Pins Button client.print("<tr>\n<td colspan=2><INPUT TYPE=\"button\" VALUE=\"Включить ВСЁ"); client.print("\" onClick=\"parent.location='/?H100"); // client.print(allOn); client.print("'\"></td>\n"); //Prints the OFF All Pins Button client.print("<td colspan=2><INPUT TYPE=\"button\" VALUE=\"Выключить ВСЁ"); client.print("\" onClick=\"parent.location='/?L100"); // client.print(allOff); client.print("'\"></td>\n<td></td>\n<td></td>\n</tr>\n"); } client.println("</table>"); if (page == 1){ client.print("</td>"); client.print("<td>"); } client.println("<table border=\"0\" align=\"center\">"); client.print("<tr>"); client.print("<td></td>"); client.print("<td><h3>текущая</h3></td>"); client.print("<td><h3>обогрев</h3</td>"); client.print("<td><h3>желаемая</h3</td>"); client.print("</tr>"); client.print("<tr>"); client.print("<td><h4>"); client.print("Первый этаж:"); client.print("</h4></td>"); client.print("<td align=\"center\">"); client.println(chartemp1); //текущая температура client.print(" °C</td>"); if ( digitalRead(PinSSR1) == LOW ) { client.println("<td align=\"center\"><font color=green><b>ВКЛ</b></font></td>"); } // вкл или выкл else { client.println("<td align=\"center\"><font color=red><b>ВЫКЛ</b></font></td>"); } client.println("<td align=\"center\">"); client.println(TargetTemp1); //отображение желаемой температуры client.println(" °C</td>"); client.print("</tr>"); client.print("<tr>"); client.print("<td><h4>"); client.print("Установить:"); //выбор желаемой температуры client.print("</h4></td>"); client.print(" <td colspan=3><table border=\"0\"><tr><td><INPUT TYPE=\"button\" VALUE=\"0" "\" onClick=\"parent.location='/?t1-00""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"5" "\" onClick=\"parent.location='/?t1-05""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"10" "\" onClick=\"parent.location='/?t1-10""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"20" "\" onClick=\"parent.location='/?t1-20""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"22" "\" onClick=\"parent.location='/?t1-22""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"24" "\" onClick=\"parent.location='/?t1-24""'\"></td></tr></table></td>"); client.print("</tr>"); client.println("</table>"); if (page == 1){ client.print("</td>"); client.print("</tr>"); client.print("<tr>"); client.print("<td>"); } client.println("<table border=\"0\" align=\"center\">"); client.print("<tr>"); client.print("<td></td>"); client.print("<td><h3>текущая</h3></td>"); client.print("<td><h3>обогрев</h3</td>"); client.print("<td><h3>желаемая</h3</td>"); client.print("</tr>"); client.print("<tr>"); client.print("<td><h4>"); client.print("Второй этаж:"); client.print("</h4></td>"); client.print("<td align=\"center\">"); client.println(chartemp2); //текущая температура client.print(" °C</td>"); if ( digitalRead(PinSSR2) == LOW ) { client.println("<td align=\"center\"><font color=green><b>ВКЛ</b></font></td>"); } // вкл или выкл else { client.println("<td align=\"center\"><font color=red><b>ВЫКЛ</b></font></td>"); } client.println("<td align=\"center\">"); client.println(TargetTemp2); //отображение желаемой температуры client.println(" °C</td>"); client.print("</tr>"); client.print("<tr>"); client.print("<td><h4>"); client.print("Установить:"); //выбор желаемой температуры client.print("</h4></td>"); client.print(" <td colspan=3><table border=\"0\"><tr><td><INPUT TYPE=\"button\" VALUE=\"0" "\" onClick=\"parent.location='/?t2-00""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"5" "\" onClick=\"parent.location='/?t2-05""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"10" "\" onClick=\"parent.location='/?t2-10""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"20" "\" onClick=\"parent.location='/?t2-20""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"22" "\" onClick=\"parent.location='/?t2-22""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"24" "\" onClick=\"parent.location='/?t2-24""'\"></td></tr></table></td>"); client.print("</tr>"); client.println("</table>"); if (page == 1){ client.print("</td>"); client.print("</tr>"); client.print("<tr>"); client.print("<td>"); } client.println("<table border=\"0\" align=\"center\">"); client.print("<tr>"); client.print("<td></td>"); client.print("<td><h3>текущая</h3></td>"); client.print("<td><h3>обогрев</h3</td>"); client.print("<td><h3>желаемая</h3</td>"); client.print("</tr>"); client.print("<tr>"); client.print("<td><h4>"); client.print("Кухня:"); client.print("</h4></td>"); client.print("<td align=\"center\">"); client.println(chartemp3); //текущая температура client.print(" °C</td>"); if ( digitalRead(PinSSR3) == LOW ) { client.println("<td align=\"center\"><font color=green><b>ВКЛ</b></font></td>"); } // вкл или выкл else { client.println("<td align=\"center\"><font color=red><b>ВЫКЛ</b></font></td>"); } client.println("<td align=\"center\">"); client.println(TargetTemp3); //отображение желаемой температуры client.println(" °C</td>"); client.print("</tr>"); client.print("<tr>"); client.print("<td><h4>"); client.print("Установить:"); //выбор желаемой температуры client.print("</h4></td>"); client.print(" <td colspan=3><table border=\"0\"><tr><td><INPUT TYPE=\"button\" VALUE=\"0" "\" onClick=\"parent.location='/?t3-00""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"5" "\" onClick=\"parent.location='/?t3-05""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"10" "\" onClick=\"parent.location='/?t3-10""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"20" "\" onClick=\"parent.location='/?t3-20""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"22" "\" onClick=\"parent.location='/?t3-22""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"24" "\" onClick=\"parent.location='/?t3-24""'\"></td></tr></table></td>"); client.print("</tr>"); client.println("</table>"); if (page == 1){ client.print("</td>"); client.print("</tr>"); client.println("</table>"); } client.println("</FORM>"); } //////////////////////////////////////////////////////////////////////// //readOutputStatuses Function //////////////////////////////////////////////////////////////////////// //Reading the Output Statuses void readOutputStatuses(){ for (int var = 0; var < outputQuantity; var++) { outputStatus[var] = digitalRead(outputAddress[var]); // Serial.print(outputStatus[var]); } } //////////////////////////////////////////////////////////////////////// //readEepromValues Function //////////////////////////////////////////////////////////////////////// //Read EEprom values and save to outputStatus void readEepromValues(){ for (int adr = 0; adr < outputQuantity; adr++) { outputStatus[adr] = EEPROM.read(adr+10); Serial.println(" "); Serial.print("adr::"); Serial.print(adr); Serial.println(" OK"); Serial.println(" "); Serial.print("outputStatus[adr]::"); Serial.print(outputStatus[adr]); Serial.println(" OK"); } } //////////////////////////////////////////////////////////////////////// //writeEepromValues Function //////////////////////////////////////////////////////////////////////// void writeEepromValues(){ for (int adr = 0; adr < outputQuantity+0; adr++) { EEPROM.write(adr+10, outputStatus[adr]); Serial.println(" "); Serial.print("adr::"); Serial.print(adr); Serial.println(" OK"); Serial.println(" "); Serial.print("outputStatus[adr]::"); Serial.print(outputStatus[adr]); Serial.println(" OK"); } } //////////////////////////////////////////////////////////////////////// //initEepromValues Function //////////////////////////////////////////////////////////////////////// //Initialiaze EEprom values //if eeprom values are not the correct format ie not euqual to 0 or 1 (thus greater then 1) initialize by putting 0 void initEepromValues(){ for (int adr = 0; adr < outputQuantity; adr++){ if (EEPROM.read(adr) > 1){ EEPROM.write(adr, 0); } } } //////////////////////////////////////////////////////////////////////// //htmlHeader Function //////////////////////////////////////////////////////////////////////// void printHtmlHeader(EthernetClient client){ Serial.print("Serving html Headers at ms -"); timeConnectedAt = millis(); //Record the time when last page was served. Serial.println(timeConnectedAt); // Print time for debbugging purposes writeToEeprom = true; // page loaded so set to action the write to eeprom // send a standard http response header client.println(F("HTTP/1.1 200 OK")); client.println(F("Content-Type: text/html; charset=utf-8")); client.println(F("Connnection: close")); client.println(); client.println(F("<!DOCTYPE HTML>")); client.println(F("<head>")); // заголовок страницы client.println(F("<title>Контроль и управление домом</title>")); client.println(F("<meta name=\"description\" content=\"Контроль и управление домом\"/>")); // время обновления страницы client.print(F("<meta http-equiv=\"refresh\" content=\"")); client.print(refreshPage); client.println(F("; url=/\">")); // конфигурация браузера client.println(F("<meta name=\"apple-mobile-web-app-capable\" content=\"yes\">")); client.println(F("<meta name=\"apple-mobile-web-app-status-bar-style\" content=\"default\">")); client.println(F("<meta name=\"viewport\" content=\"width=device-width, user-scalable=no\">")); // вставка данных стилей CSS client.println(F("<style type=\"text/css\">")); client.println(F("")); // как будет выглядеть страница графически client.println(F("html { height:100%; }")); client.println(F(" body {")); client.println(F(" height: 100%;")); client.println(F(" margin: 0;")); client.println(F(" font-family: helvetica, sans-serif;")); client.println(F(" -webkit-text-size-adjust: none;")); client.println(F(" }")); client.println(F("")); client.println(F("body {")); client.println(F(" -webkit-background-size: 100% 21px;")); client.println(F(" background-color: #c5ccd3;")); client.println(F(" background-image:")); client.println(F(" -webkit-gradient(linear, left top, right top,")); client.println(F(" color-stop(.75, transparent),")); client.println(F(" color-stop(.75, rgba(255,255,255,.1)) );")); client.println(F(" -webkit-background-size: 7px;")); client.println(F(" }")); client.println(F("")); client.println(F(".view {")); client.println(F(" min-height: 100%;")); client.println(F(" overflow: auto;")); client.println(F(" }")); client.println(F("")); client.println(F(".header-wrapper {")); client.println(F(" height: 64px;")); client.println(F(" font-weight: bold;")); client.println(F(" text-shadow: rgba(0,0,0,0.7) 0 -1px 0;")); client.println(F(" border-top: solid 1px rgba(255,255,255,0.6);")); client.println(F(" border-bottom: solid 1px rgba(0,0,0,0.6);")); client.println(F(" color: #fff;")); client.println(F(" background-color: #8195af;")); client.println(F(" background-image:")); client.println(F(" -webkit-gradient(linear, left top, left bottom,")); client.println(F(" from(rgba(255,255,255,.4)),")); client.println(F(" to(rgba(255,255,255,.05)) ),")); client.println(F(" -webkit-gradient(linear, left top, left bottom,")); client.println(F(" from(transparent),")); client.println(F(" to(rgba(0,0,64,.1)) );")); client.println(F(" background-repeat: no-repeat;")); client.println(F(" background-position: top left, bottom left;")); client.println(F(" -webkit-background-size: 100% 21px, 100% 22px;")); client.println(F(" -webkit-box-sizing: border-box;")); client.println(F(" }")); client.println(F("")); client.println(F(".header-wrapper h1 {")); client.println(F(" text-align: center;")); client.println(F(" font-size: 20px;")); client.println(F(" line-height: 44px;")); client.println(F(" margin: 0;")); client.println(F(" }")); client.println(F("")); client.println(F(".group-wrapper {")); client.println(F(" margin: 9px;")); client.println(F(" aling: center;")); client.println(F(" }")); client.println(F("")); client.println(F(".group-wrapper h2 {")); client.println(F(" color: #4c566c;")); client.println(F(" font-size: 17px;")); client.println(F(" line-height: 0.8;")); client.println(F(" font-weight: bold;")); client.println(F(" text-shadow: #fff 0 1px 0;")); client.println(F(" margin: 20px 10px 12px;")); client.println(F(" }")); client.println(F("")); client.println(F(".group-wrapper h3 {")); client.println(F(" color: #4c566c;")); client.println(F(" font-size: 12px;")); client.println(F(" line-height: 1;")); client.println(F(" font-weight: bold;")); client.println(F(" text-shadow: #fff 0 1px 0;")); client.println(F(" margin: 20px 10px 12px;")); client.println(F(" }")); client.println(F("")); client.println(F(".group-wrapper h4 {")); //Text for description client.println(F(" color: #212121;")); client.println(F(" font-size: 14px;")); client.println(F(" line-height: 1;")); client.println(F(" font-weight: bold;")); client.println(F(" text-shadow: #aaa 1px 1px 3px;")); client.println(F(" margin: 5px 5px 5px;")); client.println(F(" }")); client.println(F("")); client.println(F(".group-wrapper table {")); client.println(F(" background-color: #fff;")); client.println(F(" -webkit-border-radius: 10px;")); client.println(F(" -moz-border-radius: 10px;")); client.println(F(" -khtml-border-radius: 10px;")); client.println(F(" border-radius: 10px;")); client.println(F(" font-size: 17px;")); client.println(F(" line-height: 20px;")); client.println(F(" margin: 9px 0 20px;")); client.println(F(" border: solid 1px #a9abae;")); client.println(F(" padding: 11px 3px 12px 3px;")); client.println(F(" margin-left:auto;")); client.println(F(" margin-right:auto;")); client.println(F(" -moz-transform :scale(1);")); //Code for Mozilla Firefox client.println(F(" -moz-transform-origin: 0 0;")); client.println(F(" }")); //how the green (ON) LED will look client.println(F(".green-circle {")); client.println(F(" display: block;")); client.println(F(" height: 23px;")); client.println(F(" width: 23px;")); client.println(F(" background-color: #0f0;")); client.println(F(" -moz-border-radius: 11px;")); client.println(F(" -webkit-border-radius: 11px;")); client.println(F(" -khtml-border-radius: 11px;")); client.println(F(" border-radius: 11px;")); client.println(F(" margin-left: 1px;")); client.println(F(" background-image: -webkit-gradient(linear, 0% 0%, 0% 90%, from(rgba(46, 184, 0, 0.8)), to(rgba(148, 255, 112, .9)));@")); client.println(F(" border: 2px solid #ccc;")); client.println(F(" -webkit-box-shadow: rgba(11, 140, 27, 0.5) 0px 10px 16px;")); client.println(F(" -moz-box-shadow: rgba(11, 140, 27, 0.5) 0px 10px 16px; /* FF 3.5+ */")); client.println(F(" box-shadow: rgba(11, 140, 27, 0.5) 0px 10px 16px; /* FF 3.5+ */")); client.println(F(" }")); client.println(F("")); //how the black (off)LED will look client.println(F(".black-circle {")); client.println(F(" display: block;")); client.println(F(" height: 23px;")); client.println(F(" width: 23px;")); client.println(F(" background-color: #040;")); client.println(F(" -moz-border-radius: 11px;")); client.println(F(" -webkit-border-radius: 11px;")); client.println(F(" -khtml-border-radius: 11px;")); client.println(F(" border-radius: 11px;")); client.println(F(" margin-left: 1px;")); client.println(F(" -webkit-box-shadow: rgba(11, 140, 27, 0.5) 0px 10px 16px;")); client.println(F(" -moz-box-shadow: rgba(11, 140, 27, 0.5) 0px 10px 16px; /* FF 3.5+ */")); client.println(F(" box-shadow: rgba(11, 140, 27, 0.5) 0px 10px 16px; /* FF 3.5+ */")); client.println(F(" }")); client.println(F("")); //this will add the glare to both of the LEDs client.println(F(" .glare {")); client.println(F(" position: relative;")); client.println(F(" top: 1;")); client.println(F(" left: 5px;")); client.println(F(" -webkit-border-radius: 10px;")); client.println(F(" -moz-border-radius: 10px;")); client.println(F(" -khtml-border-radius: 10px;")); client.println(F(" border-radius: 10px;")); client.println(F(" height: 1px;")); client.println(F(" width: 13px;")); client.println(F(" padding: 5px 0;")); client.println(F(" background-color: rgba(200, 200, 200, 0.25);")); client.println(F(" background-image: -webkit-gradient(linear, 0% 0%, 0% 95%, from(rgba(255, 255, 255, 0.7)), to(rgba(255, 255, 255, 0)));")); client.println(F(" }")); client.println(F("")); //and finally this is the end of the style data and header client.println(F("</style>")); client.println(F("</head>")); //now printing the page itself client.println(F("<body>")); client.println(F("<div class=\"view\">")); client.println(F(" <div class=\"header-wrapper\">")); // client.println(F(" <h1>СМАРТ ДАЧА</h1>")); client.print(F("<table border=\"0\" align=\"center\"><tr><td><h4>Стиль страницы:</h4></td><td><INPUT TYPE=\"button\" VALUE=\"широкая" "\" onClick=\"parent.location='/?page1""'\"></td>")); client.print(F("<td><INPUT TYPE=\"button\" VALUE=\" узкая " "\" onClick=\"parent.location='/?page0""'\"></td></tr></table>")); client.println(F(" </div>")); } //end of htmlHeader //////////////////////////////////////////////////////////////////////// //htmlFooter Function //////////////////////////////////////////////////////////////////////// void printHtmlFooter(EthernetClient client){ //Set Variables Before Exiting printLastCommandOnce = false; printButtonMenuOnce = false; client.println(F("\n<h3 align=\"center\">©- Plagiary - <br> 774 KM - 2016 - ")); client.println(rev); client.println(F("</h3></div>\n</div>\n</body>\n</html>")); delay(1); // give the web browser time to receive the data client.stop(); // close the connection: Serial.println(" - Done, Closing Connection."); delay (2); //delay so that it will give time for client buffer to clear and does not repeat multiple pages. } //end of htmlFooter //////////////////////////////////////////////////////////////////////// //printHtmlButtonTitle Function //////////////////////////////////////////////////////////////////////// void printHtmlButtonTitle(EthernetClient client){ client.println(F("<div class=\"group-wrapper\">")); client.println(F("<h2 align=\"center\" >Температура на улице")); client.println(chartemp4); client.print(F(" °C </h2>")); client.println(); } ///////////////// DS18B20 float tempread(byte sensoraddr[]) // error codes: // -1 no sensors found // -2 invalid CRC // -3 not a DS1820 { byte i; byte present = 0; byte data[12]; byte addr[8]; //int HighByte, LowByte, TReading, SignBit, Tc_100, Tf_100, Whole, Fract; for ( i = 0; i < 8; i++) { addr[i]=sensoraddr[i]; } ds.reset(); // pulse the pins and wait for a response to reset the DS1820 ds.select(addr); // 0x55 (MATCH_ROM) followed by the address of the 1820 to talk to. // ds.write(0x44,1); // start conversion, with parasite power on at the end ds.write(0x44,0); //PARASITE POWER OFF // delay(800); present = ds.reset(); ds.select(addr); ds.write(0xBE); // Read Scratchpad for ( i = 0; i < 9; i++) { // we need 9 bytes data[i] = ds.read(); } int16_t raw = (data[1] << 8) | data[0]; float temp = (float)raw / 16.0; return temp; }Дружище, скинь, пожалуйста, html код получившейся странички!
И узкой и широкой...
Дружище, скинь, пожалуйста, html код получившейся странички!
И узкой и широкой...
широкая :
<!DOCTYPE HTML> <head> <title>Контроль и управление домом</title> <meta name="description" content="Контроль и управление домом"/> <meta http-equiv="refresh" content="15; url=/"> <meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-status-bar-style" content="default"> <meta name="viewport" content="width=device-width, user-scalable=no"> <style type="text/css"> html { height:100%; } body { height: 100%; margin: 0; font-family: helvetica, sans-serif; -webkit-text-size-adjust: none; } body { -webkit-background-size: 100% 21px; background-color: #c5ccd3; background-image: -webkit-gradient(linear, left top, right top, color-stop(.75, transparent), color-stop(.75, rgba(255,255,255,.1)) ); -webkit-background-size: 7px; } .view { min-height: 100%; overflow: auto; } .header-wrapper { height: 64px; font-weight: bold; text-shadow: rgba(0,0,0,0.7) 0 -1px 0; border-top: solid 1px rgba(255,255,255,0.6); border-bottom: solid 1px rgba(0,0,0,0.6); color: #fff; background-color: #8195af; background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(255,255,255,.4)), to(rgba(255,255,255,.05)) ), -webkit-gradient(linear, left top, left bottom, from(transparent), to(rgba(0,0,64,.1)) ); background-repeat: no-repeat; background-position: top left, bottom left; -webkit-background-size: 100% 21px, 100% 22px; -webkit-box-sizing: border-box; } .header-wrapper h1 { text-align: center; font-size: 20px; line-height: 44px; margin: 0; } .group-wrapper { margin: 9px; aling: center; } .group-wrapper h2 { color: #4c566c; font-size: 17px; line-height: 0.8; font-weight: bold; text-shadow: #fff 0 1px 0; margin: 20px 10px 12px; } .group-wrapper h3 { color: #4c566c; font-size: 12px; line-height: 1; font-weight: bold; text-shadow: #fff 0 1px 0; margin: 20px 10px 12px; } .group-wrapper h4 { color: #212121; font-size: 14px; line-height: 1; font-weight: bold; text-shadow: #aaa 1px 1px 3px; margin: 5px 5px 5px; } .group-wrapper table { background-color: #fff; -webkit-border-radius: 10px; -moz-border-radius: 10px; -khtml-border-radius: 10px; border-radius: 10px; font-size: 17px; line-height: 20px; margin: 5px 0 5px; border: solid 1px #a9abae; padding: 11px 3px 12px 3px; margin-left:auto; margin-right:auto; -moz-transform :scale(1); -moz-transform-origin: 0 0; } .green-circle { display: block; height: 23px; width: 23px; background-color: #0f0; -moz-border-radius: 11px; -webkit-border-radius: 11px; -khtml-border-radius: 11px; border-radius: 11px; margin-left: 1px; background-image: -webkit-gradient(linear, 0% 0%, 0% 90%, from(rgba(46, 184, 0, 0.8)), to(rgba(148, 255, 112, .9)));@ border: 2px solid #ccc; -webkit-box-shadow: rgba(11, 140, 27, 0.5) 0px 10px 16px; -moz-box-shadow: rgba(11, 140, 27, 0.5) 0px 10px 16px; /* FF 3.5+ */ box-shadow: rgba(11, 140, 27, 0.5) 0px 10px 16px; /* FF 3.5+ */ } .black-circle { display: block; height: 23px; width: 23px; background-color: #040; -moz-border-radius: 11px; -webkit-border-radius: 11px; -khtml-border-radius: 11px; border-radius: 11px; margin-left: 1px; -webkit-box-shadow: rgba(11, 140, 27, 0.5) 0px 10px 16px; -moz-box-shadow: rgba(11, 140, 27, 0.5) 0px 10px 16px; /* FF 3.5+ */ box-shadow: rgba(11, 140, 27, 0.5) 0px 10px 16px; /* FF 3.5+ */ } .glare { position: relative; top: 1; left: 5px; -webkit-border-radius: 10px; -moz-border-radius: 10px; -khtml-border-radius: 10px; border-radius: 10px; height: 1px; width: 13px; padding: 5px 0; background-color: rgba(200, 200, 200, 0.25); background-image: -webkit-gradient(linear, 0% 0%, 0% 95%, from(rgba(255, 255, 255, 0.7)), to(rgba(255, 255, 255, 0))); } </style> </head> <body> <div class="view"> <div class="header-wrapper"> <table border="0" align="center"><tr><td><h4>Стиль страницы:</h4></td><td><INPUT TYPE="button" VALUE="широкая" onClick="parent.location='/?page1'"></td><td><INPUT TYPE="button" VALUE=" узкая " onClick="parent.location='/?page0'"></td></tr></table> </div> <div class="group-wrapper"> <h2 align="center" >Температура на улице 0.0 °C </h2> <FORM> <table border="0" align="center"> <tr><td rowspan=4><table border="0" align="center"> <tr> <td><h4>01. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd11'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld11'"></td> <td><div class='green-circle'><div class='glare'></div></div></td> </tr> <tr> <td><h4>02. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd12'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld12'"></td> <td><div class='green-circle'><div class='glare'></div></div></td> </tr> <tr> <td><h4>03. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd13'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld13'"></td> <td><div class='green-circle'><div class='glare'></div></div></td> </tr> <tr> <td><h4>04. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd14'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld14'"></td> <td><div class='green-circle'><div class='glare'></div></div></td> </tr> <tr> <td><h4>05. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd15'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld15'"></td> <td><div class='green-circle'><div class='glare'></div></div></td> </tr> <tr> <td><h4>06. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd16'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld16'"></td> <td><div class='green-circle'><div class='glare'></div></div></td> </tr> <tr> <td><h4>07. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd17'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld17'"></td> <td><div class='green-circle'><div class='glare'></div></div></td> </tr> <tr> <td><h4>08. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd18'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld18'"></td> <td><div class='green-circle'><div class='glare'></div></div></td> </tr> <tr> <td><h4>09. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd19'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld19'"></td> <td><div class='green-circle'><div class='glare'></div></div></td> </tr> <tr> <td><h4>10. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd20'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld20'"></td> <td><div class='green-circle'><div class='glare'></div></div></td> </tr> <tr> <td><h4>11. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd21'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld21'"></td> <td><div class='green-circle'><div class='glare'></div></div></td> </tr> <tr> <td><h4>12. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd22'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld22'"></td> <td><div class='green-circle'><div class='glare'></div></div></td> </tr> <tr> <td><h4>13. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd23'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld23'"></td> <td><div class='green-circle'><div class='glare'></div></div></td> </tr> <tr> <td><h4>14. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd24'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld24'"></td> <td><div class='green-circle'><div class='glare'></div></div></td> </tr> <tr> <td><h4>15. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd25'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld25'"></td> <td><div class='green-circle'><div class='glare'></div></div></td> </tr> <tr> <td><h4>16. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd26'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld26'"></td> <td><div class='green-circle'><div class='glare'></div></div></td> </tr> <tr> <td><h4>17. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd27'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld27'"></td> <td><div class='green-circle'><div class='glare'></div></div></td> </tr> <tr> <td><h4>18. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd28'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld28'"></td> <td><div class='green-circle'><div class='glare'></div></div></td> </tr> <tr> <td><h4>19. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd29'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld29'"></td> <td><div class='green-circle'><div class='glare'></div></div></td> </tr> <tr> <td><h4>20. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd30'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld30'"></td> <td><div class='green-circle'><div class='glare'></div></div></td> </tr> <tr> <td><h4>21. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd31'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld31'"></td> <td><div class='green-circle'><div class='glare'></div></div></td> </tr> <tr> <td><h4>22. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd32'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld32'"></td> <td><div class='green-circle'><div class='glare'></div></div></td> </tr> <tr> <td><h4>23. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd33'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld33'"></td> <td><div class='green-circle'><div class='glare'></div></div></td> </tr> <tr> <td><h4>24. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd34'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld34'"></td> <td><div class='green-circle'><div class='glare'></div></div></td> </tr> <tr> <td colspan=2><INPUT TYPE="button" VALUE="Включить ВСЁ" onClick="parent.location='/?H100'"></td> <td colspan=2><INPUT TYPE="button" VALUE="Выключить ВСЁ" onClick="parent.location='/?L100'"></td> <td></td> <td></td> </tr> </table> </td><td height="86"><table border="0" align="center"> <tr><td></td><td><h3>текущая</h3></td><td><h3>обогрев</h3></td><td><h3>желаемая</h3></td></tr><tr><td><h4>Первый этаж:</h4></td><td align="center">20.0 °C</td><td align="center"><font color=green><b>ВКЛ</b></font></td> <td align="center"> 22 °C</td> </tr><tr><td><h4>Установить:</h4></td> <td colspan=3><table border="0"><tr><td><INPUT TYPE="button" VALUE="0" onClick="parent.location='/?t1-00'"></td> <td><INPUT TYPE="button" VALUE="5" onClick="parent.location='/?t1-05'"></td> <td><INPUT TYPE="button" VALUE="10" onClick="parent.location='/?t1-10'"></td> <td><INPUT TYPE="button" VALUE="20" onClick="parent.location='/?t1-20'"></td> <td><INPUT TYPE="button" VALUE="22" onClick="parent.location='/?t1-22'"></td> <td><INPUT TYPE="button" VALUE="24" onClick="parent.location='/?t1-24'"></td></tr></table></td></tr><tr><td><h4>Точно:</h4></td> <td colspan=3><form><input type=text name=t1- size=10> <input type=submit value=ОК> </form></td></tr></table> </td></tr><tr><td height="86"><table border="0" align="center"> <tr><td></td><td><h3>текущая</h3></td><td><h3>обогрев</h3></td><td><h3>желаемая</h3></td></tr><tr><td><h4>Второй этаж:</h4></td><td align="center">20.0 °C</td><td align="center"><font color=green><b>ВКЛ</b></font></td> <td align="center"> 24 °C</td> </tr><tr><td><h4>Установить:</h4></td> <td colspan=3><table border="0"><tr><td><INPUT TYPE="button" VALUE="0" onClick="parent.location='/?t2-00'"></td> <td><INPUT TYPE="button" VALUE="5" onClick="parent.location='/?t2-05'"></td> <td><INPUT TYPE="button" VALUE="10" onClick="parent.location='/?t2-10'"></td> <td><INPUT TYPE="button" VALUE="20" onClick="parent.location='/?t2-20'"></td> <td><INPUT TYPE="button" VALUE="22" onClick="parent.location='/?t2-22'"></td> <td><INPUT TYPE="button" VALUE="24" onClick="parent.location='/?t2-24'"></td></tr></table></td></tr><tr><td><h4>Точно:</h4></td> <td colspan=3><form><input type=text name=t2- size=10> <input type=submit value=ОК> </form></td></tr></table> </td></tr><tr><td height="86"><table border="0" align="center"> <tr><td></td><td><h3>текущая</h3></td><td><h3>обогрев</h3></td><td><h3>желаемая</h3></td></tr><tr><td><h4>Кухня:</h4></td><td align="center">0.0 °C</td><td align="center"><font color=red><b>ВЫКЛ</b></font></td> <td align="center"> 0 °C</td> </tr><tr><td><h4>Установить:</h4></td> <td colspan=3><table border="0"><tr><td><INPUT TYPE="button" VALUE="0" onClick="parent.location='/?t3-00'"></td> <td><INPUT TYPE="button" VALUE="5" onClick="parent.location='/?t3-05'"></td> <td><INPUT TYPE="button" VALUE="10" onClick="parent.location='/?t3-10'"></td> <td><INPUT TYPE="button" VALUE="20" onClick="parent.location='/?t3-20'"></td> <td><INPUT TYPE="button" VALUE="22" onClick="parent.location='/?t3-22'"></td> <td><INPUT TYPE="button" VALUE="24" onClick="parent.location='/?t3-24'"></td></tr></table></td></tr><tr><td><h4>Точно:</h4></td> <td colspan=3><form><input type=text name=t3- size=10> <input type=submit value=ОК> </form></td></tr></table> </td></tr><tr><td height="86"><table border="0" align="center"> <tr><td></td><td><h3>1 этаж</h3></td><td><h3>2 этаж</h3</td><td><h3>кухня</h3</td><td><h3>баня</h3</td></tr><tr><td><h4>Влажность:</h4></td><td align="center"> 36 %</td> <td align="center"> 30 %</td> <td align="center"> 61 %</td> <td align="center"> 75 %</td> </tr></table> </td></tr></table> </FORM> <h3 align="center">©- Plagiary - <br> 774 KM - 2016 - V1.4 </h3></div> </div> </body> </html>узкая :
<!DOCTYPE HTML> <head> <title>Контроль и управление домом</title> <meta name="description" content="Контроль и управление домом"/> <meta http-equiv="refresh" content="15; url=/"> <meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-status-bar-style" content="default"> <meta name="viewport" content="width=device-width, user-scalable=no"> <style type="text/css"> html { height:100%; } body { height: 100%; margin: 0; font-family: helvetica, sans-serif; -webkit-text-size-adjust: none; } body { -webkit-background-size: 100% 21px; background-color: #c5ccd3; background-image: -webkit-gradient(linear, left top, right top, color-stop(.75, transparent), color-stop(.75, rgba(255,255,255,.1)) ); -webkit-background-size: 7px; } .view { min-height: 100%; overflow: auto; } .header-wrapper { height: 64px; font-weight: bold; text-shadow: rgba(0,0,0,0.7) 0 -1px 0; border-top: solid 1px rgba(255,255,255,0.6); border-bottom: solid 1px rgba(0,0,0,0.6); color: #fff; background-color: #8195af; background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(255,255,255,.4)), to(rgba(255,255,255,.05)) ), -webkit-gradient(linear, left top, left bottom, from(transparent), to(rgba(0,0,64,.1)) ); background-repeat: no-repeat; background-position: top left, bottom left; -webkit-background-size: 100% 21px, 100% 22px; -webkit-box-sizing: border-box; } .header-wrapper h1 { text-align: center; font-size: 20px; line-height: 44px; margin: 0; } .group-wrapper { margin: 9px; aling: center; } .group-wrapper h2 { color: #4c566c; font-size: 17px; line-height: 0.8; font-weight: bold; text-shadow: #fff 0 1px 0; margin: 20px 10px 12px; } .group-wrapper h3 { color: #4c566c; font-size: 12px; line-height: 1; font-weight: bold; text-shadow: #fff 0 1px 0; margin: 20px 10px 12px; } .group-wrapper h4 { color: #212121; font-size: 14px; line-height: 1; font-weight: bold; text-shadow: #aaa 1px 1px 3px; margin: 5px 5px 5px; } .group-wrapper table { background-color: #fff; -webkit-border-radius: 10px; -moz-border-radius: 10px; -khtml-border-radius: 10px; border-radius: 10px; font-size: 17px; line-height: 20px; margin: 5px 0 5px; border: solid 1px #a9abae; padding: 11px 3px 12px 3px; margin-left:auto; margin-right:auto; -moz-transform :scale(1); -moz-transform-origin: 0 0; } .green-circle { display: block; height: 23px; width: 23px; background-color: #0f0; -moz-border-radius: 11px; -webkit-border-radius: 11px; -khtml-border-radius: 11px; border-radius: 11px; margin-left: 1px; background-image: -webkit-gradient(linear, 0% 0%, 0% 90%, from(rgba(46, 184, 0, 0.8)), to(rgba(148, 255, 112, .9)));@ border: 2px solid #ccc; -webkit-box-shadow: rgba(11, 140, 27, 0.5) 0px 10px 16px; -moz-box-shadow: rgba(11, 140, 27, 0.5) 0px 10px 16px; /* FF 3.5+ */ box-shadow: rgba(11, 140, 27, 0.5) 0px 10px 16px; /* FF 3.5+ */ } .black-circle { display: block; height: 23px; width: 23px; background-color: #040; -moz-border-radius: 11px; -webkit-border-radius: 11px; -khtml-border-radius: 11px; border-radius: 11px; margin-left: 1px; -webkit-box-shadow: rgba(11, 140, 27, 0.5) 0px 10px 16px; -moz-box-shadow: rgba(11, 140, 27, 0.5) 0px 10px 16px; /* FF 3.5+ */ box-shadow: rgba(11, 140, 27, 0.5) 0px 10px 16px; /* FF 3.5+ */ } .glare { position: relative; top: 1; left: 5px; -webkit-border-radius: 10px; -moz-border-radius: 10px; -khtml-border-radius: 10px; border-radius: 10px; height: 1px; width: 13px; padding: 5px 0; background-color: rgba(200, 200, 200, 0.25); background-image: -webkit-gradient(linear, 0% 0%, 0% 95%, from(rgba(255, 255, 255, 0.7)), to(rgba(255, 255, 255, 0))); } </style> </head> <body> <div class="view"> <div class="header-wrapper"> <table border="0" align="center"><tr><td><h4>Стиль страницы:</h4></td><td><INPUT TYPE="button" VALUE="широкая" onClick="parent.location='/?page1'"></td><td><INPUT TYPE="button" VALUE=" узкая " onClick="parent.location='/?page0'"></td></tr></table> </div> <div class="group-wrapper"> <h2 align="center" >Температура на улице 0.0 °C </h2> <FORM> <table border="0" align="center"> <tr> <td><h4>01. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd11'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld11'"></td> <td><div class='green-circle'><div class='glare'></div></div></td> </tr> <tr> <td><h4>02. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd12'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld12'"></td> <td><div class='green-circle'><div class='glare'></div></div></td> </tr> <tr> <td><h4>03. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd13'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld13'"></td> <td><div class='green-circle'><div class='glare'></div></div></td> </tr> <tr> <td><h4>04. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd14'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld14'"></td> <td><div class='green-circle'><div class='glare'></div></div></td> </tr> <tr> <td><h4>05. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd15'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld15'"></td> <td><div class='green-circle'><div class='glare'></div></div></td> </tr> <tr> <td><h4>06. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd16'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld16'"></td> <td><div class='green-circle'><div class='glare'></div></div></td> </tr> <tr> <td><h4>07. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd17'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld17'"></td> <td><div class='green-circle'><div class='glare'></div></div></td> </tr> <tr> <td><h4>08. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd18'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld18'"></td> <td><div class='green-circle'><div class='glare'></div></div></td> </tr> <tr> <td><h4>09. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd19'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld19'"></td> <td><div class='green-circle'><div class='glare'></div></div></td> </tr> <tr> <td><h4>10. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd20'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld20'"></td> <td><div class='green-circle'><div class='glare'></div></div></td> </tr> <tr> <td><h4>11. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd21'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld21'"></td> <td><div class='green-circle'><div class='glare'></div></div></td> </tr> <tr> <td><h4>12. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd22'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld22'"></td> <td><div class='green-circle'><div class='glare'></div></div></td> </tr> <tr> <td><h4>13. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd23'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld23'"></td> <td><div class='green-circle'><div class='glare'></div></div></td> </tr> <tr> <td><h4>14. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd24'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld24'"></td> <td><div class='green-circle'><div class='glare'></div></div></td> </tr> <tr> <td><h4>15. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd25'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld25'"></td> <td><div class='green-circle'><div class='glare'></div></div></td> </tr> <tr> <td><h4>16. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd26'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld26'"></td> <td><div class='green-circle'><div class='glare'></div></div></td> </tr> <tr> <td><h4>17. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd27'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld27'"></td> <td><div class='green-circle'><div class='glare'></div></div></td> </tr> <tr> <td><h4>18. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd28'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld28'"></td> <td><div class='green-circle'><div class='glare'></div></div></td> </tr> <tr> <td><h4>19. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd29'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld29'"></td> <td><div class='green-circle'><div class='glare'></div></div></td> </tr> <tr> <td><h4>20. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd30'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld30'"></td> <td><div class='green-circle'><div class='glare'></div></div></td> </tr> <tr> <td><h4>21. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd31'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld31'"></td> <td><div class='green-circle'><div class='glare'></div></div></td> </tr> <tr> <td><h4>22. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd32'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld32'"></td> <td><div class='green-circle'><div class='glare'></div></div></td> </tr> <tr> <td><h4>23. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd33'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld33'"></td> <td><div class='green-circle'><div class='glare'></div></div></td> </tr> <tr> <td><h4>24. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd34'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld34'"></td> <td><div class='green-circle'><div class='glare'></div></div></td> </tr> <tr> <td colspan=2><INPUT TYPE="button" VALUE="Включить ВСЁ" onClick="parent.location='/?H100'"></td> <td colspan=2><INPUT TYPE="button" VALUE="Выключить ВСЁ" onClick="parent.location='/?L100'"></td> <td></td> <td></td> </tr> </table> <table border="0" align="center"> <tr><td></td><td><h3>текущая</h3></td><td><h3>обогрев</h3></td><td><h3>желаемая</h3></td></tr><tr><td><h4>Первый этаж:</h4></td><td align="center">20.0 °C</td><td align="center"><font color=green><b>ВКЛ</b></font></td> <td align="center"> 22 °C</td> </tr><tr><td><h4>Установить:</h4></td> <td colspan=3><table border="0"><tr><td><INPUT TYPE="button" VALUE="0" onClick="parent.location='/?t1-00'"></td> <td><INPUT TYPE="button" VALUE="5" onClick="parent.location='/?t1-05'"></td> <td><INPUT TYPE="button" VALUE="10" onClick="parent.location='/?t1-10'"></td> <td><INPUT TYPE="button" VALUE="20" onClick="parent.location='/?t1-20'"></td> <td><INPUT TYPE="button" VALUE="22" onClick="parent.location='/?t1-22'"></td> <td><INPUT TYPE="button" VALUE="24" onClick="parent.location='/?t1-24'"></td></tr></table></td></tr><tr><td><h4>Точно:</h4></td> <td colspan=3><form><input type=text name=t1- size=10> <input type=submit value=ОК> </form></td></tr></table> <table border="0" align="center"> <tr><td></td><td><h3>текущая</h3></td><td><h3>обогрев</h3></td><td><h3>желаемая</h3></td></tr><tr><td><h4>Второй этаж:</h4></td><td align="center">20.0 °C</td><td align="center"><font color=green><b>ВКЛ</b></font></td> <td align="center"> 24 °C</td> </tr><tr><td><h4>Установить:</h4></td> <td colspan=3><table border="0"><tr><td><INPUT TYPE="button" VALUE="0" onClick="parent.location='/?t2-00'"></td> <td><INPUT TYPE="button" VALUE="5" onClick="parent.location='/?t2-05'"></td> <td><INPUT TYPE="button" VALUE="10" onClick="parent.location='/?t2-10'"></td> <td><INPUT TYPE="button" VALUE="20" onClick="parent.location='/?t2-20'"></td> <td><INPUT TYPE="button" VALUE="22" onClick="parent.location='/?t2-22'"></td> <td><INPUT TYPE="button" VALUE="24" onClick="parent.location='/?t2-24'"></td></tr></table></td></tr><tr><td><h4>Точно:</h4></td> <td colspan=3><form><input type=text name=t2- size=10> <input type=submit value=ОК> </form></td></tr></table> <table border="0" align="center"> <tr><td></td><td><h3>текущая</h3></td><td><h3>обогрев</h3></td><td><h3>желаемая</h3></td></tr><tr><td><h4>Кухня:</h4></td><td align="center">0.0 °C</td><td align="center"><font color=red><b>ВЫКЛ</b></font></td> <td align="center"> 0 °C</td> </tr><tr><td><h4>Установить:</h4></td> <td colspan=3><table border="0"><tr><td><INPUT TYPE="button" VALUE="0" onClick="parent.location='/?t3-00'"></td> <td><INPUT TYPE="button" VALUE="5" onClick="parent.location='/?t3-05'"></td> <td><INPUT TYPE="button" VALUE="10" onClick="parent.location='/?t3-10'"></td> <td><INPUT TYPE="button" VALUE="20" onClick="parent.location='/?t3-20'"></td> <td><INPUT TYPE="button" VALUE="22" onClick="parent.location='/?t3-22'"></td> <td><INPUT TYPE="button" VALUE="24" onClick="parent.location='/?t3-24'"></td></tr></table></td></tr><tr><td><h4>Точно:</h4></td> <td colspan=3><form><input type=text name=t3- size=10> <input type=submit value=ОК> </form></td></tr></table> <table border="0" align="center"> <tr><td></td><td><h3>1 этаж</h3></td><td><h3>2 этаж</h3</td><td><h3>кухня</h3</td><td><h3>баня</h3</td></tr><tr><td><h4>Влажность:</h4></td><td align="center"> 36 %</td> <td align="center"> 30 %</td> <td align="center"> 61 %</td> <td align="center"> 75 %</td> </tr></table> </FORM> <h3 align="center">©- Plagiary - <br> 774 KM - 2016 - V1.4 </h3></div> </div> </body> </html>Особо умный: это же ни разу не веб-сервер, давайте не путать понятия. Это просто девайс, который выдаёт жёстко захардкоженную страницу по HTTP, всё (причём - никак не анализируя запрос, но про RFC вы просили не говорить, поэтому не буду, так и быть).
Никакого отношения к понятию WEB-сервер написанный код не имеет.
почитайте определение вэб сервера. То, что автор сделал есть обычные вэб сервер. Можно спорить про функционал и качество кода, но это совсем о другом
почитайте определение вэб сервера. То, что автор сделал есть обычные вэб сервер. Можно спорить про функционал и качество кода, но это совсем о другом
Предлагаю вам сделать то же самое, чтобы в будущем не утверждать подобной чуши.
Предлагаю вам сделать то же самое, чтобы в будущем не утверждать подобной чуши.
Я про веб серверы все знаю с 1993 года. Но хорошо, приведу не свои слова, а википедию:
здесь даже более простым языком, чем я бы написал. Устройство автора этому определению соответствует.
Предлагаю вам сделать то же самое, чтобы в будущем не утверждать подобной чуши.
Я про веб серверы все знаю с 1993 года. Но хорошо, приведу не свои слова, а википедию:
здесь даже более простым языком, чем я бы написал. Устройство автора этому определению соответствует.
Если вы внимательно посмотрите код автора, то вы увидите, что устройство автора этому определению не соответствует ни в малейшей мере. С такой же уверенностью можно утверждать, что обод на палке, который катает мальчик по дороге - это супербайк.
Спор, собственно, ни о чём - вы понадёргали откуда-то поверхностных знаний о веб-серверах, процитировали кусок из википедии и считаете, что всё, что этому куску бесполезного текста соответствует - веб-серверами? Ню-ню. Я давно заметил, что уровень большинства здесь общающихся, как бы это помягче выразиться - сильно ниже среднего. Видимо, и вы с девяносто третьего года не сильно подросли в профессиональном плане.
Даю задание на дом: самостоятельно выяснить, какие минимальные требования предъявляются к веб-серверу, каким RFC должна соответствовать его имплементация - думаю, это принесёт вам немного понимания и отобьёт желание называть каждую поделку веб-сервером.
Впрочем, особо и не надеюсь.
Если вы внимательно посмотрите код автора, то вы увидите, что устройство автора этому определению не соответствует ни в малейшей мере. С такой же уверенностью можно утверждать, что обод на палке, который катает мальчик по дороге - это супербайк.
на http запросы отвечает? html отдает? значит приведенному мной определению соотвествует
с вами нет необходимости спорить ибо вы не споршик, а пальцезагибатель. спорщик приводит аргументы, а не задрав нос раздает задания. впрочем правильно не надеетесь, спора не будет, все написанное мной написано не для вас, а для автора и читателей, здесь сообщество любителей, размером палки мериться здесь зазорно, не зазорно делиться опытом
автора поздравляю, хороший проект!
Подпишусь. Сам на полпути к этой задачке.
Автору респект, всем остальным, прежде чем критиковать труд другого - покажите свой. Нечего показывать - молчите в тряпочку.
Кстати насчет обмена опытом. Тоже сейчас написал устройство с ethernet интерфейсом. Само устройство на atmega128 и enc28j60. Код написан на Си, так вся программа немного не в тему.
Что в тему. Когда стал писать код генерации вэб страниц понял, что это какая то жесть) тучи строк по формированию куска текста и во первых надо одно и тоже делать много раз, особенно если страниц много, во вторых структура html документа нечитабельна ибо размазана
в итоге я за пару часов наьросал библиотеку шаблонов, суть в том, что html описывается одной большой строкой в PROGMEM. Внутри там где нужны данные я вставляю три символа - знак процентов и две шестнадцатиричные цифры. С сделал очень простой парсер который копирует шаблон в сеть делая вставки там где находит %. Вставка делается по другому массиву структур где описан тип данных и стоит ссылка на сами данные. Данные при этом могут быть какие угодно включая ссылки на функции или ссылки на реальные глобальные переменные программы. В итоге получилась гибкая быстрая система шаблонирования. Чуть позже я прикрутил к ней обработку GET запросов так, что простые типы данных например int достаточно описать один раз, чтобы и показывать и редактировать.
если кому интересно покажу код
кроме этого сделал простую систему конфигурирования структуры сайта - опять же в массиве структур описываю url страницы в привязке к ее шаблону. При получении запроса я извлекаю url и поиском нахожу нужный элемент массива и запускаю нужный шаблон. Если не нахожу - возвращаю заголовок с кодом 404
п.с. Хотя когда я так же писал для для atmega128 с enc28j60 в 30кб у меня влезло только простое приложение с nrf24 и захардкоченными настройками сети. А сейчас в 26кб у меня автоконфигурирование с dhcp/arp и DNS, ping списка хостов и три вэб странички управления и настроек
Други, а никто не пробовал слепить сайт на внешнем домене и на него передавать данные? Просто не пойму - рисовать страницы в ардуинке это типа экономия на домене?
Други, а никто не пробовал слепить сайт на внешнем домене и на него передавать данные? Просто не пойму - рисовать страницы в ардуинке это типа экономия на домене?
решение зависит от задачи. делать можно по разному, но что оптимально - зависит от задачи
сначала библиотечка
файл axpro_tmpl.h
файл axpro_tmpl.c
#include "axpro_tmpl.h" uint16_t (*_axpro_callback)(char* buffer, axpro_enum_type type, void* data) = NULL; void axpro_tmpl_regcallback(uint16_t(func)(char* buffer, axpro_enum_type type, void* data)) { _axpro_callback = func; } uint16_t _axpro_tmpl_value_fill(char* buffer, axpro_enum_type type, void* data) { volatile uint16_t len = 0; switch(type) { case axpro_type_ipaddress: len = sprintf_P(buffer, PSTR("%d.%d.%d.%d"), ((uint8_t*)data)[0], ((uint8_t*)data)[1], ((uint8_t*)data)[2], ((uint8_t*)data)[3]); break; case axpro_type_macaddress: len = sprintf_P(buffer, PSTR("%02X:%02X:%02X:%02X:%02X:%02X"), ((uint8_t*)data)[0], ((uint8_t*)data)[1], ((uint8_t*)data)[2], ((uint8_t*)data)[3], ((uint8_t*)data)[4], ((uint8_t*)data)[5]); break; case axpro_type_uint8: len = sprintf_P(buffer, PSTR("%d"), *((uint8_t*)data)); break; case axpro_type_uint16: len = sprintf_P(buffer, PSTR("%d"), *((uint16_t*)data)); break; case axpro_type_funcuint8: { uint8_t (*f)() = data; len = sprintf_P(buffer, PSTR("%d"), f()); break; } case axpro_type_int10: len = sprintf_P(buffer, PSTR("%d.%d"), *((int*)data) / 10, abs(*((int*)data))% 10); break; case axpro_type_int100: len = sprintf_P(buffer, PSTR("%d.%d"), *((int*)data) / 100, abs(*((int*)data))% 100); break; case axpro_type_pmstr: len = strlen_P((char*)data); strcpy_P(buffer, (char*)data); break; default: if(_axpro_callback != NULL) len = _axpro_callback(buffer, type, data); break; } return len; } uint8_t _axpro_tmpl_hex(char d) { if(d >= '0' && d <= '9') return d - '0'; if(d >= 'a' && d <= 'f') return 10 + d - 'a'; if(d >= 'A' && d <= 'F') return 10 + d - 'A'; return 255; } uint16_t axpro_tmpl_fill(char* buffer, const axpro_struct_value* pgmem_config, uint16_t config_size, const char* pgmem_tmpl) { volatile uint16_t len = 0; const char *ptr1, *ptr2; char *buf1; ptr1 = pgmem_tmpl; buf1 = buffer; while((ptr2 = strchr_P(ptr1, '%')) != NULL) { volatile char d1, d2; volatile uint8_t hex1, hex2; // copy first part of string before '%' if any len = ptr2 - ptr1; if(len) { strncpy_P(buf1, ptr1, len); buf1 += len; ptr1 = ptr2; } ptr1++; // extract value id d1 = pgm_read_byte(ptr1); if(!d1) break; // bad format, end of string d2 = pgm_read_byte(++ptr1); if(!d2) break; // bad format, end of string if(d1 == '%') { // % char *buf1 = d1; buf1++; continue; } ptr1++; hex1 = _axpro_tmpl_hex(d1); hex2 = _axpro_tmpl_hex(d2); if(hex1 == 255 || hex2 == 255) continue; // bad value ID, should be HEX, skip hex2 |= (hex1 << 4); // value ID if(hex2 >= config_size) continue; // ID exceeds config size buf1 += _axpro_tmpl_value_fill(buf1, pgm_read_byte(&pgmem_config[hex2].type), pgm_read_ptr(&pgmem_config[hex2].data)); } // copy rest of the text len = strlen_P(ptr1); if(len) strcpy_P(buf1, ptr1); len += buf1 - buffer; return len; } uint8_t _axpro_tmpl_save_get(const axpro_struct_value *pgmem_config, char* value) { void* ptr = pgm_read_ptr(&pgmem_config->data); switch(pgm_read_byte(&pgmem_config->type)) { case axpro_type_uint8: { int v; if(sscanf_P(value, PSTR("%d"), &v)) { *(uint8_t*)ptr = v; return 1; } } break; case axpro_type_uint16: { int v; if(sscanf_P(value, PSTR("%d"), &v)) { *(uint16_t*)ptr = v; return 1; } } break; case axpro_type_funcget: { void (*f)(char*) = ptr; f(value); } break; default: break; } return 0; } uint8_t axpro_tmpl_save_get(char* get, const axpro_struct_value* pgmem_config, uint16_t config_size) { char* str; uint8_t res = 0; while((str = strsep(&get, "&")) != NULL) { char* str_name; uint8_t hex1, hex2; if(str_name = strsep_P(&str, PSTR("=")), str == NULL) continue; //uart_debugf_3_P(PSTR("+++ name='%s' value='%s'\n"), str_name, str); if(strncmp_P(str_name, PSTR("0x"), 2)) continue; if(str_name[0] == 0 || str_name[1] == 0) continue; if(str_name[1] == 0) continue; if((hex1 = _axpro_tmpl_hex(str_name[2])) == 255) continue; if((hex2 = _axpro_tmpl_hex(str_name[3])) == 255) continue; if((hex2 |= (hex1 << 4)) >= config_size) continue; //uart_debugf_2_P(PSTR("+++ ID=0x%X\n"), hex2); res += _axpro_tmpl_save_get(&pgmem_config[hex2], str); } return res; }пример шаблона с формами редактирования
пример вызова из программы
uint16_t http_page(char* buffer, char* url) { uint8_t indx; uint16_t len = 0; for(indx = 0; indx < sizeof(pages)/sizeof(struct_page); indx++) if(!strcmp_P(url, pgm_read_ptr(&pages[indx].url))) break; if(indx == sizeof(pages)/sizeof(struct_page)) { // not found len = strlen_P(html_404); strcpy_P(buffer, html_404); } else { len = strlen_P(html_200ok); strcpy_P(buffer, html_200ok); //uart_debugf_3_P(PSTR("+++ size %d %d\n"), sizeof(tmpl_val_config), sizeof(axpro_struct_value)); len += axpro_tmpl_fill(&buffer[len], tmpl_val_config, sizeof(tmpl_val_config)/sizeof(axpro_struct_value), pgm_read_ptr(&pages[indx].template)); } return len; }пример конфигурации данных для подстановок в шаблоны
const axpro_struct_value tmpl_val_config[] PROGMEM = { { axpro_type_ipaddress, var.config.ip.ip_address }, // 00 ip_address { axpro_type_macaddress, var.config.ip.mac_address }, // 01 mac_address { axpro_type_ipaddress, var.config.ip.gw_ip_address }, // 02 gw_address { axpro_type_ipaddress, var.config.ip.netmask }, // 03 netmask { axpro_type_custom1, NULL }, // 04 rtc clock { axpro_type_int10, (void*)&var.termistor_temp}, // 05 termistor value { axpro_type_int100, (void*)&var.temperature_rtc}, // 06 rtc temperature value { axpro_type_uint8, (void*)&var.ethernet.ping_entry[ping_entry_gw].status}, // 07 GW ping errors { axpro_type_pmstr, (void*)dns_entry_name_ntp}, // 08 ntp server name { axpro_type_ipaddress, var.ethernet.dns_entry[dns_entry_ntp].ip}, // 09 NTP ip_address { axpro_type_uint8, (void*)&var.ethernet.ping_entry[ping_entry_check3].status}, // 0A NTP ping errors { axpro_type_pmstr, (void*)dns_entry_name_check1}, // 0B check1 server name { axpro_type_ipaddress, var.ethernet.dns_entry[dns_entry_check1].ip}, // 0C check1 ip_address { axpro_type_uint8, (void*)&var.ethernet.ping_entry[ping_entry_check1].status}, // 0D check1 ping errors { axpro_type_pmstr, (void*)dns_entry_name_check2}, // 0E check2 server name { axpro_type_ipaddress, var.ethernet.dns_entry[dns_entry_check2].ip}, // 0F check2 ip_address { axpro_type_uint8, (void*)&var.ethernet.ping_entry[ping_entry_check2].status}, // 10 check2 ping errors { axpro_type_custom2, rel_1a_get}, // 11 router relay status { axpro_type_custom2, rel_1b_get}, // 12 router relay status { axpro_type_custom2, rel_2a_get}, // 13 modem relay status { axpro_type_custom2, rel_2b_get}, // 14 modem relay status { axpro_type_pmstr, (void*)html_menu}, // 15 page menu { axpro_type_uint8, &var.config.ip.dhcp_timeout_sec}, // 16 dhcp timeout seconds { axpro_type_uint8, &var.config.timers.refresh_ping_sec}, // 17 ping refresh in minutes { axpro_type_uint8, (void*)&var.timers.refresh_ping_sec}, // 18 ping timer in minutes { axpro_type_uint8, &var.config.timers.refresh_dns_min}, // 19 dns refresh in minutes { axpro_type_uint8, (void*)&var.timers.refresh_dns_min}, // 1A dns timer in minutes { axpro_type_uint16, &var.config.timers.refresh_rtc_min}, // 1B rtc refresh in minutes { axpro_type_uint16, (void*)&var.timers.refresh_rtc_min}, // 1C rtc timer in minutes { axpro_type_uint16, &var.config.timers.power_on_min}, // 1D power on in minutes { axpro_type_uint16, (void*)&var.timers.power_on_min}, // 1E power timer in minutes { axpro_type_uint8, &var.config.timers.power_router_on_hour}, // 1F router power on in minutes { axpro_type_uint8, (void*)&var.timers.power_router_on_hour}, // 20 router power timer in minutes { axpro_type_uint8, &var.config.check.dns_retry_count}, // 21 dns retry count { axpro_type_uint8, &var.config.check.ping_retry_count}, // 22 dns retry count { axpro_type_funcuint8, (void*)powerlog_n }, // 23 records in power log { axpro_type_custom3, NULL}, // 24 log { axpro_type_funcget, (void*)power_both}, // 25 request power off both { axpro_type_funcget, (void*)power_modem}, // 26 request power off modem { axpro_type_uint8, &var.config.timers.power_off_sec} // 27 off time sec for relay };пример функции call back для обработки собственных типов данных обозначенных как custom
uint16_t http_tmpl_callback(char* buffer, axpro_enum_type type, void* data) { uint16_t len = 0; switch(type) { case axpro_type_custom1: { uint8_t y, m, d, w, ho, mi, se; DS3231GetFullDate(&y, &m, &d, &w); DS3231GetFullTime24(&ho, &mi, &se); len = sprintf_P(buffer, PSTR("%04d-%02d-%02d %02d:%02d.%02d"), 2000+y, m, d, ho, mi, se); } break; case axpro_type_custom2: { uint8_t (*f)() = data; if(f()) { len = 3; strcpy_P(buffer, PSTR("OFF")); } else { len = 2; strcpy_P(buffer, PSTR("ON")); } } break; case axpro_type_custom3: { uint8_t i; for(i = powerlog_n(); i > 0;) { struct_powerlog_entry entry; if(powerlog_get(&entry, --i)) { len += sprintf_P(buffer+len, PSTR("<tr><td>%02d.%02d</td><td>%02d:%02d</td><td>"), entry.month, entry.day, entry.hour, entry.minute); len += sprintf_P(buffer+len, reasons[entry.reason]); len += sprintf_P(buffer+len, PSTR("</td><td>")); len += sprintf_P(buffer+len, (entry.type==powerlog_type_both)?PSTR("both"):((entry.type==powerlog_type_modem)?PSTR("modem"):PSTR("none"))); len += sprintf_P(buffer+len, PSTR("</td></tr>")); } } } break; default: break; } return len; }ну и последнее - настройка дерева сайта
const char page_root[] PROGMEM = "/"; const char page_config[] PROGMEM = "/config"; const char page_status[] PROGMEM = "/log"; typedef struct { const char *url; const char *template; } struct_page; const struct_page pages[] PROGMEM = { { page_root, tmpl_root }, { page_config, tmpl_config }, { page_status, tmpl_status } };приведенный выше шаблон формирует вот такую страничку где отображаются и значения переменных и можно часть данных редактировать
Подпишусь. Сам на полпути к этой задачке.
Автору респект, всем остальным, прежде чем критиковать труд другого - покажите свой. Нечего показывать - молчите в тряпочку.
Я показывал уже, и толку? Там, кстати - хоть какое-то подобие HTTP-сервера реализовано. Но толку от того, что показывал - ноль: всё равно прибегают "обвинятели в пальцезагибательстве" и начинают нести ересь. Когда их тыкаешь носом - морщатся, задирают носики и обиженно плетутся в угол, дуя щёчки. Ну дети, чесслово.
Ещё раз показать? Мне несложно, вы только попросите.
Кстати насчет обмена опытом. Тоже сейчас написал устройство с ethernet интерфейсом. Само устройство на atmega128 и enc28j60. Код написан на Си, так вся программа немного не в тему.
Что в тему. Когда стал писать код генерации вэб страниц понял, что это какая то жесть) тучи строк по формированию куска текста и во первых надо одно и тоже делать много раз, особенно если страниц много, во вторых структура html документа нечитабельна ибо размазана
в итоге я за пару часов наьросал библиотеку шаблонов, суть в том, что html описывается одной большой строкой в PROGMEM. Внутри там где нужны данные я вставляю три символа - знак процентов и две шестнадцатиричные цифры. С сделал очень простой парсер который копирует шаблон в сеть делая вставки там где находит %. Вставка делается по другому массиву структур где описан тип данных и стоит ссылка на сами данные. Данные при этом могут быть какие угодно включая ссылки на функции или ссылки на реальные глобальные переменные программы. В итоге получилась гибкая быстрая система шаблонирования. Чуть позже я прикрутил к ней обработку GET запросов так, что простые типы данных например int достаточно описать один раз, чтобы и показывать и редактировать.
если кому интересно покажу код
кроме этого сделал простую систему конфигурирования структуры сайта - опять же в массиве структур описываю url страницы в привязке к ее шаблону. При получении запроса я извлекаю url и поиском нахожу нужный элемент массива и запускаю нужный шаблон. Если не нахожу - возвращаю заголовок с кодом 404
п.с. Хотя когда я так же писал для для atmega128 с enc28j60 в 30кб у меня влезло только простое приложение с nrf24 и захардкоченными настройками сети. А сейчас в 26кб у меня автоконфигурирование с dhcp/arp и DNS, ping списка хостов и три вэб странички управления и настроек
Поздравляю, вы открыли для себя SSI! Правда, как обычно - вырезанием гланд через жопу.
Други, а никто не пробовал слепить сайт на внешнем домене и на него передавать данные? Просто не пойму - рисовать страницы в ардуинке это типа экономия на домене?
Справедливости ради - ардуина отрисовку страниц не потянет, это делает клиентский софт, например, браузер (хотя есть куча как свободных, так и проприетарных отрисовщиков HTML, например, HTMLite).
А отдавать данные может и дуина, вопрос только в скоростях отдачи, да в более-менее грамотной реализации, например, пакетная передача данных и вычитывание их из внешнего хранилища (SD, как вариант) - тогда можно хоть фильму передать на пару гигабайт.
Спасибо ВСЕМ =)
и на него передавать данные? Просто не пойму - рисовать страницы в ардуинке
это типа экономия на домене?</p>
Приветствую, данная система используется на даче где выход на внешку очень
медленный, он появился то с большими танцами вокруг 4г антенн мачт и
прочего, и служит в основном для редкого подключения из вне, да даже
при хорошем пинге обращаться на внешний домен не так приятно как на
локальную страницу, страница и команды подгружаются мнговенно. Кстати html
код хранящийся во флеш заметно медленнее выдает страницу.
Назрел вопрос (не пинайте сразу): ресурс записи-чтения eeprom 100000
циклов, страница у меня обновляется каждые 15 секунд, т.е. 5760 раз в
сутки, значит ли это что через 17 суток eeprom крякнет? =)
ресурс записи-чтения eeprom 100000
циклов, страница у меня обновляется каждые 15 секунд, т.е. 5760 раз в
сутки, значит ли это что через 17 суток eeprom крякнет? =)
Вы пишете в eeprom каждые 15 секунд, или читаете из него? Если читаете - то всё нормально, если пишете каждые 15 секунд вызовом write, вместо put - то да, может крякнуть, ибо атмеловский даташит говорит о 100 000 write cycles. Может крякнуть - но не обязан, хотя, конечно, писать раз в 15 секунд в EEPROM - это жёстко :)
Поздравляю, вы открыли для себя SSI! Правда, как обычно - вырезанием гланд через жопу.
хм. Обясните откуда server side includes если у нас нет сервера? Вы уж определитесь есть сервер или нет, иначе с логикой заявлений сплошной шлах
а насчет жопы, где ваш пример? Доставайте, всем интересно
Поздравляю, вы открыли для себя SSI! Правда, как обычно - вырезанием гланд через жопу.
хм. Обясните откуда server side includes если у нас нет сервера? Вы уж определитесь есть сервер или нет, иначе с логикой заявлений сплошной шлах
а насчет жопы, где ваш пример? Доставайте, всем интересно
Так мы про ваш проект говорим или про проект ТС? Про SSI я говорил в контексте вашей похвальбы своим проектом - будьте внимательны и не садитесь в лужу так по-детски.
Насчёт примера - уже приводил ссылку, потрудитесь перечитать тему, там всё есть, если уж действительно интересно. Хотя, думаю, что нет - так, пальцы подзагнуть лишний раз ;)
Так мы про ваш проект говорим или про проект ТС? Про SSI я говорил в контексте вашей похвальбы своим проектом - будьте внимательны и не садитесь в лужу так по-детски.
Насчёт примера - уже приводил ссылку, потрудитесь перечитать тему, там всё есть, если уж действительно интересно. Хотя, думаю, что нет - так, пальцы подзагнуть лишний раз ;)
соревноваться с вами по умению сидеть в луже не вылезая я не готов. Зарании проигрываю
мой пример если следовать вашей логике тоже не вэб сервер. Он такого же порядка как у автора. Так что очередной прокол у вас
Специально прочитал всю тему. Вы из вразумительного привели только ссылку w3.org и маленький кусочек кода. Ни там ни там нет вашего примера вэб сервера.
для этого дам вам малюсенький совет: везде где используется жесткий текст в выводе(не переменные) используйте встроенный макрос,например ваша строчка
client.println("HTTP/1.1 200 OK");пишите такclient.println(F("HTTP/1.1 200 OK"));таким образом текст вшивается во влеш,а не в оперативку...
!!!СУПЕР!!! Мой проект спасен от нехватки памяти переменных!!! :)
pastry777 Спасибо!!
таким образом текст вшивается во влеш,а не в оперативку...
очень полезное замечание. Такая уж особенность у компилятора ардуины. Но позвольте сделать маленькую поправку. В оперативку нельзя ничего вшить... Если делать так как вы предлагаете данные (текст) будут использованы напрямую из флэш. А если так не делать, то при запуске ардуины они сначала из флэш будут скопированы в оперативку и только потом использованы. Т.е. Вшиваются данные во флэш в любом случае, но с вашим советом оперативка зазря не расходуется
в атмел студии где более информативная статистика при компиляции можно видеть, что замена одного на другое не влияет на расход флэш, но влияет на расход оперативки
соревноваться с вами по умению сидеть в луже не вылезая я не готов. Зарании проигрываю
мой пример если следовать вашей логике тоже не вэб сервер. Он такого же порядка как у автора. Так что очередной прокол у вас
Специально прочитал всю тему. Вы из вразумительного привели только ссылку w3.org и маленький кусочек кода. Ни там ни там нет вашего примера вэб сервера.
Слушай, уймись уже, птица-говорун-поносник. Я где-то говорил, что написал полноценный веб-сервер? Ты бредишь как сивый мерин, срочно слезай с наркотиков! Я говорил, помнится, что нельзя называть всякую поделку веб-сервером, ибо есть, в конце концов, разумный и необходимый минимум имплементации для того, чтобы называться веб-сервером. Впрочем, тебя всё равно не унять, ты по ходу буйный.
Ты чего ко мне прицепился-то? Хочешь моего кода увидеть? Так я не скрываю, вот в этом конкретном проекте есть куски говнокода, которые хотя в какой-то степени реализуют жалкое подобие начатков веб-сервера, и то - я прекрасно понимаю, что RFC он не соответствует, поэтому и не называю сиё поделие веб-сервером: https://github.com/Porokhnya/GreenhouseProject
Уймись уже, плз. Для вас, буйнопомешанных на веб-серверах, лично готов покаяться и признать, что нихера вы веб-сервера не написали. Устроит?
Слушай, уймись уже, птица-говорун-поносник. Я где-то говорил, что написал полноценный веб-сервер? Ты бредишь как сивый мерин, срочно слезай с наркотиков! Я говорил, помнится, что нельзя называть всякую поделку веб-сервером, ибо есть, в конце концов, разумный и необходимый минимум имплементации для того, чтобы называться веб-сервером. Впрочем, тебя всё равно не унять, ты по ходу буйный.
Ты чего ко мне прицепился-то? Хочешь моего кода увидеть? Так я не скрываю, вот в этом конкретном проекте есть куски говнокода, которые хотя в какой-то степени реализуют жалкое подобие начатков веб-сервера, и то - я прекрасно понимаю, что RFC он не соответствует, поэтому и не называю сиё поделие веб-сервером: https://github.com/Porokhnya/GreenhouseProject
Уймись уже, плз. Для вас, буйнопомешанных на веб-серверах, лично готов покаяться и признать, что нихера вы веб-сервера не написали. Устроит?
Вы опустились до личных оскорблений. Мне вас жаль. Больше никогда мне не пишите, а то ведь могу найти в оффлайне и взять сполна за словоблудие.