WebGate

WebGate

Ho realizzato questo progetto per risolvere diversi problemi con il cancello di casa, primo di tutto non trovavo mai il telecomando quando ne ho bisogno, non trovavo i telecomandi di ricambio ecc...

 

Allora mi è venuta l'idea di sacrificare un telecomando e unirlo con una scheda Arduino Ethernet, cosi da poter aprire il cancello da qualsiasi dispositivo collegato alla rete di casa e perché no anche da internet.

webgate01

Qui potete vedere il circuito interno del telecomando.

L'idea per controllare il telecomando dall'Arduino è semplice, cioè sostituire i pulsanti del telecomando con due transistor (BC337).

webgate02

Per fare le cose fatte bene ho saldato dei PIN al posto dei pulsati e dei contatti della pila.

Dopo di che ho creato uno Shield per interfacciare il telecomando con l'Arduino. 

webgate03

Come potete vedere sullo Shield ci sono i PIN di connessione con il telecomando , i transistor con le loro resistenze e un tasto di reset per l'Arduino che non fa mai male.

 webgate04 webgate05

Ecco qui i tre pezzi che formano il WebGate.

Naturalmente l'Arduino Ethernet dovrà essere alimentata a 12V e dovrà essere collegata alla rete di casa.



 

Ora passiamo alla programmazione dell'Arduino.

 WebGate si basa su un mini Web server che in base alla richiesta attiva i pulsanti del telecomando.

Per funzionare il WebGate necessita di una mini SD , sulla quale possiamo mettere la nostra pagina index.htm.

Sulla mini SD viene anche creato il file config.bin dove viene salvata e letta la configurazione della rete.

Inoltre è possibile aggiornare i file sulla mini SD mediate il programma curl direttamente dalla rete.

Accedendo all'indirizzo http://192.168.1.123/BTNONE si attiverà il bottone uno del telecomando o il bottone due tramite l'indirizzo http://192.168.1.123/BTNTWO .

Sketch Arduino :

#include <pins_arduino.h>
#include <SPI.h>
#include <Ethernet.h>
#include <Flash.h>
#include <SD.h>
#include <TinyWebServer.h>

#define SD_CS 4
#define ETHER_CS 10
#define btnone 8
#define btntwo 7
#define fileconf "config.bin"

//lan
#define mc1 0x90
#define mc2 0xA2
#define mc3 0xDA
#define mc4 0x0D
#define mc5 0x6D
#define mc6 0xD5

#define ip1 192
#define ip2 168
#define ip3 1
#define ip4 123

#define sb1 255
#define sb2 255
#define sb3 255
#define sb4 0

#define gt1 192
#define gt2 168
#define gt3 1
#define gt4 1

#define dn1 8
#define dn2 8
#define dn3 8
#define dn4 8

boolean has_filesystem = false;
Sd2Card card;
SdVolume volume;
SdFile root;
SdFile file;

TinyWebServer::PathHandler handlers[] = {
	{"/", TinyWebServer::GET, &index_handler },
	{"/upload/*", TinyWebServer::PUT, &TinyWebPutHandler::put_handler },
	{"/BTNONE*", TinyWebServer::GET, &btnone_handler },
	{"/BTNTWO*", TinyWebServer::GET, &btntwo_handler },
	{"/*", TinyWebServer::GET, &file_handler },
	{NULL}
};

const char* headers[] = {
	"Content-Length",
	NULL
};

TinyWebServer web = TinyWebServer(handlers, headers);

void send_file_name(TinyWebServer& web_server, const char* filename) {
	if (!filename) {
		web_server.send_error_code(404);
		web_server.println("Could not parse URL");
	} else {
		TinyWebServer::MimeType mime_type = TinyWebServer::get_mime_type_from_filename(filename);
		web_server.send_error_code(200);
		web_server.send_content_type(mime_type);
		web_server.end_headers();
		if (file.open(&root, filename, O_READ)) {	
			web_server.send_file(file);
			file.close();
		} else {
			web_server.print("Could not find file: "); web_server.println(filename);
		}
	}
}

void file_uploader_handler(TinyWebServer& web_server, TinyWebPutHandler::PutAction action, char* buffer, int size) {
	switch (action) {
		case TinyWebPutHandler::START:
			if (!file.isOpen()) {
				char* fname = web_server.get_file_from_path(web_server.get_path());
				if (fname) {
					file.open(&root, fname, O_CREAT | O_WRITE | O_TRUNC);
					free(fname);
				}
			}
		break;
		case TinyWebPutHandler::WRITE:
			if (file.isOpen()) {
				file.write(buffer, size);
			}
		break;
		case TinyWebPutHandler::END:
			file.sync();
			file.close();
	}
}

boolean file_handler(TinyWebServer& web_server) {
	char* filename = TinyWebServer::get_file_from_path(web_server.get_path());
	send_file_name(web_server, filename);
	free(filename);
	return true;
}

boolean btnone_handler(TinyWebServer& web_server) {
	digitalWrite(btnone ,HIGH); 
	delay(500);
	digitalWrite(btnone ,LOW);
	return index_handler(web_server);
}

boolean btntwo_handler(TinyWebServer& web_server) {
	digitalWrite(btntwo ,HIGH); 
	delay(500);
	digitalWrite(btntwo ,LOW);
	return index_handler(web_server);
}

boolean index_handler(TinyWebServer& web_server) {
	send_file_name(web_server, "index.htm");
	return true;
}

void setup() {

	pinMode(btnone, OUTPUT); 
	digitalWrite(btnone, LOW);

	pinMode(btntwo, OUTPUT);
	digitalWrite(btntwo, LOW);

	pinMode(SS_PIN, OUTPUT); 

	digitalWrite(SS_PIN, HIGH);

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

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

	// Initialize the Ethernet.
	byte mac[] = { mc1, mc2, mc3, mc4, mc5, mc6 }; 
	IPAddress ip(ip1,ip2,ip3, ip4);
	IPAddress gateway(gt1,gt2,gt3, gt4);
	IPAddress subnet(sb1, sb2, sb3, sb4);
	IPAddress dnspri(dn1, dn2, dn3, dn4);

	has_filesystem = false;

	if (!card.init(SPI_FULL_SPEED, SD_CS)) {//Card Failed
	} else {
		if (!volume.init(&card)) {//Volume Init Failed!
		} else {
			if (!root.openRoot(&volume)) {//Open Root Failed
			} else {
				has_filesystem = true;
				TinyWebPutHandler::put_handler_fn = file_uploader_handler;
				File myFile;
				if (file.open(&root, fileconf, O_READ)) {//read config file.
					mac[0] = file.read()-1;
					mac[1] = file.read()-1;
					mac[2] = file.read()-1;
					mac[3] = file.read()-1;
					mac[4] = file.read()-1;
					mac[5] = file.read()-1;
					ip = IPAddress(file.read()-1,file.read()-1,file.read()-1, file.read()-1);
					gateway = IPAddress(file.read()-1,file.read()-1,file.read()-1, file.read()-1);
					subnet = IPAddress(file.read()-1, file.read()-1, file.read()-1, file.read()-1);
					dnspri = IPAddress(file.read()-1, file.read()-1, file.read()-1, file.read()-1);
					file.close();
				} else {
					if (file.open(&root, fileconf, O_CREAT | O_WRITE | O_TRUNC)) {//write config file.
						//mac
						file.write(mc1+1);
						file.write(mc2+1);
						file.write(mc3+1);
						file.write(mc4+1);
						file.write(mc5+1);
						file.write(mc6+1);
						//ip
						file.write(ip1+1);
						file.write(ip2+1);
						file.write(ip3+1);
						file.write(ip4+1);
						//gateway
						file.write(gt1+1);
						file.write(gt2+1);
						file.write(gt3+1);
						file.write(gt4+1);
						//sub
						file.write(sb1+1);
						file.write(sb2+1);
						file.write(sb3+1);
						file.write(sb4+1);
						//dns
						file.write(dn1+1);
						file.write(dn2+1);
						file.write(dn3+1);
						file.write(dn4+1);

						file.close();
					}
				}
			}
		}
	}

	//Setting up the Ethernet card.
	Ethernet.begin(mac, ip, dnspri, gateway, subnet); 
	//Web server starting.
	web.begin();

}

void loop() {
	if (has_filesystem) {
		web.process();
	}
}
Esempio di index.htm :

<html>
	<head>
		<title>WEB-GATE</title>
		<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" />
		<meta name="HandheldFriendly" content="True" />
	</head>
	<body>
		<table style="padding: 0px; margin: 0px; width: 100%; height: 100%; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-spacing: 0px; background-color: black;" >
			<tr>
				<td style="width: 50%;height:100%;">
					<button style="width: 100%;height:100%;" onclick="top.location.href = './BTNONE'">BOTTONE UNO</button>
				</td>
				<td style="width: 50%;height:100%;">
					<button style="width: 100%;height:100%;" onclick="top.location.href = './BTNTWO'">BOTTONE DUE</button>
				</td>
			</tr>
		</table>
	</body>
</html>