How do you specifically add a water level sensor device using ESP Rainmaker?

RalphHenry
Posts: 2
Joined: Tue Mar 05, 2024 5:15 pm

How do you specifically add a water level sensor device using ESP Rainmaker?

Postby RalphHenry » Tue Mar 05, 2024 5:28 pm

Hello everyone, I would like to ask on how you do specifically add a water level device using ESP Rainmaker?. Because it seems that whenever I try to create one, there's always these PARAM errors. This water level sensor device is the usual small and color red sensor that I plugged into my breadboard along with the ESP32.

This is how I declared the water level sensor device:

Code: Select all

 static Device water_level_sensor("Water Level Sensor");
Then this is how I add a water level parameter:

Code: Select all

 static Param water_level_param("Water Level", "percentage", RMAKER_VAL_TYPE_INTEGER, 0);
This is how I would send the sensor result to the ESP Rainmaker:

Code: Select all

water_level_param.updateAndReport((param_val_t)water_level_percentage); 
In this line is where the error usually occurs:

Code: Select all

static Param water_level_param("Water Level", "percentage", RMAKER_VAL_TYPE_INTEGER, 0); 
The error states that:

Code: Select all

error: no matching function for call to 'Param::Param(const char [12], const char [11], esp_rmaker_val_type_t, int)'
     static Param water_level_param("Water Level", "percentage", RMAKER_VAL_TYPE_INTEGER, 0); 
My goal is to display the water level sensor result at the ESP Rainmaker App, but it seems that it's not possible at the moment due these param errors.

This is my full source code (wherein it captures the temperature and humidity (from DHT11 sensor) and water level results (from water level sensor) and passes them to the ESP Rainmaker App):

Code: Select all

#include "RMaker.h"
#include <RMakerParam.h>
#include <RMakerDevice.h>
#include <RMakerNode.h>
#include <WiFi.h>
#include <WiFiProv.h>
#include <DHT.h>
#include <SimpleTimer.h>
#include <wifi_provisioning/manager.h>

// Set Default Values
#define DEFAULT_Temperature 0
#define DEFAULT_Humidity 0

// BLE Credentials
const char *service_name = "myservice";
const char *pop = "mypass";

// GPIO
static uint8_t gpio_reset = 0;
static uint8_t DHTPIN = 23;

bool wifi_connected = false;

DHT dht(DHTPIN, DHT11);

SimpleTimer Timer;

// Declaring Devices
static TemperatureSensor temperature("Temperature");
static TemperatureSensor humidity("Humidity");
static Device water_level_sensor("Water Level Sensor");

void sysProvEvent(arduino_event_t *sys_event) {
    switch (sys_event->event_id) {
        case ARDUINO_EVENT_PROV_START:
#if CONFIG_IDF_TARGET_ESP32
            Serial.printf("\nProvisioning Started with name \"%s\" and PoP \"%s\" on BLE\n", service_name, pop);
            printQR(service_name, pop, "ble");
#else
            Serial.printf("\nProvisioning Started with name \"%s\" and PoP \"%s\" on SoftAP\n", service_name, pop);
            printQR(service_name, pop, "softap");
#endif
            break;
        case ARDUINO_EVENT_WIFI_STA_CONNECTED:
            Serial.printf("\nConnected to Wi-Fi!\n");
            wifi_connected = true;
            delay(500);
            break;
        case ARDUINO_EVENT_PROV_CRED_RECV: {
            Serial.println("\nReceived Wi-Fi credentials");
            Serial.print("\tSSID : ");
            Serial.println((const char *)sys_event->event_info.prov_cred_recv.ssid);
            Serial.print("\tPassword : ");
            Serial.println((char const *)sys_event->event_info.prov_cred_recv.password);
            break;
        }
        case ARDUINO_EVENT_PROV_INIT:
            wifi_prov_mgr_disable_auto_stop(10000);
            break;
        case ARDUINO_EVENT_PROV_CRED_SUCCESS:
            Serial.println("Stopping Provisioning!!!");
            wifi_prov_mgr_stop_provisioning();
            break;
    }
}

void write_callback(Device *device, Param *param, const param_val_t val, void *priv_data, write_ctx_t *ctx) {
    const char *device_name = device->getDeviceName();
    Serial.println(device_name);
    const char *param_name = param->getParamName();
}

void setup() {
    Serial.begin(115200);

    // Configure the input GPIOs
    pinMode(gpio_reset, INPUT);

    // Beginning Sensor
    dht.begin();

    // Declaring Node
    Node my_node = RMaker.initNode("ESP32 Project 2");

    // Adding Devices in Node
    my_node.addDevice(temperature);
    my_node.addDevice(humidity);
    my_node.addDevice(water_level_sensor);

    // Enable OTA
    RMaker.enableOTA(OTA_USING_PARAMS);

    // Enable timezone service
    RMaker.enableTZService();

    // Enable scheduling
    RMaker.enableSchedule();

    Serial.printf("\nStarting ESP-RainMaker\n");
    RMaker.start();

    // Timer for Sending Sensor's Data
    Timer.setInterval(3000);

    WiFi.onEvent(sysProvEvent);

#if CONFIG_IDF_TARGET_ESP32
    WiFiProv.beginProvision(WIFI_PROV_SCHEME_BLE, WIFI_PROV_SCHEME_HANDLER_FREE_BTDM, WIFI_PROV_SECURITY_1, pop, service_name);
#else
    WiFiProv.beginProvision(WIFI_PROV_SCHEME_SOFTAP, WIFI_PROV_SCHEME_HANDLER_NONE, WIFI_PROV_SECURITY_1, pop, service_name);
#endif

    // Add water level parameter
    static Param water_level_param("Water Level", "percentage", RMAKER_VAL_TYPE_INTEGER, 0);
    water_level_sensor.addParam(water_level_param);
}

void loop() {
    if (Timer.isReady() && wifi_connected) {
        // Check if the timer is ready
        Serial.println("Sending Sensor's Data");
        Send_Sensor();
        Timer.reset(); // Reset the timer
    }

    // Logic to Reset RainMaker
    if (digitalRead(gpio_reset) == LOW) {
        // Push button pressed
        Serial.printf("Reset Button Pressed!\n");
        // Key debounce handling
        delay(100);
        int startTime = millis();
        while (digitalRead(gpio_reset) == LOW)
            delay(50);
        int endTime = millis();

        if ((endTime - startTime) > 10000) {
            // If key pressed for more than 10secs, reset all
            Serial.printf("Reset to factory.\n");
            wifi_connected = false;
            RMakerFactoryReset(2);
        } else if ((endTime - startTime) > 3000) {
            Serial.printf("Reset Wi-Fi.\n");
            wifi_connected = false;
            // If key pressed for more than 3secs, but less than 10, reset Wi-Fi
            RMakerWiFiReset(2);
        }
    }
    delay(100);
}

void Send_Sensor() {
    // Read temperature, humidity, and water level
    float h = dht.readHumidity();
    float t = dht.readTemperature();
    int water_level_reading = readWaterLevel();

    // Check if the readings are valid
    if (isnan(h) || isnan(t) || water_level_reading == -1) {
        Serial.println("Failed to read from sensors");
        return;
    }

    // Print sensor readings
    Serial.print("Temperature - ");
    Serial.println(t);
    Serial.print("Humidity - ");
    Serial.println(h);
    Serial.print("Water Level - ");
    Serial.println(water_level_reading);

    // Update and report temperature parameter
    temperature.updateAndReportParam("Temperature", t);

    // Update and report humidity parameter
    humidity.updateAndReportParam("Humidity", h);

    // Update and report water level parameter
    float water_level_percentage = map(water_level_reading, 0, 4095, 0, 100);
    water_level_percentage = constrain(water_level_percentage, 0, 100);
    water_level_param.updateAndReport((param_val_t)water_level_percentage);
}

int readWaterLevel() {
    const int POWER_PIN = 17; // GPIO pin connected to power pin of water level sensor
    const int SIGNAL_PIN = 36; // GPIO pin connected to signal pin of water level sensor

    int value = -1;

    // Power on the sensor
    pinMode(POWER_PIN, OUTPUT);
    digitalWrite(POWER_PIN, HIGH);
    delay(10);

    // Read the analog value from the sensor
    pinMode(SIGNAL_PIN, INPUT);
    value = analogRead(SIGNAL_PIN);

    // Power off the sensor
    digitalWrite(POWER_PIN, LOW);

    return value;
}

Your response and feedback would definitely help me in resolving these errors. Thank you very much!

liaifat85
Posts: 137
Joined: Wed Dec 06, 2023 2:46 pm

Re: How do you specifically add a water level sensor device using ESP Rainmaker?

Postby liaifat85 » Wed Mar 06, 2024 2:41 pm

The error message indicates that there's no matching function because the last parameter you're passing is an integer (0), but it should be of type param_val_t.

RalphHenry
Posts: 2
Joined: Tue Mar 05, 2024 5:15 pm

Re: How do you specifically add a water level sensor device using ESP Rainmaker?

Postby RalphHenry » Thu Mar 07, 2024 11:32 am

Yes, I already tried that several times by using

Code: Select all

param_val_t
:

Code: Select all

#include <RMaker.h>
#include <WiFi.h>
#include <WiFiProv.h>
#include <DHT.h>
#include <SimpleTimer.h>
#include <wifi_provisioning/manager.h>
#include <LiquidCrystal_I2C.h>

#define SERVICE_NAME "bethrose26"
#define SERVICE_POP "RE98rc0802"
#define GPIO_RESET 0
#define DHTPIN 23
#define POWER_PIN 17   // Power pin of water level sensor
#define SIGNAL_PIN 36  // Signal pin of water level sensor

DHT dht(DHTPIN, DHT11);
LiquidCrystal_I2C lcd(0x27, 16, 2);

Param temperature;
Param humidity;
Param waterLevelParam;
bool wifi_connected = false;

void setup() {
  Serial.begin(115200);
  dht.begin();
  lcd.init();
  lcd.backlight();
  pinMode(GPIO_RESET, INPUT);
  WiFi.onEvent(sysProvEvent);

#if CONFIG_IDF_TARGET_ESP32
  WiFiProv.beginProvision(WIFI_PROV_SCHEME_BLE, WIFI_PROV_SCHEME_HANDLER_FREE_BTDM, WIFI_PROV_SECURITY_1, SERVICE_POP, SERVICE_NAME);
#else
  WiFiProv.beginProvision(WIFI_PROV_SCHEME_SOFTAP, WIFI_PROV_SCHEME_HANDLER_NONE, WIFI_PROV_SECURITY_1, SERVICE_POP, SERVICE_NAME);
#endif
}

void loop() {
  updateLCD();
  resetCheck();
  sendSensorData();
  delay(100);
}

void updateLCD() {
  lcd.clear();
  float temperatureValue = readDHTTemperature();
  float humidityValue = readDHTHumidity();
  int waterLevel = readWaterLevel();

  if (temperatureValue != -1) {
    lcd.setCursor(0, 0);
    lcd.print("Temp:");
    lcd.print(temperatureValue);
    lcd.print(" C");
  }

  if (humidityValue != -1) {
    lcd.setCursor(0, 1);
    lcd.print("Humidity:");
    lcd.print(humidityValue);
    lcd.print("%");
  }

  if (waterLevel != -1) {
    lcd.setCursor(0, 2);
    lcd.print("Water lvl:");
    lcd.print(waterLevel);
    lcd.print("%");
  }
}

void resetCheck() {
  if (digitalRead(GPIO_RESET) == LOW) {
    Serial.println("Reset Button Pressed!");
    delay(100);
    int startTime = millis();
    while (digitalRead(GPIO_RESET) == LOW) delay(50);
    int endTime = millis();

    if ((endTime - startTime) > 10000) {
      Serial.println("Reset to factory settings.");
      RMakerFactoryReset(2);
    } else if ((endTime - startTime) > 3000) {
      Serial.println("Reset Wi-Fi configuration.");
      RMakerWiFiReset(2);
    }
  }
  delay(100);
}


float readDHTTemperature() {
  float t = dht.readTemperature();
  if (isnan(t)) {
    Serial.println("Failed to read from DHT sensor!");
    return -1;
  } else {
    Serial.println(t);
    return t;
  }
}

float readDHTHumidity() {
  float h = dht.readHumidity();
  if (isnan(h)) {
    Serial.println("Failed to read from DHT sensor!");
    return -1;
  } else {
    Serial.println(h);
    return h;
  }
}

int readWaterLevel() {
  int value = 0;
  pinMode(POWER_PIN, OUTPUT);
  digitalWrite(POWER_PIN, HIGH);
  delay(10);
  value = analogRead(SIGNAL_PIN);
  digitalWrite(POWER_PIN, LOW);
  return map(value, 0, 4095, 0, 100);
}

void sysProvEvent(arduino_event_t *sys_event) {
  switch (sys_event->event_id) {
    case ARDUINO_EVENT_PROV_START:
#if CONFIG_IDF_TARGET_ESP32
      Serial.printf("\nProvisioning Started with name \"%s\" and PoP \"%s\" on BLE\n", SERVICE_NAME, SERVICE_POP);
      printQR(SERVICE_NAME, SERVICE_POP, "ble");
#else
      Serial.printf("\nProvisioning Started with name \"%s\" and PoP \"%s\" on SoftAP\n", SERVICE_NAME, SERVICE_POP);
      printQR(SERVICE_NAME, SERVICE_POP, "softap");
#endif
      break;
    case ARDUINO_EVENT_WIFI_STA_CONNECTED:
      Serial.printf("\nConnected to Wi-Fi!\n");
      wifi_connected = true;
      delay(500);
      break;
    case ARDUINO_EVENT_PROV_CRED_RECV:
      Serial.println("\nReceived Wi-Fi credentials");
      Serial.print("\tSSID : ");
      Serial.println((const char *) sys_event->event_info.prov_cred_recv.ssid);
      Serial.print("\tPassword : ");
      Serial.println((char const *) sys_event->event_info.prov_cred_recv.password);
      break;
    case ARDUINO_EVENT_PROV_INIT:
      wifi_prov_mgr_disable_auto_stop(10000);
      break;
    case ARDUINO_EVENT_PROV_CRED_SUCCESS:
      Serial.println("Stopping Provisioning!!!");
      wifi_prov_mgr_stop_provisioning();
      break;
  }
}



void sendSensorData() {
  float h = dht.readHumidity();
  float t = dht.readTemperature();
  int water_level_reading = analogRead(SIGNAL_PIN);

  const int WATER_LEVEL_MIN = 0;
  const int WATER_LEVEL_MAX = 4025;

  if (isnan(h) || isnan(t)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }

  float water_level_percentage = ((float)(water_level_reading - WATER_LEVEL_MIN) / (WATER_LEVEL_MAX - WATER_LEVEL_MIN)) * 100;
  water_level_percentage = constrain(water_level_percentage, 0, 100);

  Serial.print("Temperature - "); Serial.println(t);
  Serial.print("Humidity - "); Serial.println(h);
  Serial.print("Water Level - "); Serial.println(water_level_percentage);

  // Create param_val_t objects
  param_val_t tempVal;
  tempVal.f_float = t;

  param_val_t humVal;
  humVal.f_float = h;

  param_val_t waterLevelVal;
  waterLevelVal.f_float = water_level_percentage;

  // Update and report parameters
  temperature.updateAndReport(tempVal);
  humidity.updateAndReport(humVal);
  waterLevelParam.updateAndReport(waterLevelVal);
}

But then again, it will give me a compilation error:

Code: Select all

Compilation error: 'param_val_t' {aka 'struct esp_rmaker_param_val_t'} has no member named 'f_float'
Thus, the error that I am encountering is because the

Code: Select all

param_val_t
structure in ESP Rainmaker library doesn't have a member named

Code: Select all

f_float
. Instead, it uses a union to represent different types of parameter values. But then again, I am confused on what correct member types that I should be using and on what exactly is this union to use.

Who is online

Users browsing this forum: No registered users and 66 guests