Go Down

Topic: Ethernet Webserver-Webclient advice needed (Read 347 times) previous topic - next topic

kingh03

Apr 18, 2018, 02:47 pm Last Edit: Apr 23, 2018, 12:13 pm by kingh03
Hello Arduino enthusiasts! I've been working on a keypad lock system for school lately and I need some advice. Basically, my code checks if the entered passcode is the same than a predefined passcode stored in a variable. I must code a local web server hosted by my Arduino Mega board that allows someone to change the correct passcode remotely via Ethernet. I have coded a working program, but I am sure it can be better designed or done in an easier way, this is why I'm asking for advice on how I could improve the performances of my program or make it shorter. If you need further explanation, let me know and I'd be happy to explain. Thank you!

Here's my code(or if you think it's plain, with colors):

Code: [Select]
#include <SPI.h>
#include <Ethernet.h>

byte mac[] = { 0x90, 0xA2, 0xDA, 0x0E, 0xA5, 0x7E };
IPAddress ip(192,168,1,250);
EthernetServer server(80);

String HttpHeader;
String nwCode="";
int curCode=19988;

void setup(){
  Serial.begin(9600);

  if(Ethernet.begin(mac)==0){
    Serial.println("Failed to use DHCP");
    Ethernet.begin(mac, ip);
  }
  Serial.println(Ethernet.localIP());
  HttpHeader="";
}

void loop(){

  EthernetClient client = server.available();
 
  if (client) {
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        if (HttpHeader.length() < 16){
           if(nwCode.length()<5){   
             if(isDigit(c)){
               nwCode.concat(c);
             }
           }
        }
        if (c == '\n') {
          if(nwCode.length()==5){
            curCode=nwCode.toInt();
            Serial.println(curCode);
          }
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("<html><head></head><body>");
          client.println();
          client.print("<form method=get>");
          client.print("<input type='password' name=code required><br>");
          client.print("<input type=submit value=submit></form>");
          client.print("</body></html>");
          nwCode="";

          client.stop();
        }
      }
    }
  }
}

In the void setup() I try to connect to the internet with DHCP, and if not, just connect with specified IP and MAC addresses. I also print the IP address used to host the webpage so we know what to type in our browser. Then in the void loop() I wait till someone visits the IP address and show them the webpage. Next, we read the incoming GET request(new passcode submitted) and make sure it's not any longer than 5 chars (correct passcode is 5 chars long), then I take only the numbers (remove GET and HTTP 1.1 from the request) and store them in the nvCode variable. Then if the request has ended and the passcode is 5 chars long, set the current code value to the new code(Without this step the serial monitor outputs 11 everytime the page is loaded or I make a request, I think this comes from the HTTP 1.1 and isDigit().)
I know there are better ways of doing this and the simpler and shorter the better, so any advice is much appreciated, thanks!

I have used Serial output for debugging purposes and to better show what the code is doing but I plan on removing that afterwards.
Here are the outputs:

This is what the Serial monitor outputs when I power the Arduino board.
(The IP is the address where the webpage is hosted)

This is the webpage hosted by the Arduino board.


After submitting a new passcode, it sends a GET request.


The Serial monitor output after sending the new passcode.


TL;DR the nwCode variable must collect the passcode entered in the HTML form and must set var curCode's value to it. nwCode being the new passcode code and curCode being the current passcode.

!!UPDATE!!
In fact, I have realized that my code is wrong somewhere because I can only change the passcode once, if I try to change it again after, my code doesn't pick up the wright numbers for some reason. Any help regarding this new issue would be appreciated.

Juraj

#1
Apr 18, 2018, 03:21 pm Last Edit: Apr 18, 2018, 07:24 pm by Juraj
replace String width c strings (zero terminated char arrays)
You can't write an Arduino sketch if you didn't learn programming. Not the language, but the concepts of programming - algorithms and data types.

PaulS

If the code works, what is the problem?

If someone uses a browser to change the code, and the Arduino resets, that change will be lost. Is that what you want?

If not, EEPROM is the solution.
The art of getting good answers lies in asking good questions.

kingh03

replace String width c strings (zero terminated char arrays)
I don't understand what you mean, could you explain please, thank you!

Juraj

the String class makes dynamic memory allocations and the memory segmentation of heap in the small memory of the mcu is hard to handle, which could lead to crash.

c-string is a char array where the text end is marked with value 0. everywhere where char* or const char* is required it is assumed to be a zero terminated c-string. a const char* s = "123" is the same as const char s[4]  = {'1', '2', '3', 0}

functions to work with c-strings are old C functions like strstr, strcmp, strcpy, sprintf etc., or you can try my new library CStringBuilder for printing the c-string the same way you print to Serial or network Client.

You can't write an Arduino sketch if you didn't learn programming. Not the language, but the concepts of programming - algorithms and data types.

Go Up