enc28J60 and Arduino (17)

by luca
29 comments

In some of the previous tutorials, you’re already learned how to program simple sketches to remotely control leds, relays… today I’m going to show you how to secure those projects with the addition of a password.

Web form

The webpage Arduino publishes contains a simple form, made by two buttons and an input field to type the password:

When you click the button, your browser sends to Arduino a POST command with the form data, besides some informations about the browser itself:

Notice in the screenshot above that data is concatenated using the & character and that the typed password is sent after the pwd= label.

Sketch

The program running on Arduino (you can find it in my repository on Github), do the following when it receives a new request from the network:

[checklist]

  • checks if it is a POST request
  • if so, extracts from the request’s body the password value and compares it with the one in memory
  • if the two password match, it extracts also which button (ON|OFF) was pressed
  • changes the output status
  • returns the HTML page

[/checklist]

In detail:

char* led_password = "SesamE";

the password is hardcoded in the sketch, by default it is SesamE

pinMode(led_pin, OUTPUT);
digitalWrite(led_pin, LOW);
led_status = false;

in the setup() the sketch initializes the PIN direction and the output status (off at first)

if(strstr((char *)Ethernet::buffer + pos, "POST /") != 0) {

then the sketch verifies – using the strstr() function – if the received packet contains the command POST /

char* password_position = strstr((char *)Ethernet::buffer + pos, "&pwd=");
if(password_position != 0) {
  strcpy(password, password_position + 5);
  if(strcmp(password, led_password) == 0) Serial.println("Valid password :)");

if so, the sketch searches for the string &pwd=; if that is found, it extracts the password and stores it in the password variable. The two passwords are then compared

if(strstr((char *)Ethernet::buffer + pos, "OFF=") != 0) {
digitalWrite(led_pin, LOW);
led_status = false;

if the password is correct and the packet contains the OFF= command, the output is switched off. A similar check is performed for the ON= command

if(led_status == true) bfill.emit_p(PSTR(
[...]

in the end, the HTML page is created dinamically using two if:

  • according to the output status, one of the two buttons is disabled (adding the disabled attribute)
  • if the password is incorrect, a warning message is displayed

Demo

Here are two screenshots about this project, one with a correct password and one with a wrong one:

Related Posts

29 comments

nasim Friday December 20th, 2013 - 10:43 AM

hi …
i just want to simulate …
how i get enc28j60 mac address for proteus simulation..

Reply
luca Monday December 23rd, 2013 - 08:41 AM

Hi Nasim,

I never used Proteus but the MAC I think you can use the same mac address I use in my sketches… while the IP address must belong to the same network (simulated one?) you’re using.

Reply
jmv Thursday January 23rd, 2014 - 05:26 PM

hi, luca, great site!.
how I send a TCP packet to a client tcp.
I intend to make a Modbus server.
sorry bad english.
thanks.

Reply
luca Monday January 27th, 2014 - 10:14 PM

Hi Jonas,

mmm are you asking how to send a tcp packet to a server? give a look to my examples, basically you have to “create” the packet in a Stash object and send to the server using the tcpSend() method.

Reply
Tony Saturday February 22nd, 2014 - 04:57 PM

Hi Luca

how to keep password remember? each time i press the button, the password cleared and i have to enter again and again to control the LED

Reply
luca Sunday March 2nd, 2014 - 01:44 PM

Hi Tony

you can include the password in the html page:

if(password_valid == true) bfill.emit_p(PSTR("

"), password);

Reply
Tunir Saha Saturday March 8th, 2014 - 08:04 AM

[backSoon]
DHCP failed
IP: 0.0.0.0
GW: 0.0.0.0
DNS: 0.0.0.0

Sir any explanation for this ? I don’t know how to figure this out.

Reply
luca Saturday March 15th, 2014 - 10:45 AM

Hi Tunir,

it seems Arduino can’t obtain an IP address from your DHCP: have you a DHCP server in your network?

Reply
meka Sunday April 27th, 2014 - 09:19 PM

luca
how to add multiple input
if i use 3 input type time
like this
“”
“”
“”
if i am runing com serial only see
ON=&tm1=01%3A02
i this only receive input time 1
do you any solution???
thanks luca

Reply
luca Tuesday April 29th, 2014 - 09:01 PM

hi meka, unfortunately your code was lost, by the way in this example you can see how I control two leds… you can easily adapt it for more outputs.

Reply
Krunal Wednesday May 14th, 2014 - 01:24 PM

Hi Luca…
Very Good Tutorials for a Ethernet beginner like me…
You have presented everything in very simple & understandable language.
Thanks a lot for posting them & making them available to all of us…
Have you compiled all the examples in one single document including codes?
can I get the link for the same?
Thanks a lot again…

Reply
luca Monday May 19th, 2014 - 08:30 PM

Hi Krunal,

all the examples are on Github, you can download a zip with all the sources from there.

Reply
sergio Friday July 11th, 2014 - 04:06 PM

hello, sorry for my english, I’m brasilian and were eliminated from the World Cup by Germany 7 x 1 shame. 🙁

you are my last hope, sorry.

I’m trying to connect a one arduno a ENC28J60 (http://www.dx.com/p/pcb-arduino-enc28j60-ethernet-module-blue-140971. U7_6DnWx3wI) module and a sd card.

The card will record data from a temperature sensor from time to time, so I can turn off the card most of the time.

Can you help me? I found a lot of theory about SPI but nothing practical that can help me, I am beginner.

I would be very grateful for your help, having seen his experience with the module ENC28J60, parabens, your site has helped much mem.

Thank you

Sergio

Reply
luca Monday July 14th, 2014 - 03:23 PM

Hi Sergio,

the only problem is if SD card and enc28j60 share the same “CS” pin… otherwise you can simply connect both to the other SPI pins without any problems. Are you using a shield for SD card?

Reply
Sérgio Monday July 14th, 2014 - 10:23 PM

Hi Luca, thanks for your reply.

I’m using a sd done with resistors like this: http://forum.allaboutcircuits.com/showthread.php?t=27913

Today I called just the network module and tried to control port 8 which is the default (on and off with LOW and HIGH) but could not.

pinMode (chipSelectRede, OUTPUT);
digitalWrite (chipSelectRede, HIGH);

It still works, also tried to connect on port 10 and the same thing.

Should not have the right network?

thanks for your help. I’m desperate for this to work.

Reply
luca Wednesday July 16th, 2014 - 08:41 AM

Hi Sergio,

which is the error you get from the sketch? Are you trying the most basic one (static or dinamic IP)?

Reply
sergio Wednesday July 16th, 2014 - 03:50 PM

hello, I’m using testeDHCP, did some adaptation.
Follow but he printa MAC and.

I realized that if I comment out the lines:
pinMode (SD_SS, OUTPUT); / / 8
digitalWrite (SD_SS, HIGH);
the sample back to work.

Thank you for everything

Code —-
#include
#include //add
#include //add

const int NW_SS = 10; //add
const int SD_SS = 4; //add
File myFile; //add

static byte mymac[] = { 0x74,0x69,0x69,0x2D,0x30,0x31 };

byte Ethernet::buffer[700];

void setup () {
Serial.begin(9600);
SPI.begin(); //add
Serial.println(“\n[testDHCP]”);

//add

Serial.println(“— STATUS —“);
pinMode(NW_SS, OUTPUT); //8
digitalWrite(NW_SS, HIGH);
Serial.print(“NW_SS apos pinMode = “);Serial.println(digitalRead(NW_SS));
pinMode(SD_SS, OUTPUT); //8
digitalWrite(SD_SS, HIGH);
Serial.print(“SD_SS apos pinMode = “);Serial.println(digitalRead(SD_SS));

digitalWrite(SD_SS, HIGH);
digitalWrite(NW_SS, LOW);

//add

Serial.print(“MAC: “);
for (byte i = 0; i < 6; ++i) {
Serial.print(mymac[i], HEX);
if (i < 5)
Serial.print(':');
}
Serial.println();

if (ether.begin(sizeof Ethernet::buffer, mymac, NW_SS) == 0)
Serial.println( "Failed to access Ethernet controller");

Serial.println("Setting up DHCP");
if (!ether.dhcpSetup())
Serial.println( "DHCP failed");

ether.printIp("My IP: ", ether.myip);
ether.printIp("Netmask: ", ether.netmask);
ether.printIp("GW IP: ", ether.gwip);
ether.printIp("DNS IP: ", ether.dnsip);

// testa_sd();
}

void loop () {}

/*
void testa_sd(){
Serial.print("Initializing SD card…");
if (!SD.begin(SD_SS)) {
Serial.println("initialization failed!");
return;
}
Serial.println("initialization done.");
if (SD.exists("example.txt")) {
Serial.println("example.txt exists.");
}
// open a new file and immediately close it:
Serial.println("Creating example.txt…");
myFile = SD.open("example.txt", FILE_WRITE);
myFile.close();
// chech if the file created
if (SD.exists("example.txt")){
Serial.println("example.txt createdexists.");
}
else {
Serial.println("example.txt doesn't exist.");
}
}
*/

Reply
Ricardo Sunday October 26th, 2014 - 08:18 PM

This post is perfect, literally! Sending info to the Arduino Webserver without having info on the url is a very good practice. There is a nice post on arduino forum by DaveO, with Zoomkat help, and they use millis() to provide session ID. Joining that with your code, we can make a login form and then turn off or on leds while the session is active. Maybe you can make one tutorial with this in mind. I’ll start my own and share it also.
Thanks.

Reply
Vlad Sunday February 22nd, 2015 - 03:02 PM

Hi,
Great stuff!

Please help:
I have a problem submitting from smartphones.
It doesn’t work.
I enter any password and it gives “Unknown command” when submitting.

br

Reply
luca Tuesday February 24th, 2015 - 08:54 PM

Hi Vlad, another user reported me the same problem: it was his provider that was blocking port 80, try changing the port arduino listens on (for example 8080) and let me know…

Reply
Alex Tuesday May 12th, 2015 - 10:52 AM

Hello Luca.

Can u implement locking for 15 sec. after 3 failed password attempts? Like routers …

Thnx.
🙂

Reply
Fabio Tuesday November 22nd, 2016 - 02:48 PM

perché quando carico questo progetto compare questo errore?

warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
char* led_password = “SesamE”;

grazie

Reply
luca Wednesday November 23rd, 2016 - 08:39 AM

Ciao Fabio, è solo un warning (avviso) che indica una conversione “deprecata”… dovrebbe comunque compilare giusto?

Reply
Fabio Thursday November 24th, 2016 - 08:12 AM

Compila carica da l’avviso si collega esce fuori il web server inserisci la password ma il led non si accende.
nel monitor scrive:

New POST request!
Unknown command 🙁

il bello è che fino a pochi giorni fa tutto funzionava correttamente nemmeno il warning compariva.

HO provato a caricai il tuo tutorial WebLed n.7 anche questo ora da lo stesso warning e non funziona
grazie

Reply
Fabio Tuesday November 29th, 2016 - 11:51 AM

Notizie cosa sbaglio?

Reply
Fabio Friday December 2nd, 2016 - 02:05 PM

Ora tutto chiaro con iMac e safari da errore:

Unknown command 🙁

mentre con iMac e chrome tutto funzionante!!!!

Reply
ronie Friday October 20th, 2017 - 09:34 AM

Can you publish/mail full code to me ? I wanted to see how exactly it is implemented.

Reply
luca Saturday October 21st, 2017 - 01:55 PM

Hi, as wrote in the article, the source code is available on Github.

Reply
lucadentella.it – ESP32 (21) – Mutua autenticazione Wednesday January 24th, 2018 - 01:45 PM

[…] soluzione classica (utilizzata anche in questo mio tutorial) è quella di richiedere l’inserimento di una password. Tale soluzione è molto semplice da […]

Reply

Leave a Comment

16 − 13 =