BlueTooth Weather Station

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

1 Like