mirror of
https://github.com/jhbruhn/catprint-rs.git
synced 2025-03-14 18:35:49 +00:00
Merge fba7b6fc3e
into a771416288
This commit is contained in:
commit
71b5089739
6 changed files with 1320 additions and 487 deletions
1696
Cargo.lock
generated
1696
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -6,11 +6,11 @@ edition = "2018"
|
|||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
btleplug = "0.8"
|
||||
uuid = "0.8"
|
||||
btleplug = "0.11"
|
||||
uuid = "1.10"
|
||||
futures = "0.3"
|
||||
tokio = {version = "1.10", features = ["rt", "macros", "rt-multi-thread"] }
|
||||
crc = { git = "https://github.com/mrhooray/crc-rs.git" }
|
||||
dither = "=1.3.7" # last version without nightly requirement
|
||||
image = "0.23"
|
||||
clap = "3.0.0-beta.4"
|
||||
image = "0.25"
|
||||
clap = { version = "4.5", features = ["derive"] }
|
|
@ -2,20 +2,19 @@ use btleplug::platform::Manager;
|
|||
use catprint::*;
|
||||
use std::error::Error;
|
||||
|
||||
use clap::{crate_authors, crate_version, AppSettings, ArgEnum, Clap};
|
||||
use clap::{Parser, ValueEnum};
|
||||
|
||||
#[derive(Clap)]
|
||||
#[clap(version = crate_version!(), author = crate_authors!())]
|
||||
#[clap(setting = AppSettings::ColoredHelp)]
|
||||
#[derive(Parser, Debug)]
|
||||
#[command(author, version, about, long_about = None)]
|
||||
struct Opts {
|
||||
/// Set the device name of your printer.
|
||||
#[clap(short, long, default_value = "GB02")]
|
||||
#[arg(short, long, default_value = "GB02")]
|
||||
device_name: String,
|
||||
#[clap(subcommand)]
|
||||
#[command(subcommand)]
|
||||
subcmd: SubCommand,
|
||||
}
|
||||
|
||||
#[derive(Clap)]
|
||||
#[derive(Parser, Debug)]
|
||||
enum SubCommand {
|
||||
/// Move the paper without printing
|
||||
Feed(Feed),
|
||||
|
@ -24,7 +23,7 @@ enum SubCommand {
|
|||
Print(Print),
|
||||
}
|
||||
|
||||
#[derive(Clap)]
|
||||
#[derive(Parser, Debug)]
|
||||
struct Feed {
|
||||
/// Print debug info
|
||||
#[clap(short, long)]
|
||||
|
@ -33,13 +32,13 @@ struct Feed {
|
|||
length: u8,
|
||||
}
|
||||
|
||||
#[derive(Clap)]
|
||||
#[derive(Parser, Debug)]
|
||||
struct Print {
|
||||
/// The path to the image you want to print out
|
||||
input_image: String,
|
||||
|
||||
/// The ditherer supposed to be used. none is good for text and vector graphics
|
||||
#[clap(arg_enum, short, long, default_value = "k-mean")]
|
||||
#[clap(value_enum, short, long, default_value = "k-mean")]
|
||||
ditherer: Ditherers,
|
||||
|
||||
/// Rotate picture by 90 degrees
|
||||
|
@ -51,7 +50,7 @@ struct Print {
|
|||
no_compress: bool,
|
||||
}
|
||||
|
||||
#[derive(ArgEnum)]
|
||||
#[derive(ValueEnum, Debug, Clone)]
|
||||
enum Ditherers {
|
||||
None,
|
||||
KMean,
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
use btleplug::api::{Central, Manager as _, Peripheral};
|
||||
use btleplug::api::{Central, Manager as _, Peripheral, ScanFilter, WriteType};
|
||||
use btleplug::platform::Manager;
|
||||
use std::collections::VecDeque;
|
||||
use std::error::Error;
|
||||
use std::time::Duration;
|
||||
use tokio::time;
|
||||
|
@ -12,7 +11,8 @@ const TX_CHARACTERISTIC_UUID: Uuid = Uuid::from_u128(0x0000ae01_0000_1000_8000_0
|
|||
pub struct Device {
|
||||
peripheral: btleplug::platform::Peripheral,
|
||||
supports_compression: bool,
|
||||
tx_buffer: VecDeque<u8>,
|
||||
tx_buffer: Vec<u8>,
|
||||
tx_characteristic: btleplug::api::Characteristic,
|
||||
}
|
||||
|
||||
impl Device {
|
||||
|
@ -26,7 +26,7 @@ impl Device {
|
|||
for adapter in adapter_list.iter() {
|
||||
println!("Starting scan...");
|
||||
adapter
|
||||
.start_scan()
|
||||
.start_scan(ScanFilter::default())
|
||||
.await
|
||||
.expect("Can't scan BLE adapter for connected devices...");
|
||||
time::sleep(Duration::from_secs(2)).await;
|
||||
|
@ -41,17 +41,27 @@ impl Device {
|
|||
if !peripheral.is_connected().await? {
|
||||
peripheral.connect().await?;
|
||||
}
|
||||
let _ = peripheral.discover_characteristics().await?;
|
||||
|
||||
let supports_compression = match name {
|
||||
"MX10" => false,
|
||||
_ => true,
|
||||
};
|
||||
println!("Connected to {}", name);
|
||||
println!("Discovering services...");
|
||||
peripheral.discover_services().await?;
|
||||
|
||||
let supports_compression = name != "MX10";
|
||||
|
||||
let characteristics = peripheral.characteristics();
|
||||
|
||||
println!("Found {} characteristics", characteristics.len());
|
||||
|
||||
let tx_characteristic = characteristics
|
||||
.iter()
|
||||
.find(|c| c.uuid == TX_CHARACTERISTIC_UUID)
|
||||
.expect("Could not find TX characteristic");
|
||||
|
||||
device_result = Ok(Device {
|
||||
peripheral,
|
||||
tx_buffer: VecDeque::new(),
|
||||
tx_buffer: Vec::new(),
|
||||
supports_compression,
|
||||
tx_characteristic: tx_characteristic.clone(),
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
@ -60,6 +70,7 @@ impl Device {
|
|||
}
|
||||
}
|
||||
|
||||
println!("Scan complete");
|
||||
device_result
|
||||
}
|
||||
|
||||
|
@ -74,46 +85,25 @@ impl Device {
|
|||
}
|
||||
|
||||
pub async fn flush(&mut self) -> Result<(), Box<dyn Error>> {
|
||||
const MTU_SIZE: usize = 20;
|
||||
let chunks = self.tx_buffer.chunks(20);
|
||||
|
||||
while !self.tx_buffer.is_empty() {
|
||||
let mut buf = Vec::with_capacity(MTU_SIZE);
|
||||
for _ in 0..MTU_SIZE {
|
||||
if let Some(byte) = self.tx_buffer.pop_front() {
|
||||
buf.push(byte);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
let write_type = if chunks.len() > 1 {
|
||||
WriteType::WithoutResponse
|
||||
} else {
|
||||
WriteType::WithResponse
|
||||
};
|
||||
|
||||
// this could be nicer i guess
|
||||
}
|
||||
|
||||
self.tx(&buf).await?;
|
||||
for chunk in chunks {
|
||||
self.peripheral
|
||||
.write(&self.tx_characteristic, chunk, write_type)
|
||||
.await
|
||||
.unwrap();
|
||||
std::thread::sleep(std::time::Duration::from_millis(10));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn tx(&mut self, data: &[u8]) -> Result<(), Box<dyn Error>> {
|
||||
let characteristics = self.peripheral.characteristics();
|
||||
|
||||
let tx_characteristic = characteristics
|
||||
.iter()
|
||||
.filter(|c| c.uuid == TX_CHARACTERISTIC_UUID)
|
||||
.next()
|
||||
.unwrap();
|
||||
|
||||
self.peripheral
|
||||
.write(
|
||||
&tx_characteristic,
|
||||
data,
|
||||
btleplug::api::WriteType::WithoutResponse,
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn destroy(self) {
|
||||
self.peripheral.disconnect().await.unwrap();
|
||||
}
|
||||
|
|
|
@ -93,7 +93,7 @@ impl Image {
|
|||
let pixel = self.image.get((x, y)).unwrap();
|
||||
let val = if pixel > &self.mean { 0 } else { 1 };
|
||||
if val == last_val {
|
||||
counter = counter + 1
|
||||
counter += 1
|
||||
} else if counter > 0 {
|
||||
compressed.extend(rle_bytes(last_val, counter));
|
||||
counter = 1;
|
||||
|
|
|
@ -72,7 +72,7 @@ impl Command {
|
|||
DeviceId(_) => 0xBB,
|
||||
SetSpeed(_) => 0xBD,
|
||||
SetDrawingMode(_) => 0xBE,
|
||||
Print(true, _, _) => 0xBf, // compressed
|
||||
Print(true, _, _) => 0xBF, // compressed
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -107,7 +107,7 @@ impl Command {
|
|||
|
||||
let mut crc = CCITT.digest();
|
||||
crc.update(&payload);
|
||||
let crc = crc.finalize() as u8;
|
||||
let crc = crc.finalize();
|
||||
|
||||
let payload_len = payload.len();
|
||||
|
||||
|
|
Loading…
Reference in a new issue