ESP32
Mengirim bacaan dari papan ESP32 ke INCLUDE dengan Arduino IDE, lewat HTTP atau MQTT. Kiriman HTTP terenkripsi dan sertifikat servernya diperiksa. MQTT bisa tanpa TLS di port 1883 (paling mudah) atau dengan TLS di port 8883.
Yang dibutuhkan
- Papan ESP32, misalnya ESP32 DevKit V1 atau ESP32-WROOM-32.
- Kabel USB yang bisa membawa data, bukan hanya daya.
- Arduino IDE versi 2.
- WiFi 2,4 GHz. ESP32 tidak bisa tersambung ke WiFi 5 GHz.
- Perangkat yang sudah dibuat di INCLUDE. Belum ada? Ikuti Perangkat rakitan sendiri, langkah 1.
1. Pasang dukungan ESP32 di Arduino IDE
Buka File > Preferences.
Di Additional boards manager URLs, tempel:
https://espressif.github.io/arduino-esp32/package_esp32_index.jsonTekan OK.
Buka Tools > Board > Boards Manager, cari
esp32, lalu pasang esp32 by Espressif Systems versi 3.x.
Cukup sekali per komputer.
2. Ambil kodenya dari INCLUDE
- Buka perangkat Anda, tab Pengaturan, lalu Koneksi & Integrasi.
- Di bagian Contoh kode, biarkan HTTP terpilih dan pilih tab ESP32.
- Tekan Salin.

Token perangkat sudah ada di dalam kode yang tersalin. Tempel ke sketsa baru di Arduino IDE.
3. Isi WiFi dan bacaan sensor
Kode lengkapnya, dengan token Anda di tempat YOUR_DEVICE_TOKEN:
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <HTTPClient.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 = 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";
WiFiClientSecure tls;
void setup() {
Serial.begin(115200);
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED) delay(500);
Serial.println("WiFi connected");
tls.setCACert(ROOT_CA);
}
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);
}Yang perlu diubah:
WIFI_SSIDdanWIFI_PASSWORD: nama dan kata sandi WiFi.- Dua baris
temperaturedanhumidity: ganti dengan bacaan sensor Anda. Nama kunci di dalambodymenjadi nama parameter di INCLUDE, jadi boleh diganti, misalnya"soil_moisture". delay(10000): jeda antarkiriman dalam milidetik. 10 sampai 60 detik cukup untuk hampir semua sensor.
ROOT_CA jangan diubah. Isinya sertifikat akar Let's Encrypt (ISRG Root X1 dan X2) yang menandatangani app.include.co.id. Dengan itu ESP32 memastikan ia benar-benar berbicara dengan INCLUDE sebelum mengirim token.
4. Unggah dan periksa
- Tools > Board > esp32 > ESP32 Dev Module (atau nama papan Anda).
- Tools > Port: pilih port papan. Di Windows
COM3atau sejenisnya, di macOS/dev/cu.usbserial-.... - Tekan Upload.
- Buka Tools > Serial Monitor dengan kecepatan 115200 baud.
Yang muncul kalau berhasil:
WiFi connected
HTTP 202 {"ok":true}Di INCLUDE, layar Koneksi & Integrasi berubah menjadi Data pertama masuk!, dan bacaan tampil di halaman perangkat.

Lewat MQTT
MQTT memakai satu koneksi yang tetap terbuka, lebih hemat untuk kiriman yang sering, dan bisa menerima perintah dari platform.
- Di Arduino IDE, buka Tools > Manage Libraries, cari
PubSubClient, pasang PubSubClient by Nick O'Leary. - Di Contoh kode, pilih MQTT, tab ESP32, lalu Salin.

#include <WiFi.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.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);
}Isi WiFi dan bacaan sensor seperti versi HTTP. Sketsa ini memakai port 1883, tanpa sertifikat. Di Serial Monitor:
WiFi connected
MQTT connected
sentDengan TLS (port 8883)
Untuk koneksi dan token yang terenkripsi, pilih port 8883 (TLS) di Contoh kode. Sketsanya membawa ROOT_CA seperti versi HTTP:
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <PubSubClient.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 = 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";
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.begin(WIFI_SSID, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED) delay(500);
Serial.println("WiFi connected");
tls.setCACert(ROOT_CA);
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);
}Membaca sensor sungguhan
Contoh dengan sensor suhu analog LM35 di pin GPIO 34. Ganti baris temperature:
float temperature = analogReadMilliVolts(34) / 10.0; // LM35: 10 mV per derajat CelsiusUntuk sensor lain, pakai library pabrikannya, lalu masukkan nilainya ke body dengan cara yang sama.
Kalau tidak berhasil
| Di Serial Monitor | Artinya |
|---|---|
Berhenti sebelum WiFi connected | Nama atau kata sandi WiFi salah, atau WiFi-nya 5 GHz. |
HTTP -1 | Tidak tersambung ke server. Periksa internet dari WiFi itu, dan ROOT_CA tidak terpotong saat disalin. |
HTTP 401 | Token salah. Salin ulang kode dari Koneksi & Integrasi. |
HTTP 429 | Terlalu sering. Perbesar delay. |
MQTT failed, state -2 | Tidak tersambung ke app.include.co.id di port 1883 atau 8883. Beberapa jaringan kantor memblokirnya; coba HTTP. |
MQTT failed, state 4 atau 5 | Device ID atau Device Token salah. |
sent lalu koneksi putus | Topik bukan milik perangkat ini. Salin ulang Topik telemetri. |
Panduan lengkapnya ada di Data belum masuk.

