2

I'm currently working on a pid regulator for at school project. Since the corona is has shut down the school we can't get any hardware to test it with. So i want to simulate the PID regulator on a microprocessor (PSoC5LP). So i'm implementing a function that returns a step respons of the chosen dc motor.

When i'm finding the output of the transferfunction "(-3.47*exp(-6.36*s)+3.47))" i get the right result if i define the value of "s" manually in the code. But when i set s to be incremented in the code "undefined reference to "exp".

The problem seems to be that i can't run exp in a loop while incrementing it. tried it in another project, where the only thing that happens is that a loop goes 10 times and prints out the exp() with the nr of times the loop have run (does not work)

float step_respons(){
    double s = 0.1;
        snprintf(outpurBuffer, sizeof(outpurBuffer), "%f \r\n", (-3.47*exp(-6.36*s)+3.47));
        pc_uart_PutString(outpurBuffer);
        snprintf(outpurBuffer, sizeof(outpurBuffer), "%f \r\n", (-3.47*exp(-6.36*1)+3.47));
        pc_uart_PutString(outpurBuffer);
    //These works just fine

    pc_uart_PutString("Loop:\r\n");

    for(s = 0.1; s < 2; s++){
        snprintf(outpurBuffer, sizeof(outpurBuffer), "%f %f \r\n", s,(-3.47*exp(-6.36*s)+3.47));
        pc_uart_PutString(outpurBuffer);
        //this does not work (if "s" is changed with a number it works fine.)

    };

    return 0;
};

So it works if i choose S manually in the loop, but if it gets incremented it stops. I've tried to use another variable and increment that on and it still does not work

    for(s = 0.1; s < 2; s++){
        snprintf(outpurBuffer, sizeof(outpurBuffer), "%f %f \r\n", s,(-3.47*exp(-6.36*s)+3.47));
        pc_uart_PutString(outpurBuffer);

    };

does not work

    for(s = 0.1; s < 2; s++){
        snprintf(outpurBuffer, sizeof(outpurBuffer), "%f %f \r\n", s,(-3.47*exp(-6.36*1)+3.47));
        pc_uart_PutString(outpurBuffer);

    };

does work but no incrementation of the result is done As you can se the only changes done in the loop is the "s" have been defined a value

double temp = 0.5;

    for(s = 0.1; s < 2; s++){
        snprintf(outpurBuffer, sizeof(outpurBuffer), "%f %f \r\n", s,(-3.47*exp(-6.36*temp)+3.47));
        pc_uart_PutString(outpurBuffer);    

    };

this works

double temp = 0.5;

for(s = 0.1; s < 2; s++){
        snprintf(outpurBuffer, sizeof(outpurBuffer), "%f %f \r\n", s,(-3.47*exp(-6.36*temp)+3.47));
        pc_uart_PutString(outpurBuffer);    
        temp += 0.5;
    };

does not This is the error: Build error: undefined reference to 'exp'

The log from the compiler output

--------------- Build Started: 04/28/2020 01:34:42 Project: Plotterkode, Configuration: ARM GCC 5.4-2016-q2-update Debug --------------- The code generation step is up to date. The compile step is up to date, no work needs to be done. arm-none-eabi-ar.exe -rs .\CortexM3\ARM_GCC_541\Debug\Plotterkode.a .\CortexM3\ARM_GCC_541\Debug\cy_em_eeprom.o .\CortexM3\ARM_GCC_541\Debug\CyDmac.o .\CortexM3\ARM_GCC_541\Debug\CyFlash.o .\CortexM3\ARM_GCC_541\Debug\CyLib.o .\CortexM3\ARM_GCC_541\Debug\cyPm.o .\CortexM3\ARM_GCC_541\Debug\CySpc.o .\CortexM3\ARM_GCC_541\Debug\cyutils.o .\CortexM3\ARM_GCC_541\Debug\pc_uart.o .\CortexM3\ARM_GCC_541\Debug\pc_uart_PM.o .\CortexM3\ARM_GCC_541\Debug\pc_uart_INT.o .\CortexM3\ARM_GCC_541\Debug\pc_uart_BOOT.o .\CortexM3\ARM_GCC_541\Debug\pc_uart_IntClock.o .\CortexM3\ARM_GCC_541\Debug\isr_pc_uart.o .\CortexM3\ARM_GCC_541\Debug\Pin_adc_input.o .\CortexM3\ARM_GCC_541\Debug\MISO.o .\CortexM3\ARM_GCC_541\Debug\MOSI.o .\CortexM3\ARM_GCC_541\Debug\SCLK.o .\CortexM3\ARM_GCC_541\Debug\pot_adc_sar.o .\CortexM3\ARM_GCC_541\Debug\pot_adc_sar_INT.o .\CortexM3\ARM_GCC_541\Debug\pot_adc_sar_PM.o .\CortexM3\ARM_GCC_541\Debug\ui_spi.o .\CortexM3\ARM_GCC_541\Debug\ui_spi_PM.o .\CortexM3\ARM_GCC_541\Debug\ui_spi_INT.o .\CortexM3\ARM_GCC_541\Debug\pot_adc_sar_IRQ.o .\CortexM3\ARM_GCC_541\Debug\pot_adc_sar_theACLK.o .\CortexM3\ARM_GCC_541\Debug\ui_spi_IntClock.o .\CortexM3\ARM_GCC_541\Debug\motor_pwm.o .\CortexM3\ARM_GCC_541\Debug\motor_pwm_PM.o .\CortexM3\ARM_GCC_541\Debug\Clock.o .\CortexM3\ARM_GCC_541\Debug\pin_pwm_x.o .\CortexM3\ARM_GCC_541\Debug\pin_pwm_y.o .\CortexM3\ARM_GCC_541\Debug\pin_enable.o .\CortexM3\ARM_GCC_541\Debug\pin_border.o .\CortexM3\ARM_GCC_541\Debug\isr_border.o .\CortexM3\ARM_GCC_541\Debug\pin_led.o .\CortexM3\ARM_GCC_541\Debug\isr_goal_left.o .\CortexM3\ARM_GCC_541\Debug\pin_goal_right.o .\CortexM3\ARM_GCC_541\Debug\pin_goal_left.o .\CortexM3\ARM_GCC_541\Debug\isr_goal_right.o .\CortexM3\ARM_GCC_541\Debug\isr_ui_spi.o .\CortexM3\ARM_GCC_541\Debug\AMux.o .\CortexM3\ARM_GCC_541\Debug\CyBootAsmGnu.o arm-none-eabi-ar.exe: creating .\CortexM3\ARM_GCC_541\Debug\Plotterkode.a arm-none-eabi-gcc.exe -Wl,--start-group -o C:\Users\Vikto\Desktop\plottercode\Plotterkode.cydsn\CortexM3\ARM_GCC_541\Debug\Plotterkode.elf .\CortexM3\ARM_GCC_541\Debug\main.o .\CortexM3\ARM_GCC_541\Debug\cyfitter_cfg.o .\CortexM3\ARM_GCC_541\Debug\cymetadata.o .\CortexM3\ARM_GCC_541\Debug\Cm3Start.o .\CortexM3\ARM_GCC_541\Debug\Plotterkode.a "C:\Program Files (x86)\Cypress\PSoC Creator\4.2\PSoC Creator\psoc\content\cycomponentlibrary\CyComponentLibrary.cylib\CortexM3\ARM_GCC_541\Debug\CyComponentLibrary.a" -mcpu=cortex-m3 -mthumb -L Generated_Source\PSoC5 -Wl,-Map,.\CortexM3\ARM_GCC_541\Debug/Plotterkode.map -T Generated_Source\PSoC5\cm3gcc.ld -specs=nano.specs -u _printf_float -Wl,--gc-sections -u_printf_float -g -ffunction-sections -Og -ffat-lto-objects -Wl,--end-group .\CortexM3\ARM_GCC_541\Debug\main.o: In function step_respons': C:\Users\Vikto\Desktop\plottercode\Plotterkode.cydsn/./plotter_position.h:125: undefined reference toexp' collect2.exe: error: ld returned 1 exit status The command 'arm-none-eabi-gcc.exe' failed with exit code '1'. --------------- Build Failed: 04/28/2020 01:34:42 ---------------

Richard Matsen
  • 20,671
  • 3
  • 43
  • 77
Viktor T
  • 23
  • 4
  • How is "[s] set to a non variable"? Anyway, `s++` might be better as something like `s += step;` (where `step` has been _previously assigned_ a suitable value). – user2864740 Apr 27 '20 at 23:07
  • @user2864740 double step is not used for anything. what i mean by non variable is if i choose number like 0.5 or 0.75 – Viktor T Apr 27 '20 at 23:11
  • Show an example of both cases. It is unclear *exactly* what changes. This should be minimal reproduction - perhaps even a single snprintf call in "OK" and "failure" cases. Is the loop related? If not, remove it. Including the *full* compiler error (copy and pasted) is also generally advisable. – user2864740 Apr 27 '20 at 23:13
  • @user2864740 i've included some more examples of what works and what does not Also included the compiler output – Viktor T Apr 27 '20 at 23:55
  • A big improvement. Does the same issue persist if *removing* the loop? This process is all about finding a minimal test/example case. – user2864740 Apr 28 '20 at 00:02
  • @user2864740 the problem is i want it to loop, it has to loop The only other way around is to manually call all the different S = values i want which would be around 100 lines of the same code – Viktor T Apr 28 '20 at 00:36
  • "Wanting" the loop is not related to creating a minimal test-case. Once a minimal test-case is found, fix the issue, then expand back to relevant context. – user2864740 Apr 28 '20 at 01:44

1 Answers1

2

You are likely not linking the library that includes the exp() function.

It works in the case where you're passing it a literal (or a value the compiler can deduce) because the compiler is computing the value and putting that in the code.

https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html

I believe exp() is included in 'libm', so adding -Wl,-lm (or however else you specify libm in your build system) should fix it.

And if it is already there, try putting it at the end of the list.

Russ Schultz
  • 2,545
  • 20
  • 22