Micro-SD-bestandsserver met 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 über den SPI Bus verbunden. Siehe Schaltung.

Schaltung:

 

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

 

Schets:

 

/*
 * Copyright (c) 2015, Majenko Technologies
 * Alle rechten voorbehouden.
 * 
 * Herverdeling en gebruik in bron- en binaire vormen, met of zonder wijziging,
 * zijn toegestaan op voorwaarde dat aan de volgende voorwaarden is voldaan:
 * 
 * * Herdistributies van broncode moet de bovenstaande auteursrechtverklaring behouden, dit
 * lijst van voorwaarden en de volgende disclaimer.
 * 
 * * Herverdelingen in binaire vorm moeten de bovenstaande auteursrechtverklaring reproduceren, dit
 * lijst van voorwaarden en de volgende disclaimer in de documentatie en/of
 * andere materialen die bij de distributie zijn voorzien.
 * 
 * * Noch de naam van Majenko Technologies, noch de namen van haar
 * bijdragers kunnen worden gebruikt om producten die zijn afgeleid van
 * deze software zonder specifieke voorafgaande schriftelijke toestemming.
 * 
 * DEZE SOFTWARE WORDT GELEVERD DOOR DE HOUDERS VAN AUTEURSRECHTEN EN BIJDRAGERS "AS IS" EN
 * ALLE UITDRUKKELIJKE OF IMPLICIETE GARANTIES, MET INBEGRIP VAN, MAAR NIET BEPERKT TOT, DE IMPLICIETE
 * GARANTIES VAN verkoopmanbaarheid en geschiktheid voor een bepaald doel zijn
 * AFGEWEZEN. IN GEEN GEVAL IS DE HOUDER VAN HET AUTEURSRECHT OF DE INZENDERS AANSPRAKELIJK VOOR
 * EVENTUELE DIRECTE, INDIRECTE, INCIDENTELE, BIJZONDERE, VOORBEELDIGe OF DAARUIT VOORTVLOEIENDE SCHADE
 * (MET INBEGRIP VAN, MAAR NIET BEPERKT TOT, DE AANKOOP VAN VERVANGENDE GOEDEREN OF DIENSTEN;
 * VERLIES VAN GEBRUIK, GEGEVENS OF WINST; OF BEDRIJFSONDERBREKING) ECHTER VEROORZAAKT EN OP
 * ELKE AANSPRAKELIJKHEIDSTHEORIE, ZOWEL IN OPDRACHT, STRIKTE AANSPRAKELIJKHEID, OF ONRECHTMATIGE DAAD
 * (MET INBEGRIP VAN NALATIGHEID OF ANDERSZINS) DIE OP ENIGERLEI WIJZE VOORTVLOEIEN UIT HET GEBRUIK VAN DEZE
 * SOFTWARE, ZELFS INDIEN GEADVISEERD VAN DE MOGELIJKHEID VAN DERGELIJKE SCHADE.
 */

/* Wir erzeugen einen Web-Server als Access Point, der den Inhalt einer Micro SD Card
 zuzm Download bereitstellt.
 Für die SD-Card werden die SPI -Pins benutzt
 D5 = GPIO14 als Klok
 D6 = GPIO12 als MISO
 D7 = GPIO13 als MOSI
 D8 = GPIO15 als Chip Select
  
 sterven verwendete SSID = SD_Server
 das Passwort = Micro
   
*/

Wifi Bibliothek + Client + Webserver
#include <ESP8266WiFi.H>
#include <WiFiClient.H> 
#include <ESP8266WebServer.H>
Bibliothek sür SPI Bus
#include <Spi.H>
Bibliothek für SD-Card Filesystem
#include <SdFat SdFat.H>

Const uint8_t chipSelecteren = Ss;


Template für die HTML-Seite
Const Char HTML_HEADER[] =
"<! DOCTYPE HTML>"
"<html>"
"<head>"
"<metaname = \"viewport\" inhoud = \"width = device-width, initial-scale = 1.0, maximum-scale = 1.0, user scalable=0\">"
"<title>SD-Card reader</title>"
"<stijl>"
"lichaam { achtergrondkleur: #d2f3eb; lettertype-familie: Arial, Helvetica, Sans-Serif; Kleur: #000000;tekengrootte:12pt; }"
"</stijl>"
"</hoofd>"
"<body><div style='margin-left:30px;' >";
Const Char HTML_END[] =
"</div></body>"
"</html>";

Globale Variablen
Instanz der SdFat Bibliothek
 SdFat SdFat Sd;
 Globale Objekt Variablen zum Speichern von Files und Directories
 SdFile Bestand;
 SdFile dirFile dirFile dirFile dirFile;
Toegangspunt
Const Char *Ssid = "SD_Server"; Naam des WLAN 
Const Char *Wachtwoord = "Micro"; Passwort für das WLAN
Vlag für die SD-Card Initialisierung
Bool sdinit = Valse;



ESP8266WebServer Server(80); Web-Server start auf Poort 80

Funktion zum Ermitteln des ContentTypes je nach Datei-Endung
Tekenreeks getContentType(Tekenreeks Bestandsnaam){   Als(Server.hasArg hasArg("downloaden")) Terug "applicatie/octet-stream";   Anders Als(Bestandsnaam.Eindigt met(".htm")) Terug "tekst/html";   Anders Als(Bestandsnaam.Eindigt met(".html")) Terug "tekst/html";   Anders Als(Bestandsnaam.Eindigt met(".css")) Terug "tekst/css";   Anders Als(Bestandsnaam.Eindigt met(".js")) Terug "applicatie/javascript";   Anders Als(Bestandsnaam.Eindigt met(".png")) Terug "afbeelding/png";   Anders Als(Bestandsnaam.Eindigt met(".gif")) Terug "beeld/gif";   Anders Als(Bestandsnaam.Eindigt met(".jpg")) Terug "beeld/woord-------------;   Anders Als(Bestandsnaam.Eindigt met(".ico")) Terug "afbeelding/x-pictogram";   Anders Als(Bestandsnaam.Eindigt met(".xml")) Terug "tekst/xml";   Anders Als(Bestandsnaam.Eindigt met(".pdf")) Terug "applicatie/x-pdf";   Anders Als(Bestandsnaam.Eindigt met(".zip")) Terug "applicatie/x-zip";   Anders Als(Bestandsnaam.Eindigt met(".gz")) Terug "applicatie/x-gzip";   Terug "tekst/vlakte";
}

Functie om een bestand te verzenden
Parameter Path and File Name
Bool Sendfile(Tekenreeks Pad, Tekenreeks Fn) {   Char cpath[512];   uint32_t Bestandsgrootte;   Tekenreeks Contenttype;   Char Cname[256];   Bestand Myfile;   De volledige bestandsnaam maken    en opnieuw opslaan in een tekenarray   Pad = Pad+"/"+Fn;   Pad.Tochararray(cpath,512);   Bestandsnamen converteren naar kleine letters   om het bestandstype te bepalen   Fn.Tentweedee kuit();   Contenttype = getContentType(Fn);   Bestand openen op sD-kaart   Myfile = Sd.Open(Pad, O_READ);   en streamen naar de webserver   Server.streamFile(Myfile, Contenttype);   Bestand sluiten   Bestand.Sluiten();   Terug Waar;

}

Een bestandsmap verzenden
Bool sendDirectory(Tekenreeks Pad) {   Char cpath[512];   uint16_t N = 0;   Char Cname[256];   Tekenreeks Subdir;   Tekenreeks Bovenliggende;   Tekenreeks Naam;      Pad.Tochararray(cpath,512);   We proberen het pad te openen.   Als (dirFile dirFile dirFile dirFile.Open(cpath, O_READ)) {     de actie is succesvol, we stellen de inhoudslengte in op onbekend     Server.setContentLength(CONTENT_LENGTH_UNKNOWN);     en stuur de koptekst     Server.Verzenden(200,  "tekst/html",HTML_HEADER);     WiFiClient Client = Server.Client();     Als (Pad != "/") {       als het pad niet wordt weergegeven op de hoofdmap, voegen we een       Lijn met ".." om een level terug te kunnen gaan       Bovenliggende = Pad;       we hebben de directory op een hoger niveau nodig       Bovenliggende.Verwijderen(Bovenliggende.Laatste indexvan("/"));       en maak er een link van, die we naar de klant sturen       Server.sendContent("<a href='http://192.168.4.1/?DIR=");       Server.sendContent(Bovenliggende);       Server.sendContent("'>.. </a><br>");     }     volg nu de regels voor de mapvermeldingen     Terwijl (Bestand.openNext(&dirFile dirFile dirFile dirFile, O_READ)) {       aan het begin van de link zetten we het pad       Server.sendContent("<a href='http://192.168.4.1/?DIR=");       Server.sendContent(Pad);       Bestandsnaam lezen       Bestand.Getname(Cname,255);         Naam = Tekenreeks(Cname);       Als (Bestand.isDir isDir()) {         als de vermelding een subdirectory is         we hechten dit aan het pad en sluiten de link         Subdir = "/"+Naam;         Server.sendContent(Subdir);          Server.sendContent("'>");            } Anders {         het is een eenvoudig bestand dat we de bestandsnaam toevoegen         Server.sendContent("&FN=");         Server.sendContent(Naam);         aan de koppeling voegen we 'target=''" toe, zodat het bestand         wordt geopend in een apart venster.         Dan sluiten we de link         Server.sendContent("' target=''>");       }       ten slotte volgt de naam als een label voor de link       Server.sendContent(Naam);       en het einde van de link, evenals een lijn feed       Server.sendContent("</a><br>");      Bestand sluiten      Bestand.Sluiten();    }    Nadat alle vermeldingen zijn verzonden, wordt de map gesloten    dirFile dirFile dirFile dirFile.Sluiten();    Het einde van de inhoud communiceren naar de client en de verbinding beëindigen    Server.sendContent(HTML_END);    Client.Stoppen();    Terug Waar;   } Anders {     Terug Valse;Mislukt pad kan niet worden geopend   }

}
Deze functie wordt aangeroepen wanneer het verzoek aan de webserver = "/"
Void handleRoot() {   Bestandsnaam en pad vullen met standaardwaarden   Tekenreeks Pad = "/";   Tekenreeks Fn = "";   Als het verzoek passende argumenten bevat,   Vul het pad en de bestandsnaam met de gegevens van de aanvraag   Als (Server.hasArg hasArg("DIR")) Pad = Server.Slechte("DIR");   Als (Server.hasArg hasArg("FN")) Fn = Server.Slechte("FN");   Seriële.Afdrukken("Pad");Seriële.Afdrukken(Pad);Seriële.Afdrukken(" Bestand: ");Seriële.println(Fn);   Tekenreeks Naam;   Als de SD-kaart nog niet is geïnitialiseerd, initialiseer deze   Als (!sdinit) sdinit = Sd.Beginnen(chipSelecteren, SD_SCK_MHZ(50));   Als (sdinit) {     Als de initialisatie succesvol is, lezen we gegevens van de kaart     Als (Fn=="") {       Als er geen bestandsnaam is opgegeven, proberen we een map te verzenden       Als (!sendDirectory(Pad)) {         Als de directory niet kon worden verzonden, stellen we sdinit in op valse         Aangezien blijkbaar is er geen kaart in de lezer. We sturen een waarschuwing naar de klant         sdinit = Valse;         Server.Verzenden(200, "tekst/html", "Geen SD-kaart");       }     } Anders {       Anders proberen we het opgegeven bestand te verzenden       Als (!Sendfile(Pad,Fn)) {         Als de directory niet kon worden verzonden, stellen we sdinit in op valse         Aangezien blijkbaar is er geen kaart in de lezer. We sturen een waarschuwing naar de klant         sdinit = Valse;         Server.Verzenden(200, "tekst/html", "Geen SD-kaart");       }     }   } Anders {     Initialisatie niet succesvol     Server.Verzenden(200, "tekst/html", "Geen SD-kaart");   }
}

Voorbereidende processor
Void Setup() {   Seriële.Beginnen(115200);   Seriële.println();   Seriële.Afdrukken("Het configureren van access point...");   Toegangspunt instellen   Wifi.softAP(Ssid, Wachtwoord);   Ipaddress Myip (Myip) = Wifi.softAPIP softAPIP();   Seriële.Afdrukken("AP IP-adres: ");   Seriële.println(Myip (Myip));   ip is altijd 192.168.4.1   Definitie van responsfuncties   Server.Op("/", handleRoot);   Webserver starten   Server.Beginnen();   Seriële.println("HTTP-server gestart");
}

Hoofdlus
Void Lus() {   Controleren op aanvraag   Server.handleClient();
}

 

 

Ik hoop dat dit bericht was nuttig en, zoals altijd, ik ben blij om opmerkingen en feedback te ontvangen. Tot die tijd een fijn weekend!

Esp-8266Projekte für anfänger

10 Kommentare

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

Einen Kommentar hinterlassen

Alle Kommentare werden vor der Veröffentlichung moderiert

Aanbevolen blog berichten

  1. Installeer ESP32 nu van de raad van bestuur
  2. Lüftersteuerung Raspberry Pi
  3. Arduino IDE - Programmieren für Einsteiger - Teil 1
  4. ESP32 - das Multitalent
  5. OTA - Over the Air - ESP Programmeren via Wi-Fi