Posted: 06/03/2023 | Edited: 06/03/2023
TLDR; Building my first embedded system to assist me in getting the perfect temperature for my derrrbs (iykyk not explainin' it). This post just goes over my adventure in building it from my process, struggles, & open source contributions I made along the way to get it working.
A Hardware Abstraction Layer (HAL) is needed to run Rust on AVR microcontrollers and other common boards.
We need to use the nightly build of the Rust compiler, & can't use Rust's standard library or even a main f(x) as we are running on bare metal (no Operating System).
#![no_std] // no standard library
#![no_main] // no main function
Instead of using a main f(x), we will use a macro from the Hardware Abstraction Layer to specify our entry point f(x):
#[arduino_hal::entry]
lsusb
export RAVEDUDE_PORT=/dev/ttyUSB1
cargo run
yo0o pretty hard, actually did it so bad it short circuits my board when connected lol.
round 2, bought new sensor and did an ok enough of a job soldering it, so it no longer short circuits the board :)
Using jumper cables and breadboard I connected the sensor.
MLX90614 SCL ->Microcontroller A5
MLX90614 SDA -> Microcontroller A4
MLX90614 GND -> Microcontroller GND
MLX90614 VCC -> Microcontroller 5V
So I found a Rust crate for my exact sensor, but quickly realized it relies on 32 bit floats, and floating point operations on bare metal are not fun lol & to make things worse AVR has a lot of bugs with floating point OPs.
After a day of hacky attempts to work with floating point operations, I decided to just contribute a feature to the crate helping my fellow Arduino user's read temperature values as 16 bit integers avoiding floating point operations.
OG method for reading temp values as 32 bit floats:
/// Read the object 1 temperature in celsius degrees
pub fn object1_temperature(&mut self) -> Result<f32, Error<E>> {
let t = self.read_u16(Register::TOBJ1)?;
let t = f32::from(t) * 0.02 - 273.15;
Ok(t)
}
New method for reading temp values as unsigned 16 bit integers:
/// Read the object 1 temperature in celsius degrees as integer
pub fn object1_temperature_as_int(&mut self) -> Result<u16, Error<E>> {
let t = self.read_u16(Register::TOBJ1)?;
let t = (t * 2) / 100 - 273; // ((t * 2) / 100 ) - 273 = (t * 0.02) - 273.15 , but integer friendly.
Ok(t)
}
Another problem is this crate uses celsius and I'm 🇺🇸 'merican, so ya we converting celsius to fahrenheit:
/// Read the object 1 temperature in fahrenheit degrees
pub fn obj1_temp_f(&mut self) -> Result<u16, Error<E>> {
let t = self.read_u16(Register::TOBJ1)?;
let t_c = (t * 2) / 100 - 273); // temp as celsius
let t_f = (t_c * 9 / 5) + 32; // temp as fahrenheit
Ok(t_f)
}
idk copyright or whateva Ⓒ 2023 Antonio Hickey