Serveur de fichiers microro - SD avec D1 mini

Dieser Beitrag beschreibt einen Webserver der 'ber einen D1-Mini den Inhalt einer Micro SD Card zum Download zur Verf’gung stellt. Als Kartenleser kommt ein Micro-Speicherkartenmodul zum Einsatz. Die Hardware ist ganz einfach. Kartenlese-Modul und D1-Mini werden den SPI Bus verbunden. Siehe Schaltung.

Schaltung:

 

STL-Dateien zum Drucken eines passenden Gehàuses findet ihr auf meinem Thinigiverse Profil

 

dessin:

 

/*
 Droit d’auteur (c) 2015, Majenko Technologies
 Tous droits réservés.
 * 
 Redistribution et utilisation sous forme source et binaire, avec ou sans modification,
 - sont autorisés à condition que les conditions suivantes soient remplies :
 * 
 Les redistributions du code source doivent conserver l’avis de copyright ci-dessus,
 liste des conditions et l’avertissement suivant.
 * 
 Les redistributions sous forme binaire doivent reproduire l’avis de copyright ci-dessus,
 - liste des conditions et l’avertissement suivant dans la documentation et/ou
 d’autres matériaux fournis avec la distribution.
 * 
 Ni le nom de Majenko Technologies ni les noms de ses
 Les contributeurs peuvent être utilisés pour approuver ou promouvoir des produits dérivés de
 - ce logiciel sans autorisation écrite préalable spécifique.
 * 
 CE LOGICIEL EST FOURNI PAR LES TITULAIRES DE DROITS D’AUTEUR ET LES CONTRIBUTEURS "TEL QU’IL EST" ET
 TOUTE GARANTIE EXPRESSE OU IMPLICITE, Y COMPRIS, MAIS SANS S’Y LIMITER, LES
 LES GARANTIES DE MARCHANDITÉ ET DE REMISE EN FORME À DES FINS PARTICULIÈRES SONT
 - REFUSÉ. EN AUCUN CAS LE TITULAIRE DU DROIT D’AUTEUR OU LES CONTRIBUTEURS NE DOIVENT ÊTRE TENUS RESPONSABLES
 TOUT DOMMAGE DIRECT, INDIRECT, ACCESSOIRE, SPÉCIAL, EXEMPLAIRE OU CONSÉQUENT
 (Y COMPRIS, MAIS SANS S’Y LIMITER, L’ACHAT DE BIENS OU DE SERVICES DE REMPLACEMENT;
 PERTE D’UTILISATION, DE DONNÉES OU DE PROFITS; OU INTERRUPTION D’ENTREPRISE) TOUTEFOIS CAUSÉ ET SUR
 TOUTE THÉORIE DE LA RESPONSABILITÉ, QUE CE SOIT DANS LE CONTRAT, LA RESPONSABILITÉ STRICTE OU LA
 (Y COMPRIS LA NÉGLIGENCE OU AUTRE) DÉCOULANT D’UNE QUELCONQUE SORTIE DE L’UTILISATION DE CETTE
 - LOGICIEL, MÊME S’IL EST CONSEILLÉ DE LA POSSIBILITÉ DE TELS DOMMAGES.
 */

Wir erzeugen einen Web-Server als Access Point, der den Inhalt einer Micro SD Card
 zuzm Télécharger bereitstellt.
 Fâr die SD-Card werden die SPI -Pins benutzt
 D5 - Horloge gpIO14 als
 D6 - GPIO12 als MISO
 D7 - GPIO13 als MOSI
 D8 - GPIO15 als Chip Select
  
 die verwendete SSID - SD_Server
 das Passwort - Micro
   
*/

Wifi Bibliothek - Client et Web-Server
#include <ESP8266WiFi.h>
#include <WiFiClient (WiFiClient).h> 
#include <ESP8266WebServateur.h>
Bus Bibliothek s’r SPI
#include <Spi.h>
Bibliothek f’r SD-Card Filesystem
#include <SdFat (SdFat).h>

Const uint8_t chipSelect = Ss;


Template f’r die HTML-Seite
Const char HTML_HEADER[] =
"Lt;! DOCTYPE HTML -GT;"
"Lt;html-gt;"
"Lt;head’gt;"
"Lt;meta name " contenu 'viewport'' ''largeur', échelle initiale'1.0, échelle maximale '1.0', utilisateur-évolutif''0'"gt;"
"Lt;title’gt;SD-Card reader’lt;/title’gt;"
"Lt;style’gt;"
"corps - couleur de fond: #d2f3eb; police-famille: Arial, Helvetica, Sans-Serif; Couleur: #000000;font-taille:12pt; }"
"Lt;/style’gt;"
"Lt;/tête-gt;"
"lt;body’lt;lt;div style’margin-left:30px;' -gt;";
Const char HTML_END[] =
"Lt;/div’lt;/body’gt;"
"Lt;/html’gt;";

Variablen Globalen
Instanz der SdFat Bibliothek
 SdFat (SdFat) Sd;
 Globale Objekt Variablen zum Speichern von Files und Directories
 SdFile (SdFile) Fichier;
 SdFile (SdFile) dirFile;
Point d’accès
Const char *Ssid = "SD_Server"; Nom des WLAN 
Const char *mot de passe = "Micro"; Passwort f’r das WLAN
Drapeau f’r die SD-Card Initialisierung
Bool sdinit = Faux;



ESP8266WebServateur Serveur(80); Web-Server starten auf Port 80

Funktion zum Ermitteln des ContentTypes je nach Datei-Endung
String getContentType(String Fichier){   Si(Serveur.hasArg("télécharger")) Retour "application/octet-stream";   Autre Si(Fichier.Endswith(".htm")) Retour "texte/html";   Autre Si(Fichier.Endswith(".html")) Retour "texte/html";   Autre Si(Fichier.Endswith(".css")) Retour "texte/css";   Autre Si(Fichier.Endswith(".js")) Retour "application/javascript";   Autre Si(Fichier.Endswith(".png")) Retour "image/png";   Autre Si(Fichier.Endswith(".gif")) Retour "image/gif";   Autre Si(Fichier.Endswith(".jpg")) Retour "image/mot-------------;   Autre Si(Fichier.Endswith(".ico")) Retour "image/x-icon";   Autre Si(Fichier.Endswith(".xml")) Retour "texte/xml";   Autre Si(Fichier.Endswith(".pdf")) Retour "application/x-pdf";   Autre Si(Fichier.Endswith(".zip")) Retour "application/x-zip";   Autre Si(Fichier.Endswith(".gz")) Retour "application/x-gzip";   Retour "texte/plaine";
}

Fonction d’envoyer un fichier
Paramètre de nom de chemin et de fichier
Bool Sendfile Sendfile(String Chemin, String Fn) {   Char Char cpath[512];   uint32_t Taille;   String Contenttype;   Char Char Cname[256];   Fichier Monfichier;   Créer le nom complet du fichier    et resave à un tableau de caractère   Chemin = Chemin+"/"+Fn;   Chemin.Tochararray Tochararray(cpath,512);   Convertir les noms de fichiers en lowercase   pour déterminer le type de fichier   Fn.Tolowercase Tolowercase();   Contenttype = getContentType(Fn);   Fichier ouvert sur la carte SD   Monfichier = Sd.Ouvert(Chemin, O_READ);   et flux vers le serveur web   Serveur.streamFile streamFile(Monfichier, Contenttype);   Fichier fermé   Fichier.Proche();   Retour Vrai;

}

Envoyer un répertoire de fichiers
Bool envoyerDirectory(String Chemin) {   Char Char cpath[512];   uint16_t ¡n = 0;   Char Char Cname[256];   String Sous-répertoire;   String Parent;   String Nom;      Chemin.Tochararray Tochararray(cpath,512);   Nous essayons d’ouvrir le chemin   Si (dirFile.Ouvert(cpath, O_READ)) {     l’action est un succès, nous définissons la longueur du contenu à des inconnus     Serveur.setContentLength(CONTENT_LENGTH_UNKNOWN);     et envoyer l’en-tête     Serveur.Envoyer(200,  "texte/html",HTML_HEADER);     WiFiClient (WiFiClient) Client = Serveur.Client();     Si (Chemin != "/") {       si le chemin ne se montre pas sur le répertoire racine, nous ajoutons un       Ligne avec ".." pour être en mesure de revenir en arrière un niveau       Parent = Chemin;       nous avons besoin de l’annuaire de haut niveau       Parent.Retirer(Parent.Lastindexof("/"));       et créer un lien à partir de lui, que nous envoyons au client       Serveur.envoyerContent("Lt;a href’http://192.168.4.1/?DIR");       Serveur.envoyerContent(Parent);       Serveur.envoyerContent("'gt;.. Lt;/a’lt;lt;br’gt;");     }     maintenant suivre les lignes pour les entrées d’annuaire     Tandis que (Fichier.openNext(&dirFile, O_READ)) {       au début du lien, nous avons mis le chemin       Serveur.envoyerContent("Lt;a href’http://192.168.4.1/?DIR");       Serveur.envoyerContent(Chemin);       Lire Le nom de fichier       Fichier.Getname(Cname,255);         Nom = String(Cname);       Si (Fichier.isDir()) {         si l’entrée est une sous-direction         nous attachons cela au chemin et fermons le lien         Sous-répertoire = "/"+Nom;         Serveur.envoyerContent(Sous-répertoire);          Serveur.envoyerContent("'>");            } Autre {         c’est un fichier simple que nous ajoutons le nom du fichier         Serveur.envoyerContent("ET FN");         Serveur.envoyerContent(Nom);         au lien que nous ajoutons « cible » afin que le fichier         s’ouvre dans une fenêtre séparée.         Ensuite, nous fermons le lien         Serveur.envoyerContent("' cible'''gt;");       }       enfin, le nom suit comme une étiquette pour le lien       Serveur.envoyerContent(Nom);       et la fin du lien ainsi qu’un flux en ligne       Serveur.envoyerContent("Lt;/a’lt;lt;br’gt;");      Fichier fermé      Fichier.Proche();    }    Une fois que toutes les entrées ont été envoyées, l’annuaire est fermé    dirFile.Proche();    Communiquer la fin du contenu au client et mettre fin à la connexion    Serveur.envoyerContent(HTML_END);    client.arrêter();    retour vrai;   } d'autre {     retour faux;// erreur, le chemin n'a pas pu être ouvert   }

}
// Cette fonction est appelée lorsque la requête au serveur web = "/"
nul handleRoot() {   // Remplissez le nom et le chemin du fichier avec des valeurs par défaut   String chemin = "/";   String fn = "";   // Si la demande contient des arguments appropriés   // Remplissez le chemin et le nom du fichier avec les données de la demande   si (serveur.hasArg("VOUS")) chemin = serveur.mauvais("VOUS");   si (serveur.hasArg("FN")) fn = serveur.mauvais("FN");   Série.imprimer("Chemin");Série.imprimer(chemin);Série.imprimer("Fichier:");Série.println(fn);   String nom;   // Si la carte SD n'a pas encore été initialisée, initialisez-la   si (!sdinit) sdinit = sd.commencer(chipSelect, SD_SCK_MHZ(50));   si (sdinit) {     // Si l'initialisation a réussi, nous lisons les données de la carte     si (fn=="") {       // Si aucun nom de fichier n'a été donné, nous essayons d'envoyer un répertoire       si (!sendDirectory(chemin)) {         // Si le répertoire n'a pas pu être envoyé, nous définissons sdinit sur false         // Puisqu'il n'y a apparemment pas de carte dans le lecteur. Nous envoyons un avertissement au client         sdinit = faux;         serveur.envoyer(200, "text / html", "Pas de carte SD");       }     } d'autre {       // Sinon, nous essayons d'envoyer le fichier spécifié       si (!sendFile(chemin,fn)) {         // Si le répertoire n'a pas pu être envoyé, nous définissons sdinit sur false         // Puisqu'il n'y a apparemment pas de carte dans le lecteur. Nous envoyons un avertissement au client         sdinit = faux;         serveur.envoyer(200, "text / html", "Pas de carte SD");       }     }   } d'autre {     // L'initialisation a échoué     serveur.envoyer(200, "text / html", "Pas de carte SD");   }
}

// Préparez le processeur
nul configuration() {   Série.commencer(115200);   Série.println();   Série.imprimer("Configuration du point d'accès ...");   // Configurer le point d'accès   WiFi.softAP(ssid, mot de passe);   IPAddress myIP = WiFi.softAPIP();   Série.imprimer("Adresse IP AP:");   Série.println(myIP);   // ip est toujours 192.168.4.1   // Définition des fonctions de réponse   serveur.sur("/", handleRoot);   // démarre le serveur web   serveur.commencer();   Série.println("Le serveur HTTP a démarré");
}

// boucle principale
nul boucle() {   // Vérifier la demande   serveur.handleClient();
}

 

 

J'espère que ce message a été utile et, comme toujours, je suis heureux des commentaires et des commentaires. D'ici là, passez un bon week-end!

Esp-8266Projets pour les débutants

10 commentaires

Lompe

Lompe

Postscriptum:

Am PC mit dem Chrome-Browser geht es auch nicht.
Auch nicht, wenn die Anzeige unsicherer Seiten zu gelassen ist.

Lompe

Lompe

Funktioniert einwandfrei auf dem WIN 10 pc im Browser (Firefox).
Aber nicht auf dem Android Smartphone wenn über den Access Point aufgerufen. Die Routinen werden abgearbeitet (Serial-Monitor der Arduino IDE zur Kontrolle) und die Seiten gesendet, aber auf dem Bildschirm des Smartphones erscheint nichts.

fritzoskar

fritzoskar

Gibt es einen funktionierenden Sketsch?
Grüße

Henkel

Henkel

Welche SDFat Library braucht man? Mit der hier geht es nicht!
https://github.com/greiman/SdFat

Bibliothek 1. ESP8266 2.6.3
Hardwareziel Wemos D1 Mini
Arduino 1.8.12
Fehlermeldungen:

In file included from L:\arduino-1.8.12\portable\sketchbook\libraries\SdFat\src/FatLib/FatLib.h:27:0,

from L:\arduino-1.8.12\portable\sketchbook\libraries\SdFat\src/SdFat.h:33, from L:\arduino-1.8.12\portable\sketchbook\ESP8266WebserverSD\ESP8266WebserverSD\ESP8266WebserverSD.ino:51:

L:\arduino-1.8.12\portable\sketchbook\libraries\SdFat\src/FatLib/ArduinoFiles.h:122:7: error: redefinition of ‘class fs::File’

class File : public FatFile, public Stream { ^

In file included from L:\arduino-1.8.12\portable\packages\esp8266\hardware\esp8266\2.6.3\libraries\ESP8266WiFi\src/CertStoreBearSSL.h:26:0,

from L:\arduino-1.8.12\portable\packages\esp8266\hardware\esp8266\2.6.3\libraries\ESP8266WiFi\src/WiFiClientSecureBearSSL.h:30, from L:\arduino-1.8.12\portable\packages\esp8266\hardware\esp8266\2.6.3\libraries\ESP8266WiFi\src/WiFiClientSecure.h:41, from L:\arduino-1.8.12\portable\packages\esp8266\hardware\esp8266\2.6.3\libraries\ESP8266WiFi\src/WiFiServerSecure.h:20, from L:\arduino-1.8.12\portable\packages\esp8266\hardware\esp8266\2.6.3\libraries\ESP8266WiFi\src/ESP8266WiFi.h:41, from L:\arduino-1.8.12\portable\sketchbook\ESP8266WebserverSD\ESP8266WebserverSD\ESP8266WebserverSD.ino:45:

L:\arduino-1.8.12\portable\packages\esp8266\hardware\esp8266\2.6.3\cores\esp8266/FS.h:52:7: error: previous definition of ‘class fs::File’

class File : public Stream ^

In file included from L:\arduino-1.8.12\portable\sketchbook\libraries\SdFat\src/FatLib/FatLib.h:28:0,

from L:\arduino-1.8.12\portable\sketchbook\libraries\SdFat\src/SdFat.h:33, from L:\arduino-1.8.12\portable\sketchbook\ESP8266WebserverSD\ESP8266WebserverSD\ESP8266WebserverSD.ino:51:

L:\arduino-1.8.12\portable\sketchbook\libraries\SdFat\src/FatLib/FatFileSystem.h: In member function ‘fs::File FatFileSystem::open(const char*, oflag_t)’:

L:\arduino-1.8.12\portable\sketchbook\libraries\SdFat\src/FatLib/FatFileSystem.h:95:13: error: ‘class fs::File’ has no member named ‘open’

tmpFile.open(vwd(), path, oflag); ^

Mehrere Bibliotheken wurden für “SdFat.h” gefunden
Benutzt: L:\arduino-1.8.12\portable\sketchbook\libraries\SdFat
Nicht benutzt: L:\arduino-1.8.12\portable\packages\esp8266\hardware\esp8266\2.6.3\libraries\ESP8266SdFat
exit status 1
Fehler beim Kompilieren für das Board LOLIN D1 R2 & mini.

Moritz

Moritz

That means i can serve files of the sd card? That would be nice even if it is slow!

jean-marie

jean-marie

Guten Abend, ich mache alle Projekte für Ihre Website.
Sie sind großartig, aber ich habe ein Problem mit der SDFAT-Bibliothek. Ich habe den Fehler “‘SdFat’ benennt keinen Typ”.
Kannst du mir helfen?
Ich habe schon im Netz gesucht aber ….
++

jm

Gerald

Gerald

Sorry, ich hatte das Programm vergessen. Ist jetzt dabei.

michael

michael

Hallo Gerald,
hast Du dafür kein Programm?
Grüße michael

michael

michael

Hallo, wo ist das Programm dazu?

Frank Eisenwiener

Frank Eisenwiener

Danke erstmal für die anregenden Projekte!

Irgendwie fehlt mir persönlich bei diesem hier aber die Software (oder habe ich was überlesen?)…

Gruß
Frank

Laisser un commentaire

Tous les commentaires sont modérés avant d'être publiés

Messages de blogs recommandés

  1. Installez maintenant ESP32 via l'administrateur de la carte
  2. Lüftersteuerung Raspberry Pi
  3. Arduino IDE - Programmieren für Einsteiger - Teil 1
  4. ESP32 - das Multitalent
  5. OTA-Over the Air-ESP Programmation par WiFi