Apricancello con 3 funzioni differenti

Ciao ragazzi, chiedo il vostro aiuto per il progetto in questione.
Ho la necessità di creare un sistema che mi permette di aprire il cancello tramite internet con Arduino + ENC28J60.

Ho trovato un progetto che vedete di seguito, che mi permette di fare ciò, ma quello che servirebbe a me sarebbe leggermente differente, ovvero:

Devo poter avere 3 funzioni differenti:

1- “Apri ORA” Apri il cancello e dopo 2 min deve andare in OFF il Relè (quindi deve chiudersi)
2- “Apri per 1h” apri il cancello e deve aprire ogini 5 min per 1h e poi andare in OFF definitivamente
3- “apri tra 30 sec” apre tra 3 sec e dopo 2 min chiude

Sapreste aiutarmi gentilmente a modificare questo sketch?
Grazie mille, sono nelle vostre mani :slight_smile: :slight_smile: :slight_smile:

/*
Controllo Luci 1.0

Sketch per il controllo remoto di una lampada da Arduino.

Pietro Lodi Rizzini
Dicembre 2015
*/
#include <EtherCard.h>

static byte mymac[] = {0xDA,0xDB,0xDC,0x01,0x02,0x03}; //definizione dei parametri base per la connessione alla rete
static byte myip[] = {192,168,1,200};
static byte gwip[] = {192,168,1,254};

byte Ethernet::buffer[700];

const int ledPin = 2;
boolean ledStatus;

char* on = "ON";
char* off = "OFF";
char* statusLabel;
char* buttonLabel;

void setup () {

Serial.begin(57600);
Serial.println("Controllo Luci");
if (ether.begin(sizeof Ethernet::buffer, mymac) == 0)
Serial.println( "Failed to access Ethernet controller"); //avviso via seriale di eventuali errori (solo per debug)
ether.staticSetup(myip, gwip); //configurazione IP statico (no DHCP) e IP del gateway
ether.hisport = 80; // porta default HTTP

Serial.println();

pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, LOW);
ledStatus = false;
}

void loop() {

word len = ether.packetReceive();
word pos = ether.packetLoop(len);

if(pos) {

if(strstr((char *)Ethernet::buffer + pos, "GET /?status=ON") != 0) {
Serial.println("Received ON command");
ledStatus = true;
}

if(strstr((char *)Ethernet::buffer + pos, "GET /?status=OFF") != 0) {
Serial.println("Received OFF command");
ledStatus = false;
}

if(ledStatus) {
digitalWrite(ledPin, HIGH);
statusLabel = on;
buttonLabel = off;
} else {
digitalWrite(ledPin, LOW);
statusLabel = off;
buttonLabel = on;
}

BufferFiller bfill = ether.tcpOffset();
bfill.emit_p(PSTR("HTTP/1.0 200 OK\r\n"
"Content-Type: text/html\r\nPragma: no-cache\r\n\r\n"
"<html><head><title>Controllo Luci</title></head>"
"<body>Stato Luci: $S "
"<a href=\"/?status=$S\"><input type=\"button\" value=\"$S\"></a>"
"</body></html>"
), statusLabel, buttonLabel, buttonLabel);
ether.httpServerReply(bfill.position());
}
}

Io ti aiuto, però prima butta nella spazzatura la ENC28J60, perchè è spazzatura :slight_smile:

Nooooo dai, ormai l'ho acquistata ahahah

Prova, cambiarai anche Tu fra poco idea.

Poi mi dai il Tuo IP e Ti apro e chiudo il cancello da Bolzano.
Stai programmando una pagina pubblica che ognuno puó accedere.

Prendi un Raspberry PI e fai almeno un minimo di connessione shttp e password.

Ciao Uwe

Per la sicurezza non è un problema ma preferisco farlo con quello che ho a disposizione. Come posso fare secondo voi ?

Ragazzi nessuno sa aiutarmi?

la sicurezza non è un problema anche perché arduino per ora è settato su 192.168 che è lan interna quindi dall esterno prima devi autenticarti e farti proiettare nella rete locale o creare un tunnel. a meno che tu non faccia la stupidata di inoltrarti la porta e basta.
detto questo non è scopo del forum scrivere codice controterzi.... per questo non ti rispondono... prova tu e se hai problemi ti aiuteranno ma la programmazione intesa come disciplina deve essere del tuo sacco

qsecofr:
detto questo non è scopo del forum scrivere codice controterzi… per questo non ti rispondono… prova tu e se hai problemi ti aiuteranno ma la programmazione intesa come disciplina deve essere del tuo sacco

ESATTO !!!

>Onlysteg: ti prego di considerare che, purtroppo qui NON funziona così …
qui nessuno scrive software per conto terzi o realizza schemi su ordinazione, ma si aiuta chi viene qui a correggere/ottimizzare il software che lui scrive o gli schemi che lui realizza :slight_smile:

Se non hai mai sviluppato su Arduino, puoi cominciare con QUESTO proseguire con QUESTO e puoi scaricarti QUESTO libro o QUESTO (… tranquillo, è un sito legale, purché per esclusivo uso PERSONALE) … dopo di che puoi cominciare a scrivere il tuo programma, metterlo qui (… mi raccomando, sempre racchiuso tra i tag CODE che, in fase di edit, ti inserisce il bottone </> … primo a sinistra) e chiedere aiuto sui punti che non ti funzionano o che non capisci.

Guglielmo

P.S.: … e non trascurare gli esempi dell’IDE … che spesso forniscono le basi per la soluzione … :wink:

OK va bene, grazie mille ragazzi provvedo a creare qualcosa e ci aggiorniamo per eventuali consigli :slight_smile:

Ciao a tutti ragazzi, ho iniziato a modificare il progetto ma non riesco ad andare avanti, vi pongo il problema:
Ho impostato che dopo aver aperto il cancello in automatico dopo una (PAUSA) di 1200mllsec torna in OFF, funziona ma il problema è che l'URL della pagina rimane /?status=APRI e ovviamente se ricarico la pagina da uno smartphone lo riapre e posi si richiude.
Come faccio per far ricaricare la pagina e farla tornare in OFF?

if(ledStatus) {
digitalWrite(ledPin, HIGH);
statusLabel = on;
buttonLabel = off;
delay (Pausa );
digitalWrite(ledPin, LOW);
Serial.println("Received OFF command");
ledStatus = false;
statusLabel = off;
buttonLabel = on;

} 


else {
digitalWrite(ledPin, LOW);
statusLabel = off;
buttonLabel = on;
}

non entro nel merito del refresh "continuo" della pagina HTML ma noto che hai fatto un delay e poi hai ripristinato uno stato di off. Durante il delay l'arduino sta bloccato in un ciclo senza fare un tubo: non accetta richieste di alcun genere, sta li fermo.
Quindi quanto tu accendi il relay questo si accende per 1 secondo, tu durante questo secondo non potrai fare nulla ne vedrai nessun flusso html e dopo ritornerà a stato off inesorabilmente.
In pratica per fare i delay non devi usare la funzione delay ma devi fare un uso accorto della funzione millis (studia l'esempio blinkwithoutdelay)

Ho provato ad utilizzare quell’esempio ma nulla :confused: :confused: :confused:

if(pos) {

if(strstr((char *)Ethernet::buffer + pos, "GET /?status=APRI") != 0) {
Serial.println("Received ON command");
ledStatus = true;

}

if(strstr((char *)Ethernet::buffer + pos, "GET /?status=CHIUDI") != 0) {
Serial.println("Received OFF command");
ledStatus = false;
}

if (currentMillis - previousMillis >= interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;
    
if(ledStatus) {
digitalWrite(ledPin, HIGH);
statusLabel = on;
buttonLabel = off;

if (currentMillis - previousMillis >= interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;
if (ledStatus == LOW) {
      ledStatus = HIGH;
    } else {
      ledStatus = LOW;
   }
  }
 }
digitalWrite(ledPin, LOW);
Serial.println("Received OFF command");
ledStatus = false;
statusLabel = off;
buttonLabel = on;

} 


else {
digitalWrite(ledPin, LOW);
statusLabel = off;
buttonLabel = on;
}

BufferFiller bfill = ether.tcpOffset();
bfill.emit_p(PSTR("HTTP/1.0 200 OK\r\n"
"Content-Type: text/html\r\nPragma: no-cache\r\n\r\n"
"<html><head><title>Domotica Gadaleta</title></head>"
"<body>Cancello: $S "
"<a href=\"/?status=$S\"><input type=\"button\" value=\"$S\"></a>"
"</body></html>"
), statusLabel, buttonLabel, buttonLabel);
ether.httpServerReply(bfill.position());
}
}

formatta il codice se no impazziamo tutti... e qui secondo me se formatti il codice ti rendi conto che:

if (currentMillis - previousMillis >= interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;
    
if(ledStatus) {
digitalWrite(ledPin, HIGH);

...bla bla bla

l'if(ledStatus) viene eseguito se e solo se il millis è scaduto... volevi una cosa del genere?

si si esatto grazie, ma non funziona questo è il problema. Inoltre la pagina rimane su /?status=APRI invece voglio che debba tornare su /?status=CHIUDI dopo i tot millisecondi impostati

una roba per volta: prima fallo funzionare... quello non funziona perchè imho hai messo male gli if... poi per l'aggiornamento dell'html si vedrà.

Buonasera ragazzi, ammetto che sto impazzendo davvero dietro a questo codice da cui non riesco ad uscirne.
Questo è quello che ho creato usando la funzione mills ma continua a non andare :confused: :confused: :confused:

/*
Controllo Luci 1.0

Sketch per il controllo remoto di una lampada da Arduino.

Pietro Lodi Rizzini
Dicembre 2015
*/
#include <EtherCard.h>

int Pausa = 1200;

static byte mymac[] = {0xDA,0xDB,0xDC,0x01,0x02,0x03}; //definizione dei parametri base per la connessione alla rete
static byte myip[] = {192,168,1,150};
static byte gwip[] = {192,168,1,254};

byte Ethernet::buffer[700];

const int ledPin = 2; //pin di uscita n2
boolean ledStatus;
unsigned long previousMillis = 0;        // will store last time LED was updated
const long interval = 8000;           // interval at which to blink (milliseconds)

char* on = "APRI";
char* off = "CHIUDI";
char* statusLabel;
char* buttonLabel;

void setup () {

Serial.begin(57600);
Serial.println("Domotica Gadaleta");
if (ether.begin(sizeof Ethernet::buffer, mymac) == 0)
Serial.println( "Failed to access Ethernet controller"); //avviso via seriale di eventuali errori (solo per debug)
ether.staticSetup(myip, gwip); //configurazione IP statico (no DHCP) e IP del gateway
ether.hisport = 90; // porta default HTTP

Serial.println();

pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, LOW);
ledStatus = false;
}

void loop() {

word len = ether.packetReceive();
word pos = ether.packetLoop(len);
unsigned long currentMillis = millis();

if(pos) {

if(strstr((char *)Ethernet::buffer + pos, "GET /?status=APRI") != 0) {
Serial.println("Received ON command");
ledStatus = true;

}

if(strstr((char *)Ethernet::buffer + pos, "GET /?status=CHIUDI") != 0) {
Serial.println("Received OFF command");
ledStatus = false;
}

if (currentMillis - previousMillis >= interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;


if(ledStatus) {
digitalWrite(ledPin, HIGH);
statusLabel = on;
buttonLabel = off;

 if (ledStatus == true) {
      ledStatus = false;
    } else {
      ledStatus = false;
    }

 } 
}


else {
digitalWrite(ledPin, LOW);
statusLabel = off;
buttonLabel = on;
}

BufferFiller bfill = ether.tcpOffset();
bfill.emit_p(PSTR("HTTP/1.0 200 OK\r\n"
"Content-Type: text/html\r\nPragma: no-cache\r\n\r\n"
"<html><head><title>Domotica Gadaleta</title></head>"
"<body>Cancello: $S "
"<a href=\"/?status=$S\"><input type=\"button\" value=\"$S\"></a>"
"</body></html>"
), statusLabel, buttonLabel, buttonLabel);
ether.httpServerReply(bfill.position());
}
}

formatta il codice… Tu NON vuoi eseguire l if ledstatus SOLO quando scade il millis… almeno presumo…

Purtroppo non riesco a comprenderti, io voglio che quando da internet clicco su apri lui dopo tot secondi deve chiudere e ricaricare la pagina. Tutto qui e sto diventando davvero pazzo

Ragazzi ho deciso di abbandonare il progetto dato che la funzione mills non riesco ad utilizzarla.
Ho reinserito la funzione delay e funziona tutto perfettamente, ma adesso mi serve capire come effettuare il refresh della pagina web, sapete consigliarmi come fare?
Grazie mille.