Hallo
Ich bin relativ neu im Arduino porgrammieren und habe auch kaum C++ Erfahrung. Daher bitte ich um Entschuldigung falls ich falsche Begriffe verwende.
Um die Übersicht zu bewahren habe ich begonnen mein Programm in verschiedenen Dateien zu strukturiren.
Der Konstruktor in meiner Library TemperatureSensors soll dabei aus der "OneWire" und "DallasTemperature" Libraries Objekte generieren.
Wenn ich nun in der Funktion auf "sensors" zugreifen möchte, kommt vom Kompiler die Fehlermeldung: "'sensors' was not declared in this scope". Wie muss ich den Code abändern, damit ich das Objekt "sensors" in allen Funktionen ansprechen kann?
Danke jetzt schon für eure wertvollen Tipps,
Urs
TemperatureSensors.h:
/// This files are made for a simple include of the temperature sensors (DS18B20) read.
/// The data wire of the sensors are all connected to 1 communication pin. This pin need to be connected over a 4k7 ohm
/// resistor to VCC. The identification of the sensors is according their serial number and need to be identified
/// before setting the up.
// Temperature Conversion Time
// 9-bit resolution -> 93.75 ms
// 10-bit resolution -> 187.5 ms
// 11-bit resolution -> 375.0 ms
// 12-bit resolution -> 750.0 ms
#ifndef __TEMPERATURESENSORS__
#define __TEMPERATURESENSORS__
#define MAX_AMOUNT_TEMPERATURE_SENSORS 8
#include <Arduino.h>
#include <OneWire.h>
#include <DallasTemperature.h>
class TemperatureSensors {
private:
byte _oneWirePin;
uint8_t _DeviceCount;
DeviceAddress TempAddress[MAX_AMOUNT_TEMPERATURE_SENSORS];
public:
TemperatureSensors (byte oneWirePin);
uint8_t getSensorAmount() ;
void printDetails() ;
};
#endif
TemperatureSensors.cpp:
#include "TemperatureSensors.h"
TemperatureSensors::TemperatureSensors (byte oneWirePin)
{
this->_oneWirePin = oneWirePin;
// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(_oneWirePin);
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
// Start up the library
sensors.begin();
// locate devices on the bus
_DeviceCount = sensors.getDeviceCount();
}
uint8_t TemperatureSensors::getSensorAmount() {
return _DeviceCount;
}
void TemperatureSensors::printDetails() {
Serial.println(_DeviceCount);
Serial.println(" Temperature Sensors were found on the one wire bus\n");
// Print adresses
for (uint8_t i = 0; i < _DeviceCount; i++) {
if ( sensors.getAddress(TempAddress[i], i) ) {
//Serial.print(i);
//Serial.print(": ");
//printAddress(TempAddress[i]);
}
else {
Serial.print("Unable to find address for Device ");
Serial.println(i);
}
//Serial.println(" ");
}
}
TemperatureSensors.cpp (1.04 KB)
TemperatureSensors.h (964 Bytes)
Du solltest das DallasTemperature Objekt nicht lokal im Konstruktor erzeugen, sondern zu einem Klassenbestandteil machen.
Da du das Objekt erzeugen willst, hast du grundsätzlich zwei Möglichkeiten.
- du erzeugst ein Member Objekt
- du machst dich zu einer Unterklasse des Objekts
Ein konkretes Beispiel, dass dir die Vorgehensweisen deutlich machen sollte:
class BeispielObjekt {
byte _pin;
public:
BeispielObjekt(byte pin) : _pin(pin) {
}
byte getPin() {
return _pin;
}
};
class IchHabeEinBeispielObjekt {
BeispielObjekt meins;
public:
IchHabeEinBeispielObjekt(byte pin) : meins(pin) {
}
byte getPin() {
return meins.getPin();
}
};
class IchBinEinBeispielObjekt : public BeispielObjekt {
public:
IchBinEinBeispielObjekt(byte pin) : BeispielObjekt(pin) {
}
};
IchHabeEinBeispielObjekt Habe(2);
IchBinEinBeispielObjekt Bin(3);
void setup() {
Serial.begin(250000);
Serial.print(F("Pin von Habe "));
Serial.println(Habe.getPin());
Serial.print(F("Pin von Bin "));
Serial.println(Bin.getPin());
}
void loop() {}
Pin von Habe 2
Pin von Bin 3
So kommt der Pin ins Objekt. 
Das Stichwort heißt "Initialisierungsliste". Wurde oben gezeigt.
Wenn du im Konstruktor bist, hast du erstens lokalen Scope und zweitens wurden alle Objekte die immer Header deklariert wurden schon erzeugt sofern das mit dem Standard Konstruktor möglich ist. Wenn man also Parameter an den Konstruktor des Member-Objekts durchreichen muss, muss das außerhalb des Konstruktors geschehen. Und dafür gibt es eben die Liste mit dem Doppelpunkt
Initialisierungslisten erlauben auch das Setzen von Konstanten,
im konkreten Beispiel könnte man also _pin const machen (und es geht immer noch)
class BeispielObjekt {
const byte _pin;
public:
BeispielObjekt(byte pin) : _pin(pin) {
}
byte getPin() {
return _pin;
}
};
Herzlichen Dank für eure Hilfe. Ein paar kleine Änderungen und es funktioniert wie gewünscht und ich habe wieder was gelernt. Hier die Umsetzung. Jetzt kann ich weiter machen =)
TemperatureSensors.h
/// This files are made for a simple include of the temperature sensors (DS18B20) read.
/// The data wire of the sensors are all connected to 1 communication pin. This pin need to be connected over a 4k7 ohm
/// resistor to VCC. The identification of the sensors is according their serial number and need to be identified
/// before setting the up.
// Temperature Conversion Time
// 9-bit resolution -> 93.75 ms
// 10-bit resolution -> 187.5 ms
// 11-bit resolution -> 375.0 ms
// 12-bit resolution -> 750.0 ms
#ifndef __TEMPERATURESENSORS__
#define __TEMPERATURESENSORS__
#define MAX_AMOUNT_TEMPERATURE_SENSORS 8
#include <Arduino.h>
#include <OneWire.h>
#include <DallasTemperature.h>
class TemperatureSensors {
// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire;
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors;
private:
byte _oneWirePin;
uint8_t _DeviceCount;
DeviceAddress TempAddress[MAX_AMOUNT_TEMPERATURE_SENSORS];
public:
TemperatureSensors (byte oneWirePin);
uint8_t getSensorAmount() ;
void printDetails() ;
};
#endif
TemperatureSensors.cpp
#include "TemperatureSensors.h"
TemperatureSensors::TemperatureSensors (byte oneWirePin):
oneWire(oneWirePin), sensors(&oneWire)
{
this->_oneWirePin = oneWirePin;
// Start up the library
sensors.begin();
// locate devices on the bus
_DeviceCount = sensors.getDeviceCount();
}
uint8_t TemperatureSensors::getSensorAmount() {
return _DeviceCount;
}
void TemperatureSensors::printDetails() {
Serial.println(_DeviceCount);
Serial.println(" Temperature Sensors were found on the one wire bus\n");
// Print adresses
for (uint8_t i = 0; i < _DeviceCount; i++) {
if ( sensors.getAddress(TempAddress[i], i) ) {
//Serial.print(i);
//Serial.print(": ");
//printAddress(TempAddress[i]);
}
else {
Serial.print("Unable to find address for Device ");
Serial.println(i);
}
//Serial.println(" ");
}
}
Warum speicherst du den Pin zusätzlich nochmal in der Klasse ab?
Nötig ist das nicht, OneWire muss es wissen, sonst eigentlich doch niemand, oder?