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 '10';
почему же не может,очень даже может...
а вот 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 вообще...а, увидел, вы так и делаете... Десятка приходит? Тяжко с телефона сидеть)
Вы меня извините, но ссылки у меня не оттображаются похоже=)
меняю в строке 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, добавляешь после неё:
После строки 288:
проверяешь - если вычитал H или L, то дальше все символы складываешь в command. Как только встретишь пробел, символ '\r' или символ '\n' - не сохраняешь этот символ в command, а смотришь, что у тебя там внутри, в твоём случае - вызываешь command.toInt() и проверяешь, что за число пришло.
Но, строго говоря, лучше делать это по-другому, смотри: каждый GET-запрос имеет параметры вида ключ=значение, эти параметры разделены символом '&'. Можно написать простенький класс, который выщемляет все параметры в массив, и потом уже работать с отдельными параметрами будет удобно очень. Вот кусок моего говнокода на этот случай:
Что касаемо реализации, то:
Благодарю! После праздников конечно было тяжело, но что то получилось)
и конечно есть вопрос =)
почему во время загрузки при чтении из флеш сохраненых состоянии пинов, 0, 2, и 4 байты всегда "1" с остальными все впорядке, пишутся и считываюся нормально
подпишусь. может и я когда нибудь страничку смогу сделать
хотя выглядит так просто. но это наверно первое неверное впечатление
и конечно есть вопрос =)
почему во время загрузки при чтении из флеш сохраненых состоянии пинов, 0, 2, и 4 байты всегда "1" с остальными все впорядке, пишутся и считываюся нормально
Сходу не нашёл проблемы с EEPROM, но код тяжело читать и сопровождать, поэтому так вот сразу и не скажу, к тому же цифры какие-то магические - 0, 2, 4.
Сходу не нашёл проблемы с EEPROM, но код тяжело читать и сопровождать, поэтому так вот сразу и не скажу, к тому же цифры какие-то магические - 0, 2, 4.
решил проблему увеличив начальный адрес байта флеш памяти в двух строках:
измененный скейтч:
Дружище, скинь, пожалуйста, html код получившейся странички!
И узкой и широкой...
Дружище, скинь, пожалуйста, 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
пример шаблона с формами редактирования
пример вызова из программы
пример конфигурации данных для подстановок в шаблоны
пример функции call back для обработки собственных типов данных обозначенных как custom
ну и последнее - настройка дерева сайта
приведенный выше шаблон формирует вот такую страничку где отображаются и значения переменных и можно часть данных редактировать
Подпишусь. Сам на полпути к этой задачке.
Автору респект, всем остальным, прежде чем критиковать труд другого - покажите свой. Нечего показывать - молчите в тряпочку.
Я показывал уже, и толку? Там, кстати - хоть какое-то подобие 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
Уймись уже, плз. Для вас, буйнопомешанных на веб-серверах, лично готов покаяться и признать, что нихера вы веб-сервера не написали. Устроит?
Вы опустились до личных оскорблений. Мне вас жаль. Больше никогда мне не пишите, а то ведь могу найти в оффлайне и взять сполна за словоблудие.