Web e comandi telnet

Ciao a tutti! volevo porvi una domanda… è possibile passare dei valori(premendo un bottone) da pagina web a telnet?? Il mio scopo è quello di gestire delle uscite tramite telnet ricevendo però i valori da pagina web!!! Grazie…

si, è possibile :)

e il che non è poco!!! :)… sai per caso come potrei fare??? io ho fatto un programma che tramite comandi via telnet gestisce dei led(a=lampeggia led 2, b lampeggia led 3…), adesso però vorrei mandare i comandi dal web al telnet!!ti posto il codice… se mi puoi aiutare mi renderesti felicissimo!!! :slight_smile:

// variabili per la gestione delle uscite

#include <Firmata.h>

#include <Client.h>
#include <Ethernet.h>
#include <Server.h>

#include <SPI.h>
const int num_output = 3;
int stato_uscita = 0; // indica se l’uscita n-esima è ON o OFF
int comando_uscita = 0; // indica se l’uscita n-esima è abilitata a lampeggiare
byte mac = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip = { 192,168,1,134 };
byte gateway = {192,168,1,1};
byte subnet = {255,255,255,0};
Server server(77);

// i seguenti define servono solo a ricordare che l’uscita 1 è mappata sul primo bit, la 2 sul secondo e così via
#define OUT_1 0x01
#define OUT_2 0x02
#define OUT_3 0x04

// permette di utilizzare non necessariamente le prime 8 uscite digitali
int trascodifica_uscite[num_output] = {
// OUT_5
2, // OUT_6
3, // OUT_7
4}; // OUT_8

// variabili per le tempistiche
unsigned long istante_cambio_stato[num_output];
unsigned long tempo_on[num_output] = { 200, // OUT_1
200, // OUT_2
200 // OUT_3
}; // OUT_8

unsigned long tempo_off[num_output] = {
200, // OUT_6
200, // OUT_7
200}; // OUT_8

int rcv;
// elenco dei comandi
// i comandi per abilitare il blink devono essere consecutivi
#define BLINK_OUT_1 int(‘a’)
#define BLINK_OUT_2 int(‘b’)
#define BLINK_OUT_3 int(‘c’)
// può esserci un buco tra i comandi di blink e di disabilitazione
// i comandi per disabilitare il blink devono essere consecutivi
#define DISABLE_OUT_1 int(‘k’)
#define DISABLE_OUT_2 int(‘l’)
#define DISABLE_OUT_3 int(‘m’)

void gestione_comandi(int rcv)
{
if ((rcv >= BLINK_OUT_1) && (rcv <= BLINK_OUT_3))
{
comando_uscita |= (1 << (rcv - BLINK_OUT_1));
}
if ((rcv >= DISABLE_OUT_1) && (rcv <= DISABLE_OUT_3))
{
comando_uscita &= ~(1 << (rcv - DISABLE_OUT_1));
}
}

void gestione_uscite()
{
unsigned long currentMillis = millis();
int i;

for (i = 0; i < num_output ; i++)
{
if(comando_uscita & (1 << i))
{
// l’i-esima uscita deve lampeggiare
if (stato_uscita & (1 << i))
{
// l’i-esima uscita è ON
if((currentMillis - istante_cambio_stato) >= tempo_on*)
_
{_
digitalWrite(trascodifica_uscite, LOW);
stato_uscita ^= (1 << i);
istante_cambio_stato = currentMillis;
_ }
}
else*

* {
// l’i-esima uscita è OFF*

if((currentMillis - istante_cambio_stato) >= tempo_off*)*
* {_
digitalWrite(trascodifica_uscite, HIGH);
stato_uscita ^= (1 << i);
istante_cambio_stato = currentMillis;
_ }
}
}
else*

* {
// l’i-esima uscita deve essere disabilitata*

digitalWrite(trascodifica_uscite*, LOW);*
* }
}
}
void setup()
{*_

* Ethernet.begin(mac, ip, gateway, subnet);*
* server.begin();*
* byte i;*
* for (i = 0; i < num_output ; i++)
_ {_
pinMode(trascodifica_uscite, OUTPUT);
digitalWrite(trascodifica_uscite, LOW);
_ }
Serial.begin(9600);
}
void loop()
{
Client client = server.available();
server.write(rcv);
if (client) {*_

* int rcv = client.read();*
* gestione_comandi(rcv);
_ }_
gestione_uscite();
_}*_

per il codice usa i tag [code][/code] che rendono il codice più leggibile

Ora, il telnet non è altro che un programma che invia quello che scrivi via TCP, quindi non capisco perchè ti serva un ponte tra web->telnet... se il server è tuo, probabilmente stai usando un linguaggio server-side (php, asp, ecc..) che possono creare connessioni TCP (devono però essere abilitate nelle impostazioni). Se il server web è esterno e le connessioni esterne disabilitate la cosa non si può fare. Infine una soluzione potrebbe essere rendere l'arduino un server web, quindi quando ti colleghi ad esso con un browser vedi le tue belle pagine html con pulsanti ecc.. che ti permettono di inviare i comandi.

Ciao lesto ti ringrazio per la tua risposta! ti spiego brevemente quello che vorrei fare poi magari riuscirai a indirizzarmi meglio su quale strada è più consona!! vorrei che da dei bottoni di una pagina web vengono passati all'arduino dei valori e successivamente accesi dei led (logicamente però la parte html non si deve trovare nell'ide del programma nell'arduino). Avevo pensato al telnet solo perchè volevo utilizzarlo come punto di partenza, però sono aperto a qls tua idea su come fare, te ne sarei molto grato perchè sto impazzendo!! Grazie

secondo me la cosa migliore è trasformare l'arduino in un server web. So che un'altra persona sul forum italiano ci sta riuscendo.. dai uno sguardo alle discussioni recenti (prima o seconda pagina)

l'html ovviamente ti toccherà salvarlo su arduino.. o lo includi nel codice, oppure crei un comando che via seriale invii le pagine html e arduino se le salva in eeprom..

quindi: arduino si mette in ascolto della porta 80 e sulla seriale. Se riceve una pagina html via seriale, la salva su eeprom. Se riceve una connessione sulla porta 80 (richiesta get) controlla se ci sono dati da elaborare, altrimenti visualizza la pagina di default... la get è facile da elaborare perchè i dati vengono incollati a fine URL, fai qualche prova con una pagina HTML sul tuo pc con una form con un pulsante e un'area di testo, e vedi come si comporta il browser quando invii i dati

Ti ringrazio lesto.. ho già letto il post a cui ti riferisci però sono alle prime armi e non so veramente come muovermi. Per adesso ho solo fatto qlc programma che accende e spenge il led via etherneth shield!!!! :~

bhè allora il prossimo passo è proprio quello: ricevere una richesta HTTP e rispondere... c'è pure un pò di codice da cui puoi partire :)

Ok!!! ora ci provo!!! :)

Se ho capito bene vuoi mandare dati da una pagina web via telnet al tuo arduino…
Però immagino che tu non conosca alcun linguaggio di programm. web se hai aperto questo topic, ti do la pappa pronta :stuck_out_tongue:
Ovviamente devi avere un webserver che permette le connessioni in uscita (NON altervista) e che supporti il PHP (quasi tutti) e devi aprire le porte del router.

Ti posto parte del codice che uso per gestire le luci in casa mia:

Luce cucina: <a href="?a=1a">Accendi</a> | <a href="?a=1s">Spegni</a>

Luce Garage: <a href="?a=2a">Accendi</a> | <a href="?a=2s">Spegni</a>

Luce camera: <a href="?a=3a">Accendi</a> | <a href="?a=3s">Spegni</a>


<?php
$ip ="IP della tua connessione";
$porta = "porta arduino";
$comando = $_GET['a'];
$comandi = array("1a", "1s", "2a", "2s", "3a", "3s");// Per essere sicuro che vadano all' arduino solo comandi da te approvati..
if ($comando!="" && in_array($comando, $comandi)){
$fp = fsockopen($ip, $porta, $errno, $errstr, 30);
if (!$fp) {
    echo "$errstr ($errno)
\n";
} else {
    $out = $comando;
    $out .= "\r\n\r\n";
    fwrite($fp, $out);
    while (!feof($fp)) {
        echo fgets($fp, 128);
    }
    fclose($fp);
}
}
?>

Diciamo che via telnet era un 'idea, ma andrebbe bene anche dal web direttamente sull'arduino sempre utilizzando un web server. Ti ringrazio per il codice e ora guardo come utilizzarlo.. Apache andrebbe bene come web server??

se vuoi installarti un server web sul pc apache va benissimo, però installa anche il modulo PHP, e sappi che a pc spento non funziona nulla. Invece trasformando arduino in un server web, puoi collegarti da un qualsiasi pc in qualsiasi momento, basta che arduino sia acceso e collegato :)

Ah ok.. in effetti non è una cosa da poco questa!! ora cmq stavo provando a ricevere una richiesta http e rispondere, cerco di fare un passo alla volta!!! Lesto ho letto un tuo post precedente e volevo sapere se ql che dovevo utilizzare era questo:

http://arduino.cc/forum/index.php/topic,50721.15.html

A riguardo vorrei porti una domanda... quello che scrivo nella casella di testo dove viene salvato??

nella riga

client.println("<form name=\"input\" method=\"POST\">");

cambiala in

client.println("<form name=\"input\" method=\"GET\">");

a questo punto i tuoi dati verranno messi in coda all’url: quindi il browser invierà una richiesta simile a questa:

GET /?variabile=arduino HTTP/1.1
Host: 192.168.1.145

Ciao lesto! e ciao a tutti! sfruttando un pò di codice trovati in rete sono riuscito nell’intento comandare l’arduino da una pagina html esterna all’ide dell’arduino stesso. per adesso faccio accendere e spengere due led però vorrei provare a dargli dei tempi con il millis cosa che per adesso non riesco a fare. Non mi torna tanto perchè ho già fatto altri programmi con il millis(senza etherneth shield) e tutti funzoinanti mentre questo no. spero che tu mi possa aiutare!!! ti ringrazio anticipatamente… posto il codice.

if(readString.startsWith(r_pinOutRelay_up))  // questo è nel loop e la stringa presente in  r_pinOutRelay_up="GET /?out=5&status=1 HTTP/1.1"(dichiarata prima del setup) gliela passo tramite comando html;

	    {
	    digitalWrite(pinOutRelay, LOW);
                 if(tempo+5000<=now){  // la variabile now è dichiarata uguale a millis now=millis(); sia nel void setup sia all'inizio dell loop
                 digitalWrite(pinOutRelay, HIGH);
                 tempo=millis();
          }

dunque, non capisco (neanche guardando il codice) che cosa vuoi fare. per come è scritto ora quello che succede è il seguente: (sostituisco relay con led che è più intuitivo) arriva il comando, spegne il led, poniamo l'if vero, si accende il led, altrimenti resta spento arriva (di nuovo) il comando, spegne il led, poi l'if è vero se è passato più di 5000 millis dall'ultimo comando, e riaccende il led, altrimenti rimane spento

Se vuoi che il LED resti sempre acceso tranne per 5 secondi quando arriva il comando, allora l'if sul tempo va messo FUORI dall'if sul comando, perché possono anche passare ore prima che arrivi il prossimo comando, e il programma, se non arriva il comando, non controlla se è il caso di riaccendere il LED

Scusami ho invertito le cose prima accendo il led e dopo 5 secondi vorrei che si spengesse. semplicemente sarrebbe un delay usando il millis però. ti posto l’intero codice…

#include <SPI.h>
#include <Ethernet.h>


byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xBE };
byte ip[] = { 192 ,168 ,1 ,134 };
byte gateway[] = { 192 ,168 ,1 ,1 };
byte subnet[] = { 255 ,255 ,255 ,0 };
Server server(80); 

String readString = String(30);
String DOWN= "GET /?out=5&status=0 HTTP/1.1";// stringa richiamata dall'href html esterna all'ide
String UP = "GET /?out=5&status=1 HTTP/1.1";stringa richiamata dall'href html esterna all'ide

int acceso=5000;
unsigned long tempo=0;


void setup(){
Ethernet.begin(mac, ip, gateway, subnet);
pinMode(5, OUTPUT);
digitalWrite(5, LOW);
Serial.begin(9600);
} 

void loop(){
Client client = server.available();
if (client) {
while (client.connected()) {
if (client.available()) {
char c = client.read();
if (readString.length() < 30)
{
readString = readString + c;
}
if (c == '\n') {
Serial.print(readString);
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println();

if(readString.startsWith(UP))// viene richiamato il comando up per accendere il led
{Serial.print("\n 5 HIGH \n");
digitalWrite(5, HIGH);
tempo=millis();


}
if((millis()-tempo<=acceso))// millis di 5 secondi che però non funziona
  {
 
    digitalWrite(5,LOW);
   
  }

if(readString.startsWith(DOWN))// richiama la funzione down per spengere il led
{Serial.print("\n 5 LOW \n");
digitalWrite(5, LOW);
}



readString="";
client.stop();
}
}
}
}
}

tramite una pagina html esterna con due link href chiamo la stringa UP e DOWN.

ok, il problema è sempre lo stesso: metti l'if per controllare se c'è da spegnare il led all'interno dell'if che viene attivato solo se arriva un comando. Quindi arduino controlla se c'è da spegnere il led SOLO SE ARRIVA UN COMANDO! invece tu vuoi controllare se c'è da spegnare il led OGNI LOOP... buon coding :)

quindi il tuo consiglio è quello di metterlo tipo all'inizio del loop? controllando lo stato del led ?

si :slight_smile: