tinygo-org / tinygo

Go compiler for small places. Microcontrollers, WebAssembly (WASM/WASI), and command-line tools. Based on LLVM.
https://tinygo.org
Other
15.32k stars 905 forks source link

Arduino: float64 variable returns zero when tried to divide 1 with it #1470

Closed judokan9 closed 1 year ago

judokan9 commented 3 years ago

Hi,

i am new to Go and TinyGo. It's been pretty fun until now, so thank you for this great project! I have a strange problem when I try to process a variable with the type of float64 on my Arduino UNO. The main goal is to implement the full steinhart and hart equation in TinyGo. So i have a resistance value where i need to do some math with (like applying a logarithm) and at the end i need to divide 1 with my calculatet values.

But the result is always 0. Except when i use the direct variable declaration :=.

I have written a short code example, so that the problem can be reproduced:

package main

import (
    "math"
)

var testlog float64
var resistance uint32

func main() {
    resistance = 11050
    //resistance := 11050

    println(int(resistance))

    testlog = math.Log(float64(resistance))
    println(testlog)
    testlog = 0.001 + 0.001 * testlog
    println(testlog)
    testlog = 1.0 / testlog
    println(uint32(testlog))
}

PS: I've also tryed to use the short declaration on a new variable like resistlog with following codeline resistlog := math.Log(float64(resistance)) But when i try to calculate with this it also does not work.

aykevl commented 3 years ago

I cannot reproduce this issue.

$ tinygo run ./tmp/issue1470.go
11050
+9.310186e+000
+1.031019e-002
96

$ go run ./tmp/issue1470.go
11050
+9.310186e+000
+1.031019e-002
96
judokan9 commented 3 years ago

Thank you for your response!

I am using Windows 10 2004 with TinyGo ver. 0.15.0 and avrdude version 6.3. I was not aware that TinyGo does not support float64 with AVR. I had Some issues to calculate float64 Numbers with the Mega2560 (like basic multiplying of float64 vars).

But it worked pretty well with the arduino UNO until i tried to calculate the steinhart and hart equation with it.

Should TinyGo officially support float64 vars in the near future and is there anything i can help with to support it?

I also tested the code successful with the https://play.golang.org/ editor before i posted it here.

tinygo flash -target=arduino -port=COM7 .\test2.go

avrdude.exe: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.04s

avrdude.exe: Device signature = 0x1e950f (probably m328p)
avrdude.exe: NOTE: "flash" memory has been specified, an erase cycle will be performed
             To disable this feature, specify the -D option.
avrdude.exe: erasing chip
avrdude.exe: reading input file "C:\Users\XXX\AppData\Local\Temp\tinygo101386807\main.hex"
avrdude.exe: writing flash (7424 bytes):

Writing | ################################################## | 100% 3.51s

avrdude.exe: 7424 bytes of flash written
avrdude.exe: verifying flash memory against C:\Users\XXX\AppData\Local\Temp\tinygo101386807\main.hex:
avrdude.exe: load data flash data from input file C:\Users\XXX\AppData\Local\Temp\tinygo101386807\main.hex:
avrdude.exe: input file C:\Users\XXX\AppData\Local\Temp\tinygo101386807\main.hex contains 7424 bytes
avrdude.exe: reading on-chip flash data:

Reading | ################################################## | 100% 3.00s

avrdude.exe: verifying ...
avrdude.exe: 7424 bytes of flash verified

avrdude.exe: safemode: Fuses OK (E:00, H:00, L:00)

avrdude.exe done.  Thank you.
aykevl commented 3 years ago

Yes, TinyGo will eventually support float64 on AVR. But it would be best to avoid that if possible: use integers if you can and float32 if it really has to be a float. Float64, while it should eventually be supported, will be big and expensive.

What is the avr-gcc toolchain that you are using, and which version is it?

Regarding your Steinhart-Hart equation, you could take a look here for example: https://math.stackexchange.com/questions/2894807/integer-part-of-natural-logarithm

judokan9 commented 3 years ago

Great! So float32 is currently supported on AVR?

Regarding to avr-gcc:

scoop list
Installed apps:

  avr-gcc 10.1.0 [main]
  tinygo 0.15.0 [main]
choco version avrdude golang
avrdude v6.3
golang v1.15.3

Those are the only applications installed on my pc regarding to tinygo.

Thank you for this link, i will try to change my code to not use float variables!

Just out of curiosity: Did you have any recommendations for an ARM board, which is well supported by TinyGo?

aykevl commented 3 years ago

So float32 is currently supported on AVR?

...kind of. The AVR target itself is still not entirely stable. We do run a few CI tests but not the full compiler test suite like for ARM and RISC-V. However, float32 probably works for the most part.

scoop list
Installed apps:

  avr-gcc 10.1.0 [main]
  tinygo 0.15.0 [main]

That explains it. GCC 10 includes support for float64 (in the form of C double) for AVR: https://gcc.gnu.org/wiki/avr-gcc#Libf7 That's probably why you didn't have any linker errors.

Unfortunately, I'm still working with the massively outdated avr-gcc 5.4.0 as that's what Debian ships.

Just out of curiosity: Did you have any recommendations for an ARM board, which is well supported by TinyGo?

That really depends on what you want to do with it. Most ARM boards from Arduino and Adafruit are well supported and a few others like the BBC micro:bit. It's perhaps more about the chip inside: currently the nrf, atsamd21 and atsamd51 chips are well supported. Chips in the stm32 familiy have varying support, but generally not (yet) as well as the other chips. All these chips should fully support float64 (although they will all use software emulation).

aykevl commented 1 year ago

Float64 is now supported on AVR, for those who really want to use it. It's better to use integer math, or maybe float32 if you really must, but TinyGo won't be complaining anymore when you use float64 anyway.