├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── img └── esp32-rest-api-server.png ├── include └── README ├── lib └── README ├── platformio.ini ├── src └── main.cpp └── test └── README /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Object files 5 | *.o 6 | *.ko 7 | *.obj 8 | *.elf 9 | 10 | # Linker output 11 | *.ilk 12 | *.map 13 | *.exp 14 | 15 | # Precompiled Headers 16 | *.gch 17 | *.pch 18 | 19 | # Libraries 20 | *.lib 21 | *.a 22 | *.la 23 | *.lo 24 | 25 | # Shared objects (inc. Windows DLLs) 26 | *.dll 27 | *.so 28 | *.so.* 29 | *.dylib 30 | 31 | # Executables 32 | *.exe 33 | *.out 34 | *.app 35 | *.i*86 36 | *.x86_64 37 | *.hex 38 | 39 | # Debug files 40 | *.dSYM/ 41 | *.su 42 | *.idb 43 | *.pdb 44 | 45 | # Kernel Module Compile Results 46 | *.mod* 47 | *.cmd 48 | .tmp_versions/ 49 | modules.order 50 | Module.symvers 51 | Mkfile.old 52 | dkms.conf 53 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: python 2 | python: 3 | - "2.7" 4 | # 5 | sudo: false 6 | cache: 7 | directories: 8 | - "~/.platformio" 9 | # 10 | install: 11 | - pip install -U platformio 12 | # - platformio update 13 | # 14 | script: 15 | - platformio run 16 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Surviving with android (by Francesco Azzola) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ESP32-Rest-API-Server 2 | Implement a Rest API Server using ESP32 to expose Rest JSON API 3 | 4 | 5 | Link: [ESP32 Rest API Server](https://www.survivingwithandroid.com/esp32-rest-api-esp32-api-server/) 6 | 7 | [![Build Status](https://travis-ci.org/survivingwithandroid/ESP32-Rest-API-Server.svg?branch=master)](https://travis-ci.org/survivingwithandroid/ESP32-Rest-API-Server) 8 | 9 | [![twitter](https://img.shields.io/twitter/follow/survivingwithan.svg?style=social)](https://twitter.com/intent/follow?screen_name=survivingwithan) 10 | 11 | ## Schematics 12 | 13 | ![Web server running on ESP8266](https://github.com/survivingwithandroid/ESP32-Rest-API-Server/blob/master/img/esp32-rest-api-server.png) 14 | -------------------------------------------------------------------------------- /img/esp32-rest-api-server.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/survivingwithandroid/ESP32-Rest-API-Server/2545967787ff8d2e3fb58dc2debf5e2b132e0242/img/esp32-rest-api-server.png -------------------------------------------------------------------------------- /include/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for project header files. 3 | 4 | A header file is a file containing C declarations and macro definitions 5 | to be shared between several project source files. You request the use of a 6 | header file in your project source file (C, C++, etc) located in `src` folder 7 | by including it, with the C preprocessing directive `#include'. 8 | 9 | ```src/main.c 10 | 11 | #include "header.h" 12 | 13 | int main (void) 14 | { 15 | ... 16 | } 17 | ``` 18 | 19 | Including a header file produces the same results as copying the header file 20 | into each source file that needs it. Such copying would be time-consuming 21 | and error-prone. With a header file, the related declarations appear 22 | in only one place. If they need to be changed, they can be changed in one 23 | place, and programs that include the header file will automatically use the 24 | new version when next recompiled. The header file eliminates the labor of 25 | finding and changing all the copies as well as the risk that a failure to 26 | find one copy will result in inconsistencies within a program. 27 | 28 | In C, the usual convention is to give header files names that end with `.h'. 29 | It is most portable to use only letters, digits, dashes, and underscores in 30 | header file names, and at most one dot. 31 | 32 | Read more about using header files in official GCC documentation: 33 | 34 | * Include Syntax 35 | * Include Operation 36 | * Once-Only Headers 37 | * Computed Includes 38 | 39 | https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html 40 | -------------------------------------------------------------------------------- /lib/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for project specific (private) libraries. 3 | PlatformIO will compile them to static libraries and link into executable file. 4 | 5 | The source code of each library should be placed in a an own separate directory 6 | ("lib/your_library_name/[here are source files]"). 7 | 8 | For example, see a structure of the following two libraries `Foo` and `Bar`: 9 | 10 | |--lib 11 | | | 12 | | |--Bar 13 | | | |--docs 14 | | | |--examples 15 | | | |--src 16 | | | |- Bar.c 17 | | | |- Bar.h 18 | | | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html 19 | | | 20 | | |--Foo 21 | | | |- Foo.c 22 | | | |- Foo.h 23 | | | 24 | | |- README --> THIS FILE 25 | | 26 | |- platformio.ini 27 | |--src 28 | |- main.c 29 | 30 | and a contents of `src/main.c`: 31 | ``` 32 | #include 33 | #include 34 | 35 | int main (void) 36 | { 37 | ... 38 | } 39 | 40 | ``` 41 | 42 | PlatformIO Library Dependency Finder will find automatically dependent 43 | libraries scanning project source files. 44 | 45 | More information about PlatformIO Library Dependency Finder 46 | - https://docs.platformio.org/page/librarymanager/ldf.html 47 | -------------------------------------------------------------------------------- /platformio.ini: -------------------------------------------------------------------------------- 1 | ; PlatformIO Project Configuration File 2 | ; 3 | ; Build options: build flags, source filter 4 | ; Upload options: custom upload port, speed and extra flags 5 | ; Library options: dependencies, extra library storages 6 | ; Advanced options: extra scripting 7 | ; 8 | ; Please visit documentation for the other options and examples 9 | ; https://docs.platformio.org/page/projectconf.html 10 | 11 | [env:esp32dev] 12 | platform = espressif32 13 | board = esp32dev 14 | framework = arduino 15 | lib_deps= 16 | https://github.com/adafruit/Adafruit_BME280_Library 17 | https://github.com/adafruit/Adafruit_NeoPixel 18 | https://github.com/bblanchon/ArduinoJson 19 | 20 | -------------------------------------------------------------------------------- /src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | const char *SSID = "your_wifi-ssid"; 12 | const char *PWD = "your_wifi_password"; 13 | 14 | #define NUM_OF_LEDS 9 15 | #define PIN 4 16 | 17 | // Web server running on port 80 18 | WebServer server(80); 19 | 20 | // Sensor 21 | Adafruit_BME280 bme; 22 | 23 | // Neopixel LEDs strip 24 | Adafruit_NeoPixel pixels(NUM_OF_LEDS, PIN, NEO_GRB + NEO_KHZ800); 25 | 26 | // JSON data buffer 27 | StaticJsonDocument<250> jsonDocument; 28 | char buffer[250]; 29 | 30 | // env variable 31 | float temperature; 32 | float humidity; 33 | float pressure; 34 | 35 | void connectToWiFi() { 36 | Serial.print("Connecting to "); 37 | Serial.println(SSID); 38 | 39 | WiFi.begin(SSID, PWD); 40 | 41 | while (WiFi.status() != WL_CONNECTED) { 42 | Serial.print("."); 43 | delay(500); 44 | // we can even make the ESP32 to sleep 45 | } 46 | 47 | Serial.print("Connected. IP: "); 48 | Serial.println(WiFi.localIP()); 49 | } 50 | 51 | void create_json(char *tag, float value, char *unit) { 52 | jsonDocument.clear(); 53 | jsonDocument["type"] = tag; 54 | jsonDocument["value"] = value; 55 | jsonDocument["unit"] = unit; 56 | serializeJson(jsonDocument, buffer); 57 | Serial.println("Buffer:"); 58 | Serial.println(buffer); 59 | } 60 | 61 | void add_json_object(char *tag, float value, char *unit) { 62 | JsonObject obj = jsonDocument.createNestedObject(); 63 | obj["type"] = tag; 64 | obj["value"] = value; 65 | obj["unit"] = unit; 66 | } 67 | 68 | void read_sensor_data(void * parameter) { 69 | for (;;) { 70 | temperature = bme.readTemperature(); 71 | humidity = bme.readHumidity(); 72 | pressure = bme.readPressure() / 100; 73 | Serial.println("Read sensor data"); 74 | 75 | // delay the task 76 | vTaskDelay(60000 / portTICK_PERIOD_MS); 77 | } 78 | } 79 | 80 | void getTemperature() { 81 | Serial.println("Get temperature"); 82 | create_json("temperature", temperature, "°C"); 83 | server.send(200, "application/json", buffer); 84 | } 85 | 86 | void getHumidity() { 87 | Serial.println("Get humidity"); 88 | create_json("humidity", humidity, "%"); 89 | server.send(200, "application/json", buffer); 90 | } 91 | 92 | void getPressure() { 93 | Serial.println("Get pressure"); 94 | create_json("pressure", pressure, "mBar"); 95 | server.send(200, "application/json", buffer); 96 | } 97 | 98 | void getEnv() { 99 | Serial.println("Get env"); 100 | jsonDocument.clear(); 101 | add_json_object("temperature", temperature, "°C"); 102 | add_json_object("humidity", humidity, "%"); 103 | add_json_object("pressure", pressure, "mBar"); 104 | serializeJson(jsonDocument, buffer); 105 | server.send(200, "application/json", buffer); 106 | } 107 | 108 | void handlePost() { 109 | if (server.hasArg("plain") == false) { 110 | //handle error here 111 | } 112 | 113 | String body = server.arg("plain"); 114 | Serial.println(body); 115 | deserializeJson(jsonDocument, body); 116 | 117 | // Get RGB components 118 | int red = jsonDocument["red"]; 119 | int green = jsonDocument["green"]; 120 | int blue = jsonDocument["blue"]; 121 | 122 | Serial.print("Red: "); 123 | Serial.print(red); 124 | 125 | 126 | pixels.fill(pixels.Color(red, green, blue)); 127 | delay(30); 128 | pixels.show(); 129 | 130 | // Respond to the client 131 | server.send(200, "application/json", "{}"); 132 | } 133 | 134 | 135 | // setup API resources 136 | void setup_routing() { 137 | server.on("/temperature", getTemperature); 138 | server.on("/pressure", getPressure); 139 | server.on("/humidity", getHumidity); 140 | server.on("/env", getEnv); 141 | server.on("/led", HTTP_POST, handlePost); 142 | 143 | // start server 144 | server.begin(); 145 | } 146 | 147 | 148 | void setup_task() { 149 | xTaskCreate( 150 | read_sensor_data, 151 | "Read sensor data", // Name of the task (for debugging) 152 | 1000, // Stack size (bytes) 153 | NULL, // Parameter to pass 154 | 1, // Task priority 155 | NULL // Task handle 156 | ); 157 | } 158 | 159 | void setup() { 160 | Serial.begin(9600); 161 | 162 | // Sensor setup 163 | if (!bme.begin(0x76)) { 164 | Serial.println("Problem connecting to BME280"); 165 | } 166 | connectToWiFi(); 167 | setup_task(); 168 | setup_routing(); 169 | 170 | // Initialize Neopixel 171 | pixels.begin(); 172 | } 173 | 174 | void loop() { 175 | server.handleClient(); 176 | 177 | } -------------------------------------------------------------------------------- /test/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for PIO Unit Testing and project tests. 3 | 4 | Unit Testing is a software testing method by which individual units of 5 | source code, sets of one or more MCU program modules together with associated 6 | control data, usage procedures, and operating procedures, are tested to 7 | determine whether they are fit for use. Unit testing finds problems early 8 | in the development cycle. 9 | 10 | More information about PIO Unit Testing: 11 | - https://docs.platformio.org/page/plus/unit-testing.html 12 | --------------------------------------------------------------------------------