ESP8266

Overview

This tutorial implements a very simple http-server and an http-client; both running on an ESP8266 board

Project structure

This example uses the ESP8266 RTOS SDK toolchain, and therefore the project structure follows their standard Make-based format. All files are inside the directory src:

  • src/main/ - a "main" component directory which includes application code
    • src/main/component.mk - a component-level project Make file
    • src/main/main.c - main application file, contains Mongoose logic
    • src/main/wifi.c - contains Wifi setup routine, wifi_init()
    • src/main/mongoose.c - a symlink to repo's mongose.c
    • src/main/mongoose.h - a symlink to repo's mongose.h
  • src/Makefile - a top-level project Make file
  • Makefile - mainly invokes Docker to call the SDK utilities

In production code, all project files should be copied to the src/main/ directory instead of creating symlinks.

Note: the file src/sdkconfig, containing build values, will be automatically generated by the build process

Build and try

  • If you've not already done so, clone the Mongoose Library repo
    $ git clone https://github.com/cesanta/mongoose
    
  • This example requires you have Docker installed and your user is able to run it. If in doubt, check
    $ docker ps
    
  • Before building the project, open the src/main/main.c file and edit your WiFi network name and WiFi password settings:
  • Build the example. Unless you already have an SDK image, this will download it, what will take some time. The first build process also takes a while.
    $ cd mongoose/examples/esp8266/http-client-server
    $ make build
    ...
    Toolchain version: esp-2020r3-49-gd5524c1
    Compiler version: 8.4.0
    ...
    Generating esp8266.project.ld
    ...
    esptool.py v2.4.0
    App built. Default flash app command is:
    ...
    
  • Now let's flash it. We need to know the device name for the serial port that was assigned to the ESP8266. If it is the only USB serial port we have, it will usually be /dev/ttyUSB0:
    $ make flash PORT=/dev/ttyUSB0
    ...  
    Connecting....
    Chip is ESP8266EX
    Features: WiFi
    MAC: 5c:cf:7f:da:19:f1
    Uploading stub...
    Running stub...
    Stub running...
    Configuring flash size...
    ...
    Hash of data verified.
    
    Leaving...
    Hard resetting via RTS pin...
    
  • Let's reset our board and see how it starts. If everything goes OK, you should see the HTML code of the first web page in history.
    $ make monitor PORT=/dev/ttyUSB0
    
  • Now start your browser and point it to the IP address reported, it will depend on your network and how your Access Point DHCP server is configured; you can also check there with the MAC reported above, in case for some reason you are unable to see the log. You will see a Hello from ESP!page.

How it works

Here we'll cover those aspects that are specific to the ESP8266 implementation, for the details on the application, please see the http-server tutorial, and the http-client tutorial.

Compilation options

Network operations need a time base to calculate timeouts; this, as well as random number generation, will be provided by the RTOS SDK, and Mongoose needs to know how to link to them. We define these options in mongoose_config.h

  • MG_ARCH = MG_ARCH_ESP8266 - configures Mongoose to work with Espressif's RTOS SDK for the ESP8266

Main function

The app_main() function has two blocks:

  1. Initialize WiFi
  2. Run Mongoose

Initialize wifi

There we call a wifi_init() function which is defined in src/main/wifi.c. That is a blocking function, i.e. it does not return until the board gets an IP address:

Run Mongoose

Next goes Mongoose. Note that it should be run after network initialization is complete - which is true in our case. The logic is standard - initialize the event manager, start a listener on port 80, and fall into an infinite event loop:

As we also included a client example, we also call the connect function.

Browse latest code

Troubleshooting notes

The ESP8266 is a mature product and there are numerous boards with really diverse configurations. In some cases you can try changing the file src/sdkconfig, particularly when you will be manually sending commands and need to set a serial port, for example.

Bootloader

Some old bootloaders do not support loading applications built with default parameters of newer IDF versions. In such a case, you can just build a new bootloader and flash it along with the app.

  • We've added two commands to the Makefile to do that:
    $ make buildall
    ...
    $ make flashall PORT=/dev/ttyUSB0
    

Flash memory

The DEVKIT-C board uses an ESP-WROOM-02 module, and there are several versions of these modules with different flash sizes and structures. If the make process described here does not work for you, you should check your board information and either modify the Makefile or send your own commands manually. The relevant esptool.py parameters are: write_flash -z --flash_mode dio --flash_freq 40m --flash_size 2MB; some boards require a lower frequency, others require using a different SPI flash mode, and the size and structure will be indicated in the last parameter.