ESP-12E Nano Web Server

My idea, a minimalistic, portable web server as tiny as possible which can server a static web page on the go.

Parts

ESP-12E or any similar ESP8266 module
SD adapter MicroSD card adapter, if possible those default modules including some safety resistors and capacitors
Li-ion battery ~250mAh should be enough
Li-ion charger charging module with USB port; if your battery has no protection, this must include that
AMS1117-3V3 voltage regulator to convert the 3.7V to 4.2V to the 3.3V the ESP needs
10kΩ resistor 0603 or 0805 SMD if possible, a normal package would work too, of course
Switch simple on/off switch, I used a 3 pin
Pushbutton simple momentary pushbutton to enter program mode on boot
1x5 header header to connect the USB to serial adapter to, I used a female header
MicroSD card everything above 256MB or Class4 is too much because of the ESP speed
Wires you can use almost any thin wire; this doesn't use any current basically :D

Circuit diagram

ESP-12E

  • 1 RST → programmer RST
  • 3 EN → +3.3V
    (to enable chip)
  • 5 GPIO14 → SDCard CLK
  • 6 GPIO12 → SDCard MISO
  • 7 GPIO13→ SDCard MOSI
  • 8 VCC → +3.3V (absolute max 3.6V)
  • 15 GND → ground
  • 16 GPIO15 → SDCard CS / SS
    16 GPIO15 → 10kΩ resistor → ground
    (to pull down the pin low at boot)
  • 18 GPIO00 → pushbutton → ground
    (to allow setting low to enable program mode at boot)
  • 21 RXD0 → programmer TX
  • 22 TXD0 → programmer RX

Power supply

The basic build is batterycharge moduileAMS1117 3V3 &arr; server. My battery has a safty circuit built-in and the charger-board also has a protection chip included; one protection is needed but also enough. The charger board usually directly connects the bat+ to out+ but bat- is managed by the protection, so I connected the power switch to the latter.

The battery may have a nominal output voltage of 3.7V but there will be up to 4.2V on the wires when it'S fully or being charged. So, to provide the 3.3V the ESP needs, I connected the AMS1117 3V3:

  • 1 GND → charger board out-
  • 2 OUT → ESP and SDCard VCC
  • 3 IN → charger board out+

Flashing

The ESP has several boot modes which are selected at boot time via the following pin states. There two modes are important here:

Mode GPIO00 GPIO02 GPIO15
UART (programming) LOW HIGH LOW
Flash (normal) HIGH HIGH LOW

To set a pin high, you can just not connect it.

To begin flashing via the Arduino IDE, first connect the ESP to the USB-to-Serial adapter:

  • Serial VCC → ESP 8 VCC (make sure that it's 3.3V!!!)
  • Serial GND → ESP 15 GND
  • Serial TX → ESP RX
  • Serial RX → ESP TX
  • Serial RSTRSP (optional, only to allow automatic reset after flashing)

Then, while holding the pushbutton (pulling 18 GPIO00 low), connect the USB-to-Serial adapter to the PC. Select its serial port via ToolsPort (something like /dev/ttyUSB0 or COM4). Start upload.

Software

I code using the Arduino IDE with the board manager http://arduino.esp8266.com/stable/package_esp8266com_index.json and basically just copy'n'pasted example code together.

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <SPI.h>
#include <SD.h>

const char* ssid = "NanoServer";
const char* password = NULL;
const char* host = "nano";
IPAddress apIP(192, 168, 8, 1); 

ESP8266WebServer server(80);
static bool hasSD = false;

bool respondFromSD(String path) {
  String dataType = "text/plain";
  if (path.endsWith("/")) path += "index.htm";

  if (path.endsWith(".htm")) dataType = "text/html";
  else if (path.endsWith(".css")) dataType = "text/css";
  else if (path.endsWith(".js")) dataType = "application/javascript";
  else if (path.endsWith(".png")) dataType = "image/png";
  else if (path.endsWith(".gif")) dataType = "image/gif";
  else if (path.endsWith(".jpg")) dataType = "image/jpeg";
  else if (path.endsWith(".ico")) dataType = "image/x-icon";
  else if (path.endsWith(".xml")) dataType = "text/xml";
  else if (path.endsWith(".pdf")) dataType = "application/pdf";
  else if (path.endsWith(".zip")) dataType = "application/zip";
  else if (path.endsWith(".ttf")) dataType = "font/ttf";
  else if (path.endsWith(".eot")) dataType = "application/vnd.ms-fontobject";
  else if (path.endsWith(".woff")) dataType = "font/woff";
  else if (path.endsWith(".woff2")) dataType = "font/woff2";

  File dataFile = SD.open(path.c_str());
  if (dataFile.isDirectory()) {
    path += "/index.htm";
    dataType = "text/html";
    dataFile = SD.open(path.c_str());
  }

  if (!dataFile) return false;

  if (server.streamFile(dataFile, dataType) != dataFile.size()) {
    Serial.println("Sent less data than expected!");
  }

  dataFile.close();
  return true;
}

unsigned char h2int(char c) {
    if (c >= '0' && c <='9')
        return((unsigned char)c - '0');
    if (c >= 'a' && c <='f')
        return((unsigned char)c - 'a' + 10);
    if (c >= 'A' && c <='F')
        return((unsigned char)c - 'A' + 10);
    return(0);
}

String urldecode(String str) {
    String encodedString = "";
    char c;
    char code0;
    char code1;
    for (int i =0; i < str.length(); i++) {
        c=str.charAt(i);
      if (c == '+') 
        encodedString += ' ';
      else if (c == '%') {
        i++;
        code0=str.charAt(i);
        i++;
        code1=str.charAt(i);
        c = (h2int(code0) << 4) | h2int(code1);
        encodedString += c;
      } else
        encodedString += c;

      yield();
    }

   return encodedString;
}

void handleFileRequest() {
  if (hasSD && respondFromSD(urldecode(server.uri()))) return;
  String message = "SDCARD Not Detected\n\n";
  message += "URI: ";
  message += server.uri();
  message += "\nMethod: ";
  message += (server.method() == HTTP_GET) ? "GET" : "POST";
  message += "\nArguments: ";
  message += server.args();
  message += "\n";
  for (uint8_t i = 0; i < server.args(); i++) {
    message += " NAME:"+server.argName(i) + "\n VALUE:" + server.arg(i) + "\n";
  }
  server.send(404, "text/plain", message);
  Serial.print(message);
}

void setup(void) {
  Serial.begin(115200);
  Serial.setDebugOutput(true);
  Serial.print("\n");

  // configure access point
  WiFi.mode(WIFI_AP);
  WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0));
  WiFi.softAP(ssid, password, 5, false, 8); // WiFi name
  Serial.println("SoftAP started.");
  Serial.print("Server IP: ");
  Serial.print(WiFi.softAPIP());
  Serial.print("\n");

  server.onNotFound(handleFileRequest);
  server.begin();
  Serial.println("HTTP server started");

  if (SD.begin(SS)) {
     Serial.println("SD Card initialized.");
     hasSD = true;
  }
}

void loop(void) {
  server.handleClient();
}

This page was last edited on 2025-12-18 15:07

Powered by Wiki|Docs

This page was last edited on 2025-12-18 15:07

Bjørn Singer
Private wiki!

Powered by Wiki|Docs