ESP8266
Send readings from a NodeMCU, Wemos D1 mini or other ESP8266 board with the Arduino IDE, over HTTP or MQTT. HTTP is encrypted and the server certificate is checked. MQTT goes without TLS on port 1883 (the easiest, and the lightest on ESP8266 memory) or with TLS on port 8883.
What you need
- An ESP8266 board, for example NodeMCU v2/v3 or Wemos D1 mini.
- A USB cable that carries data.
- Arduino IDE version 2.
- 2.4 GHz WiFi.
- A device created in INCLUDE. None yet? Follow Your own device, step 1.
1. Add ESP8266 support to the Arduino IDE
Open File > Preferences.
In Additional boards manager URLs, paste (if the ESP32 URL is already there, separate them with a comma):
https://arduino.esp8266.com/stable/package_esp8266com_index.jsonOpen Tools > Board > Boards Manager, search for
esp8266, and install esp8266 by ESP8266 Community version 3.x.
2. Get the code from INCLUDE
- Open your device, the Pengaturan (settings) tab, then Koneksi & Integrasi.
- In Code examples, choose HTTP and the ESP8266 tab, then Copy.

3. Fill in WiFi and the sensor reading
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClientSecure.h>
#include <time.h>
const char* WIFI_SSID = "your-wifi";
const char* WIFI_PASSWORD = "your-password";
const char* URL = "https://app.include.co.id/api/v1/YOUR_DEVICE_TOKEN/telemetry";
// Root certificates for app.include.co.id (Let's Encrypt ISRG Root X1 and X2).
const char ROOT_CA[] PROGMEM = R"PEM(
-----BEGIN CERTIFICATE-----
MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4
WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu
ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY
MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc
h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+
0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U
A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW
T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH
B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC
B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv
KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn
OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn
jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw
qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI
rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV
HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq
hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL
ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ
3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK
NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5
ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur
TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC
jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc
oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq
4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA
mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d
emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIICGzCCAaGgAwIBAgIQQdKd0XLq7qeAwSxs6S+HUjAKBggqhkjOPQQDAzBPMQsw
CQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJuZXQgU2VjdXJpdHkgUmVzZWFyY2gg
R3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBYMjAeFw0yMDA5MDQwMDAwMDBaFw00
MDA5MTcxNjAwMDBaME8xCzAJBgNVBAYTAlVTMSkwJwYDVQQKEyBJbnRlcm5ldCBT
ZWN1cml0eSBSZXNlYXJjaCBHcm91cDEVMBMGA1UEAxMMSVNSRyBSb290IFgyMHYw
EAYHKoZIzj0CAQYFK4EEACIDYgAEzZvVn4CDCuwJSvMWSj5cz3es3mcFDR0HttwW
+1qLFNvicWDEukWVEYmO6gbf9yoWHKS5xcUy4APgHoIYOIvXRdgKam7mAHf7AlF9
ItgKbppbd9/w+kHsOdx1ymgHDB/qo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0T
AQH/BAUwAwEB/zAdBgNVHQ4EFgQUfEKWrt5LSDv6kviejM9ti6lyN5UwCgYIKoZI
zj0EAwMDaAAwZQIwe3lORlCEwkSHRhtFcP9Ymd70/aTSVaYgLXTWNLxBo1BfASdW
tL4ndQavEi51mI38AjEAi/V3bNTIZargCyzuFJ0nN6T5U6VR5CmD1/iQMVtCnwr1
/q4AaOeMSQ+2b1tbFfLn
-----END CERTIFICATE-----
)PEM";
BearSSL::X509List roots(ROOT_CA);
BearSSL::WiFiClientSecure tls;
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA);
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED) delay(500);
Serial.println("WiFi connected");
// Certificate checks need the real time.
configTime(0, 0, "pool.ntp.org", "time.google.com");
while (time(nullptr) < 1700000000) delay(500);
tls.setTrustAnchors(&roots);
}
void loop() {
float temperature = 25.4; // replace with your sensor reading
float humidity = 61;
String body = "{\"temperature\": " + String(temperature, 1) +
", \"humidity\": " + String(humidity, 0) + "}";
HTTPClient http;
http.begin(tls, URL);
http.addHeader("Content-Type", "application/json");
int status = http.POST(body);
Serial.printf("HTTP %d %s\n", status, http.getString().c_str());
http.end();
delay(10000);
}- Fill in
WIFI_SSIDandWIFI_PASSWORD. - Replace the
temperatureandhumidityvalues with your sensor reading. - Leave
ROOT_CAand theconfigTimepart as they are.
The difference from the ESP32: the ESP8266 can only check a certificate when it knows today's date. So the program first gets the time from pool.ntp.org, and only sends after that. If your network blocks NTP (UDP port 123), the program stops at that step.
4. Upload and check
- Tools > Board > esp8266 > NodeMCU 1.0 (ESP-12E Module), or LOLIN(WEMOS) D1 R2 & mini for a Wemos.
- Tools > Port: pick the board's port.
- Press Upload, then open the Serial Monitor at 115200 baud.
When it works:
WiFi connected
HTTP 202 {"ok":true}Over MQTT
- Install the PubSubClient by Nick O'Leary library from Tools > Manage Libraries.
- In Code examples, choose MQTT, the ESP8266 tab, then Copy.
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
// MQTT on port 1883, the simplest way: no certificate needed.
// For an encrypted connection, choose port 8883 (TLS) instead.
const char* WIFI_SSID = "your-wifi";
const char* WIFI_PASSWORD = "your-password";
const char* HOST = "app.include.co.id";
const int PORT = 1883;
const char* DEVICE_ID = "YOUR_DEVICE_ID";
const char* DEVICE_TOKEN = "YOUR_DEVICE_TOKEN";
const char* TOPIC = "includeapps/YOUR_ORG_ID/YOUR_SOLUTION_SLUG/YOUR_DEVICE_ID/telemetry";
WiFiClient net;
PubSubClient mqtt(net);
void connectMqtt() {
while (!mqtt.connected()) {
if (mqtt.connect(DEVICE_ID, DEVICE_ID, DEVICE_TOKEN)) {
Serial.println("MQTT connected");
} else {
Serial.printf("MQTT failed, state %d, retrying\n", mqtt.state());
delay(5000);
}
}
}
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA);
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED) delay(500);
Serial.println("WiFi connected");
mqtt.setServer(HOST, PORT);
mqtt.setBufferSize(512);
}
void loop() {
connectMqtt();
mqtt.loop();
float temperature = 25.4; // replace with your sensor reading
float humidity = 61;
String payload = "{\"temperature\": " + String(temperature, 1) +
", \"humidity\": " + String(humidity, 0) + "}";
bool sent = mqtt.publish(TOPIC, payload.c_str());
Serial.println(sent ? "sent" : "send failed");
delay(10000);
}This sketch uses port 1883, with no certificate and no NTP. In the Serial Monitor: WiFi connected, MQTT connected, then sent every 10 seconds.
With TLS (port 8883)
Choose port 8883 (TLS) in Code examples. Like the HTTP version, the sketch gets the time from NTP, then checks the server certificate:
#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>
#include <PubSubClient.h>
#include <time.h>
const char* WIFI_SSID = "your-wifi";
const char* WIFI_PASSWORD = "your-password";
const char* HOST = "app.include.co.id";
const int PORT = 8883;
const char* DEVICE_ID = "YOUR_DEVICE_ID";
const char* DEVICE_TOKEN = "YOUR_DEVICE_TOKEN";
const char* TOPIC = "includeapps/YOUR_ORG_ID/YOUR_SOLUTION_SLUG/YOUR_DEVICE_ID/telemetry";
// Root certificates for app.include.co.id (Let's Encrypt ISRG Root X1 and X2).
const char ROOT_CA[] PROGMEM = R"PEM(
-----BEGIN CERTIFICATE-----
MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4
WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu
ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY
MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc
h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+
0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U
A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW
T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH
B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC
B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv
KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn
OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn
jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw
qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI
rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV
HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq
hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL
ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ
3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK
NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5
ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur
TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC
jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc
oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq
4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA
mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d
emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIICGzCCAaGgAwIBAgIQQdKd0XLq7qeAwSxs6S+HUjAKBggqhkjOPQQDAzBPMQsw
CQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJuZXQgU2VjdXJpdHkgUmVzZWFyY2gg
R3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBYMjAeFw0yMDA5MDQwMDAwMDBaFw00
MDA5MTcxNjAwMDBaME8xCzAJBgNVBAYTAlVTMSkwJwYDVQQKEyBJbnRlcm5ldCBT
ZWN1cml0eSBSZXNlYXJjaCBHcm91cDEVMBMGA1UEAxMMSVNSRyBSb290IFgyMHYw
EAYHKoZIzj0CAQYFK4EEACIDYgAEzZvVn4CDCuwJSvMWSj5cz3es3mcFDR0HttwW
+1qLFNvicWDEukWVEYmO6gbf9yoWHKS5xcUy4APgHoIYOIvXRdgKam7mAHf7AlF9
ItgKbppbd9/w+kHsOdx1ymgHDB/qo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0T
AQH/BAUwAwEB/zAdBgNVHQ4EFgQUfEKWrt5LSDv6kviejM9ti6lyN5UwCgYIKoZI
zj0EAwMDaAAwZQIwe3lORlCEwkSHRhtFcP9Ymd70/aTSVaYgLXTWNLxBo1BfASdW
tL4ndQavEi51mI38AjEAi/V3bNTIZargCyzuFJ0nN6T5U6VR5CmD1/iQMVtCnwr1
/q4AaOeMSQ+2b1tbFfLn
-----END CERTIFICATE-----
)PEM";
BearSSL::X509List roots(ROOT_CA);
BearSSL::WiFiClientSecure tls;
PubSubClient mqtt(tls);
void connectMqtt() {
while (!mqtt.connected()) {
if (mqtt.connect(DEVICE_ID, DEVICE_ID, DEVICE_TOKEN)) {
Serial.println("MQTT connected");
} else {
Serial.printf("MQTT failed, state %d, retrying\n", mqtt.state());
delay(5000);
}
}
}
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA);
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED) delay(500);
Serial.println("WiFi connected");
// Certificate checks need the real time.
configTime(0, 0, "pool.ntp.org", "time.google.com");
while (time(nullptr) < 1700000000) delay(500);
tls.setTrustAnchors(&roots);
mqtt.setServer(HOST, PORT);
mqtt.setBufferSize(512);
}
void loop() {
connectMqtt();
mqtt.loop();
float temperature = 25.4; // replace with your sensor reading
float humidity = 61;
String payload = "{\"temperature\": " + String(temperature, 1) +
", \"humidity\": " + String(humidity, 0) + "}";
bool sent = mqtt.publish(TOPIC, payload.c_str());
Serial.println(sent ? "sent" : "send failed");
delay(10000);
}Reading a real sensor
The ESP8266 has one analog pin, A0, reading 0 to 1023. For an analog soil moisture sensor:
float soil = analogRead(A0) * 100.0 / 1023.0; // percent, 0 = dryThen send it under a matching key, for example "{\"soil_moisture\": " + String(soil, 0) + "}".
If it does not work
| In the Serial Monitor | Meaning |
|---|---|
Stops before WiFi connected | Wrong WiFi name or password, or the WiFi is 5 GHz. |
Stops after WiFi connected | No time from NTP yet. Try another network or a phone hotspot. |
HTTP -1 | No connection to the server, or the certificate was refused. Check ROOT_CA is complete. |
HTTP 401 | Wrong token. Copy the code again from Koneksi & Integrasi. |
MQTT failed, state 4 or 5 | Wrong Device ID or Device Token. |
| The board keeps restarting | Not enough power. Use another USB port or a 5 V 1 A supply. |
See also No data arriving.

