rjwats / esp8266-react

A framework for ESP8266 & ESP32 microcontrollers with a React UI
GNU Lesser General Public License v3.0
470 stars 145 forks source link

Variable declaration issue with DHT seonsor library #277

Closed spyflox closed 2 years ago

spyflox commented 2 years ago

Hi, I want to use DHT22 sensor (for read temperature and humidity). I use adafruit /DHT-sensor-library

I created a class in DhtSensorService.h

#define DHTPIN 14      // Digital pin connected to the DHT sensor
#define DHTTYPE DHT22   // DHT 22 (AM2302)

class DhtSensorService : public StatefulService<DhtSensor> {
  public: 
    DhtSensorService(AsyncWebServer* server, SecurityManager* securityManager);
    void begin();

  private:
    HttpEndpoint<DhtSensor> _httpEndpoint;
    WebSocketTxRx<DhtSensor> _webSocket;

    void readSensor(); 
};

Then in DhtSensorService.cpp

DhtSensorService::DhtSensorService(AsyncWebServer* server, SecurityManager* securityManager) :
    _httpEndpoint(DhtSensor::read, DhtSensor::update, this, server, DHT_SENSOR_ENDPOINT_PATH, securityManager, AuthenticationPredicates::IS_AUTHENTICATED),
    _webSocket(DhtSensor::read, DhtSensor::update, this, server, DHT_SENSOR_SOCKET_PATH, securityManager, AuthenticationPredicates::IS_AUTHENTICATED) {
    addUpdateHandler([&](const String& originId) { readSensor(); }, false);
}

DHT_Unified dht (DHTPIN, DHTTYPE);

void DhtSensorService::begin() {
  dht.begin();
  readSensor();
}
void DhtSensorService::readSensor() {
  // Get temperature event and print its value.
  sensors_event_t event;
  dht.temperature().getEvent(&event);
  if (isnan(event.temperature)) {
    Serial.println(F("Error reading temperature!"));
  }
  else {
    Serial.print(F("Temperature: "));
    Serial.print(event.temperature);
    Serial.println(F("°C"));
  }
}

The problem is that i can't read the temperature. The console displays : "Error reading temperature!"

I think I declared the dht variable incorrectly. Can you tell me how to do it please.

rjwats commented 2 years ago

Make sure you have include guards on your header file and you should probably move the declaration of the variable into the header file too.

Here's an example of this sort of thing (header and cpp):

https://github.com/rjwats/esp8266-react/blob/fermentation-chamber2/src/FermentationChamber.h https://github.com/rjwats/esp8266-react/blob/fermentation-chamber2/src/FermentationChamber.cpp

On Fri, 28 Jan 2022, 13:04 pontex, @.***> wrote:

Hi, I want to use DHT22 sensor (for read temperature and humidity). I use adafruit /DHT-sensor-library https://github.com/adafruit/DHT-sensor-library

I created a class in DhtSensorService.h

define DHTPIN 14 // Digital pin connected to the DHT sensor

define DHTTYPE DHT22 // DHT 22 (AM2302)

class DhtSensorService : public StatefulService {

public:

DhtSensorService(AsyncWebServer* server, SecurityManager* securityManager);

void begin();

private:

HttpEndpoint<DhtSensor> _httpEndpoint;

WebSocketTxRx<DhtSensor> _webSocket;

void readSensor();

};

Then in DhtSensorService.cpp

DHT_Unified dht (DHTPIN, DHTTYPE);

void DhtSensorService::begin() {

dht.begin();

readSensor();

}

void DhtSensorService::readSensor() {

// Get temperature event and print its value.

sensors_event_t event;

dht.temperature().getEvent(&event);

if (isnan(event.temperature)) {

Serial.println(F("Error reading temperature!"));

}

else {

Serial.print(F("Temperature: "));

Serial.print(event.temperature);

Serial.println(F("°C"));

}

}

I have a compilation error: .pio\build\node32s\src\main.cpp.o:(.bss.dht+0x0): multiple definition of `dht' .pio\build\node32s\src\DhtSensorService.cpp.o:(.bss.dht+0x0): first defined here

I think I I declared the dht variable incorrectly. Can you tell me how to do it please.

— Reply to this email directly, view it on GitHub https://github.com/rjwats/esp8266-react/issues/277, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAKE4VH4IZZMKA5Y4ZZ4LWTUYKH47ANCNFSM5NAWM5DQ . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

You are receiving this because you are subscribed to this thread.Message ID: @.***>

spyflox commented 2 years ago

Thanks @rjwats, I can read the values ​​of my sensor now and the data is displayed in web REST interface. I created a loop function that measures temperature and humidity every 5s.

void DhtSensorService::loop() {
    sensors_event_t event;
    _dht.temperature().getEvent(&event);

    if (isnan(event.temperature)) {
      Serial.println(F("Error reading temperature!"));
    }
    else {
      temperature = event.temperature;
      _state.temperature = event.temperature;
    }
   [... same for humidity]
}

However, I can't update automaticaly the websocket with every change in temperature or humidity. I must reload the page to see the changes.

I have understood that it is necessary to return StateUpdateResult::CHANGED to automatically update the websocket. Right ? But I don't understand where and how to implement this. Do you have an example?

rjwats commented 2 years ago

Yes, you will need to update the state using the callback approach so the observers get fired. Avoid mutating the state held by a stateful service directly because it bypasses the observer pattern.

So in your loop you will have somthing like:

update([&](DhtSensorState& state) {
  state.temperature = event.temperature;
  state.humidity = event.humidity;
  return StateUpdateResult::CHANGED;
}, "loop");

The docs describe this here:

https://github.com/rjwats/esp8266-react#stateful-service

spyflox commented 2 years ago

Thank you ! It works perfectly ;)

Small follow-up question: I plan to make a heating regulation for the home. I have relay outputs, some temperature probes, analogic sensors and a flow meter.

What is the best approach/practices in your opinion?

  1. just 2 files (.cpp and .h) with only one service (like https://github.com/rjwats/esp8266-react/tree/fermentation-chamber2/src)
  2. 1 service for each items (relay, sensors, flowmeter, etc.) + 1 global service which ensures the regulation of the outputs according to the values ​​of the inputs.
rjwats commented 2 years ago

Sorry I missed your follow-up question here. At this point it's probably personal preference but I generally prefer single purpose units and segregation (SOLID) where possible :)