Skip to content

Commit

Permalink
added way to disconnect the board
Browse files Browse the repository at this point in the history
  • Loading branch information
metasophiea committed Oct 9, 2024
1 parent 57171bc commit 38599e6
Show file tree
Hide file tree
Showing 8 changed files with 60 additions and 9 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "firmata-client"
version = "0.5.3"
version = "0.6.0"
license = "MIT OR Apache-2.0"
authors = ["Brandon Walsh <[email protected]>"]
readme = "README.md"
Expand Down
4 changes: 2 additions & 2 deletions examples/blink.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use serialport::*;
fn main() {
tracing_subscriber::fmt::init();

let serial_port_builder = serialport::new("/dev/tty.usbmodem14301", 57_600)
let serial_port_builder = serialport::new("/dev/tty.usbmodem14201", 57_600)
.data_bits(DataBits::Eight)
.parity(Parity::None)
.stop_bits(StopBits::One)
Expand All @@ -19,7 +19,7 @@ fn main() {
}
println!("setup complete");

let pin = 15;
let pin = 13;
board.set_pin_mode(pin, firmata_client::PIN_MODE_OUTPUT).expect("pin mode set");

let mut state = false;
Expand Down
2 changes: 1 addition & 1 deletion examples/button.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ fn main() {
}
println!("setup complete");

let led = 5;
let led = 13;
let button = 2;

board.report_digital(button, true).expect("digital reporting mode");
Expand Down
7 changes: 7 additions & 0 deletions src/board/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,13 @@ use crate::types::{
}
}

// disconnect
impl Board {
pub fn disconnect(&mut self) -> Result<()> {
self.connection_wrapper.disconnect()
}
}

// tools
impl Board {
/// Write on the internal connection.
Expand Down
14 changes: 14 additions & 0 deletions src/connection_wrapper/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,15 @@ use serialport::{

use crate::types::{Error, Result};

use super::Command;

pub struct Engine {
//loop control
halt: bool,

//communication
receiver: std::sync::mpsc::Receiver<Vec<u8>>,
command_receiver: std::sync::mpsc::Receiver<Command>,
sender: std::sync::mpsc::Sender<Vec<u8>>,
error_sender: std::sync::mpsc::Sender<Error>,

Expand All @@ -23,6 +26,7 @@ pub struct Engine {
impl Engine {
pub fn new(
receiver: std::sync::mpsc::Receiver<Vec<u8>>,
command_receiver: std::sync::mpsc::Receiver<Command>,
sender: std::sync::mpsc::Sender<Vec<u8>>,
error_sender: std::sync::mpsc::Sender<Error>,
serial_port_builder: SerialPortBuilder,
Expand All @@ -36,6 +40,7 @@ impl Engine {
halt: false,

receiver,
command_receiver,
sender,
error_sender,

Expand All @@ -53,6 +58,15 @@ impl Engine {
impl Engine {
#[tracing::instrument(skip(self), level = "DEBUG")]
fn revolution(&mut self) {
for command in self.command_receiver.try_iter() {
match command {
Command::Halt => {
self.halt = true;
return;
}
}
}

let buf = self.receiver.try_iter().flatten().collect::<Vec<u8>>();
if let Err(write_all_error) = self.connection.write_all(&buf) {
tracing::warn!("write_all error: {write_all_error}");
Expand Down
16 changes: 16 additions & 0 deletions src/connection_wrapper/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,33 @@ use serialport::SerialPortBuilder;

use crate::types::{Error, Result};

mod to_engine_command;
pub use to_engine_command::Command;

mod engine;
use engine::Engine;


#[derive(Debug)]
pub struct ConnectionWrapper {
thread_handle: std::thread::JoinHandle<()>,
receiver: std::sync::mpsc::Receiver<Vec<u8>>,
sender: std::sync::mpsc::Sender<Vec<u8>>,
command_sender: std::sync::mpsc::Sender<Command>,
error_receiver: std::sync::mpsc::Receiver<Error>,
}

impl ConnectionWrapper {
pub fn new(serial_port_builder: SerialPortBuilder) -> ConnectionWrapper {
let (to_engine_sender, to_engine_receiver) = std::sync::mpsc::channel::<Vec<u8>>();
let (to_engine_command_sender, to_engine_command_receiver) = std::sync::mpsc::channel::<Command>();
let (from_engine_sender, from_engine_receiver) = std::sync::mpsc::channel::<Vec<u8>>();
let (from_engine_error_sender, from_engine_error_receiver) = std::sync::mpsc::channel::<Error>();

let thread_handle = std::thread::spawn(move || {
match Engine::new(
to_engine_receiver,
to_engine_command_receiver,
from_engine_sender,
from_engine_error_sender.clone(),
serial_port_builder,
Expand All @@ -42,6 +49,7 @@ impl ConnectionWrapper {
thread_handle,
receiver: from_engine_receiver,
sender: to_engine_sender,
command_sender: to_engine_command_sender,
error_receiver: from_engine_error_receiver
}
}
Expand All @@ -51,6 +59,14 @@ impl ConnectionWrapper {
pub fn is_active(&self) -> bool {
!self.thread_handle.is_finished()
}
pub fn disconnect(&mut self) -> Result<()> {
if self.thread_handle.is_finished() {
return Err(Error::Disconnected);
}

self.command_sender.send(Command::Halt)?;
return Ok(());
}
}

impl ConnectionWrapper {
Expand Down
3 changes: 3 additions & 0 deletions src/connection_wrapper/to_engine_command.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pub enum Command {
Halt
}
21 changes: 16 additions & 5 deletions src/types/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ use std::sync::mpsc::SendError;

use serialport::Error as SerialPortError;

use super::super::connection_wrapper::Command;

/// Firmata error type.
#[derive(Debug)]
pub enum Error {
Expand All @@ -15,8 +17,10 @@ pub enum Error {
StdIo(std::io::Error),
/// UTF8 error
Utf8(std::str::Utf8Error),
/// Mpsc `SendError`
MpscSend(SendError<Vec<u8>>),
/// Mpsc Buf `SendError`
MpscBufSend(SendError<Vec<u8>>),
/// Mpsc Command `SendError`
MpscCommandSend(SendError<Command>),
/// Invalid Pin Mode
InvalidPinMode { pin: u8, modes: Vec<u8> },
/// Pin out of bounds
Expand All @@ -35,15 +39,16 @@ impl Error {
}
}

impl std::fmt::Display for Error {
impl std::fmt::Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Error::Disconnected => write!(f, "Disconnected"),
Error::UnknownSysEx { code } => write!(f, "Unknown `SysEx` code: {code}"),
Error::BadByte(byte) => write!(f, "Received a bad byte: {byte}"),
Error::StdIo(error) => write!(f, "I/O error: {error}"),
Error::Utf8(error) => write!(f, "UTF8 error: {error}"),
Error::MpscSend(error) => write!(f, "Mpsc SendError error: {error}"),
Error::MpscBufSend(error) => write!(f, "Mpsc Buf SendError error: {error}"),
Error::MpscCommandSend(error) => write!(f, "Mpsc Command SendError error: {error}"),
Error::InvalidPinMode { pin, modes } => write!(f, "Invalid Pin Mode: {pin} modes: {modes:?}"),
Error::PinOutOfBounds { pin, len, source } => write!(f, "Pin out of bounds: {pin} ({len}) source: {source}"),
Error::Serialport(error) => write!(f, "Serialport Error: {error}"),
Expand All @@ -65,7 +70,13 @@ impl From<std::str::Utf8Error> for Error {

impl From<SendError<Vec<u8>>> for Error {
fn from(error: SendError<Vec<u8>>) -> Self {
Error::MpscSend(error)
Error::MpscBufSend(error)
}
}

impl From<SendError<Command>> for Error {
fn from(error: SendError<Command>) -> Self {
Error::MpscCommandSend(error)
}
}

Expand Down

0 comments on commit 38599e6

Please sign in to comment.