Skocz do zawartości

Odczyt temperatur (ds18b20, esp8266) - nie działa gdy kod w klasie


Pomocna odpowiedź

Napisano (edytowany)

Witam.

Mam Moduł WiFi ESP8266 + NodeMCU v3 do którego mam podłączone dwa czujniki DS18B20 pod pin D7.

Z jakiegoś powodu czujniki nie są wykrywane.
Proszę o naprowadzenie dlaczego.

 

main.cpp

#include <Arduino.h>
#include "TemperatureSensorController.cpp"

TemperatureSensorController temperatureSensorController;

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

  temperatureSensorController = TemperatureSensorController(D7);
}

void loop()
{
  temperatureSensorController.printTemperatures();
  
  delay(1000);
}

TemperatureSensorController.cpp

#include <DallasTemperature.h>
#ifndef MYCLASS_H
#define MYCLASS_H

class TemperatureSensorController
{
public:
    TemperatureSensorController()
    {
    }

    TemperatureSensorController(uint8_t oneWireBus) : TemperatureSensorController()
    {
        _oneWire = OneWire(oneWireBus);
        _sensors = DallasTemperature(&_oneWire);
    }

    void printTemperatures()
    {  
        Serial.println("Print Temperatures");
        Serial.println("");

        delay(100);

        _sensors.begin();

        delay(100);

        _sensors.requestTemperatures();

        Serial.print("Device count: ");
        Serial.println(_sensors.getDeviceCount());
        Serial.println("");

        for (int i = 0; i < _sensors.getDeviceCount(); i++)
        {
            Serial.print("Device no. ");
            Serial.print(i + 1);
            Serial.print(" Temperature: ");
            Serial.print(_sensors.getTempCByIndex(i));
            Serial.println(" °C");
            delay(100);
        }

        Serial.println("");
        Serial.println("-----------------------");
        Serial.println("");
    }

public:
    OneWire _oneWire;
    DallasTemperature _sensors;
};

#endif

 

Wynik działania programu:
image.thumb.png.3d824c859cc52584c178d52593dbbdae.png


Fizycznie połączenia są ok - uruchamiając kod w którym wszystko jest w main.cpp odczyty wykonywane są poprawnie.

 

main.cpp

#include <Arduino.h>
#include "TemperatureSensorController.cpp"

OneWire oneWire = OneWire(D7);
DallasTemperature sensors = DallasTemperature(&oneWire);

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

  sensors.begin();
}

void loop()
{
  Serial.println("Print Temperatures");
  Serial.println("");

  delay(100);

  sensors.begin();

  delay(100);

  sensors.requestTemperatures();

  Serial.print("Device count: ");
  Serial.println(sensors.getDeviceCount());
  Serial.println("");

  for (int i = 0; i < sensors.getDeviceCount(); i++)
  {
    Serial.print("Device no. ");
    Serial.print(i + 1);
    Serial.print(" Temperature: ");
    Serial.print(sensors.getTempCByIndex(i));
    Serial.println(" °C");
    delay(100);
  }

  Serial.println("");
  Serial.println("-----------------------");
  Serial.println("");

  delay(5000);
}

 

Wynik działania programu:

image.thumb.png.77fbce02ce7a32cae5b7aa1ce645dd97.png


Z góry dziękuję za pomoc.

Edytowano przez TomaszFilipek

Wygląda na to, że klasa nie jest prawidłowo inicjowana. Proponuję jej definicję zmienić tak:

zamiast

    TemperatureSensorController(uint8_t oneWireBus) : TemperatureSensorController()
    {
        _oneWire = OneWire(oneWireBus);
        _sensors = DallasTemperature(&_oneWire);
    }

niech będzie

    void begin(uint8_t oneWireBus)
    {
        _oneWire = OneWire(oneWireBus);
        _sensors = DallasTemperature(&_oneWire);
    }

Zaś w setup() zmiast

temperatureSensorController = TemperatureSensorController(D7);

Wywołujemy wtedy

temperatureSensorController.begin(D7);

 

(edytowany)

@jand szczerze mówiąc nie bardzo rozumiem dlaczego, ale... działa!

W sumie rozumiem czemu teraz działa, ale nie rozumiem czemu z konstruktorem nie działało 😉

 

Dziękuję bardzo za pomoc.

Edytowano przez TomaszFilipek
Dnia 9.05.2024 o 15:13, TomaszFilipek napisał:

nie rozumiem czemu z konstruktorem nie działało

Pewnie by też działało, gdyby inicjalizacja danych w konstruktorze była przeprowadzona prawidłowo, tzn. zamiast:

    TemperatureSensorController(uint8_t oneWireBus) : TemperatureSensorController()

wpisałbyś:

  public:
    uint8_t oneWireBus = 0;
  TemperatureSensorController(uint8_t oneWirePin) : oneWireBus(oneWirePin)

Moje sugestie poszły jednak trochę dalej, gdyż jakoś mi się nie podobało dwukrotne używanie konstruktora (w różnych wersjach) dla tego samego obiektu - raz żeby go utworzyć, drugi raz by przypisać mu pin.

I jeszcze dwie kwestie:

W funkcji printTemperatures() nie używaj sensors.begin(). Jeden raz, w setup() wystarczy.

Nie ma potrzeby pisania domyślnego konstruktora (pustego). W razie potrzeby kompilator sam go doda.

 

 

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...