Newbie needs help with error "invalid operands of types 'float' and 'float()' to

Hello,

I need help with a error message "invalid operands of types 'float' and 'float()' to binary 'operator*'

This is the code:

float AIR_HUMIDITY = 50.0;

float KORREKTURFAKTOR = 0.985;

float a = 331.3;
float b = 0.6;
float c = 1.5;
float d = 100.0;

float TMP36 = A2;

float TEMPERATUR()
{
float sensorwert;
sensorwert = analogRead(TMP36);
float TEMP= map(sensorwert, 0, 410, -50, 150);
return TEMP;
}

float SONIC_SPEED = a * KORREKTURFAKTOR + b * TEMPERATUR + c * AIR_HUMIDITY / d;

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

}

void loop() {
TEMPERATUR()
Serial.print(F("SONIC_SPEED [µs/2]: ")); Serial.println(SONIC_SPEED);

}

  1. analogRead requires uint8_t as parameter not float
  2. TEMPERATUR() is a function - missed () on line 23
  3. ; on Ln32
float AIR_HUMIDITY = 50.0;


  float KORREKTURFAKTOR = 0.985;

  float a = 331.3;
  float b = 0.6;
  float c = 1.5;
  float d = 100.0;


  //float TMP36 = A2;
 #define TMP36 A2

  float TEMPERATUR()
{
  float sensorwert;
  sensorwert = analogRead(TMP36);
  float TEMP= map(sensorwert, 0, 410, -50, 150);
  return TEMP;
}

  float SONIC_SPEED = a * KORREKTURFAKTOR + b * TEMPERATUR() + c * AIR_HUMIDITY / d;


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

}

void loop() {
  TEMPERATUR();
  Serial.print(F("SONIC_SPEED    [µs/2]: ")); Serial.println(SONIC_SPEED);

}

Thank you very much. It works now.

  1. analogRead requires uint8_t as parameter not float

The syntax for reading signal from an ADC channel, according to Arduino Refrence Manual:
analogRead(pin);
Where pin: the number of the analog input pin to read from (0 to 5 on most boards, 0 to 7 on the Mini and Nano, 0 to 15 on the Mega)

Then all of the following declarations/definitions should be correct!

1. analogRead(2);
2. analogRead(2.0);
3.
int pin = 2;
ananlogRead(pin);

4.
float pin = 2.0;
analogRead(pin);

5.
int TMP36 = A2; //using Arduino's Keyword A2 for Channel-2
analogRead(A2);

6.
float TMP36 = A2;
analogRead(A2);

GolamMostafa:
Then all of the following declarations/definitions should be correct!

1. analogRead(2);
2. analogRead(2.0);
3.
int pin = 2;
ananlogRead(pin);

4.
float pin = 2.0;
analogRead(pin);

5.
int TMP36 = A2; //using Arduino's Keyword A2 for Channel-2
analogRead(A2);

6.
float TMP36 = A2;
analogRead(A2);

Your assertion is not supported by the function's prototype in Arduino.h:

int analogRead(uint8_t);

CORRECTION:
Well, the compiler will implicitly cast a float to uint8_t. But, why would you do that?

@GolamMostafa
Yes it accepts also others, but can you show some advantage of float pin numbering?

Frankly speaking, I am always in favor of what you have declared as:

#define TMP36 A2 which is clean and makes very logical sense.

The other declarations have come as part of discussion following your statement -- 1. analogRead requires uint8_t as parameter not float :slight_smile:

Then all of the following declarations/definitions should be correct!

  1. analogRead(2.0);

I have looked at several Arduino boards and cannot see a pin 2.0 anywhere. Have you got one with such a pin ?

I have looked at several Arduino boards and cannot see a pin 2.0 anywhere. Have you got one with such a pin ?

This is not my proposition for the legends of the analog connector of the Arduino Board; it has just followed OP's declaration -- float TMP36 = A2; which, perhaps, has come from here: The on-line Reference Manual of Arduino says: pin: the number of the analog input pin to read from (0 to 5 on most boards, 0 to 7 on the Mini and Nano, 0 to 15 on the Mega)

2.0 could be thought as a high level floating point representation (without any advantage) of the integer value 2.

On the physical board of Arduino UNO, we have the legends: A0, A1, A2, A3, A4, A5 and not 0, 1, .., 5 as could be conceived from the Reference Manual of Arduino.

GolamMostafa:
The other declarations have come as part of discussion following your statement -- 1. analogRead requires uint8_t as parameter not float :slight_smile:

OK, I understand if it is just academic discussion but it should be explained for other people, especially for beginners like OP seems to be. So:

  1. integer constant or any macro definition is the same
  2. float constant is like in 1. case from compiler view, but nonsense in real world
  3. int pin = 2; the ananlogRead(pin) requires 1 byte so it waste 1 byte (int has 2 bytes) by storage if it is not required by some other reason, of course use of variable absolute has no meaning in the sketch posted by OP, it has meaning if you want to remember more ports or use it for some cycle etc.
  4. float pin = 2.0; analogRead(pin);
    even if it is correctly processed, it waste 3 bytes of RAM for storage (float has 4 bytes) but there is added code for conversion to byte to be able use it as parameter for the analogRead, which waste the flash and also CPU time.
    Finally it is nonsense like #2.
  5. was explained in 3
  6. explained in 4
  1. float pin = 2.0; analogRead(pin);
    even if it is correctly processed, it waste 3 bytes of RAM for storage (float has 4 bytes) but there is added code for conversion to byte to be able use it as parameter for the analogRead, which waste the flash and also CPU time.

Now, we may request the OP -- @Diddi68

Will you please tell us the source/link from which you have got the codes of your post. With reference to the quoted text of Post#9, it is a matter of great concern to investigate how the keyword float has entered (perhaps for the first time!) in the definition of an analog pin of the MCU. Is it intentional or just fun?

Budvar10:

  float TEMP= map(sensorwert, 0, 410, -50, 150);

Don't use map() for floats.
Use arithmetic instead. Like this:

  float TEMP = (sensorwert * (200.0 / 410.0)) - 50.0;

Don't use map() for floats.

What is wrong with this declaration/definition: float TEMP= map(sensorwert, 0, 410, -50, 150);?

The map() function is evaluated to:
(sensorwert - min_inputRange)*(max_outputRange - min_outputRange) / (max_inpuRange - min_inputRange) + min_outputRange

==> (sensorwert - 0) * (150 +50) / (410 - 0) + (-50)
==> sensorwert * (200/410) - 50

But, the variable sensorwert has been declared as: float sensorwert; in the original post; so, sensorwert * (200/410) - 50 will turn out as float which is assigned to float TEMP. There is no compatibility problem with data types! Therefore, it is not necessary to re-write the integer operands (200, 410, 50) into their floating point representations (200.0, 410.0, 50.0).

It will actually evaluate to:

(sensorwert * 200)/410 - 50

Using integer math.

GolamMostafa:
The map() function is evaluated to:
(sensorwert - min_inputRange)*(max_outputRange - min_outputRange) / (max_inpuRange - min_inputRange) + min_outputRange

That is not an accurate way to think about it.

map() is a function, not a macro:

long map(long x, long in_min, long in_max, long out_min, long out_max)
{
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

So it's equivilent to:
((long)sensorwert - (long)min_inputRange)*((long)max_outputRange - (long)min_outputRange) / ((long)max_inpuRange - (long)min_inputRange) + (long)min_outputRange

Both here and with the pin number declared as a float, you can get unexpected behavior when they're converted from float to an integer datatype, since it's truncated, not rounded. 2.0 can turn into 1 due to truncation and floating point precision limits. AND if OP really wants decimals to be retained, using map won't do that - every intermediate value will also be truncated since it's all conducted with longs, not floats.

I suspect OP was unaware of the disadvantages of floats, and just figured "well, since they can represent more numbers, and handle decimals, I should always use floats" - but:

  • floats are imprecise (as noted above)
  • floats get truncated when converted to integers (as noted above)
  • floats take up more ram to store (4 bytes) vs an int (2 bytes) or byte (1 byte)
  • floats bloat the sketch size if you do math with them - there's no hardware floating point math support, so it's all implemented in software, and compiler has to pull in a routine to handle each mathematical operator your sketch uses with floats.
  • most library functions take integer datatypes, so often your float ends up getting cast to an integer datatype anyway.

It will actually evaluate to:

(sensorwert * 200)/410 - 50

Using integer math.

I stood corrected.

Thanks for pointing the mistake.

UKHeliBob:
I have looked at several Arduino boards and cannot see a pin 2.0 anywhere. Have you got one with such a pin ?

It's the pin between sqrt(2) and pi.