Offline
Newbie
Karma: 0
Posts: 14
|
 |
« on: June 29, 2012, 01:05:08 am » |
I'm using webserver from SD card :
#include <SPI.h> #include <Ethernet.h> #include <SD.h> byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; IPAddress ip(10,20,90,66); File htmlFile; EthernetServer server(80);
void setup() { Serial.begin(9600); Ethernet.begin(mac, ip); server.begin(); if (!SD.begin(4)) { return; } } void loop() { EthernetClient client = server.available(); if (client) { boolean currentLineIsBlank = true; while (client.connected()) { if (client.available()) { char c = client.read(); if (c == '\n' && currentLineIsBlank) { client.println("HTTP/1.1 200 OK"); client.println("Content-Type: text/html"); client.println(); Serial.print("OteviRm index.htm"); htmlFile = SD.open("index.htm"); if (htmlFile) { while (htmlFile.available()) { client.write(htmlFile.read()); } // close the file: htmlFile.close(); } break; } if (c == '\n') { currentLineIsBlank = true; } else if (c != '\r') { currentLineIsBlank = false; } } } delay(1); client.stop(); } }
Into index.htm I can write my HTML code, but question is how display on webserver also jpg picture from SD card. If I will write into index.htm : <img src="picture.jpg"> and file picture.jpg I will copy to root of SD card, webserver will not show this picture - only square with cross.
What's wrong ?
Thanks for help
Alda
|
|
|
|
« Last Edit: June 29, 2012, 03:28:03 am by alda »
|
Logged
|
|
|
|
|
Switzerland
Offline
Faraday Member
Karma: 69
Posts: 3310
|
 |
« Reply #1 on: June 29, 2012, 04:00:25 am » |
You don't even read what the client is sending to you so you cannot parse it too. In the client's request it specifies what resource (file) it wants, you don't care and just send the HTML file. You have to parse the client's request, at least the first line, else you won't be able to serve more than the current HTML file.
If you search for Webduino on Google you'll find a webserver for Arduino that is probably doing what you wanna do.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 14
|
 |
« Reply #2 on: June 29, 2012, 07:24:14 am » |
Yes, I made a update to : #include <SPI.h> #include <SD.h> #include <SdFatUtil.h> #include <Ethernet.h>
/************ ETHERNET STUFF ************/ byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; IPAddress ip(10,20,90,66); char rootFileName[] = "index.htm"; EthernetServer server(80);
/************ SDCARD STUFF ************/ Sd2Card card; SdVolume volume; SdFile root; SdFile file;
// store error strings in flash to save RAM #define error(s) error_P(PSTR(s))
void error_P(const char* str) { PgmPrint("error: "); SerialPrintln_P(str); if (card.errorCode()) { PgmPrint("SD error: "); Serial.print(card.errorCode(), HEX); Serial.print(','); Serial.println(card.errorData(), HEX); } while(1); }
void setup() { Serial.begin(115200);
PgmPrint("Free RAM: "); Serial.println(FreeRam()); // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with // breadboards. use SPI_FULL_SPEED for better performance. pinMode(10, OUTPUT); // set the SS pin as an output (necessary!) digitalWrite(10, HIGH); // but turn off the W5100 chip!
if (!card.init(SPI_HALF_SPEED, 4)) error("card.init failed!"); // initialize a FAT volume if (!volume.init(&card)) error("vol.init failed!");
PgmPrint("Volume is FAT"); Serial.println(volume.fatType(),DEC); Serial.println(); if (!root.openRoot(&volume)) error("openRoot failed");
// list file in root with date and size PgmPrintln("Files found in root:"); root.ls(LS_DATE | LS_SIZE); Serial.println(); // Recursive list of all directories PgmPrintln("Files found in all dirs:"); root.ls(LS_R); Serial.println(); PgmPrintln("Done"); // Debugging complete, we start the server! Ethernet.begin(mac, ip); server.begin(); }
// How big our line buffer should be. 100 is plenty! #define BUFSIZ 100
void loop() {
char clientline[BUFSIZ]; char *filename; int index = 0; int image = 0; EthernetClient client = server.available(); if (client) { // an http request ends with a blank line boolean current_line_is_blank = true; // reset the input buffer index = 0; while (client.connected()) { if (client.available()) { char c = client.read(); // If it isn't a new line, add the character to the buffer if (c != '\n' && c != '\r') { clientline[index] = c; index++; // are we too big for the buffer? start tossing out data if (index >= BUFSIZ) index = BUFSIZ -1; // continue to read more data! continue; } // got a \n or \r new line, which means the string is done clientline[index] = 0; filename = 0; // Print it out for debugging Serial.println(clientline); // Look for substring such as a request to get the root file if (strstr(clientline, "GET / ") != 0) { filename = rootFileName; } if (strstr(clientline, "GET /") != 0) { // this time no space after the /, so a sub-file if (!filename) filename = clientline + 5; // look after the "GET /" (5 chars) // a little trick, look for the " HTTP/1.1" string and // turn the first character of the substring into a 0 to clear it out. (strstr(clientline, " HTTP"))[0] = 0; // print the file we want Serial.println(filename); if (! file.open(&root, filename, O_READ)) { client.println("HTTP/1.1 404 Not Found"); client.println("Content-Type: text/html"); client.println(); client.println("<h2>File Not Found!</h2>"); break; } Serial.println("Opened!"); client.println("HTTP/1.1 200 OK"); if (strstr(filename, ".htm") != 0) client.println("Content-Type: text/html"); else if (strstr(filename, ".css") != 0) client.println("Content-Type: text/css"); else if (strstr(filename, ".png") != 0) client.println("Content-Type: image/png"); else if (strstr(filename, ".jpg") != 0) client.println("Content-Type: image/jpeg"); else if (strstr(filename, ".gif") != 0) client.println("Content-Type: image/gif"); else if (strstr(filename, ".3gp") != 0) client.println("Content-Type: video/mpeg"); else if (strstr(filename, ".pdf") != 0) client.println("Content-Type: application/pdf"); else if (strstr(filename, ".js") != 0) client.println("Content-Type: application/x-javascript"); else if (strstr(filename, ".xml") != 0) client.println("Content-Type: application/xml"); else client.println("Content-Type: text");
client.println(); int16_t c; while ((c = file.read()) >= 0) { // uncomment the serial to debug (slow!) //Serial.print((char)c); client.print((char)c); } file.close(); } else { // everything else is a 404 client.println("HTTP/1.1 404 Not Found"); client.println("Content-Type: text/html"); client.println(); client.println("<h2>File Not Found!</h2>"); } break; } } // give the web browser time to receive the data delay(1); client.stop(); } } Now I can see also picture from SDcard, but my next question is - is possible insert into this webserver any line which will show me actual values ( analog values ) of andruino ? Thanks Alda
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Edison Member
Karma: 4
Posts: 1133
If you're not living on the Edge, you're taking up too much space!
|
 |
« Reply #3 on: June 29, 2012, 07:30:57 am » |
I have seen examples which do that. Sorry I can't find link now I'm traveling.
This works to display JPG? Great! I want to do this too! Please let me know if you have any problems with this code you provided. Because I would like to use it soon. Will you update it here with any improvements?
|
|
|
|
|
Logged
|
If you fall... I'll be there for you! -Floor
Skype Brighteyes3333 (262) 696-9619
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 14
|
 |
« Reply #4 on: June 29, 2012, 08:03:02 am » |
It's working for me without problems, now I can have all stored on SDcard, also pictures, but show picture on the webserver is quite slow. You can also click on three places on the picture which will open other page....
But I'm still looking for improvements ( see values on the screen with picture and speed up loading )
Alda
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Edison Member
Karma: 4
Posts: 1133
If you're not living on the Edge, you're taking up too much space!
|
 |
« Reply #5 on: June 29, 2012, 08:31:39 am » |
What 3 places on picture? What is the other page? I cannot test it today.
|
|
|
|
|
Logged
|
If you fall... I'll be there for you! -Floor
Skype Brighteyes3333 (262) 696-9619
|
|
|
|
Bavaria
Offline
Newbie
Karma: 0
Posts: 6
|
 |
« Reply #6 on: December 27, 2012, 07:39:40 am » |
Hello Alda,
i have downloaded your update code and turned it into a wifi shield code. It functions so somewhat with my modifications.
I don t know how do you call pictures from the sd card. Please tell me.
Many Greetings.
Rokitz.
|
|
|
|
|
Logged
|
Thank you for all help!
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 24
|
 |
« Reply #7 on: February 16, 2013, 03:04:23 pm » |
Thanks for your advice ,,, but pictures downloading slowly when i open the webpage do u know why ?
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Tesla Member
Karma: 51
Posts: 6592
Arduino rocks
|
 |
« Reply #8 on: February 16, 2013, 03:09:06 pm » |
Thanks for your advice ,,, but pictures downloading slowly when i open the webpage do u know why ?
The arduino is slow compared to computer based servers.
|
|
|
|
|
Logged
|
|
|
|
|
Switzerland
Offline
Faraday Member
Karma: 69
Posts: 3310
|
 |
« Reply #9 on: February 18, 2013, 05:11:59 am » |
but pictures downloading slowly when i open the webpage do u know why ? Additionally to zoomkat's explanation there's another reason: int16_t c; while ((c = file.read()) >= 0) { // uncomment the serial to debug (slow!) //Serial.print((char)c); client.print((char)c); }
You're reading the file byte by byte and then hand it over to the Ethernet library using the print() method. This way you create a packet for every byte you want to send. This is highly inefficient. It's a drawback of the Ethernet library but there is a reason for this: the lack of memory in the Arduino forced that decision. If you create a buffer of let's say 256 bytes and read that quarter kB from the card and send it using the write() method you will get faster (but not fast) responses.
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Tesla Member
Karma: 51
Posts: 6592
Arduino rocks
|
 |
« Reply #10 on: February 19, 2013, 01:14:56 am » |
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 37
|
 |
« Reply #11 on: February 19, 2013, 10:37:34 am » |
Je mets le code complet (Je débute donc c'est peut être pas très propre  ) mais ce qui me surprend c'est que ce code "allegé" ne marche pas tout de suite. Il faut le transferer 2 ou 3 fois avant que ca remarche...juste transferer 2 ou 3 fois sans rien modifier... //********************************************************************************************************************************** //**********************************************************************************************************************************
#include <Ethernet.h> #include <SD.h> // crée automatiquement un objet racine SD représentant la carte mémoire SD #include <SPI.h>
/* Détails technique de la connexion ethernet */ byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; byte ip[] = { 192,168,1, 177 }; byte gateway[] = { 192,168,1, 1 };
// Attachement d'un objet "server" sur le port 1337 EthernetServer server(80);
//********************************************************************************************************************************** //**********************************************************************************************************************************
void setup() {
// Variables d'Usage int Resultat_fct = false; // Initialisation port serie Serial.begin(115200); // Affichage de la SRAM utilisée // Serial.print(F("Memoire SRAM restante :")); // Serial.println(freeRam());
// Affectation des directions pins pinMode(53, OUTPUT); // broche de selection WIZNET pinMode(4, OUTPUT); // broche de selection SD card digitalWrite(4,LOW); digitalWrite(53,HIGH); // Initialisation de la carte SD avec broche 4 en tant que CS Resultat_fct=SD.begin(4); if (Resultat_fct!=true) { Serial.println(F("Echec initialisation SD!")); } delay(1000); // Initialisation de la librairie ethernet Ethernet.begin(mac, ip, gateway); server.begin();
}
//********************************************************************************************************************************** // MAIN //**********************************************************************************************************************************
void loop() { // Scrutation reseau Com_reseau(); }
//********************************************************************************************************************************** // FONCTION COMMUNICATION RESEAU //**********************************************************************************************************************************
void Com_reseau() {
//_____________________________________________________________________________________ // Variables d'usage String chaineRecue=""; // réception chaine requete int comptChar=0; // comptage des caractères reçus int resultat_SD=0; // resultat fonction lecture carte SD int index_paquet=0; // numéro de ligne à lire dans la carte SD int datas[150]; // ligne lue dans la carte SD char c; // caractère récupéré par Ethernet //_____________________________________________________________________________________
// Crée un objet client basé sur le client connecté au serveur EthernetClient client = server.available(); // si l'objet client n'est pas vide if (client) { // si le client est connecté if (client.connected()) { //_____________________________________________________________________________________ // Initialisation variables comptChar = 0; chaineRecue = ""; // Boucle sur reception client while (client.available()) { // l'octet suivant reçu du client est mis dans la variable c c = client.read(); // incrémente le compteur de caractère reçus comptChar=comptChar+1;
// Concatenation caractere dans une chaine dans une limite de 50 caracteres if (comptChar<50) { chaineRecue=chaineRecue+c; } } //_____________________________________________________________________________________ // Chaine reçue est une requete GET alors affichage page Web if (chaineRecue.startsWith("GET / HTTP")) { // Lecture carte SD et affichage page Web while (resultat_SD!=1 && resultat_SD<100) // Tant que pas fin de fichier texte et pas d'erreur { resultat_SD = Lecture_ligne_SD(index_paquet,"/Web/Image.txt",datas); int idx=0; while(idx<150 && datas[idx]>0) { if (datas[idx]>0) { client.print((char)datas[idx]); idx++; } } index_paquet++; } } //_____________________________________________________________________________________ // Attente et libération client delay(1); client.stop(); //_____________________________________________________________________________________ } } }
//********************************************************************************************************************************** // FONCTION DE RECUPERATION D'UNE LIGNE DANS UN FICHIER TXT D'UNE CARTE SD //**********************************************************************************************************************************
int Lecture_ligne_SD(int index_paquet,char path[20], int tableau[150]) {
//_____________________________________________________________________________________ // Variables d'Usage int File_exist=0; File myFile; // objet file
//_____________________________________________________________________________________ // Selection de la SD Card digitalWrite(53,HIGH); digitalWrite(4,LOW); //_____________________________________________________________________________________ // Test si le fichier existe - renvoie true/false File_exist=SD.exists(path);
// Si fichier n'existe pas if (File_exist!=true) { return 100; } // Si fichier existe else { // Ouverture du fichier en lecture myFile=SD.open(path,FILE_READ); myFile.seek(index_paquet*150);
for (int index=0;index<=150;index++) { tableau[index] = 0; } for (int index_c_ec=0;index_c_ec<150;index_c_ec++) { tableau[index_c_ec] = myFile.read();
if (tableau[index_c_ec]<0) { //tableau[index_c_ec]=0; return 1; } } return 2; }
//_____________________________________________________________________________________ // Selection du Wiznet digitalWrite(53,LOW); digitalWrite(4,HIGH); //_____________________________________________________________________________________ }
//********************************************************************************************************************************** // FONCTION LECTURE SRAM UTILISEE //**********************************************************************************************************************************
//int freeRam () //{ // extern int __heap_start, *__brkval; // int v; // return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); //}
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 37
|
 |
« Reply #12 on: February 19, 2013, 10:42:22 am » |
Oops Sorry I post here by error 
|
|
|
|
|
Logged
|
|
|
|
|
|