Davide Rosa Hack
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.
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).
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.
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.
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.
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>