Would appreciate some help/advice; I am trying to send signals to the gpio pins of the raspberry pi. Sending the signal to the gpio pins is straightford, but stopping a signal running in a loop in a thread, by sending a meessage using (tx, rx) = mpsc::channel to break the loop simply won't work as rx is getting dropped each time the closure returns, if that's the right way to put it. Chayim Friedman very kindly put me on the right track by advising me to put the channel in the struct which I have done here. The code below compiles and runs but rx is still getting dropped as soon as the loop commences. I confirmed this by temporarily replacing the changing output to a continuous unchanging output and rx still doesn't respond. Can anyone please help me with an answer to this problem? Maybe the mpsc:channel crate simply isn't up to the job? I'm on a steep initial learning curve with rust, with the aim of being able to make my own gui to control instrumentation using a gui and the pi gpio pins.
use chrono::Utc;
use iced::pure::widget::{Button, Column, Container, Text};
use iced::pure::Sandbox;
use iced::Settings;
use rust_gpiozero::*;
use std::thread;
use std::thread::sleep;
//use std::io::{self, BufRead};
use std::env;
use std::io;
use std::io::BufRead;
use std::process;
use std::sync::mpsc;
use std::sync::mpsc::channel;
use std::time::Duration;
fn main() -> Result<(), iced::Error> {
Block::run(Settings::default())
}
struct Block {
//tx: SyncSender,
//tx: mpsc::channel():: u8,
tx: u8,
//rx: u8,
}
#[derive(Debug, Clone, Copy)]
enum CounterMessage {
Flash1,
Stop,
}
impl Sandbox for Block {
type Message = CounterMessage;
fn new() -> Self {
Block {
tx:2,
//rx:1,
}
}
fn title(&self) -> String {
String::from("RPi gpio gui")
}
fn update(&mut self, message: Self::Message) {
let (tx, rx) = channel::<Block>();
Block {
tx:2,
//rx:1,
};
match message {
CounterMessage::Flash1 => {
//let _ = rx.clone();
thread::spawn(move||
loop {
let led = LED::new(17);
led.on();
sleep(Duration::from_millis(500));
led.off();
sleep(Duration::from_millis(500));
//for received in &rx {
// println!("rec ok");
// break;
// }
match rx.try_recv() {
Ok(Block{tx: 0_u8..=u8::MAX}) => {
println!("rec ok");
break;
}
Err(_recv_error) => {
println!("error");
continue
}
}
//});
}); }
CounterMessage::Stop => {
tx.send(Block{ tx: 2_u8 }).unwrap();
println!("stop button pressed");
}
}
}
fn view(&self) -> iced::pure::Element<Self::Message> {
//let label = Text::new(format!("Count: {}", self.count));
//let incr = Button::new("Increment").on_press(CounterMessage::Increment);
let flash1 = Button::new("FLASH1").on_press(CounterMessage::Flash1);
let stop = Button::new("STOP FLASH!").on_press(CounterMessage::Stop);
let col = Column::new()
.push(flash1)
.push(stop);
Container::new(col)
.center_x()
.center_y()
.width(iced::Length::Fill)
.height(iced::Length::Fill)
.into()
}
}
type here
I have also tried using crossbeam_channel but had the same problem with that. I'm wondering if the problem with rx getting dropped is because I'm using it in a non main() function? I have also tried cloning tx but that doesn't work, and there is no provision for cloning rx so I can't stop rx from going out of scope. I have also tried putting the loop inside a thread without a closure to attempt to prevent tx from going out of scope or getting dropped but Rust won't allow it,with the compiler responding with ownership issues.