Hi all, would appreciate some help and advice sorting out my Rust code here. I need to display the output from an MCP3002 SPI chip on an egui ui.
The MCP3002 is fed into the spi pins on a Raspberry Pi 5 running Rust. The issue I have faced is that when using the standard spidev crate and
the SPI driver, I cannot send the output, in this case the variable “dog1” to the standard UPDATE function that the egui crate uses, to an egui GUI.
I can send the output to “println” which is no good as I need to display the output from the MCP3002 SPI chip graphically. If I call the
UPDATE function from FULL_DUPLEX then dog1 goes out of scope which actually shouldn’t happen as UPDATE is called before the closing brace of
FULL_DUPLEX. So what I have done (see code below) is to modify the function signature for FULL_DUPLEX to call
egui::Context and eframe::Frame as parameters so that |ui| and the spi output “dog1” are part of the same function and hence dog1 does not now
go out of scope. See code below which compiles, but NO GUI is displayed. I have tried re-writing the code using a standard struct and impl’s but
then I run into the same problem of dog1 going out of scope.
I’d appreciate if someone could put me right and tell me what needs to be done to get the egui ui show and to display my variable “dog1”. I have been
tearing my hair out over this for several weeks now! Code here:
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] // hide console window on Windows in release
#![allow(rustdoc::missing_crate_level_docs)] // it's an example
use std::error::Error;
use std::io;
use eframe::egui;
use egui::Context;
//use eframe::egui::Context;
use eframe::Frame;
use egui::RawInput;
use egui::Ui;
use std::io::prelude::*;
use spidev::{Spidev, SpidevOptions, SpidevTransfer, SpiModeFlags};
//static mut rx_buf: [u8; 2] = [0, 0];//REF: bookmark: How to specify const array in global scope in Rust
fn main() {
let _ = create_spi();
}
fn create_spi() -> io::Result {
let mut spi = Spidev::open("/dev/spidev0.0")?;
let options = SpidevOptions::new()
.bits_per_word(8)
.max_speed_hz(40_000)
.mode(SpiModeFlags::SPI_MODE_0)
.build();
spi.configure(&options)?;
let mut ctx = egui::Context::default();
let mut _frame = eframe::Frame::_new_kittest();
full_duplex(&mut spi, &mut ctx, &mut _frame);
Ok(spi)
}
fn full_duplex(spi: &mut Spidev, ctx: &mut egui::Context, _frame: &mut eframe::Frame) {
let tx_buf = [0x0D, 0x02];
let mut rx_buf = [4; 2];
let mut transfer = SpidevTransfer::read_write(&tx_buf, &mut rx_buf);
let _ = spi.transfer(&mut transfer);
let dog1 =rx_buf[1].to_string();
let raw_input = egui::RawInput::default();
let _= ctx.run(raw_input, |ctx| {egui::CentralPanel::default().show(ctx, |ui| {
ui.heading("My egui Application");
ui.horizontal(|ui| {
ui.label(dog1.clone());
});
});
});
}