i try to write a small program to control a pump and a valve connected with two ds18b20 temperature sensors on a raspberry pi 3B+. I defined a class for the pump and one for the valve, in the future more pumps and valves will be added, i also created a class for the ds18b20 sensor that is connected over 1 wire. The sensor can read out via a "file", so there is a base directory string baseDir = "/sys/bus/w1/devices/";
followed by the device id string tSensor1 = "28-3c01a81688f4";
and the temperature "file" string tempFile = "/w1_slave";
, the full path should look like this /sys/bus/w1/devices/28-3c01a81688f4/w1_slave
.
BUT what i get is this TestSensor1= Error reading file at /sys/bus/w1/devices//w1_slave
the device is missing, the same for TestSensor2= Error reading file at /sys/bus/w1/devices//w1_slave
.
the code is directly compiled on the rPi with g++ -Wall -o oww ofen-warmwasser.cpp -lwiringPi
this is my code
#include <wiringPi.h> // library to access the GPIO Pins on a raspberryPI !!deprecated!!
#include <iostream> // cout
#include <fstream> // file stream access
#include <string> // string class
#include <sstream> // string stream needed for file access to put data into string
//... code skipped ...
class temperaturSensor {
private:
string device;
string baseDir = "/sys/bus/w1/devices/";
string tempFile = "/w1_slave";
string path = baseDir + device + tempFile;
stringstream buffer;
string data;
string strTemp;
double temp = 987.6;
public:
// constructor declaration
temperaturSensor(string str);
// methodes
double temperatur() {
//cout << "----->>>> " << device << " ----->>>> " << path << endl;
ifstream infile(path);
if (infile) {
buffer << infile.rdbuf();
data = buffer.str();
infile.close();
}
else {
infile.close();
cout << "Error reading file at " << path << endl;
return -100;
}
size_t crcCheck = data.find("YES");
if (crcCheck == string::npos) {
cout << "CRC fail not reading temperatur" << endl;
return -101;
}
size_t TempPos = data.find("t=");
if (TempPos == string::npos) {
cout << "failed to find value -> abort!" << endl;
return -102;
}
strTemp = data.substr(TempPos+2);
temp = stod(strTemp)/1000;
return temp;
}
};
// constructor
temperaturSensor::temperaturSensor(string str) {
device = str;
}
int main(void) {
// test setup
pump boilerpumpe(21);
valve boilervalve(28);
string tSensor1 = "28-3c01a81688f4";
temperaturSensor testSensor1(tSensor1);
temperaturSensor testSensor2("28-3c01a816d9c1");
while (true)
{
boilerpumpe.on();
boilervalve.close();
cout << "TestSensor1= " << testSensor1.temperatur() << "°C \nTestSensor2= " << testSensor2.temperatur() << "°C" << endl;
delay(5*1000);
boilerpumpe.off();
boilervalve.open();
delay(5*1000);
}
return 0;
}
as you might see in the code i tried different things from declaring the the string device;
variable from private: to public: from the end of the class to the beginning, when i cout
the device variable it gets correctly displayed, i think the problem is somewhere here string path = baseDir + device + tempFile;
, i also tried string path = baseDir.append(device);
but with no success
any help appreciated, if more information is needed just tell me what and i try to provide
thanks etch
In your class declaration:
string device;
This class member is default-initialized to an empty string.
string baseDir = "/sys/bus/w1/devices/";
This class member gets default-initialized to the given string.
string tempFile = "/w1_slave";
This class member gets default-initialized to the given string.
string path = baseDir + device + tempFile;
And this class member gets initialized to the combined string. Remember that device
is an empty string, so path ends up getting set to "/sys/bus/w1/devices//w1_slave", which is what your code ends up attempting to open, and fails.
In your class's constructor:
device = str;
This sets a new value for device
. However it is too late, since the other class member, and path
specifically, are already initialized. It's not going to get initialized again, after the value of device
gets set. C++ does not work this way.
The simplest fix here is for your constructor to use its initialization section to initialize all class members, in order.