How to put the object creation from the cpp into the h without getting an error.
-
Hello,
im trying to evaluate the Temperature with QT on Raspberry.
In order to do this depending on the time i'm using a qtimer or rather a loop.
So e.g. the sensor will be evaluate every 10 sec.To my problem:
Every 10 sec the funktion ReadTemperature will be called:Header: class ReadTemperature { private: char w1_address[16]; char w2_address[16]; const char* adr1 = "10-000803670e3c"; //Address Sensor 1 const char* adr2 = "10-000803676a62"; //Address Sensor 2 public: float actualTemp1; float actualTemp2; float ReadTemp(int number); }; Source: float ReadTemperature::ReadTemp(int number) { DS18B20 w1Device1 (adr1); DS18B20 w1Device2 (adr2); if(number == 1) { actualTemp1 = w1Device1.getTemp(); return actualTemp1; } else if(number == 2) { actualTemp2 = w1Device2.getTemp(); return actualTemp2; } }
the code for the .getTemp():
Header: #define CELCIUS 1 #define FAHRENHEIT 0 #define BUS "/sys/bus/w1/devices/" #define TEMPFILE "/w1_slave" class DS18B20 { public: DS18B20(const char* address); virtual ~DS18B20(); uint8_t getUnits(); void setUnits(uint8_t); float getTemp(); float CtoF(float); private: QMessageBox* ErrorBox = new QMessageBox; QPixmap P; uint8_t unit_; char* address_; char path[46]; // path should be 46 chars }; Source: float DS18B20::getTemp() { FILE *devFile; try { devFile = fopen(path, "r"); if (devFile == NULL) { throw "Sensor Initialisationerror"; } float temp = -1; if (devFile != NULL) { if (!ferror(devFile)) { unsigned int tempInt; char crcConf[5]; fscanf(devFile, "%*x %*x %*x %*x %*x %*x %*x %*x %*x : crc=%*x %s", crcConf); if (strncmp(crcConf, "YES", 3) == 0) { fscanf(devFile, "%*x %*x %*x %*x %*x %*x %*x %*x %*x t=%5d", &tempInt); temp = (float) tempInt / 1000.0; } } } fclose(devFile); if (unit_ == CELCIUS) { return temp; } else return CtoF(temp); } catch (const char* e) { ErrorBox->setText(e); ErrorBox->setWindowTitle("ERROR"); ErrorBox->setModal(false); ErrorBox->setIcon(QMessageBox::Critical); ErrorBox->show(); } }
Now really to the problem:
if the error trigger the errorbox will spawn every 10 sec. even if I haven't closed it. So after 10 minutes the hole screen is full of Msg boxes^^.
I think the mistake is that every time i call the funktion ReadTemperature i'm creating a new Object of DS18B20.
I think if i create it only once e.g. in the header file of ReadTemperature it will work. But if i put it into the header file im receiving a lot of errors:The first error, if i only put it into the header file:
the second way i tried:
Header:
Source:
thanks for helping
-
Hi,
One other and likely cleaner thing to do is to do the error showing management in your GUI class rather than in your lower level objects. This decouple things more cleanly and allows you, for example, to properly stop querying the device when an error occurs or do something else beside showing a message.
-
@SGaist Ou yes that solved to problem.
Now i return the problems till i reach the mainwindow and dependent on the error a error box will be created.But one thing. If the program start. The Sensors will be evaluate. If that dont work cause of an error. The Error Message "Initialisationerror" will pop up.
but in the other ways if the program runs the error message "Sensor .. not connected" should pop up.i tried it so:
float MainWindow::ErrorBox(int Sensornumber) { try { float x; x = R.ReadTemp(Sensornumber); if (x == 1000) throw "Initialisationerror Sensor "; //if Sensor couldn't be reached if (x == 999) throw 999; // The first 2 minutes when the sensor lost the supply the file is still under 0. So if temp >= 0 ReadTemp == 999 return x; } catch (const char*) { if (Sensornumber == 1) { if (FirstStart == 0) { MsgErrorBox->setText("Initialisierungsfehler Sensor 1!"); MsgErrorBox->setIcon(QMessageBox::Critical); } else { MsgErrorBox->setText("Sensor 1 not connected!"); MsgErrorBox->setIcon(QMessageBox::Warning); } MsgErrorBox->setModal(false); MsgErrorBox->show(); return 999; } if (Sensornumber == 2) { if (FirstStart == 0) { MsgErrorBox->setText("Initialisierungsfehler Sensor 2!"); MsgErrorBox->setIcon(QMessageBox::Critical); } else { MsgErrorBox->setText("Sensor 2 not connected!"); MsgErrorBox->setIcon(QMessageBox::Warning); } MsgErrorBox->setModal(false); MsgErrorBox->show(); return 999; } } catch (int) { if (Sensornumber == 1) { MsgErrorBox->setText("Sensor 1 not connected"); MsgErrorBox->setModal(false); MsgErrorBox->setIcon(QMessageBox::Warning); MsgErrorBox->show(); return 999; } else if (Sensornumber == 2) { MsgErrorBox->setText("Sensor 2 not connected"); MsgErrorBox->setModal(false); MsgErrorBox->setIcon(QMessageBox::Warning); MsgErrorBox->show(); return 999; } } }
Problem: If the messagebox "Initialisierungsfehler Sensor 2!" poped up at the beginning. After the time cycle of the sensorevaluation the Text will be changed to "Sensor 2 not connected!"e.g. if the program start to ran, it displays "Initialisierungsfehler Sensor 2!" after 20 sec it changes to "Sensor 2 not connected!" but it should stay on "Sensor 2 not connected!".
-
@AlexKrammer
I have not analyzed your code to see whether this could be the cause of the errors. But you should not be doing the following:float x; if (x == 1000) ...; if (x == 999) ...;
x
is of typefloat
. Floating point values are only approximate. You should never test them with==
. Use Qt's qFuzzyCompare.On a separate issue, having a method named
ErrorBox()
which returns afloat
, shows message boxes, duplicates similar code, and works bycatch()
ingconst char*
&int
is literally all over the place. What have you been smoking? ;-) You should rewrite this logic completely to something which is consistent and makes sense before you do anything else from here. -
@JonB
Yes i understand what you mean.
But the function R.ReadTemp() looks like this:FILE *devFile; try { devFile = fopen(path, "r"); if (devFile == NULL)throw "Sensor Initialisierungsfehler"; float temp = -1; if (devFile != NULL) { if (!ferror(devFile)) { unsigned int tempInt; char crcConf[5]; fscanf(devFile, "%*x %*x %*x %*x %*x %*x %*x %*x %*x : crc=%*x %s", crcConf); if (strncmp(crcConf, "YES", 3) == 0) { fscanf(devFile, "%*x %*x %*x %*x %*x %*x %*x %*x %*x t=%5d", &tempInt); temp = (float) tempInt / 1000.0; } } } fclose(devFile); if (temp <= 0)throw 999; if (unit_ == CELCIUS) return temp; else return CtoF(temp); } catch (const char* e) { return 1000; } catch (int) { return 999; }
So every time the file can't be open it will return 1000; So in this fault the float is exactly 1000;
The second fault, everytime the temperature is lower den 0 that funktion will return 999. In that fault the float is exactly 999.
so I don't see any reason not to compare. Otherwise I understand that you don't compare a float with somethingContinue:
This seperation with the two catches.First that one with Error 999.
This happens every time the first minutes when the sensor lost connection. So e.g. the sensor gives for 2 minutes a signal of -1250°C.
This gives the error 999 and show the error box "Sensor .. not connected"
After that the FirstStart Variable is going to increment and that point will be skipped.Now that one with Error 1000.
When i start the program the first time all sensors will be evaluated.
If the file of the temperature cant be reached it gives Error "Initialisationerror Sensor"
Also if the program ran for a while and one sensor lost connection longer then eg. 2 minutes the file isn't reachable anymore. So its the same error "1000" but FirstStart isn't equal to 0, so that Messagebox "Sensor .. not connected!" show.But if "Initialisationerror Sensor" is shown and i dont click ok. after 20 sec, when that sensor is evaluate again, it changes to "Sensor .. not connected!"
-
One thing that can become problematic is that you do not ensure that the file is properly closed in all cases so you are leaking handles and since you reopen the file each time your system is going to run out of file handle.
In any case, it looks like you are over engineering stuff here with your custom exception throwing and handling.
You are reading a temperature but returning some fixed values as errors. There are other ways in C++ now if you want to return some value or an error.
-
@AlexKrammer said in How to put the object creation from the cpp into the h without getting an error.:
So in this fault the float is exactly 1000;
In that fault the float is exactly 999.
so I don't see any reason not to compare. Otherwise I understand that you don't compare a float with somethingThen I'm afraid you have not understood how floating point numbers work on computers and what the potential problem in your code is. I suggested you use
qFuzzyCompare()
and gave the link, there is a reason it is provided.The
catch()
stuff has nothing to do with explaining how/whether it works. It is just very odd to mix exception types.