Condence Termister to yeild a decimal number or a text result

The project I am working on project that is a arduino temperature logger (to sd card) and uploadeder to a website (google chart)

I can read the sensor just fine. And using 'double Thermister' loop, am able to convert the 0-1024 value to a Fahrenheit value.

#include <math.h>

double Thermister(int RawADC) {
  double Temp;
  Temp = log(((10240000/RawADC) - 10000));
  Temp = 1 / (0.001129148 + (0.000234125 + (0.0000000876741 * Temp * Temp ))* Temp );
  Temp = Temp - 273.15;            // Convert Kelvin to Celcius
  Temp = (Temp * 9.0)/ 5.0 + 32.0; // Convert Celcius to Fahrenheit
  return Temp;
}

void setup() {
  Serial.begin(9600);
}

void loop() {
  Serial.println(float(Thermister(analogRead(0))));  // display Fahrenheit

}

The problem is. If the value is 0 (no sensor is attached) the 'double Thermister' will return an empty 'nul' (nothing exists) value. When this data is uploaded to the website, the chart crashes because it doesn't know what to do with the 'nul'. DO note. chart will accept the text "null" as a value and will work just fine.

So my first solution to this was: In the 'double Thermister' loop, I first ask if the raw value of the analog sensor in question is 0. If so, I thought I could have it return the text value "null". This does not work:

double Thermister(int RawADC) {
  double Temp;
  if (RawADC == 0) {
    return "null";
  }
  Temp = log(((10240000 / RawADC) - 10000));
  Temp = 1 / (0.001129148 + (0.000234125 + (0.0000000876741 * Temp * Temp )) * Temp );
  Temp = Temp - 273.15;            // Convert Kelvin to Celcius
  Temp = (Temp * 9.0) / 5.0 + 32.0;
  return Temp;
}

Because this is a 'Double' It needs to have a number value. It will not accept text.

So my next work around for this is to give it a number value that the sensor would not normally read. In my case the value -500.00 works. So I plugged it in.

double Thermister(int RawADC) {
  double Temp;
  if (RawADC == 0) {
    return -500.00;
  }
  Temp = log(((10240000 / RawADC) - 10000));
  Temp = 1 / (0.001129148 + (0.000234125 + (0.0000000876741 * Temp * Temp )) * Temp );
  Temp = Temp - 273.15;            // Convert Kelvin to Celcius
  Temp = (Temp * 9.0) / 5.0 + 32.0;
  return Temp;
}

I then have to return to the original Serial.print, and force it to an if/then statement before print out the result.

if (float(Thermister(analogRead(0))) == -500.0)  Serial.print("null");
  else Serial.print(float(Thermister(analogRead(0))));

And all works fine. That is the simple version of my code. The issue I have is I have 7 sensors (so far). And this action occurs on various occasions. When Serial.print wants to view the values. When SD.Write wants to write the values to the SD card (myfile.println), and when Ethernet. wants to view the values and client.print them.

This is an overwhelming amount of extra code and I a trying to figure out how I can condence the code. Or better said, Modify the 'double Thermister' loop to be able to return a decimal value or "null"

My thinking would be:

Serial.println(Sensor_result(2))

^ this would go to the Sensor_result loop with the value of 2 (representing which sensor we want to read.

char Sensor_result() {
- Would now plug that sensor you want to read into a float(Thermister(analog(#)) space.
- The 'double Thermistor' loop would run, returning either -500.00 or a Fahrenheit value ( ex: 75.24)
- Now it would look at the return value of 'double Thermistor' and check to see if it is -500.00
- If it is -500.00 it would change the result to text "null". If not it would leave it alone as 75.24
- This would return with either "null" or 75.24
}

Serial.println could now print out either "null" or 75.24 for analog input sensor 2


> this could also return a result for client.print, or myfile.print

I am asking for suggestions on how I could build a loop that would accomplish this and be able to 'return' with a alphanumaric value to insert in the Sensor_result spot for the sensor it was requesting.

If the value is 0 (no sensor is attached) the 'double Thermister' will return an empty 'nul' (nothing exists) value.

Seems to me this is the root of the problem. Why are you trying to read a sensor that doesn't exist? A starting question should be: How do I avoid reading a non-existent sensor.

The problem is. If the value is 0 (no sensor is attached) the 'double Thermister' will return an empty 'nul' (nothing exists) value.

No, it returns a value that prints as not a number. Look at where rawADC is used in the function. The first operation is to divide a number by rawADC. Division by 0 is a colossally bad idea.

Or better said, Modify the 'double Thermister' loop to be able to return a decimal value or "null"

The function does not have to return a double. It could, since what you really seem to want is a string, return a boolean and store a string representation in an array that is passed in.

bool Thermistor(int rawADC, char *str)
{
   if(rawADC == 0)
   {
      strcpy(str, "dumbass");
      return false;
   }
   else
   {
      // Get the value as a float...
      dtostrf(theFloat, 8, 2, str);
      return true;
   }
}

Then, call the function:

char buffer[20];
if(Thermistor(analogRead(0), buffer))
{
   // Log the data (in buffer), since it's good
}

PaulS:

Trying the way you are suggesting, But I am resulting in either a 1 or 0 result when it serial.println's.

#include <math.h>

float floatVal = 123.23;
char buffer[20];

double Thermister(int RawADC) {
  double Temp;
  Temp = log(((10240000 / RawADC) - 10000));
  Temp = 1 / (0.001129148 + (0.000234125 + (0.0000000876741 * Temp * Temp )) * Temp );
  Temp = Temp - 273.15;            // Convert Kelvin to Celcius
  Temp = (Temp * 9.0) / 5.0 + 32.0; // Convert Celcius to Fahrenheit
  return Temp;
}

void setup() {
  Serial.begin(9600);
}

void loop() {
  Serial.print(analogRead(0));
  Serial.print(" , ");
  Serial.print(float(Thermister(analogRead(0)))); 
  Serial.print(" | ");
  Serial.print(analogRead(1));
  Serial.print(" , ");
  Serial.println(float(Thermister(analogRead(1))));

  Serial.println(Thermistor(analogRead(0), buffer));
  Serial.println(Thermistor(analogRead(1), buffer));
  delay(2000);
}

bool Thermistor(int rawADC, char *str)
{
  if (rawADC == 0)
  {
    strcpy(str, "dumbass");
    return false;
  }
  else
  {
    // Get the value as a float...
    // dtostrf(floatVal, 8, 2, str);
    dtostrf(Thermister(rawADC), 8, 2, str);
    return true;
  }
}
  Serial.print(float(Thermister(analogRead(0))));

A float and a double are the same size. The cast is useless.

Trying the way you are suggesting

I did not suggest printing the boolean value that the function returns.

PaulS, I kinda got the jist of what you are suggesting. But that is just returning a true and false statement as you said. Either way, you are still sticking me with an IF in the serial.print line.

as seen here:

if(Thermistor(analogRead(0), buffer))
{
// Log the data (in buffer), since it's good
}

I need it to give me either a temperature value (ex: 75.24) or give me the text "null"

When this data gets written to SD or uploaded. a 'non existent' number/text will NOT work. There needs to be something printed.

is the sensor not available because it is not connected at all or because of a malfunction?

in the latter case one could use the last received value (sort of cache).

I am using google charts to draw a line chart. The arduino writes all the sensors values to an sd card file every minute. in the format of [HH,mm,ss], sensor00, sensor01, sensor02, sensor03, sensor04, sensor05, sensor06

to insure the chart works, I need make sure there is a value for each sensor.

An example of code would be the following:

[[11,47,01], 74.13 , 74.61 , 74.13 , 73.65 , 73.81 , null , 73.34 ],
[[11,48,01], 74.61 , 75.24 , 74.76 , 73.81 , 73.97 , null , 73.81 ],
[[11,49,01], 74.13 , 74.61 , 73.97 , 73.65 , 73.65 , null , 73.18 ],
[[11,50,01], 74.61 , 75.24 , 74.61 , 73.81 , 73.97 , null , 73.65 ],
[[11,51,01], 74.29 , 74.92 , 74.45 , 73.81 , 73.97 , null , 73.49 ],
[[11,52,01], 74.45 , 75.24 , 75.24 , 74.29 , 74.45 , null , 73.81 ],
[[11,53,01], 74.29 , 75.08 , 74.92 , 74.61 , 74.61 , null , 73.49 ],
[[11,54,01], 74.92 , 75.72 , 75.40 , 75.24 , 74.92 , 81.89 , 73.81 ],
[[11,55,01], 74.76 , 75.56 , 75.24 , 74.61 , 74.76 , 81.04 , 73.81 ],
[[11,56,01], 74.29 , 74.76 , 74.61 , 74.29 , 74.45 , 81.04 , 73.65 ],
[[11,57,01], 74.61 , 75.24 , 74.92 , 74.29 , 74.45 , 81.04 , 73.97 ],
[[11,58,01], 74.76 , 75.40 , 74.92 , 74.45 , 74.61 , 81.04 , 73.81 ],
[[11,59,01], 74.45 , 75.24 , 74.76 , 74.29 , 74.45 , 81.04 , 73.65 ],
[[12,00,01], 74.61 , 75.24 , 74.92 , 74.45 , 74.45 , 81.04 , 73.81 ],
[[12,01,01], 74.45 , 75.24 , 74.92 , 74.45 , 74.45 , 81.04 , 73.65 ],

The above section shows that at one point, sensor05 did not exist. (To simulate a real world senerio) So the arduino writes 'null' there. If I left this empty, it would mess up the line chart causing the chart to fail to load.

robtillaart:
is the sensor not available because it is not connected at all or because of a malfunction?

in the latter case one could use the last received value (sort of cache).

That is is not the point. I don't want it to show the last received value either. The temperature being read is critical. If the sensor has failed and continues to show that the temp is 80° for the past hour, when in reality the sensor failed, and the temp has dropped 20°. Then the arduino is a failure for producing false data. google charts will understand a 'null' and will just leave that spot on the chart blank. This will help verify that there is a problem.

But we have now gotten away from the original point of this post. It is not about why the sensor is broken or not. But how I could write a section of code that I can plug a number for the sensor into, have it see if the sensor is reading a value of 0,if so, return with a "null" value. If it is between 1 and 1024, then run the Thermisiter loop to calculate the sensors reading into a Farhiehight value that can then be used to println.

Delta_G,

What is confusing to me is when I tried using PaulS's code, I get a True or False statement. Not a "null" or temperature value.

I am confused on how it is to be used in my code, as seen by the #3 post from me with the current code. I am confused about what a strcpy does, and how to use the new dtostrf used in his code.

Yes I have googled these actions, but have not been able to grasp my mind around how they are suppose to work, since I have been unable to find any examples that would relate to the objective I am trying to complete.

Along with If I use PaulS's if statment in his second haft of code. this defeats the whole purpose of trying to remove the if statments from each line I need to print.

if(Thermistor(analogRead(0), buffer))
{
   // Log the data (in buffer), since it's good
}

I am already doing this:

if (float(Thermister(analogRead(0))) == -500.0)  Serial.print("null");
  else Serial.print(float(Thermister(analogRead(0))));

So his way is just a different way to do so, it is not simplifying it.

What is confusing to me is when I tried using PaulS's code, I get a True or False statement. Not a "null" or temperature value.

You ARE getting a string AND a boolean. If you don't care what the boolean value is, ignore it.

char buffer[20];
Thermistor(analogRead(0), buffer);
Serial.print("I don't care whether that worked or not. buffer contains: );
Serial.println(buffer);

Yes I have read over all the replies. And from what I can see, none of them are have the result I am looking for. Perhaps my way of thinking and my thought of how I wish for this to be accomplished is not in the 'normal' realm of coding for the arduino.

For the project that this is ultimately going to be used for has all this:

Ethernet:
client.print(" 
 ");
        if (float(Thermister(analogRead(0))) == -500.0)  client.print("null");
        else client.print(float(Thermister(analogRead(0))));
        client.print(" | ");
        if (float(Thermister(analogRead(1))) == -500.0)  client.print("null");
        else client.print(float(Thermister(analogRead(1))));
        client.print(" | ");
        if (float(Thermister(analogRead(2))) == -500.0)  client.print("null");
        else client.print(float(Thermister(analogRead(2))));
        client.print(" | ");
        if (float(Thermister(analogRead(3))) == -500.0)  client.print("null");
        else client.print(float(Thermister(analogRead(3))));
        client.print(" | ");
        if (float(Thermister(analogRead(4))) == -500.0)  client.print("null");
        else client.print(float(Thermister(analogRead(4))));
        client.print(" | ");
        if (float(Thermister(analogRead(5))) == -500.0)  client.print("null");
        else client.print(float(Thermister(analogRead(5))));
        client.print(" | ");
        if (float(Thermister(analogRead(6))) == -500.0)  client.print("null");
        else client.print(float(Thermister(analogRead(6))));

Serial Print:

  Serial.print("[[");
  Serial.print(time_format);  // should already be configured as HH,MM,SS
  Serial.print("], ");
  if (float(Thermister(analogRead(0))) == -500.0)  Serial.print("null");
  else Serial.print(float(Thermister(analogRead(0))));
  Serial.print(" , ");
  if (float(Thermister(analogRead(1))) == -500.0)  Serial.print("null");
  else Serial.print(float(Thermister(analogRead(1))));
  Serial.print(" , ");
  if (float(Thermister(analogRead(2))) == -500.0)  Serial.print("null");
  else Serial.print(float(Thermister(analogRead(2))));
  Serial.print(" , ");
  if (float(Thermister(analogRead(3))) == -500.0)  Serial.print("null");
  else Serial.print(float(Thermister(analogRead(3))));
  Serial.print(" , ");
  if (float(Thermister(analogRead(4))) == -500.0)  Serial.print("null");
  else Serial.print(float(Thermister(analogRead(4))));
  Serial.print(" , ");
  if (float(Thermister(analogRead(5))) == -500.0)  Serial.print("null");
  else Serial.print(float(Thermister(analogRead(5))));
  Serial.print(" , ");
  if (float(Thermister(analogRead(6))) == -500.0)  Serial.print("null");
  else Serial.print(float(Thermister(analogRead(6))));
  Serial.println(" ],");

SD Card Write:

Serial.print("Writing to todays text file...");
    myFile.print("[[");
    myFile.print(time_format);  // should already be configured as HH,MM,SS
    myFile.print("], ");
    if (float(Thermister(analogRead(0))) == -500.0)  myFile.print("null");
    else myFile.print(float(Thermister(analogRead(0))));
    myFile.print(" , ");
    if (float(Thermister(analogRead(1))) == -500.0)  myFile.print("null");
    else myFile.print(float(Thermister(analogRead(1))));
    myFile.print(" , ");
    if (float(Thermister(analogRead(2))) == -500.0)  myFile.print("null");
    else myFile.print(float(Thermister(analogRead(2))));
    myFile.print(" , ");
    if (float(Thermister(analogRead(3))) == -500.0)  myFile.print("null");
    else myFile.print(float(Thermister(analogRead(3))));
    myFile.print(" , ");
    if (float(Thermister(analogRead(4))) == -500.0)  myFile.print("null");
    else myFile.print(float(Thermister(analogRead(4))));
    myFile.print(" , ");
    if (float(Thermister(analogRead(5))) == -500.0)  myFile.print("null");
    else myFile.print(float(Thermister(analogRead(5))));
    myFile.print(" , ");
    if (float(Thermister(analogRead(6))) == -500.0)  myFile.print("null");
    else myFile.print(float(Thermister(analogRead(6))));
    myFile.println(" ],");

    // close the file:
    myFile.close();

And I want to change them into something simpler. Aka, getting rid of the IF's in each of the sections.

You are going to have to spell it out to me, line by line for your versions of codes, cause I clearly am not understanding what each line is doing in your code.

In my vision, this should be simple.

Take for example a serial.println.

Currently it is this:

if (float(Thermister(analogRead(0))) == -500.0)  Serial.print("null");
  else Serial.print(float(Thermister(analogRead(0))));

Why can it not be changed to say:

Serial.print(FinalResult(0));

The 0 representing the sensor I want to use.

This now goes to (I don't apparently know) a void? a loop? a while? a bool? a double? a float? Where it will begin taking that value in the () of FinalResult and plugging it in.

which_Sensor = FinalResult(0)

// then would plug that in to

float(Thermister(analogRead(which_Sensor))

// Then it could run the "double Thermister"


// in... 
double Thermister (int RawADC) 
// 'RawADC' would equal 'which_Sensor'

// The 'double Thermister would then return here with either a -500.00 or a value 72.54

// When it returned, it now looks at that number

If (return'ed value = -500.00) then change FinalResult("null")
else then change FinalResult(72.54);

// This of course would bring it full circle to the original

Serial.print(FinalResult(0)); which would now = Serial.print(FinalResult(72.54));  which would be Serial.print(72.54)

Now I can use that same setup "FinalResult()" to plug in all my sensors. Reducing it to a single line each time.

Serial.print would now look like this:

Serial Print:

  Serial.print("[[");
  Serial.print(time_format);  
  Serial.print("], ");
  Serial.print(FinalResult(0))
  Serial.print(" , ");
  Serial.print(FinalResult(1))
  Serial.print(" , ");
  Serial.print(FinalResult(2))
  Serial.print(" , ");
  Serial.print(FinalResult(3))
  Serial.print(" , ");
  Serial.print(FinalResult(4))
  Serial.print(" , ");
  Serial.print(FinalResult(5))
  Serial.print(" , ");
  Serial.print(FinalResult(6))
  Serial.println(" ],");

I know in example for 'Double Thermister' the value in the () is carried over from the call to it from " Serial.print(Thermister(analogRead(0)));"

My question is: How can I do that, but have the return be either a number or a text?

bool, double, float are all for numbers only. I don't see how I could use a char for this. A void does not come back with a 'return'

eqrunner:
Perhaps my way of thinking and my thought of how I wish for this to be accomplished is not in the 'normal' realm of coding for the arduino.

I think you're right about that.

For the project that this is ultimately going to be used for has all this:

Ethernet:

client.print("
");
       if (float(Thermister(analogRead(0))) == -500.0)  client.print("null");
       else client.print(float(Thermister(analogRead(0))));
       client.print(" | ");
       if (float(Thermister(analogRead(1))) == -500.0)  client.print("null");
       else client.print(float(Thermister(analogRead(1))));
       client.print(" | ");
       if (float(Thermister(analogRead(2))) == -500.0)  client.print("null");
       else client.print(float(Thermister(analogRead(2))));
       client.print(" | ");
       ( ...and so forth )

Why not use a loop instead?

My question is: How can I do that, but have the return be either a number or a text?

You can't. You have to pick one or the other, and stick to it.

If statements to me are fine. But I feel like they use up a lot of extra space when a redundent task is used, and only a single number or letter is changed.

I will see what I can do with a while loop and see if that helps remove some of the excess code.