More consistent bluetooth notify
This commit is contained in:
@ -27,6 +27,6 @@ CONFIG_BT_NIMBLE_NVS_PERSIST=y
|
|||||||
# Change this to set log levels for the esp_idf; but unfortunately also the maximum for cargo.toml.
|
# Change this to set log levels for the esp_idf; but unfortunately also the maximum for cargo.toml.
|
||||||
# Changing maximum level does not seem to accomplish anything despite this commit https://github.com/esp-rs/esp-idf-svc/commit/c76720402b3dc32cc42aec7c2feb4539cc7d2af9
|
# Changing maximum level does not seem to accomplish anything despite this commit https://github.com/esp-rs/esp-idf-svc/commit/c76720402b3dc32cc42aec7c2feb4539cc7d2af9
|
||||||
# The unfortunate side effect of this is a 2k larger binary and log spam on startup.
|
# The unfortunate side effect of this is a 2k larger binary and log spam on startup.
|
||||||
# TODO: revisit and remove this for release?
|
# TODO DEBUG: revisit and remove this for release?
|
||||||
CONFIG_LOG_DEFAULT_LEVEL_VERBOSE=y
|
CONFIG_LOG_DEFAULT_LEVEL_VERBOSE=y
|
||||||
CONFIG_LOG_MAXIMUM_LEVEL_VERBOSE=y
|
CONFIG_LOG_MAXIMUM_LEVEL_VERBOSE=y
|
||||||
|
|||||||
@ -14,9 +14,6 @@ const BLE_MAX_INTERVAL: u16 = 48; // x 1.25ms
|
|||||||
const BLE_LATENCY: u16 = 0; // Number of packets that can be missed, extending interval
|
const BLE_LATENCY: u16 = 0; // Number of packets that can be missed, extending interval
|
||||||
const BLE_TIMEOUT: u16 = 500; // x10ms
|
const BLE_TIMEOUT: u16 = 500; // x10ms
|
||||||
|
|
||||||
const BUTTON_PRESSED: [u8; 1] = [0x1];
|
|
||||||
const BUTTON_RELEASED: [u8; 1] = [0x0];
|
|
||||||
|
|
||||||
const DEVICE_NAME: &str = "Gem Remotes";
|
const DEVICE_NAME: &str = "Gem Remotes";
|
||||||
|
|
||||||
const UUID_SERVICE_PAIR: BleUuid = uuid128!("9966ad5a-f13c-4b61-ba66-0861e08d09b4");
|
const UUID_SERVICE_PAIR: BleUuid = uuid128!("9966ad5a-f13c-4b61-ba66-0861e08d09b4");
|
||||||
@ -34,14 +31,9 @@ pub struct BleServer {
|
|||||||
impl BleServer {
|
impl BleServer {
|
||||||
pub fn new(dp: &mut Dispatch) -> Self {
|
pub fn new(dp: &mut Dispatch) -> Self {
|
||||||
let cmds = vec![
|
let cmds = vec![
|
||||||
// Switch to getting and updating notices; use the command version for sending commands only.
|
Commands::NotifyMotorDown { data: 0 },
|
||||||
//Commands::BluetoothUp { data: 0 },
|
Commands::NotifyMotorStop { data: 0 },
|
||||||
//Commands::BluetoothDown { data: 0 },
|
Commands::NotifyMotorUp { data: 0 },
|
||||||
//Commands::BluetoothStop { data: 0 },
|
|
||||||
Commands::NotifyMotorDown,
|
|
||||||
Commands::NotifyMotorStopping,
|
|
||||||
Commands::NotifyMotorUp,
|
|
||||||
Commands::NotifyMotorStopped,
|
|
||||||
];
|
];
|
||||||
let r = dp.get_callback_channel(&cmds);
|
let r = dp.get_callback_channel(&cmds);
|
||||||
let s = dp.get_cmd_channel();
|
let s = dp.get_cmd_channel();
|
||||||
@ -110,25 +102,14 @@ impl BleServer {
|
|||||||
trace!("Received update to bluetooth variable {:?}", cmd);
|
trace!("Received update to bluetooth variable {:?}", cmd);
|
||||||
match cmd {
|
match cmd {
|
||||||
// TODO DISCUSS: This logic (if one button is pressed others are released) could be done in app instead.
|
// TODO DISCUSS: This logic (if one button is pressed others are released) could be done in app instead.
|
||||||
Commands::NotifyMotorUp => {
|
Commands::NotifyMotorUp{data} => {
|
||||||
button_up.lock().set_value(&BUTTON_PRESSED).notify();
|
button_up.lock().set_value(&[data]).notify();
|
||||||
button_down.lock().set_value(&BUTTON_RELEASED).notify();
|
|
||||||
button_stop.lock().set_value(&BUTTON_RELEASED).notify();
|
|
||||||
}
|
}
|
||||||
Commands::NotifyMotorDown => {
|
Commands::NotifyMotorDown{data} => {
|
||||||
button_up.lock().set_value(&BUTTON_RELEASED).notify();
|
button_down.lock().set_value(&[data]).notify();
|
||||||
button_down.lock().set_value(&BUTTON_PRESSED).notify();
|
|
||||||
button_stop.lock().set_value(&BUTTON_RELEASED).notify();
|
|
||||||
}
|
}
|
||||||
Commands::NotifyMotorStopping => {
|
Commands::NotifyMotorStop{data} => {
|
||||||
button_up.lock().set_value(&BUTTON_RELEASED).notify();
|
button_up.lock().set_value(&[data]).notify();
|
||||||
button_down.lock().set_value(&BUTTON_RELEASED).notify();
|
|
||||||
button_stop.lock().set_value(&BUTTON_PRESSED).notify();
|
|
||||||
}
|
|
||||||
Commands::NotifyMotorStopped => {
|
|
||||||
button_up.lock().set_value(&BUTTON_RELEASED).notify();
|
|
||||||
button_down.lock().set_value(&BUTTON_RELEASED).notify();
|
|
||||||
button_stop.lock().set_value(&BUTTON_RELEASED).notify();
|
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
error!("Invalid command received by bluetooth handler {:?}", cmd);
|
error!("Invalid command received by bluetooth handler {:?}", cmd);
|
||||||
|
|||||||
@ -24,10 +24,17 @@ pub enum Commands {
|
|||||||
ButtonTimerRestart,
|
ButtonTimerRestart,
|
||||||
ButtonTimerClear,
|
ButtonTimerClear,
|
||||||
|
|
||||||
NotifyMotorUp,
|
NotifyMotorUp {data: u8},
|
||||||
NotifyMotorDown,
|
NotifyMotorDown {data: u8},
|
||||||
NotifyMotorStopping,
|
NotifyMotorStop {data: u8},
|
||||||
NotifyMotorStopped, // Signaled after stop timeout
|
}
|
||||||
|
|
||||||
|
#[non_exhaustive]
|
||||||
|
pub struct Button;
|
||||||
|
|
||||||
|
impl Button {
|
||||||
|
pub const PRESSED: u8 = 0x1;
|
||||||
|
pub const RELEASED: u8 = 0x0;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type CmdType = std::mem::Discriminant<Commands>;
|
pub type CmdType = std::mem::Discriminant<Commands>;
|
||||||
|
|||||||
@ -29,9 +29,12 @@ fn main() {
|
|||||||
// Do basic initialization
|
// Do basic initialization
|
||||||
esp_idf_svc::sys::link_patches();
|
esp_idf_svc::sys::link_patches();
|
||||||
esp_idf_svc::log::EspLogger::initialize_default();
|
esp_idf_svc::log::EspLogger::initialize_default();
|
||||||
|
|
||||||
|
// Set log level based on compiler flags
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
log::set_max_level(log::LevelFilter::Trace);
|
log::set_max_level(log::LevelFilter::Trace);
|
||||||
//TODO DEBUG: remove trace logging
|
#[cfg(not(debug_assertions))]
|
||||||
//log::set_max_level(log::LevelFilter::Info);
|
log::set_max_level(log::LevelFilter::Info);
|
||||||
|
|
||||||
// Set panic to use error! instead of write! (as we will potentially log errors)
|
// Set panic to use error! instead of write! (as we will potentially log errors)
|
||||||
panic::set_hook(Box::new(|panic_info| {
|
panic::set_hook(Box::new(|panic_info| {
|
||||||
@ -49,6 +52,7 @@ fn main() {
|
|||||||
error!("A panic occurred at {}:{}: {}", filename, line, cause);
|
error!("A panic occurred at {}:{}: {}", filename, line, cause);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
// Start up our main loop
|
||||||
match future::block_on(main_loop()) {
|
match future::block_on(main_loop()) {
|
||||||
Ok(_) => {error!("Exited main loop with no errors, but this should not happen."); panic!();}
|
Ok(_) => {error!("Exited main loop with no errors, but this should not happen."); panic!();}
|
||||||
Err(e) => {error!("Exited main loop with error {}", e); panic!();}
|
Err(e) => {error!("Exited main loop with error {}", e); panic!();}
|
||||||
@ -62,7 +66,7 @@ async fn main_loop() -> Result<()> {
|
|||||||
let mut dp = dispatch::Dispatch::new();
|
let mut dp = dispatch::Dispatch::new();
|
||||||
|
|
||||||
// Debug Drivers (TODO DEBUG: remove debug)
|
// Debug Drivers (TODO DEBUG: remove debug)
|
||||||
let motor_driver = motor_driver::MotorDriverDebug::new(dp.get_cmd_channel());
|
let motor_driver = motor_driver::MotorDriverDebug::new();
|
||||||
|
|
||||||
// Setup of various drivers that need to out-live the executor
|
// Setup of various drivers that need to out-live the executor
|
||||||
let m_chan = motor_controller::Controller::prepare_controller(&mut dp);
|
let m_chan = motor_controller::Controller::prepare_controller(&mut dp);
|
||||||
|
|||||||
@ -5,7 +5,7 @@ use log::*; //{trace, debug, info, warn, error}
|
|||||||
//use async_channel::Receiver;
|
//use async_channel::Receiver;
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
|
||||||
use crate::commands::Commands;
|
use crate::commands::{Commands, Button};
|
||||||
use crate::motor_driver::Commands as MotorCommands;
|
use crate::motor_driver::Commands as MotorCommands;
|
||||||
use crate::motor_driver::SendQ as MotorSendQ;
|
use crate::motor_driver::SendQ as MotorSendQ;
|
||||||
use crate::dispatch::{Dispatch, RecvQ, SendQ};
|
use crate::dispatch::{Dispatch, RecvQ, SendQ};
|
||||||
@ -55,19 +55,22 @@ impl Controller {
|
|||||||
match new_s {
|
match new_s {
|
||||||
ControllerStates::Stopped => {
|
ControllerStates::Stopped => {
|
||||||
// Other notify commands are sent directly from the motor controller
|
// Other notify commands are sent directly from the motor controller
|
||||||
self.send.send(Commands::NotifyMotorStopped).await?;
|
self.send.send(Commands::NotifyMotorStop{data: Button::RELEASED}).await?;
|
||||||
}
|
}
|
||||||
ControllerStates::Stopping => {
|
ControllerStates::Stopping => {
|
||||||
self.send.send(Commands::StopTimerRestart).await?;
|
self.send.send(Commands::StopTimerRestart).await?;
|
||||||
self.motor_q.send(MotorCommands::Stop).await?;
|
self.motor_q.send(MotorCommands::Stop).await?;
|
||||||
|
self.send.send(Commands::NotifyMotorStop{data: Button::PRESSED}).await?;
|
||||||
}
|
}
|
||||||
ControllerStates::GoingUp => {
|
ControllerStates::GoingUp => {
|
||||||
self.send.send(Commands::ButtonTimerRestart).await?;
|
self.send.send(Commands::ButtonTimerRestart).await?;
|
||||||
self.motor_q.send(MotorCommands::StartUp).await?;
|
self.motor_q.send(MotorCommands::StartUp).await?;
|
||||||
|
self.send.send(Commands::NotifyMotorUp{data: Button::PRESSED}).await?;
|
||||||
}
|
}
|
||||||
ControllerStates::GoingDown => {
|
ControllerStates::GoingDown => {
|
||||||
self.send.send(Commands::ButtonTimerRestart).await?;
|
self.send.send(Commands::ButtonTimerRestart).await?;
|
||||||
self.motor_q.send(MotorCommands::StartDown).await?;
|
self.motor_q.send(MotorCommands::StartDown).await?;
|
||||||
|
self.send.send(Commands::NotifyMotorUp{data: Button::PRESSED}).await?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -92,9 +95,11 @@ impl Controller {
|
|||||||
}
|
}
|
||||||
ControllerStates::GoingUp => {
|
ControllerStates::GoingUp => {
|
||||||
self.send.send(Commands::ButtonTimerClear).await?;
|
self.send.send(Commands::ButtonTimerClear).await?;
|
||||||
|
self.send.send(Commands::NotifyMotorUp{data: Button::RELEASED}).await?;
|
||||||
}
|
}
|
||||||
ControllerStates::GoingDown => {
|
ControllerStates::GoingDown => {
|
||||||
self.send.send(Commands::ButtonTimerClear).await?;
|
self.send.send(Commands::ButtonTimerClear).await?;
|
||||||
|
self.send.send(Commands::NotifyMotorDown{data: Button::RELEASED}).await?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@ -4,9 +4,6 @@ use log::*; //{trace, debug, info, warn, error}
|
|||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use async_channel::{unbounded, Receiver, Sender};
|
use async_channel::{unbounded, Receiver, Sender};
|
||||||
|
|
||||||
use crate::dispatch;
|
|
||||||
use crate::commands::Commands as Dispatch_Commands;
|
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
pub enum Commands {
|
pub enum Commands {
|
||||||
StartUp,
|
StartUp,
|
||||||
@ -20,17 +17,15 @@ pub type RecvQ = Receiver<Commands>;
|
|||||||
pub struct MotorDriverDebug{
|
pub struct MotorDriverDebug{
|
||||||
endpoint: SendQ,
|
endpoint: SendQ,
|
||||||
recv_q: RecvQ,
|
recv_q: RecvQ,
|
||||||
dispatch: dispatch::SendQ,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Debug / example version of Motor Driver.
|
/// Debug / example version of Motor Driver.
|
||||||
impl MotorDriverDebug {
|
impl MotorDriverDebug {
|
||||||
pub fn new(send_q: dispatch::SendQ) -> Self {
|
pub fn new() -> Self {
|
||||||
let (s,r) = unbounded();
|
let (s,r) = unbounded();
|
||||||
MotorDriverDebug {
|
MotorDriverDebug {
|
||||||
endpoint: s,
|
endpoint: s,
|
||||||
recv_q: r,
|
recv_q: r,
|
||||||
dispatch:send_q
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,17 +51,14 @@ impl MotorDriverDebug {
|
|||||||
|
|
||||||
pub async fn start_up(&self) -> Result<()> {
|
pub async fn start_up(&self) -> Result<()> {
|
||||||
warn!("Starting motor, direction: Up");
|
warn!("Starting motor, direction: Up");
|
||||||
self.dispatch.send(Dispatch_Commands::NotifyMotorUp).await?;
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
pub async fn start_down(&self) -> Result<()> {
|
pub async fn start_down(&self) -> Result<()> {
|
||||||
warn!("Starting motor, direction: Down");
|
warn!("Starting motor, direction: Down");
|
||||||
self.dispatch.send(Dispatch_Commands::NotifyMotorDown).await?;
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
pub async fn stop(&self) -> Result<()> {
|
pub async fn stop(&self) -> Result<()> {
|
||||||
warn!("Stopping motor");
|
warn!("Stopping motor");
|
||||||
self.dispatch.send(Dispatch_Commands::NotifyMotorStopping).await?;
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user