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!
19 Reacties
Andreas Wolter
@Andreas: die Libraries wurden teilweise komplett in den ESP Core integriert und/oder nicht weiter gepflegt. Ich würde daher versuchen, es komplett anders aufzubauen.
Wenn die Zeit es zulässt, werden wir versuchen, den Beitrag zu aktualisieren.
Grüße,
Andreas Wolter
AZ-Delivery Blog
Andreas
Hallo,
ich habe mich heute Abend auch damit abgekämpft, diesen Sketch zum Laufen zu bringen. Auch ich bekomme die Fehlermeldung
‘operator=’ (operad types are ‘fs::File’ and ‘FsFile’)
Wenn ich es recht verstanden habe, kommt mit dem ESP8662-Library Paket auch eine FS.h, auf die dann von den anderen Libraries aus dem Paket zugegriffen wird. Und nun ist aber in unterschiedlichen Libraries der gleiche Ausdruck “File”, mit dem man die Variable “myfile” deklariert, vorhanden. Der Compiler weiß nun nicht, welche Deklaration aus welcher Library er für “File” verwenden soll. Es ist wohl ein Problem des ESP-Library-Pakets, das anscheinend auch nicht mehr gepflegt wird – jedenfalls hat ESP8266WiFi bei mir noch die Versionsnummer 1.0
Wie man das nun abstellt bzw. den Konflikt behebt, damit kenne ich mich leider zu wenig aus und bin auch aus den wenigen Foreneinträgen, die ich zu ähnlichen Problemen gefunden habe, nicht wirklich schlau geworden bzw. die Lösungscorschläge haben nicht funktioniert.
Markus
Hallo,
ich wäre auch an einer aktuellen Version interessiert. Leider sind meine eigenen Versuche bisher gescheitert :-( .
Grüße
Markus
Andreas Wolter
aus Zeitgründen aktuell noch nicht.
Vielleicht finden SIe auch selbst eine Lösung, die wir dann hier zeigen können. Es gibt sehr viele neue und alte Bibliotheken, die zusammen funktionieren müssen.
Grüße,
Andreas Wolter
Markus
Hallo,
gibt es schon einen neuen Sketch mit der SD Bibliothek?
Grüße
Markus
Andreas Wolter
ich habe mir das noch einmal angesehen. Es scheint, als wäre die Bibliothek und damit auch der Sketch in diesem Beitrag outdated. Wenn man den aktuellen ESP8266 Arduino Core installiert, wird dort die SD Bibliothek mit installiert. Außerdem die SDFAT Bibliothek. Beides scheint sich nicht zu vertragen. Wenn man nun noch versucht, manuell die angegebenen Bibliotheken zu installieren, geht das komplett in die Hose. Ich werde versuchen, mit der SD Bibliothek den Sketch zu aktualisieren. Das wird allerdings ein bisschen dauern.
Grüße,
Andreas Wolter
AZ-Delivery Blog
Norbert
Danke Herr Wolter für die schnelle Antwort.
Ich habe leider immer noch keinen Erfolg.
Die entsprechenden Bibliotheken (Ihr angegebener Link) habe ich installiert.
Leider kommt beim Kompilieren In Zeile 124 : " myfile = sd.open(path, O_READ);"
der Fehler " no match for ‘operator=’ (operad types are ‘fs::File’ and ‘FsFile’)
Ich verwende Arduino IDE 1.8.15
Ich würde gern den Micro-SD File Server nachbauen!
Könnten Sie mir bitte noch einen Tipp geben wo der Fehler liegen könnte.
Leider bin ich Anfänger und kann mit den Fehlermeldungen wenig anfangen.
Ich bedanke mich für Ihre Bemühungen
und verbleibe mit freundlichen Grüßen
Norbert
Im Fehlerfenster erscheint folgendes in Rot:
C:\Users\norbe\Desktop\Stromzähler – Messwerterfassung\PC und WEB-Server\Versuch3\Versuch3.ino: In function ‘bool sendFile(String, String)’:
Versuch3:81:32: error: no match for ‘operator=’ (operand types are ‘fs::File’ and ‘FsFile’)
In file included from C:\Users\norbe\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\ESP8266WiFi\src/CertStoreBearSSL.h:26,
from C:\Users\norbe\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\ESP8266WiFi\src/WiFiClientSecureBearSSL.h:30,
from C:\Users\norbe\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\ESP8266WiFi\src/WiFiClientSecure.h:23,
from C:\Users\norbe\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\ESP8266WiFi\src/WiFiServerSecure.h:20,
from C:\Users\norbe\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\ESP8266WiFi\src/ESP8266WiFi.h:41,
from C:\Users\norbe\Desktop\Stromzähler – Messwerterfassung\PC und WEB-Server\Versuch3\Versuch3.ino:2:
C:\Users\norbe\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\cores\esp8266/FS.h:52:7: note: candidate: ‘fs::File& fs::File::operator=(const fs::File&)’
52 | class File : public Stream
| ^~~~
C:\Users\norbe\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\cores\esp8266/FS.h:52:7: note: no known conversion for argument 1 from ‘FsFile’ to ‘const fs::File&’
C:\Users\norbe\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\cores\esp8266/FS.h:52:7: note: candidate: ‘fs::File& fs::File::operator=(fs::File&&)’
C:\Users\norbe\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\cores\esp8266/FS.h:52:7: note: no known conversion for argument 1 from ‘FsFile’ to ‘fs::File&&’
Bibliothek ESP8266WiFi in Version 1.0 im Ordner: C:\Users\norbe\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\ESP8266WiFi wird verwendet
Bibliothek ESP8266WebServer in Version 1.0 im Ordner: C:\Users\norbe\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\ESP8266WebServer wird verwendet
Bibliothek SPI in Version 1.0 im Ordner: C:\Users\norbe\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\SPI wird verwendet
Bibliothek SdFat-2.1.1 in Version 2.1.1 im Ordner: C:\Users\norbe\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\SdFat-2.1.1 wird verwendet
exit status 1
no match for ‘operator=’ (operand types are ‘fs::File’ and ‘FsFile’)
Andreas Wolter
Die SD-Card Bibliotheken finden Sie als Download auf der verlinkten Produktseite des SD-Card Moduls: https://cdn.shopify.com/s/files/1/1509/1638/files/Micro_Memory_Card_Arduino.rar?9306531954326920108
Wir ergänzen das im Beitrag
Andreas Wolter
AZ-Delivery Blog
Norbert Patschorke
Hallo,
ich möchte es gern nachbauen.
Aber ich finde nirgends die passende SDFAT-Bibliothek.
Bitte gebt mir eine Hinweis (Link).
Gruß Norbert
Lompe
Postscriptum:
Am PC mit dem Chrome-Browser geht es auch nicht.
Auch nicht, wenn die Anzeige unsicherer Seiten zu gelassen ist.
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
Gibt es einen funktionierenden Sketsch?
Grüße
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
That means i can serve files of the sd card? That would be nice even if it is slow!
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
Sorry, ich hatte das Programm vergessen. Ist jetzt dabei.
michael
Hallo Gerald,
hast Du dafür kein Programm?
Grüße michael
michael
Hallo, wo ist das Programm dazu?
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