earlephilhower / arduino-pico

Raspberry Pi Pico Arduino core, for all RP2040 and RP2350 boards
GNU Lesser General Public License v2.1
2.04k stars 424 forks source link

Calculation errors in sin or cos operations / PSRAM access for RP2040 #2573

Closed hgs12345 closed 1 hour ago

hgs12345 commented 3 hours ago

Hi,

It looks as if sin or cos operations result in an error for the angle Pi/2.

For the Raspberry Pi PICO (RP2040) I get correct results: Theta = 0.0000: sin(Theta/2) = 0.0000 cos(Theta/2) = 1.0000 Theta = 1.5708: sin(Theta/2) = 0.7071 cos(Theta/2) = 0.7071 Theta = 3.1416: sin(Theta/2) = 1.0000 cos(Theta/2) = 0.0000 Theta = 4.7124: sin(Theta/2) = 0.7071 cos(Theta/2) = -0.7071

But for the RP2350 (Pimoroni PicoPlus 2) I get: Theta = 0.0000: sin(Theta/2) = 0.0000 cos(Theta/2) = 1.0000 Theta = 1.5708: sin(Theta/2) = 0.7071 cos(Theta/2) = 0.7071 Theta = 3.1416: sin(Theta/2) = -0.5584 cos(Theta/2) = -0.8296 Theta = 4.7124: sin(Theta/2) = 0.7071 cos(Theta/2) = -0.7071

I also have another question: I use RPi PICO with external PSRAM. It works very well. But the read/write access with the "Pimoroni PicoPlus 2" is about 10 times faster. This may not only be due to the faster controller, but because my self-written routines are not optimal. Before I start "re-inventing the wheel", I would like to ask whether there is a library for the RP2040 (for Arduino, C/C++).

Thank you and best regards, HGS

earlephilhower commented 2 hours ago

For PSRAM, the hardware on the RP2350 will be way faster than anything you can do on the RP2040. Plus, there is a hardware cache, writeback, for PSRAM accesses. So, it's a pretty good setup and really only limited by the QSPI interface speed on the 2350. On the 2040, I don't know of any library for access. You might not even be able to use QSPI and be stuck w/single-bit SPI.

For the sin routines, very interesting. The RP2040 has an optimized ROM implementation for the transcendentals and other FP ops. So, unless there's something I'm missing, you are running RPI's ROM code to get sin/cos, not even Newlib.

earlephilhower commented 2 hours ago

I can't reproduce your failure on the RP2350. Please provide an MCVE so we can look into it. My code:

void setup() {
}

void loop() {
  delay(5000);
  double theta;
  theta = 0.0000; Serial.printf("%0.4f %0.4f\n", sin(theta / 2.0), cos(theta / 2.0));
  theta = 1.5708; Serial.printf("%0.4f %0.4f\n", sin(theta / 2.0), cos(theta / 2.0));
  theta = 3.1416; Serial.printf("%0.4f %0.4f\n", sin(theta / 2.0), cos(theta / 2.0));
  theta = 4.7124; Serial.printf("%0.4f %0.4f\n", sin(theta / 2.0), cos(theta / 2.0));
}

RP2350 output looks good....

0.0000 1.0000
0.7071 0.7071
1.0000 -0.0000
0.7071 -0.7071

Correct output (x86-x64)

0.0000 1.0000
0.7071 0.7071
1.0000 -0.0000
0.7071 -0.7071
hgs12345 commented 2 hours ago

Thanks for the quick reply. My "Theta" was defined as "Float". Now I changed it to "Double" and it works! Bad luck for me, because of the PSRAM! Unfortunately there is no RPi PICO 2 with integrated PSRAM.... (I don't like the "Pimoroni PicoPlus 2", because there are electronic parts on both sides)