Add message builder
This commit is contained in:
parent
5ec6ace462
commit
efbad0d676
5 changed files with 120 additions and 55 deletions
|
@ -20,22 +20,6 @@ struct Button {
|
||||||
const int button_count = 8;
|
const int button_count = 8;
|
||||||
|
|
||||||
const Button buttons[button_count] = {
|
const Button buttons[button_count] = {
|
||||||
{
|
|
||||||
.pin_id = 2,
|
|
||||||
.last_state = LOW
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.pin_id = 3,
|
|
||||||
.last_state = LOW
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.pin_id = 4,
|
|
||||||
.last_state = LOW
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.pin_id = 5,
|
|
||||||
.last_state = LOW
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
.pin_id = 6,
|
.pin_id = 6,
|
||||||
.last_state = LOW
|
.last_state = LOW
|
||||||
|
@ -51,6 +35,22 @@ const Button buttons[button_count] = {
|
||||||
{
|
{
|
||||||
.pin_id = 9,
|
.pin_id = 9,
|
||||||
.last_state = LOW
|
.last_state = LOW
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.pin_id = 10,
|
||||||
|
.last_state = LOW
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.pin_id = 11,
|
||||||
|
.last_state = LOW
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.pin_id = 12,
|
||||||
|
.last_state = LOW
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.pin_id = 13,
|
||||||
|
.last_state = LOW
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -98,43 +98,35 @@ void check_pin(Button* button, byte index) {
|
||||||
if (button->last_state == LOW) {
|
if (button->last_state == LOW) {
|
||||||
button->last_state = HIGH;
|
button->last_state = HIGH;
|
||||||
|
|
||||||
send_message("HIGH");
|
/*
|
||||||
|
// assemble message
|
||||||
|
Serial.print(message_start);
|
||||||
|
Serial.print(index + 1);
|
||||||
|
Serial.print(message_end);
|
||||||
|
|
||||||
|
// force new line
|
||||||
|
Serial.print('\n');
|
||||||
|
*/
|
||||||
|
|
||||||
|
debug_message(button->pin_id, "HIGH");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (button->last_state == HIGH) {
|
if (button->last_state == HIGH) {
|
||||||
button->last_state = LOW;
|
button->last_state = LOW;
|
||||||
|
|
||||||
send_message("LOW");
|
debug_message(button->pin_id, "LOW");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void send_message(char c) {
|
void debug_message(byte pin_id, char c[]) {
|
||||||
// assemble message
|
// assemble message
|
||||||
Serial.print(message_start);
|
Serial.print(message_start);
|
||||||
|
Serial.print(pin_id);
|
||||||
|
Serial.print(' ');
|
||||||
Serial.print(c);
|
Serial.print(c);
|
||||||
Serial.print(message_end);
|
Serial.print(message_end);
|
||||||
|
|
||||||
// force new line
|
// force new line
|
||||||
Serial.print('\n');
|
Serial.print('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
void send_message(char c[]) {
|
|
||||||
// assemble message
|
|
||||||
Serial.print(message_start);
|
|
||||||
Serial.print(c);
|
|
||||||
Serial.print(message_end);
|
|
||||||
|
|
||||||
// force new line
|
|
||||||
Serial.print('\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
void send_message(byte b) {
|
|
||||||
// assemble message
|
|
||||||
Serial.print(message_start);
|
|
||||||
Serial.print(b);
|
|
||||||
Serial.print(message_end);
|
|
||||||
|
|
||||||
// force new line
|
|
||||||
Serial.print('\n');
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,24 +1,31 @@
|
||||||
mod port;
|
mod service_specific;
|
||||||
|
|
||||||
|
use service_specific::*;
|
||||||
use utilities::prelude::*;
|
use utilities::prelude::*;
|
||||||
|
|
||||||
use port::*;
|
|
||||||
|
|
||||||
fn main() -> VerboseResult<()> {
|
fn main() -> VerboseResult<()> {
|
||||||
let settings = SerialPortSettings {
|
let mut port = Port::open(SerialPortSettings {
|
||||||
baud_rate: 9600,
|
baud_rate: 9600,
|
||||||
data_bits: DataBits::Eight,
|
data_bits: DataBits::Eight,
|
||||||
parity: Parity::None,
|
parity: Parity::None,
|
||||||
stop_bits: StopBits::One,
|
stop_bits: StopBits::One,
|
||||||
flow_control: FlowControl::None,
|
flow_control: FlowControl::None,
|
||||||
timeout: Duration::from_millis(2500),
|
timeout: Duration::from_millis(2500),
|
||||||
};
|
})?;
|
||||||
|
|
||||||
let port = Port::open(settings)?;
|
let mut message_builder = MessageBuilder::default();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
match port.read()? {
|
match port.read()? {
|
||||||
SerialReadResult::Message(msg) => println!("{}", msg),
|
SerialReadResult::Message(msg) => {
|
||||||
|
if let Some(remaining) = message_builder.check(msg) {
|
||||||
|
assert!(message_builder.is_complete());
|
||||||
|
|
||||||
|
println!("{}", message_builder.message());
|
||||||
|
|
||||||
|
message_builder = MessageBuilder::default();
|
||||||
|
}
|
||||||
|
}
|
||||||
SerialReadResult::Timeout => (),
|
SerialReadResult::Timeout => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
65
src/service_specific/message_builder.rs
Normal file
65
src/service_specific/message_builder.rs
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
const MESSAGE_START: char = '<';
|
||||||
|
const MESSAGE_END: char = '>';
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct MessageBuilder {
|
||||||
|
message: String,
|
||||||
|
complete: bool,
|
||||||
|
started: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MessageBuilder {
|
||||||
|
pub fn check(&mut self, mut msg: String) -> Option<String> {
|
||||||
|
// if message hasn't started, search for message start token
|
||||||
|
if !self.started {
|
||||||
|
let token_position = match msg.chars().position(|c| c == MESSAGE_START) {
|
||||||
|
Some(position) => position,
|
||||||
|
None => return None,
|
||||||
|
};
|
||||||
|
|
||||||
|
msg = msg.split_off(token_position + 1);
|
||||||
|
self.started = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if !self.complete {
|
||||||
|
match msg.chars().position(|c| c == MESSAGE_END) {
|
||||||
|
Some(position) => {
|
||||||
|
let mut remaining_msg = msg.split_off(position);
|
||||||
|
|
||||||
|
self.message.push_str(&msg);
|
||||||
|
self.complete = true;
|
||||||
|
|
||||||
|
msg = remaining_msg;
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
self.message.push_str(&msg);
|
||||||
|
msg.clear();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if msg.is_empty() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(msg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_complete(&self) -> bool {
|
||||||
|
self.complete
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn message(&self) -> &str {
|
||||||
|
&self.message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for MessageBuilder {
|
||||||
|
fn default() -> MessageBuilder {
|
||||||
|
MessageBuilder {
|
||||||
|
message: String::new(),
|
||||||
|
complete: false,
|
||||||
|
started: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
5
src/service_specific/mod.rs
Normal file
5
src/service_specific/mod.rs
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
mod message_builder;
|
||||||
|
mod port;
|
||||||
|
|
||||||
|
pub use message_builder::*;
|
||||||
|
pub use port::*;
|
|
@ -3,7 +3,6 @@ use serialport::prelude::*;
|
||||||
|
|
||||||
use utilities::prelude::*;
|
use utilities::prelude::*;
|
||||||
|
|
||||||
use std::cell::RefCell;
|
|
||||||
use std::io;
|
use std::io;
|
||||||
|
|
||||||
pub use serialport::{DataBits, FlowControl, Parity, SerialPortSettings, StopBits};
|
pub use serialport::{DataBits, FlowControl, Parity, SerialPortSettings, StopBits};
|
||||||
|
@ -15,7 +14,7 @@ pub enum SerialReadResult {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Port {
|
pub struct Port {
|
||||||
serial_port: RefCell<Box<dyn SerialPort>>,
|
serial_port: Box<dyn SerialPort>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Port {
|
impl Port {
|
||||||
|
@ -31,16 +30,14 @@ impl Port {
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
Ok(Port {
|
Ok(Port { serial_port: port })
|
||||||
serial_port: RefCell::new(port),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
pub fn read(&self) -> VerboseResult<SerialReadResult> {
|
pub fn read(&mut self) -> VerboseResult<SerialReadResult> {
|
||||||
let mut buf: Vec<u8> = (0..255).collect();
|
let mut buf: Vec<u8> = (0..255).collect();
|
||||||
|
|
||||||
match self.serial_port.try_borrow_mut()?.read(&mut buf[..]) {
|
match self.serial_port.read(&mut buf[..]) {
|
||||||
Ok(t) => Ok(SerialReadResult::Message(
|
Ok(t) => Ok(SerialReadResult::Message(
|
||||||
String::from_utf8(buf[0..t].to_vec())
|
String::from_utf8(buf[0..t].to_vec())
|
||||||
.map_err(|err| format!("failed converting utf8 buffer ({})", err))?,
|
.map_err(|err| format!("failed converting utf8 buffer ({})", err))?,
|
||||||
|
@ -51,9 +48,8 @@ impl Port {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
pub fn write(&self, msg: &str) -> VerboseResult<()> {
|
pub fn write(&mut self, msg: &str) -> VerboseResult<()> {
|
||||||
self.serial_port
|
self.serial_port
|
||||||
.try_borrow_mut()?
|
|
||||||
.write(msg.as_bytes())
|
.write(msg.as_bytes())
|
||||||
.map_err(|err| format!("failed writing to serial port ({})", err))?;
|
.map_err(|err| format!("failed writing to serial port ({})", err))?;
|
||||||
|
|
Loading…
Reference in a new issue