Chiarimenti su uso Oggetto "terzo" in una Classe

ciao a Tutti,

per un progetto che sto seguendo devo gestire delle sonde DS18B20; queste ovviamente richiedono l'inclusione della OneWire e della DallasTemperature...e fin qui nessun problema.
volevo attribuira/aggiungere ad ogni sonda una serie di "servizi" tipo ritorno stato del dato come "nuovo dato", "allarme", "no nuovo dato" etc..e quindi stavo creando una mia libreria; in un primo tentativo passavo al costruttore della nuova libreria l'Oggetto DallasTemperature come riferimento (quindi relativi oggetti OneWire e Dallas creati nel corpo del programma)...nella libreria gestino la Dallas come puntatore e fin qui nessun problema...poi ho pensato che avrei potuto creare l'oggetto OneWire e Dallas direttamente nella libreria e così il corpo del programma sarebbe stato più snello...e qua i problemi...il compilatore NON da errori ma ho un comportamento strano ...il valore dello stato ritorna semore "no nuovo dato" anche se il valore ritornato dalla sonda è "-127.0" che vuol dire "errore"...e questo è il valore che ho permanentemente.
giù allego codice prima funzionante e poi non funzionante.

file.h

// CLASSE PER SONDA DS18B20 SENZA DELAY
#ifndef SONDA_h // inizio file Sonda.h
#define SONDA_h

#define DATA_UPDATE 1000

#include <Arduino.h>
#include <DallasTemperature.h>

enum class stato : int8_t {
  errore = -1,
  noData = 0,
  newData = 1,
};

class Sonda {

  private:
    stato _return;
    DallasTemperature *_sonda; // puntatore oggetto sonda DS18B20
    uint32_t _millis; // tiene in memoria il tempo trascorso

  public:
    Sonda(DallasTemperature &); // costruttore a cui passare oggetto DallasTemperature
    void start(void); // per inizializzare oggetto
    stato execute(int32_t &); // da eseguire nel loop per acquisire temperatura
};
#endif // fine file Sonda.h

file .cpp

#include "Sonda.h"

Sonda::Sonda(DallasTemperature &__sonda) {
  _sonda = &__sonda;
}

void Sonda::start(void) {
  _sonda->begin();
  _sonda->setWaitForConversion(false);
  _sonda->requestTemperatures();
  _millis = millis();
  _return = stato::noData;
}


stato Sonda::execute(int32_t &_TempInt) {
  if (_return == stato::newData || _return == stato::errore) {
    _return = stato::noData;
  }
  if (DATA_UPDATE < millis() - _millis) {
    _return = stato::newData;
    _TempInt = (int32_t)(_sonda->getTempCByIndex(0) * 10);
    _millis = millis();
    _sonda->requestTemperatures();
  }
  if (_TempInt == -1270) {
    _TempInt = -1271;
    _return = stato::errore;
  }
  return _return;
}

file .ino

#include "Sonda.h"
#include <OneWire.h>
#include <DallasTemperature.h>

OneWire ow(4);
DallasTemperature sonda(&ow);
Sonda mySonda(sonda);

void setup() {
  mySonda.start();
  Serial.begin(19200);

}

void loop() {
  int32_t value = 0;
  stato _stato;
  _stato = mySonda.execute(value);
  if (_stato == stato::newData) {
    Serial.print(millis());
    Serial.print(' ');
    Serial.println(value);
  }
  if (_stato == stato::errore) {
    Serial.print(millis());
    Serial.print(' ');
    Serial.println("errore");
  }
}

NON funzionante .h

// CLASSE PER SONDA DS18B20 SENZA DELAY
#ifndef SONDA_h // inizio file Sonda.h
#define SONDA_h

#define DATA_UPDATE 1000

#include <Arduino.h>
#include <DallasTemperature.h>
#include <OneWire.h>

enum class stato : int8_t {
  errore = -1,
  noData = 0,
  newData = 1,
};

class Sonda {

  private:
    stato _return;
    uint8_t _pin; // pin per onewire
    OneWire ow; // onewire
    DallasTemperature _sonda2; // sonda
    uint32_t _millis; // tiene in memoria il tempo trascorso

  public:
    Sonda(uint8_t); // costruttore a cui passare pin per OneWire
    void start2(void); // inizializza oggetto 
    stato execute(int32_t &); // da eseguire nel loop per acquisire temperatura e stato
};
#endif // fine file Sonda.h

NON funzionante .cpp

#include "Sonda.h"

Sonda::Sonda(uint8_t __pin) {
  _pin = __pin;
}

void Sonda::start2(void) {
  Serial.println(_pin);
  OneWire ow(_pin);
  DallasTemperature _sonda2(&ow);
  _sonda2.begin();
  _sonda2.setWaitForConversion(false);
  _sonda2.requestTemperatures();
  _millis = millis();
  _return = stato::noData;
}

stato Sonda::execute(int32_t &_TempInt) {
  if (_return == stato::newData || _return == stato::errore) {
    _return = stato::noData;
  }
  if (DATA_UPDATE < millis() - _millis) {
    _return = stato::newData;
    _TempInt = (int32_t)(_sonda2.getTempCByIndex(0) * 10);
    _millis = millis();
    _sonda2.requestTemperatures();
  }
  if (_TempInt == -1270) {
    _TempInt = -1271;
    _return = stato::errore;
  }
  return _return;
}

NON funzionante .ino

#include "Sonda.h"

Sonda mySonda(4);

void setup() {
  Serial.begin(19200);
    mySonda.start2();
}

void loop() {
  int32_t value = 0;
  stato _stato;
  _stato = mySonda.execute(value);
  if (_stato == stato::newData) {
    Serial.print(millis());
    Serial.print(' ');
    Serial.println(value);
  }
  if (_stato == stato::errore) {
    Serial.print(millis());
    Serial.print(' ');
    Serial.println("errore");
  }
}

non è un problema tornare al passaggio per riferimento all'Oggetto Dallas...ma volevo capire cosa sbaglio...

PS: dico che la sonda ritorna semore "-127.0", che poi converto in "-1270" perchè avevo messo una Serial.print all'interno del metodo per vedere cosa succedeva e con quel valore mi aspetterei almento di stampare "errore" nel .ino....ma non è così...

hai un problema di scope qui (void Sonda::start2(void) { )
ow è locale alla funzione e verrà distrutto al termine della funzione.

Così come dichiari ow non è corretto. Tu dichiari un oggetto ow di classe OneWire come membro ed anche un'altro oggetto ow di classe OneWire dentro a start, che solo x caso hanno lo stesso nome. Devono essere puntatori a quegli oggetti. Non oggetti veri e propri.

È come se tu dichiarassi 2 int con stesso nome ma i due si nascondono tra loro (scope e visibilità variabili del C). Fossero int, devi dichiarare un puntatore int e poi quando chiami start2 assegni a puntatore ow un nuovo int creato in quel momento con new

int *ow; alloca un puntatore a nulla
....start2()
{ ow= new int(123); ora ow punta ad un int che vale 123

Mentre tu fai
int ow;
....start2()
{ int ow=123; questo ow è locale e non è lo stesso ow scritto fuori

grazie ad entrambi...immaginavo fosse un problema di visibilità ma non capivo come risolvere...l'inesperienza...ora funziona...

file .h

// CLASSE PER SONDA DS18B20 SENZA DELAY
#ifndef SONDA_h // inizio file Sonda.h
#define SONDA_h

#define DATA_UPDATE 1000

#include <Arduino.h>
#include <DallasTemperature.h>
#include <OneWire.h>

enum class stato : int8_t {
  errore = -1,
  noData = 0,
  newData = 1,
};

class Sonda {

  private:
    stato _return;
    uint8_t _pin; // pin per onewire
    OneWire *ow; // onewire
    DallasTemperature *_sonda2; // sonda
    uint32_t _millis; // tiene in memoria il tempo trascorso

  public:
    Sonda(uint8_t); // costruttore a cui passare pin per OneWire
    void start2(void); // inizializza oggetto 
    stato execute(int32_t &); // da eseguire nel loop per acquisire temperatura e stato
};
#endif // fine file Sonda.h

file .cpp

#include "Sonda.h"

Sonda::Sonda(uint8_t __pin) {
  _pin = __pin;
}

void Sonda::start2(void) {
  ow = new OneWire(_pin);
  _sonda2 = new DallasTemperature(ow);
  _sonda2->begin();
  _sonda2->setWaitForConversion(false);
  _sonda2->requestTemperatures();
  _millis = millis();
  _return = stato::noData;
}

stato Sonda::execute(int32_t &_TempInt) {
  if (_return == stato::newData || _return == stato::errore) {
    _return = stato::noData;
  }
  if (DATA_UPDATE < millis() - _millis) {
    _return = stato::newData;
    _TempInt = (int32_t)(_sonda2->getTempCByIndex(0) * 10);
    _millis = millis();
    _sonda2->requestTemperatures();
  }
  if (_TempInt == -1270) {
    _TempInt = -1271;
    _return = stato::errore;
  }
  return _return;
}

file .ino

#include "Sonda.h"

Sonda mySonda(4);

void setup() {
  Serial.begin(19200);
    mySonda.start2();
}

void loop() {
  int32_t value = 0;
  stato _stato;
  _stato = mySonda.execute(value);
  if (_stato == stato::newData) {
    Serial.print(millis());
    Serial.print(' ');
    Serial.println(value);
  }
  if (_stato == stato::errore) {
    Serial.print(millis());
    Serial.print(' ');
    Serial.println("errore");
  }
}

Bravo

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.