Closed nebelgrau77 closed 2 years ago
I agree, this feature makes the driver practically unusable on embedded where Delay
cannot be cloned.
I am looking to write a version that will allow this to work by borrowing but as a first pass i have implemented a very simple release()
function here https://github.com/fishrockz/bme280-rs/tree/willsalmon/release
Release is not ideal but it lets you do things like
loop {
delay(clocks.sysclk().0 / 100);
// The Aidafruit boards have address 0x77 without closing the jumper on the back, the BME280 lib connects to 0x77 with `new_secondary`, use
// `new_primary` for 0x76 if you close teh jumper/solder bridge.
{
let mut bme280 = BME280::new(spi, cs_bme, delay_ob).unwrap();
bme280
.init()
.map_err(|error| {
hprintln!("Could not initialize bme280, Error: {:?}", error).unwrap();
panic!();
})
.unwrap();
match bme280.measure() {
Ok(measurements) => {
hprintln!("Relative Humidity = {}%", measurements.humidity).unwrap();
hprintln!("Temperature = {} deg C", measurements.temperature).unwrap();
hprintln!("Pressure = {} pascals", measurements.pressure).unwrap();
write!(&mut arr_message, "The presure is {}", measurements.pressure)
.expect("Can't write");
}
Err(error) => {
hprintln!("Could not read bme280 due to error: {:?}", error).unwrap();
}
}
for (i, c) in arr_message.chars().enumerate() {
buffer[i] = c as u8;
}
hprintln!("buffer {:?}?", buffer).unwrap();
(spi, cs_bme, delay_ob) = bme280.release();
}
{
//lora.set_mode(sx127x_lora::RadioMode::Tx).unwrap();
let mut lora = sx127x_lora::LoRa::new(spi, cs_lora, reset, 434, delay_ob).unwrap();
lora.set_tx_power(17, 1).unwrap(); //Using PA_BOOST. See your board for correct pin.
let transmit = lora.transmit_payload(buffer, arr_message.len());
match transmit {
Ok(()) => hprintln!("Sent packet").unwrap(),
Err(e) => hprintln!("Error {:?}", e).unwrap(),
};
delay(clocks.sysclk().0 * 5);
(spi, cs_lora, reset, delay_ob) = lora.release();
}
}
Which is no good if you need to quickly swap back and forth but dose let you swap back and for slowly.
I have not created a PR yet as I am working on top of https://github.com/uber-foo/bme280-rs/pull/6 which is approved but not merged.
Notice that VersBinarii has a solution.
Notice that VersBinarii has a solution.
I'm missing something: what is the solution? Looks to me like it has the same problem, consuming the delay. Which unfortunately is a problem of some other sensors, too, those that require a specific amount of time between one thing and another. Ideally there is a bit you can keep reading, but if the datasheet says "wait 30 ms", the delay seems to be the (only?) option.
Let me first say that I'm just a Rust beginner. As far as I know VersBinarii's version does not consume the delay. That's the whole point. It takes mutable reference (or whatever that's called in Rust).
/// Initializes the BME280
pub fn init<D>(&mut self, delay: &mut D) -> Result<(), Error<E>>
where
D: DelayMs<u8>,
{...}
The constructor doesn't even see the delay. With VersBinarii's version I was able to build my little nRF example, reading sensor data in a loop with a 1s delay.
let mut delay = Delay::new(cp.SYST);
// initialize the BME280 using the primary I2C address 0x76
let mut bme280 = BME280::new_secondary(i2c);
let _ = bme280.init(&mut delay).unwrap();
loop {
delay.delay_ms(1000u16);
let measurements = bme280.measure(&mut delay).unwrap();
rprintln!("Relative Humidity = {:.2}%", measurements.humidity);
rprintln!("Temperature = {:.1} °C", measurements.temperature);
rprintln!("Pressure = {:.2} hPa", measurements.pressure / 100f32);
}
Let me first say that I'm just a Rust beginner. As far as I know VersBinarii's version does not consume the delay. That's the whole point. It takes mutable reference (or whatever that's called in Rust).
Gotcha! Yes, I didn't notice that it was only borrowing the delay (yep, it is called a mutable reference). Thanks!!!
The driver works great, but consumes the delay provider, making it unavailable for the rest of the code. Of course the delay is necessary for
soft_reset
andmeasure
functions, but I was wondering whether it could be done differently. Possible ideas (which may or may not work):I don't know enough Rust to try and tackle it myself yet, but maybe one of these could be tried?