no-std and microcontroller friendlieness
Closed this issue · 6 comments
First of all thanks for making this, seems very useful.
I considered using this for my embedded temperature sensor crate, but noticed that the lib does not declare no-std compatibility (but it seems that it actually is). Also temperature values are represented as f64, which is not optimal because MCUs often do not have a floating-point unit.
Not sure how a good solution looks like, is this something you already considered?
Hi. Er, this is complicated - @jocull originally wrote rust-measurements
and I used it for https://github.com/thejpster/sensehat-rs. I had a few fixes to push and was invited to collaborate and given cargo publish rights. The development has since migrated to https://github.com/thejpster/rust-measurements, largely because I've been lazy and doing a cargo publish
from my tree.
You'll find the version at https://github.com/thejpster/rust-measurements matches what's on crates.io at the moment, and it is #![no_std]
compatible. It turns out this is actually non-trivial thanks to the use of std::time::Duration
and it not being available in core
until very recently, but it's done. Just set the no_std
feature in your Cargo.toml
.
The use of f64
is something @jocull started, and I'm quite happy to continue. Yes, you could have smaller integer types, but it gets complicated very quickly. For example, if you have a uint16 value of millivolts and you multiply it by a uint16 value in milliamps, what should be the type of the resulting output? u16 milliwatts? What if we had 65.535 V * 65.535 A? u32 milliwatts? Well now we've got two underlying types. If everything sticks to f64
then it's all much simpler and there is more than enough dynamic range for most usecases. Yes, float code is a little larger on an MCU, but at least you can use all the same floating point code everywhere, rather than having some monomorphised code here for this operation and there for that operation.
If someone had a PR which allowed the f64 to be switched out, but without bringing a whole bunch of problems to do with overflowing types then I'd be really interested in reviewing it.
I see, thanks for the detailed response. Was thinking more along the lines of 64bit integers, but I don't really know about fixed point math and such.
Do you have an idea on what the actual performance and size differences on soft-float 32bit targets are? I'm a bit out of my element here, as I'm not doing this stuff on a daily basis.
actual performance and size differences
It's not something I've looked in to to be honest. If I need floats, I use floats. If I'm in a tight loop I really need performance, I might try and avoid them with some fixed point code, but it's case by case.
Unfortunately, this is likely to be over my head as well. When I wrote this library I only intended to learn a little bit of Rust and hopefully make something useful. I honestly never expected anyone else would find or use it!
I think @thejpster has covered any thoughts I would have had, particularly about the use of floating point math. Because of the very wide range of units, dropping down to integer precision would be difficult (or at least very confusing to implement).
However! The internals of this library are really not that complex. It's some simple math wrapped in concrete units to hopefully prevent errors from using raw number types. If the use of f64
types is concerning, the structures used to wrap the units may be concerning as well (again, I know very little about programming for microcontrollers).
I'm guessing you don't need all of the types provided by this library, so perhaps your best bet would be to either copy out the parts you need (MIT license so 🤷♂️😄) or fork the library and rework the implementation as you see fit.
So how does all that sound?
Sounds like there would probably be little payoff for a serious amount of work. The I2C transaction certainly takes longer than doing the FP math to convert the values, so for now I guess its ok as it is. Thanks anyway!
Thanks for your interest! If you end up doing any separate open work using a fork or copy of this I’d love to hear about it with a follow up link :)