WebServer caricaere HTML su memoria esterna (I2C) con etherCard

Buona giornata, sto realizzando un "piccolo" web server con atmega2560, enc28J60, uso la libreria EtherCard.h ed ho provato gli esempi di [Luca Dentella enc28J60 & arduino].
L'esempio "_7_WebLed" sono riuscito ad eseguirlo, finché visualizzo un paio di pulsanti tutto bene, ma ho bruciato tutta la memoria programma nel tentativo di aggiungere 8 pulsanti, 6 letture analogiche, qualche lettura di digitale.
La mia domanda è se possibile (e come) usare una memoria esterna tipo I2c o SPI per memorizzare il testo HTML.
Ringrazio cortesemente per qualsiasi aiuto.

#include <EtherCard.h>
;
  word len = ether.packetReceive();	
  word pos = ether.packetLoop(len);	
if(pos)	// e' arrivato qualche cosa.
  {
     if(strstr((char *)Ethernet::buffer + pos, "GET /?staT_led_C=ON") != 0)
	{
      if(ledStatus_C == false)
	  {		  
		Serial.println("Received ON command, led_C");
		ledStatus_C = true;	  
	  }
    }
    if(strstr((char *)Ethernet::buffer + pos, "GET /?staT_led_C=OFF") != 0)
	{
      if(ledStatus_C == true)
	  {
		Serial.println("Received OFF command, led_C");
		ledStatus_C = false;
	  }		
    }
;
;
    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>"
    "<meta http-equiv='refresh' content='3'>" // refresh ogni 3 sec.
	"<meta charset=\"utf-8\">"
	"<meta name='viewport' content='width=device-width, initial-scale=1.0'>"
 "<BODY BGCOLOR= honeydew>"  // colore di sfondo 'generale'  aliceblue  thistle    #D8F0FF
 "<title>WebLed_5e </title> </head>"
  "<body>"   "<p>"
"<input type='button' style='position:absolute;top:105px;left:150px;background-color:aliceblue; border:outset;' value='$D'  />"
 "</p>"
"<a href='/?staT_led_C=$S'><input type='button' style='position:absolute;top:300;left:100px; background-color:$S; border:outset; border-color:gainsboro;' value='$S' /> </a>"      // (buttonLabel), (kolore), (buttonLabel)
 ;
;
      "</body> </html>"    
      ), Anal_1,
         buttonLabel, kolore, buttonLabel
);
	
  }

Una scheda SD non ti va bene?
Comunque hai postato solo spezzoni di codice (tra l'altro "strani", con punti e virgole in giro "a caso"...): o posti tutto il codice oppure non possiamo darti indicazioni.

PS: magari alla variabile "Anal_1" cambierei nome... :wink:

Buongiorno e benvenuto nella sezione Italiana del forum,

cortesemente, come prima cosa, leggi attentamente il REGOLAMENTO di detta sezione, (... e, per evitare future possibili discussioni/incomprensioni, prestando molta attenzione al punto 15), dopo di che, come da suddetto regolamento (punto 16.7), fai la tua presentazione NELL'APPOSITA DISCUSSIONE spiegando bene quali esperienze hai in elettronica e programmazione, affinché noi possiamo conoscere la tua esperienza ed esprimerci con termini adeguati.

Grazie,

Guglielmo

P.S.: Ti ricordo che, purtroppo, fino a quando non sarà fatta la presentazione nell’apposita discussione, nel rispetto del succitato regolamento nessuno ti risponderà (eventuali risposte o tuoi ulteriori post, verrebbero temporaneamente nascosti), quindi ti consiglio di farla al più presto. :wink:

Ho ripulito la discussione da tutti i post non relativi ad essa così che sia più pulita e leggibile :wink:

Guglielmo

ok invio il codice nel suo insieme funzionante ma per non distogliere l'attenzione sul quesito non moltiplico le misure analogiche e i pulsanti per 10.
Ho visto qualche cosa con l'SD e francamente non volevo impelagarmi ora con qualcosa che è un terreno minato (almeno per me e per ora). la soluzione più pratica (a intuito) era usare la mem. esterna (che ho già implementato).
nell' esempio il buffer è di 700 byte, ma man mano che aggiungevo elementi
all' html è stato aumentata fino a consumare tutta la mem. Programma.

#include <EtherCard.h>


static byte mymac[] = { 0x74,0x69,0x69,0x2D,0x3A,0x31 };
static byte myip[] = {192,168,1,2};
byte Ethernet::buffer[700];

const int LED_C = 7; 		// rH4  led VERDE
boolean ledStatus;

char on[] = "ON";    // char* on = "ON";  non gli piace!
char off[] = "OFF";  // char* off = "OFF";  non gli piace!
char* statusLabel;
char* buttonLabel;

char grigio[] = "silver";
char blu[] = "blue";
char verde[] = "green";
char giallo[]= "yellow";
char rosso[] = "red";

char* kolore;

unsigned int Pout;

void setup ()
 {
  Serial.begin(57600); 
  Serial.println("7_WebLed Demo-1a");
  if ( ether.begin(sizeof Ethernet::buffer, mymac, SS) == 0 )
  {    Serial.println( "Failed to access Ethernet controller");    }
  else
  {    Serial.println("Ethernet controller initialized");    }

 if (!ether.dhcpSetup())  // DHCP implementation, se non va..
  {
    Serial.println( F("DHCP failed"));
    // Setup IP statically
    ether.staticSetup(myip);
    Serial.println( F("Setting static IP"));  
  }
  else    {      Serial.println( F("Setting up DHCP"));      }

  Serial.println();
  
		// leggo i valori configurati e li scrivo sulla seriale
  ether.printIp("My IP: ", ether.myip);
  ether.printIp("Netmask: ", ether.netmask);
  ether.printIp("GW IP: ", ether.gwip);
  ether.printIp("DNS IP: ", ether.dnsip);
  
  Serial.println(); 
  
  pinMode(LED_C, OUTPUT);
  digitalWrite(LED_C, LOW);
  ledStatus = false;
}
  
void loop()
 {
  word len = ether.packetReceive();
  word pos = ether.packetLoop(len);
  
  if(pos) {
    
    if(strstr((char *)Ethernet::buffer + pos, "GET /?statusLed=ON") != 0) {
      Serial.println("Received ON command");
      ledStatus = true;
    }

    if(strstr((char *)Ethernet::buffer + pos, "GET /?statusLed=OFF") != 0) {
      Serial.println("Received OFF command");
      ledStatus = false;
    }
    
    if(ledStatus ==1) {
      digitalWrite(LED_C, HIGH);
      statusLabel = on;
	  kolore = verde;
      buttonLabel = off;
    } else {
      digitalWrite(LED_C, LOW);
	  kolore = grigio;
      statusLabel = off;
      buttonLabel = on;
    }



    //
	Pout = analogRead(A0);		// int


	 
    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"
    "<meta http-equiv='refresh' content='3'>" // refresh ogni 3 sec.
	"<meta charset=\"utf-8\">"
	"<meta name='viewport' content='width=device-width, initial-scale=1.0'>"
	 "<BODY BGCOLOR= honeydew>"  // colore di sfondo 'generale'
	 "<title>WebLed_1a </title> </head>"


	"<body>"	  
	"<p>"
	  "<input type='button' style='position:absolute;top:105px;left:150px;background-color:aliceblue; border:outset;' value='$D'  />" 	//  '$D'     (Pout) 
    "</p>"
	  
	"<p>"
	  "<a href='/?statusLed=$S'><input type='button' style='position:absolute;top:300;left:100px; background-color:$S; border:outset; border-color:gainsboro;' value='$S' /> </a>"      // ,(buttonLabel), (kolore), (buttonLabel)
	"</p>"

    "</body></html>"      
      ), Pout,
	  buttonLabel, kolore, buttonLabel);
	//  
    ether.httpServerReply(bfill.position());
  }
}

E invece sarebbe proprio l'approccio migliore e potenzialmente in grado di servire pagine web efficienti, gradevoli esteticamente e funzionali.

A patto però di abbandonare questa tecnica di generazione della pagina web che prevede dei placeholder, tecnica che secondo me, parlando di tecnologie web, è proprio concettualmente sbagliata: il grosso del lavoro va fatto fare al browser e non al server.

Non ho capito bene, i programmi che ho visto di webserver con SD fanno uso
comunque di placeholder e con metodo similare al mio, forse ho capito male ,suggerisci di inviare solo dei dati e sarebbe compito del pc analizzare e rappresentare i dati nel web o cosa, puoi fare un esempio?

La tecnica si chiama AJAX che sta per Asynchronous JavaScript and XML

In pratica il tuo webserver fornisce al browser delle risorse statiche: la pagina HTML, dei file di styling CSS e dei file di script Javascript.
Può anche essere tutto un unico file fintanto che il progetto è semplice, ma di solito si preferisce dividere in più file per avere maggior chiarezza.

Il codice Javascript che viene eseguito dal browser, farà poi delle richieste asincrone al server per ottenere i valori dei dati variabili e andando poi direttamente ad aggiornare la pagina renderizzata senza dover ogni volta ricaricare dall'inizio come devi fare adesso.

Con il mega trovi poco materiale online perché non è proprio la scelta migliore per un webserver; trovi tonnellate di esempi per ESP32 o ESP8266, ma a parte l'utilizzo della libreria che gestisce la comunicazione il principio rimane sostanzialmente lo stesso.

Il server rimane "scarico" di lavoro perché non deve fare altro che inviare all'inizio la pagina web (che è salvata sulla SD) e poi rispondere alle chiamate asincrone del browser con qualche manciata di byte (il valore di una variabile, lo stato di un'uscita etc etc) su richiesta.

Se ho tempo a sufficienza nel weekend ti adatto un esempio "significativo" che puoi provare anche con il Mega. Magari intanto cerca di familiarizzare con il concetto di AJAX.

Grazie, è completamente un altro concetto mi toccherà studiare quasi tutto, per me è tutto nuovo ...... Comunque proviamo.

Buongiorno, avrei un altro quesito che mi assilla, è possibile conoscere l'IP del proprio client e come posso fare il ping su di esso.
Ho trovato un esempio del ping ,ma lo fa con il server di google.
Se avete qualche buona dritta (magari con un possibile esempio).....
Ringrazio anticipatamente.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.