This project requires:
esp32 w/ ble
arduino ide
esp extension for arduino ide
dht-11 sensor
breadboard
jumper wires
thunkable
https://x.thunkable.com/projectPage/62a20fbda09dfa016f680c47
Once you upload the code to your esp32, connect your dht11 to power, grnd, and pin14, you’re set! restart the device, then fire up the thunkable app. connect your device and ensure the UUID’s are matching. from there you should be able to start reading directly from your device and displaying it nicely in your Thunkable app!
/*
Based on Neil Kolban example for IDF: https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLE%20Tests/SampleServer.cpp
Ported to Arduino ESP32 by Evandro Copercini
updates by chegewara
*/
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>
#include "DHTesp.h"
#include <string>
/** Comfort profile */
ComfortState cf;
// See the following for generating UUIDs:
// https://www.uuidgenerator.net/
#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"
BLECharacteristic *pCharacteristic;
#define DHTpin 14 //D5 of NodeMCU is GPIO14
DHTesp dht;
void setup() {
Serial.begin(115200);
Serial.println("Starting BLE work!");
Serial.println("Status\tHumidity (%)\tTemperature (C)\t(F)\tHeatIndex (C)\t(F)");
dht.setup(DHTpin, DHTesp::DHT11); //for DHT11 Connect DHT sensor to GPIO 17
BLEDevice::init("esp32 Weather Station");
BLEServer *pServer = BLEDevice::createServer();
BLEService *pService = pServer->createService(SERVICE_UUID);
pCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID,
BLECharacteristic::PROPERTY_READ |
BLECharacteristic::PROPERTY_WRITE
);
pCharacteristic->setValue("Hello World says Neil");
pService->start();
// BLEAdvertising *pAdvertising = pServer->getAdvertising(); // this still is working for backward compatibility
BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
pAdvertising->addServiceUUID(SERVICE_UUID);
pAdvertising->setScanResponse(true);
pAdvertising->setMinPreferred(0x06); // functions that help with iPhone connections issue
pAdvertising->setMinPreferred(0x12);
BLEDevice::setPower(ESP_PWR_LVL_P7, ESP_BLE_PWR_TYPE_DEFAULT);
BLEDevice::setPower(ESP_PWR_LVL_P7, ESP_BLE_PWR_TYPE_CONN_HDL0);
BLEDevice::setPower(ESP_PWR_LVL_P7, ESP_BLE_PWR_TYPE_CONN_HDL1);
BLEDevice::setPower(ESP_PWR_LVL_P7, ESP_BLE_PWR_TYPE_CONN_HDL2);
BLEDevice::setPower(ESP_PWR_LVL_P7, ESP_BLE_PWR_TYPE_CONN_HDL3);
BLEDevice::setPower(ESP_PWR_LVL_P7, ESP_BLE_PWR_TYPE_CONN_HDL4);
BLEDevice::setPower(ESP_PWR_LVL_P7, ESP_BLE_PWR_TYPE_CONN_HDL5);
BLEDevice::setPower(ESP_PWR_LVL_P7, ESP_BLE_PWR_TYPE_CONN_HDL6);
BLEDevice::setPower(ESP_PWR_LVL_P7, ESP_BLE_PWR_TYPE_CONN_HDL7);
BLEDevice::setPower(ESP_PWR_LVL_P7, ESP_BLE_PWR_TYPE_CONN_HDL8);
BLEDevice::setPower(ESP_PWR_LVL_P7, ESP_BLE_PWR_TYPE_ADV);
BLEDevice::setPower(ESP_PWR_LVL_P7, ESP_BLE_PWR_TYPE_SCAN);
BLEDevice::startAdvertising();
Serial.println("Characteristic defined! Now you can read it in your phone!");
}
void loop() {
delay(dht.getMinimumSamplingPeriod());
float humidity = dht.getHumidity();
float temperature = dht.getTemperature();
Serial.print(dht.getStatusString());
Serial.print("\t");
Serial.print(humidity, 1);
Serial.print("\t\t");
Serial.print(temperature, 1);
Serial.print("\t\t");
Serial.print(dht.toFahrenheit(temperature), 1);
Serial.print("\t\t");
Serial.print(dht.computeHeatIndex(temperature, humidity, false), 1);
Serial.print("\t\t");
Serial.println(dht.computeHeatIndex(dht.toFahrenheit(temperature), humidity, true), 1);
TempAndHumidity newValues = dht.getTempAndHumidity();
// Check if any reads failed and exit early (to try again).
if (dht.getStatus() != 0) {
Serial.println("DHT11 error status: " + String(dht.getStatusString()));
}
float heatIndex = dht.computeHeatIndex(newValues.temperature, newValues.humidity);
float dewPoint = dht.computeDewPoint(newValues.temperature, newValues.humidity);
float cr = dht.getComfortRatio(cf, newValues.temperature, newValues.humidity);
String comfortStatus;
switch (cf) {
case Comfort_OK:
comfortStatus = "Decent";
break;
case Comfort_TooHot:
comfortStatus = "Too hot";
break;
case Comfort_TooCold:
comfortStatus = "Too cold";
break;
case Comfort_TooDry:
comfortStatus = "Too dry";
break;
case Comfort_TooHumid:
comfortStatus = "Too humid";
break;
case Comfort_HotAndHumid:
comfortStatus = "Hot and humid";
break;
case Comfort_HotAndDry:
comfortStatus = "Hot and dry";
break;
case Comfort_ColdAndHumid:
comfortStatus = "Cold and humid";
break;
case Comfort_ColdAndDry:
comfortStatus = "Cold and dry";
break;
default:
comfortStatus = "psh, we don't know what to call it.";
break;
};
// create string
String myString = String("{\"T\":\"" + String(dht.toFahrenheit(newValues.temperature)) + "\",\"H\":\"" + String(newValues.humidity) + "\",\"I\":\"" + String(dht.toFahrenheit(heatIndex)) + "\",\"D\":\"" + String(dht.toFahrenheit(dewPoint)) + "\",\"comfort\":\" " + comfortStatus + "\"}");
Serial.println(myString);
// get length of string (with one extra character for the null terminator)
int str_len = myString.length() + 1;
// Prepare the character array (the buffer)
char char_array[str_len];
// copy the string into char_array
myString.toCharArray(char_array, str_len);
//update the ble characteristic
pCharacteristic->setValue(char_array);
}
d