Problem with "analogread" and "pow"

Hello,
I have the following problem:

float val = 0;
float _val = 0;
//#define SHARPFRONTLEFTFAC = 15972
//#define SHARPFRONTLEFTEXP = -0.89

	val = SHARPFRONTLEFTFAC * pow(((float)analogRead(port)), SHARPFRONTLEFTEXP);

This error message appears. "math.h" is included. Can anyone help me?

Best regards Kucky

c:/winavr/bin/../lib/gcc/avr/4.3.3/../../../../avr/lib/avr6\libm.a(modf.o): In function modff': (.text.avr-libc.fplib+0x3e): relocation truncated to fit: R_AVR_13_PCREL against symbol __subsf3' defined in .text section in c:/winavr/bin/../lib/gcc/avr/4.3.3/avr6\libgcc.a(_addsub_sf.o)
make: *** [Robot4.elf] Error 1

There's not enough of your sketch here to say for sure.

I notice that your #defines are commented out. And that they are syntactically incorrect to begin with, because there's an "=" in there. I uncommented and corrected them and and added some missing bits t o get this, which builds fine:

#include <math.h>

int port = A0;

void setup() {
  // put your setup code here, to run once:
float val = 0;
float _val = 0;

#define SHARPFRONTLEFTFAC  15972.0
#define SHARPFRONTLEFTEXP -0.89

 val = SHARPFRONTLEFTFAC * pow(((float)analogRead(port)), SHARPFRONTLEFTEXP);

}

All seems well to me.

Thank you for your answer.
Your code is correct, of course.

The important thing is the line.

val = SHARPFRONTLEFTFAC * pow(((float)analogRead(port)), SHARPFRONTLEFTEXP);

The rest was only meant as a comment. In my project does not this line.

val = SHARPFRONTLEFTFAC * pow(_val, SHARPFRONTLEFTEXP); Error

val = SHARPFRONTLEFTFAC * pow(345, SHARPFRONTLEFTEXP); OK

val = SHARPFRONTLEFTFAC * pow(_val, -1); OK

val = SHARPFRONTLEFTFAC * pow(_val, -0.89); Error

Hey,

pow requires two float values and returns a double value.
http://arduino.cc/en/Reference/Pow

"val" have to be a double variable.
Did you try explicit typecasting on the constant, too?

double val = pow(((float)analogRead(port)), u[/u] SHARPFRONTLEFTEXP)

Maybe that's working now?

Thank you, but unfortunately, no.

In an old project, it has exactly work that way.

//-----------------------------------------------------------------------------
int readAnalog(int port){
	int val = 0;

	for (int i = 0; i <= 3; i++)
	{
		val = val + analogRead(port);
	}
	val = val/3;

	return val;
}

//-----------------------------------------------------------------------------
int CalcSharpDistance(int port, int sharpNr){
	int val = 0;
	int _val = 0;

	_val = readAnalog(port);

	switch (sharpNr)
	{
		case 3:
			val = SHARPFRONTLEFTFAC * pow(_val, SHARPFRONTLEFTEXP);
//				  Serial.print("Front left - ");Serial.println(_val);
		break;
		case 4:
			val = SHARPFRONTRIGHTFAC * pow(_val, SHARPFRONTRIGHTEXP);
//				  Serial.print("Front right - ");Serial.println(_val);
		break;
	}
	return val;
}
//-----------------------------------------------------------------------------
void ReadSharpState(){

	if (sensor.sharp == SHARP){

		int left_distance = 0;
		int right_distance = 0;
		const int anKathete = 9604;
		float distance = 0;
		float _arcsinus = 0;
		float degree = 0;

		left_distance = CalcSharpDistance(SHARP_FRONT_LEFT, 3);
		right_distance = CalcSharpDistance(SHARP_FRONT_RIGHT, 4);

		if (left_distance >= right_distance)
		{
			distance = left_distance - right_distance;
		}
		else if(left_distance < right_distance)
		{
			distance = right_distance - left_distance;
		}

			_arcsinus = asin(distance / (sqrt((pow(distance, 2)) + anKathete)));

			degree = _arcsinus * 180 / PI;
	}
}
//-----------------------------------------------------------------------------

I no longer believe that there is a problem with "pow". I rather think it is due to the variable declaration. But I'm probably blind. I 'do not see the error.

//-----------------------------------------------------------------------------
float readAnalog(int port)
{
float val = 0;

	for (int i = 0; i <= 3; i++)
		{
			val = val + analogRead(port);
		}
	val = val/3;
	return val;
}
//-----------------------------------------------------------------------------
int CalcSharpDistance(int port, int sharpNr)
{
double val = 0;
float _val = 234.0;
float test = 1.0;

	_val = analogRead(port);

	val = pow(_val, test);  ERROR
        val = pow(_val, 1.0);   No ERROR

	return val;
}

It is certainly a trifle. But I do not see it. Who can help. :~
Kucky

Hi kucky,

i tried your snippet of the sketch (with empty loop and setup routines) and it worked with both 0.22 and 1.0 IDE.

btw: it should be called "double CalcSharpDistance(int port, int sharpNr)"

float readAnalog(int port)
{
  float val = 0;
  for (int i = 0; i <= 3; i++)  // <<<<<< that is four times so 
  {
    val += analogRead(port);
  }
  return val/4 ;  // <<<<<<<<<<<<<<<<<<<<<  divide by 4 not by 3 ....
}

4 cents,

Thanks to robtillaart,
that was a mistake too. This has made the odd values??. Shame on me.

But the original error is still not resolved.

Best regards Kucky

kucky:

c:/winavr/bin/../lib/gcc/avr/4.3.3/../../../../avr/lib/avr6\libm.a(modf.o): In function `modff':

(.text.avr-libc.fplib+0x3e): relocation truncated to fit: R_AVR_13_PCREL against symbol `__subsf3' defined in .text section in c:/winavr/bin/../lib/gcc/avr/4.3.3/avr6\libgcc.a(_addsub_sf.o)
make: *** [Robot4.elf] Error 1

A bit more information please. What chip is this? How big is your code? Is it possible it is too large to fit?

My guess is that this is the case. I think this is a linker error.

Can you post your whole sketch so that I can reproduce the error?

c:/winavr/bin/../lib/gcc/avr/4.3.3/../../../../avr/lib/avr6\libm.a(modf.o):

So you're not using the Arduino IDE to do the compile?
What compile command ARE you using?

The "relocation doesn't fit" error usually happens if you have some compiler switch for small code (ie from bootloaders) combined with a library that needs full-sized calls/etc.

Last I saw, Arduino floats and doubles are both 4 bytes.

Thanks to everyone for the quick responses. Tonight I will forward all information.
LG Kucky

Here the project.
IDE Eclipse Indigo
Arduino Lib. (WProgam.h)
Arduino Mega

Windows - Preferences - C/C++ - Build - Environments - PATH - C:\cygwin\bin
Windows - Preferences - AVR - Paths - C:\WinAVR\xxx

The size of the project.
Program: 24286bytes (9,3% Full)
Data: 1515bytes (18,5% Full)

@ westfw:
Can you please look into the project. I am not sure what you mean. I was a beginner. :roll_eyes:

Robot4.rar (209 KB)

Had written yesterday, that I have eliminated the error. Oddly, the posting has not been published. Should it have someone read, the error still exists. Unfortunately. =(
LGK

I was not idle. I activated a previous version again. The changes I've grudge, so it is all so again, as in the erroneous code. No error message in the said place. Several times compiled and flashed. Everything OK. :wink:
Then I wrote a code in the same place, which is to calculate an angle. And what do you think? Right, the error is back. :stuck_out_tongue:

I note that the error is always associated with...
pow, asin or sqrt.

I've included the WProgram.h Arduinio from version 0.22. Even if I am explicitly added math.h, the error occurs.
#include<WProgram.h>
#include<math.h>

I once read that makes math.h in Eclipse problems. Find the information but no longer. You can start here with what?
For your help, I would like to thank you in advance.

LGK

Still waiting for:

What compile command ARE you using?

(output log of the compile, show each command and its output.)
(No, I can't derive that from your eclipse-based project directory.)

I hope, I got that right.

AVR Compiler : Command : avr-gcc
All Options: -I"D:\workspace\ArduinoMegaCore" -Wall -g2 -gstabs -O0 -fpack-struct -fshort-enums -std=gnu99 -funsigned-char -funsigned- bitfields -mmcu=atmega2560 -DF_CPU=16000000UL
Command line pattern: ${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}

AVR C++ Compiler : Command : avr-g++
All Options: -I"D:\workspace\ArduinoMegaCore" -Wall -g2 -gstabs -O0 -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -fno-exceptions -mmcu=atmega2560 -DF_CPU=16000000UL
Command line pattern: ${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}

AVR C++ Linker: Command : avr-g++
All Options: -Wl,-Map,Robot5.map,--cref -L"D:\Users\Kucky\workspace\ArduinoMegaCore\Release" -L"D:\workspace\ArduinoMegaCore\Release" -mmcu=atmega2560
Command line pattern: ${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}

By the way:
The problem was solved as follows:
AVR C++ Linker: Command : avr-g++ -lm
And by Linker - Libraries - Libraries (-l) = m

Of course I did not even find out, but read here.

http://www.zhous.net/groups/cprogramming/wiki/dbe38/

That with the "m" has been elsewhere.

I have not understood. Is probably one of yours. Once is enough for me the result.
Thanks again to all.
LGK