first
This commit is contained in:
28
src-tauri/src/algorithm/mod.rs
Normal file
28
src-tauri/src/algorithm/mod.rs
Normal file
@ -0,0 +1,28 @@
|
||||
mod smoothmethod;
|
||||
mod spectraltools;
|
||||
mod sharpmethod;
|
||||
|
||||
|
||||
#[tauri::command]
|
||||
pub fn interpolate_spline(x: Vec<f64>, y: Vec<f64>, step: f64) ->Vec<(f64, f64)>{
|
||||
spectraltools::interpolate_spline(x, y, step).unwrap()
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn interpolate_spline_at_points(x: Vec<f64>, y: Vec<f64>, x_target: Vec<f64>) -> Vec<f64>{
|
||||
spectraltools::interpolate_spline_at_points(x, y, x_target).unwrap()
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn sg_smooth(data: Vec<f64>, window: usize, order: usize) -> Vec<f64> {
|
||||
smoothmethod::savgol(data, window, order)
|
||||
}
|
||||
#[tauri::command]
|
||||
pub fn Gaussian_filter_high(data: Vec<f64>, sigma: f64) -> Vec<f64> {
|
||||
sharpmethod::high_pass_gaussian_filter(data, sigma)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn find_peek(data: Vec<f64>, minheigh: f64) -> Vec<(u32, f64)> {
|
||||
spectraltools::find_peek(data, minheigh)
|
||||
}
|
42
src-tauri/src/algorithm/sharpmethod.rs
Normal file
42
src-tauri/src/algorithm/sharpmethod.rs
Normal file
@ -0,0 +1,42 @@
|
||||
extern crate ndarray;
|
||||
extern crate ndarray_ndimage;
|
||||
|
||||
use ndarray::prelude::*;
|
||||
use ndarray_ndimage::{gaussian_filter, BorderMode};
|
||||
|
||||
pub fn high_pass_gaussian_filter(input: Vec<f64>, sigma: f64) -> Vec<f64> {
|
||||
// 将输入 Vec<f64> 转换为 Array1<f64>
|
||||
let mut input_array = Array1::from_vec(input);
|
||||
// for i in 0..input_array.len(){
|
||||
//
|
||||
// input_array[i]=input_array[i]*input_array[i]/( 65535f64);
|
||||
// }
|
||||
// return input_array.to_vec();
|
||||
|
||||
|
||||
|
||||
// 高斯低通滤波
|
||||
let mut low_pass = gaussian_filter(&input_array, sigma, 0, BorderMode::Reflect, 3);
|
||||
// Modify the result: set values less than zero to zero
|
||||
println!("{:?}",low_pass);
|
||||
// 高通滤波:原始信号 - 低通滤波结果
|
||||
let mut addarry=&input_array - &low_pass;
|
||||
for i in 0..addarry.len(){
|
||||
if addarry[i] < 0.0 {
|
||||
addarry[i] = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
let high_pass =&input_array+ &addarry;
|
||||
|
||||
// 找到原始数据和锐化后数据的最大值
|
||||
let max_original = input_array.iter().cloned().fold(f64::MIN, f64::max);
|
||||
let max_sharpened = high_pass.iter().cloned().fold(f64::MIN, f64::max);
|
||||
|
||||
// 计算系数
|
||||
let coefficient = max_original / max_sharpened;
|
||||
|
||||
// 应用系数并将输出 Array1<f64> 转换回 Vec<f64>
|
||||
high_pass.map(|&x| x * coefficient).to_vec()
|
||||
}
|
23
src-tauri/src/algorithm/smoothmethod.rs
Normal file
23
src-tauri/src/algorithm/smoothmethod.rs
Normal file
@ -0,0 +1,23 @@
|
||||
extern crate savgol_rs;
|
||||
|
||||
|
||||
use savgol_rs::savgol_filter;
|
||||
pub fn savgol(data: Vec<f64>, window: usize, order: usize) -> Vec<f64> {
|
||||
let svinput= savgol_rs::SavGolInput{data:&data,window_length:window,poly_order:order,derivative:0};
|
||||
|
||||
savgol_filter(&svinput).unwrap()
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn test_savgol() {
|
||||
// 示例数据
|
||||
let data = vec![1.0, 1.9, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0];
|
||||
let window = 5;
|
||||
let order = 2;
|
||||
|
||||
// 调用 savgol 函数
|
||||
let smoothed_data = savgol(data.clone(), window, order);
|
||||
println!("Smoothed data: {:?}", smoothed_data);
|
||||
|
||||
}
|
140
src-tauri/src/algorithm/spectraltools.rs
Normal file
140
src-tauri/src/algorithm/spectraltools.rs
Normal file
@ -0,0 +1,140 @@
|
||||
extern crate splines;
|
||||
|
||||
use splines::{Spline, Key, Interpolation};
|
||||
use std::error::Error;
|
||||
|
||||
use find_peaks::PeakFinder;
|
||||
|
||||
pub fn interpolate_spline<T: Copy + Into<f64>,>(x_T: Vec<T>, y_T: Vec<T>, step: f64) -> Result<Vec<(f64, f64)>, Box<dyn Error>> {
|
||||
let x: Vec<f64> = x_T.iter().map(|&x| x.into()).collect();
|
||||
let y: Vec<f64> = y_T.iter().map(|&y| y.into()).collect();
|
||||
|
||||
if x.len() != y.len() {
|
||||
return Err("x and y must have the same length".into());
|
||||
}
|
||||
|
||||
// 创建样条曲线
|
||||
let keys: Vec<Key<f64, f64>> = x.iter()
|
||||
.zip(y.iter())
|
||||
.map(|(&x, &y)| Key::new(x, y, Interpolation::Linear))
|
||||
.collect();
|
||||
|
||||
let spline = Spline::from_vec(keys);
|
||||
|
||||
// 计算 x 的最大值和最小值
|
||||
let &start = x.iter().min_by(|a, b| a.partial_cmp(b).unwrap()).unwrap();
|
||||
let &end = x.iter().max_by(|a, b| a.partial_cmp(b).unwrap()).unwrap();
|
||||
|
||||
// 插值到间隔为 step 的点
|
||||
let mut result = Vec::new();
|
||||
let mut t = start;
|
||||
|
||||
while t <= end {
|
||||
if let Some(value) = spline.clamped_sample(t) {
|
||||
result.push((t, value));
|
||||
}
|
||||
t += step;
|
||||
}
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
pub fn interpolate_spline_at_points<T: Copy + Into<f64>>(x_T: Vec<T>, y_T: Vec<T>, x_target: Vec<f64>) -> Result<Vec<(f64)>, Box<dyn Error>> {
|
||||
let x: Vec<f64> = x_T.iter().map(|&x| x.into()).collect();
|
||||
let y: Vec<f64> = y_T.iter().map(|&y| y.into()).collect();
|
||||
|
||||
if x.len() != y.len() {
|
||||
return Err("x and y must have the same length".into());
|
||||
}
|
||||
|
||||
// 创建样条曲线
|
||||
let keys: Vec<Key<f64, f64>> = x.iter()
|
||||
.zip(y.iter())
|
||||
.map(|(&x, &y)| Key::new(x, y, Interpolation::Linear))
|
||||
.collect();
|
||||
|
||||
let spline = Spline::from_vec(keys);
|
||||
|
||||
// 插值到 x_target 指定的点
|
||||
let mut result = Vec::new();
|
||||
|
||||
for &t in x_target.iter() {
|
||||
if let Some(value) = spline.clamped_sample(t) {
|
||||
result.push(value);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
pub fn find_peek(data:Vec<f64>,minheigh:f64)->Vec<(u32,f64)>{
|
||||
let mut fp = PeakFinder::new(&data);
|
||||
fp.with_min_prominence(200.);
|
||||
fp.with_min_height(minheigh);
|
||||
let mut retvec=Vec::new();
|
||||
let peaks = fp.find_peaks();
|
||||
for p in peaks {
|
||||
// println!("{} {}", p.middle_position(), p.height.unwrap());
|
||||
retvec.push((p.middle_position().try_into().unwrap(),p.height.unwrap()));
|
||||
|
||||
}
|
||||
retvec
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn testinterpolate_spline() -> Result<(), Box<dyn Error>> {
|
||||
// 示例数据
|
||||
let x = vec![0.0,0.5, 0.569, 1.138, 1.707, 2.276, 2.845];
|
||||
let y = vec![0.0, 0.4,0.5, 1.0, 0.5, 0.0, -0.5];
|
||||
let step = 0.1;
|
||||
|
||||
// 调用插值函数
|
||||
let interpolated_values = interpolate_spline(x, y, step)?;
|
||||
|
||||
// 输出结果
|
||||
for (xi, yi) in interpolated_values {
|
||||
println!("x = {:.3}, y = {:.3}", xi, yi);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
#[test]
|
||||
fn tset_interpolate_spline_at_points() -> Result<(), Box<dyn Error>> {
|
||||
let x = vec![0.0,0.5, 0.569, 1.138, 1.707, 2.276, 2.845];
|
||||
let y = vec![0.0, 0.4,0.5, 1.0, 0.5, 0.0, -0.5];
|
||||
let x_target = vec![0.1, 0.2, 0.3];
|
||||
|
||||
let result = interpolate_spline_at_points(x, y, x_target)?;
|
||||
|
||||
for (yi) in result {
|
||||
println!("y = {:.3}", yi);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
use csv::ReaderBuilder;
|
||||
fn read_csv_to_vec(file_path: &str) -> Result<Vec<f64>, Box<dyn Error>> {
|
||||
let mut rdr = ReaderBuilder::new().from_path(file_path)?;
|
||||
let mut values = Vec::new();
|
||||
|
||||
for result in rdr.records() {
|
||||
let record = result?;
|
||||
if let Some(value) = record.get(1) {
|
||||
values.push(value.parse::<f64>()?);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(values)
|
||||
}
|
||||
|
||||
|
||||
|
||||
#[test]
|
||||
fn test_find_peek(){
|
||||
let data = read_csv_to_vec("D:\\06Learn\\rust\\tarui\\myfirst_tauri\\src-tauri\\test0_UP.csv").unwrap();
|
||||
let peaks = find_peek(data,10000.0);
|
||||
for p in peaks {
|
||||
println!("{} {}", p.0, p.1);
|
||||
}
|
||||
}
|
471
src-tauri/src/main.rs
Normal file
471
src-tauri/src/main.rs
Normal file
@ -0,0 +1,471 @@
|
||||
// Prevents additional console window on Windows in release, DO NOT REMOVE!!
|
||||
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
||||
use core::str;
|
||||
use serialport::new;
|
||||
use std::ffi::c_float;
|
||||
use std::fmt::format;
|
||||
use std::fs;
|
||||
use std::fs::File;
|
||||
use std::io::{self, Read, Write};
|
||||
// use std::sync::WaitTimeoutResult;
|
||||
use std::path::Path;
|
||||
mod algorithm;
|
||||
mod mylog;
|
||||
mod serport;
|
||||
use algorithm::interpolate_spline;
|
||||
use algorithm::sg_smooth;
|
||||
use std::mem;
|
||||
|
||||
use mylog::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_with::serde_as;
|
||||
use serport::serport::*;
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
struct RetStruct {
|
||||
datatype: u8,
|
||||
content: String,
|
||||
data: IS11DataStruct,
|
||||
}
|
||||
#[serde_as]
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[repr(C)]
|
||||
struct IS11DataStruct {
|
||||
datatype: u8, // Using r# to allow the use of the keyword 'type'
|
||||
direction: u8,
|
||||
tuigan_stat: u8,
|
||||
shutter_time: u32,
|
||||
index: u64,
|
||||
temprature: [f32; 8],
|
||||
#[serde_as(as = "[_; 2048]")]
|
||||
data: [f32; 2048],
|
||||
}
|
||||
impl Default for IS11DataStruct {
|
||||
fn default() -> Self {
|
||||
IS11DataStruct {
|
||||
datatype: 0,
|
||||
direction: 10,
|
||||
tuigan_stat: 0,
|
||||
shutter_time: 0,
|
||||
index: 0,
|
||||
temprature: [0.0; 8],
|
||||
data: [0.0; 2048],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
fn savecalibratefile(Gain: Vec<f32>, shutter: u32, direction: bool, filepath: String) -> String {
|
||||
let mut data = IS11DataStruct::default();
|
||||
data.data = Gain.as_slice().try_into().unwrap();
|
||||
data.shutter_time = shutter as u32;
|
||||
data.direction = if direction { 1 } else { 0 };
|
||||
data.datatype = 0x04;
|
||||
let mut buffer = vec![0u8; mem::size_of::<IS11DataStruct>()];
|
||||
|
||||
// 序列化为二进制数据
|
||||
unsafe {
|
||||
let ptr = &data as *const IS11DataStruct as *const u8;
|
||||
std::ptr::copy_nonoverlapping(ptr, buffer.as_mut_ptr(), mem::size_of::<IS11DataStruct>());
|
||||
}
|
||||
// 序列化为二进制数据
|
||||
let file_path = Path::new(&filepath);
|
||||
|
||||
// 获取文件路径的父目录
|
||||
if let Some(parent) = file_path.parent() {
|
||||
// 确保父目录存在
|
||||
if !parent.exists() {
|
||||
fs::create_dir_all(parent).unwrap();
|
||||
println!("父目录已创建: {:?}", parent);
|
||||
} else {
|
||||
println!("父目录已存在: {:?}", parent);
|
||||
}
|
||||
} else {
|
||||
println!("文件路径没有父目录");
|
||||
}
|
||||
let mut file = File::create(filepath).unwrap();
|
||||
file.write_all(&buffer).unwrap();
|
||||
|
||||
"OK".to_string()
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
fn sendcalibratetodev(Gain: Vec<f32>, shutter: u32, direction: bool) -> String {
|
||||
let mut data = IS11DataStruct::default();
|
||||
data.data = Gain.as_slice().try_into().unwrap();
|
||||
data.shutter_time = shutter as u32;
|
||||
data.direction = if direction { 1 } else { 0 };
|
||||
data.datatype = 0x04;
|
||||
let mut buffer = vec![0u8; mem::size_of::<IS11DataStruct>()];
|
||||
// 序列化为二进制数据
|
||||
unsafe {
|
||||
let ptr = &data as *const IS11DataStruct as *const u8;
|
||||
std::ptr::copy_nonoverlapping(ptr, buffer.as_mut_ptr(), mem::size_of::<IS11DataStruct>());
|
||||
}
|
||||
sendtoportbinary(buffer, 0x03);
|
||||
"OK".to_string()
|
||||
}
|
||||
|
||||
fn sendtoportbinary(data: Vec<u8>, command: u8) -> String {
|
||||
let lenth = data.len() as u16;
|
||||
let high: u8 = (lenth >> 8) as u8;
|
||||
let low: u8 = (lenth & 0xFF) as u8;
|
||||
let mut header = vec![];
|
||||
header.push(0x55);
|
||||
header.push(0xAA);
|
||||
let mut crcbody = vec![];
|
||||
// crcbody.push(high);
|
||||
// crcbody.push(low);
|
||||
crcbody.extend(data);
|
||||
let crc = iris_calc_crc(&crcbody);
|
||||
let crchigh: u8 = (crc >> 8) as u8;
|
||||
let crclow: u8 = (crc & 0xFF) as u8;
|
||||
let mut senddata = vec![];
|
||||
senddata.extend(header);
|
||||
senddata.push(command);
|
||||
senddata.push(high);
|
||||
senddata.push(low);
|
||||
senddata.extend(crcbody);
|
||||
senddata.push(crchigh);
|
||||
senddata.push(crclow);
|
||||
|
||||
// println!("sendtoport data:{}",senddata.len());
|
||||
println!(
|
||||
"sendtoport data content:{:X?}",
|
||||
senddata
|
||||
.iter()
|
||||
.map(|&byte| format!("{:02X}", byte))
|
||||
.collect::<Vec<String>>()
|
||||
.join(" ")
|
||||
);
|
||||
sendtoprot(senddata);
|
||||
"send ok".to_string()
|
||||
}
|
||||
|
||||
// Learn more about Tauri commands at https://tauri.app/v1/guides/features/command
|
||||
#[tauri::command]
|
||||
fn greet(name: &str) -> String {
|
||||
format!("Hello, {}! You've been greeted from Rust!", name)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
fn getportnames() -> Vec<String> {
|
||||
get_port_name()
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
fn opencom(portname: serde_json::Value, baudrate: serde_json::Value) -> String {
|
||||
//tauri
|
||||
let portname = portname.as_str().unwrap();
|
||||
let baudrate = baudrate.as_u64().unwrap() as u32;
|
||||
set_port_info(&portname.to_string(), baudrate);
|
||||
|
||||
println!("opencom portname:{} baudrate:{}", portname, baudrate);
|
||||
logtorust(format!(
|
||||
"opencom portname:{} baudrate:{}",
|
||||
portname, baudrate
|
||||
));
|
||||
tryuseport()
|
||||
}
|
||||
#[tauri::command]
|
||||
fn closecome() -> String {
|
||||
closeport()
|
||||
}
|
||||
#[tauri::command]
|
||||
fn sendtoport(data: serde_json::Value, datatype: serde_json::Value) -> String {
|
||||
// println!("sendtoport data:{}",data.to_string());
|
||||
//判断是否存在data
|
||||
// if !data.is_object() {
|
||||
// return String::from("Invalid data");
|
||||
// }
|
||||
println!("sendtoport data:{}", data.to_string());
|
||||
logtorust(format!("sendtoport data:{}", data.to_string()));
|
||||
let data = data.to_string().as_bytes().to_vec();
|
||||
let lenth = data.len() as u16;
|
||||
let high: u8 = (lenth >> 8) as u8;
|
||||
let low: u8 = (lenth & 0xFF) as u8;
|
||||
let mut header = vec![];
|
||||
header.push(0x55);
|
||||
header.push(0xAA);
|
||||
let mut command: u8 = 0;
|
||||
let datatype = datatype.as_str().unwrap();
|
||||
println!("datatype:{}", datatype);
|
||||
if datatype == "hex" {
|
||||
command = 0x03;
|
||||
}
|
||||
if datatype == "string" {
|
||||
command = 0x01;
|
||||
}
|
||||
if datatype == "json" {
|
||||
command = 0x00;
|
||||
}
|
||||
let mut crcbody = vec![];
|
||||
// crcbody.push(high);
|
||||
// crcbody.push(low);
|
||||
crcbody.extend(data);
|
||||
let crc = iris_calc_crc(&crcbody);
|
||||
let crchigh: u8 = (crc >> 8) as u8;
|
||||
let crclow: u8 = (crc & 0xFF) as u8;
|
||||
let mut senddata = vec![];
|
||||
senddata.extend(header);
|
||||
senddata.push(command);
|
||||
senddata.push(high);
|
||||
senddata.push(low);
|
||||
senddata.extend(crcbody);
|
||||
senddata.push(crchigh);
|
||||
senddata.push(crclow);
|
||||
|
||||
// println!("sendtoport data:{}",senddata.len());
|
||||
// println!(
|
||||
// "sendtoport data content:{:X?}",
|
||||
// senddata
|
||||
// .iter()
|
||||
// .map(|&byte| format!("{:02X}", byte))
|
||||
// .collect::<Vec<String>>()
|
||||
// .join(" ")
|
||||
// );
|
||||
logtorust(format!(
|
||||
"sendtoport data content:{:X?}",
|
||||
senddata
|
||||
.iter()
|
||||
.map(|&byte| format!("{:02X}", byte))
|
||||
.collect::<Vec<String>>()
|
||||
.join(" ")
|
||||
));
|
||||
|
||||
sendtoprot(senddata);
|
||||
"send ok".to_string()
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
fn readformport(commanid: serde_json::Value, wait_time_json: serde_json::Value) -> String {
|
||||
let mut waittime = 50;
|
||||
if wait_time_json.is_u64() {
|
||||
waittime = wait_time_json.as_u64().unwrap() as u32;
|
||||
}
|
||||
|
||||
let commanid = commanid.as_u64().unwrap() as u8;
|
||||
let ret = readdatafromport(waittime as u64, commanid);
|
||||
let str = String::from_utf8_lossy(&ret);
|
||||
println!("read data: {}", str);
|
||||
return str.to_string();
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
fn sendtoportAndgetreturn(
|
||||
data: serde_json::Value,
|
||||
datatype: serde_json::Value,
|
||||
) -> Result<RetStruct, String> {
|
||||
// println!("sendtoport data:{}",data.to_string());
|
||||
//判断是否存在data
|
||||
// if !data.is_object() {
|
||||
// return String::from("Invalid data");
|
||||
// }
|
||||
|
||||
//println!("sendtoport data:{}", data.to_string());
|
||||
|
||||
let command = data.get("command").unwrap().to_string();
|
||||
let mut isneedlog = true;
|
||||
let mut isgetdata = false;
|
||||
if command == "\"get_caiji_state\"" {
|
||||
isneedlog = false;
|
||||
}
|
||||
if command == "\"get_data\"" {
|
||||
isgetdata = true;
|
||||
|
||||
}
|
||||
|
||||
if isneedlog {
|
||||
logtorust(format!("sendtoport data:{}", data.to_string()));
|
||||
}
|
||||
|
||||
let data = data.to_string().as_bytes().to_vec();
|
||||
let lenth = data.len() as u16;
|
||||
let high: u8 = (lenth >> 8) as u8;
|
||||
let low: u8 = (lenth & 0xFF) as u8;
|
||||
let mut header = vec![];
|
||||
header.push(0x55);
|
||||
header.push(0xAA);
|
||||
let mut command: u8 = 0;
|
||||
let datatype = datatype.as_str().unwrap();
|
||||
println!("datatype:{}", datatype);
|
||||
if datatype == "hex" {
|
||||
command = 0x03;
|
||||
}
|
||||
if datatype == "string" {
|
||||
command = 0x01;
|
||||
}
|
||||
if datatype == "json" {
|
||||
command = 0x00;
|
||||
}
|
||||
let mut crcbody = vec![];
|
||||
// crcbody.push(high);
|
||||
// crcbody.push(low);
|
||||
crcbody.extend(data);
|
||||
let crc = iris_calc_crc(&crcbody);
|
||||
let crchigh: u8 = (crc >> 8) as u8;
|
||||
let crclow: u8 = (crc & 0xFF) as u8;
|
||||
let mut senddata = vec![];
|
||||
senddata.extend(header);
|
||||
senddata.push(command);
|
||||
senddata.push(high);
|
||||
senddata.push(low);
|
||||
senddata.extend(crcbody);
|
||||
senddata.push(crchigh);
|
||||
senddata.push(crclow);
|
||||
|
||||
println!("sendtoport data:{}", senddata.len());
|
||||
// println!(
|
||||
// "sendtoport data content:{:X?}",
|
||||
// senddata
|
||||
// .iter()
|
||||
// .map(|&byte| format!("{:02X}", byte))
|
||||
// .collect::<Vec<String>>()
|
||||
// .join(" ")
|
||||
// );
|
||||
if isneedlog {
|
||||
logtorust(format!(
|
||||
"sendtoport data content:{:X?}",
|
||||
senddata
|
||||
.iter()
|
||||
.map(|&byte| format!("{:02X}", byte))
|
||||
.collect::<Vec<String>>()
|
||||
.join(" ")
|
||||
));
|
||||
}
|
||||
|
||||
sendtoprot(senddata);
|
||||
let mut ret = readdatafromport(50, 0xff);
|
||||
let datatype = ret[0];
|
||||
|
||||
if isneedlog {
|
||||
if !isgetdata{
|
||||
logtorust(format!(
|
||||
"read content: {:X?}",
|
||||
ret.iter()
|
||||
.map(|&byte| format!("{:02X}", byte))
|
||||
.collect::<Vec<String>>()
|
||||
.join(" ")
|
||||
));
|
||||
}
|
||||
}
|
||||
if isgetdata{
|
||||
logtorust("Get data Back SUCCESS".to_string());
|
||||
logtorust("_____________________________one_data_over_____________________________\n".to_string());
|
||||
}
|
||||
|
||||
|
||||
ret.remove(0);
|
||||
ret.remove(0);
|
||||
ret.remove(0);
|
||||
if datatype == 0x02 {
|
||||
let mut is11data = IS11DataStruct::default();
|
||||
unsafe {
|
||||
let mut is11data_ptr = &mut is11data as *mut IS11DataStruct;
|
||||
let mut ret_ptr = &mut ret[0] as *mut u8;
|
||||
std::ptr::copy_nonoverlapping(
|
||||
ret_ptr,
|
||||
is11data_ptr as *mut u8,
|
||||
std::mem::size_of::<IS11DataStruct>(),
|
||||
);
|
||||
return Ok(RetStruct {
|
||||
datatype: datatype,
|
||||
content: "null".to_string(),
|
||||
data: is11data,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
let str = String::from_utf8_lossy(&ret);
|
||||
// println!("read data: {}", str);
|
||||
if datatype==0x00 &&isneedlog {
|
||||
logtorust(format![
|
||||
"read string: {}",
|
||||
str.to_string()
|
||||
]);
|
||||
|
||||
}
|
||||
return Ok(RetStruct {
|
||||
datatype: datatype,
|
||||
content: str.to_string(),
|
||||
data: IS11DataStruct::default(),
|
||||
});
|
||||
|
||||
// return str.to_string();
|
||||
}
|
||||
#[tauri::command]
|
||||
fn clearportbuff() -> String {
|
||||
clearserilport()
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
fn setport(data: serde_json::Value) -> String {
|
||||
//判断是否存在portname和baudrate
|
||||
if !data.is_object() {
|
||||
return String::from("Invalid data");
|
||||
}
|
||||
if !data["portname"].is_string() || !data["baudrate"].is_u64() {
|
||||
return String::from("Invalid data");
|
||||
}
|
||||
let portname = data["portname"].as_str().unwrap();
|
||||
let baudrate = data["baudrate"].as_u64().unwrap() as u32;
|
||||
set_port_info(&portname.to_string(), baudrate);
|
||||
//println!("{}",readdatafromport(1000));
|
||||
String::from("Port set ok")
|
||||
}
|
||||
|
||||
use tauri::{LogicalSize, Manager, Size};
|
||||
|
||||
fn main() {
|
||||
// 使用宏生成处理程序列表
|
||||
mylog::initlog();
|
||||
mylog::logtorust("welecome to rust log");
|
||||
mylog::logtojs("welecome to rust log");
|
||||
|
||||
tauri::Builder::default()
|
||||
.invoke_handler(tauri::generate_handler![
|
||||
clearportbuff,
|
||||
greet,
|
||||
getportnames,
|
||||
opencom,
|
||||
setport,
|
||||
closecome,
|
||||
sendtoportAndgetreturn,
|
||||
readformport,
|
||||
sendtoport,
|
||||
interpolate_spline,
|
||||
sg_smooth,
|
||||
savecalibratefile,
|
||||
sendcalibratetodev,
|
||||
algorithm::Gaussian_filter_high,
|
||||
algorithm::interpolate_spline_at_points,
|
||||
algorithm::find_peek
|
||||
])
|
||||
.setup(|app| {
|
||||
let main_window = app.get_window("main").unwrap();
|
||||
|
||||
// 获取屏幕大小
|
||||
if let Some(monitor) = main_window.primary_monitor().unwrap() {
|
||||
let scale_factor = monitor.scale_factor();
|
||||
let physical_size = monitor.size();
|
||||
let logical_width = physical_size.width as f64 / scale_factor;
|
||||
let logical_height = physical_size.height as f64 / scale_factor;
|
||||
let new_width = logical_width * 0.8;
|
||||
let new_height = logical_height * 0.8;
|
||||
|
||||
// 设置窗口大小为屏幕大小的 80%
|
||||
main_window
|
||||
.set_size(Size::Logical(LogicalSize {
|
||||
width: new_width,
|
||||
height: new_height,
|
||||
}))
|
||||
.unwrap();
|
||||
|
||||
main_window.set_cursor_visible(true).unwrap();
|
||||
}
|
||||
|
||||
Ok(())
|
||||
})
|
||||
.run(tauri::generate_context!())
|
||||
.expect("error while running tauri application");
|
||||
}
|
78
src-tauri/src/mylog.rs
Normal file
78
src-tauri/src/mylog.rs
Normal file
@ -0,0 +1,78 @@
|
||||
use tklog::{
|
||||
debugs, errors, fatals, infos,
|
||||
sync::Logger,LEVEL, LOG,
|
||||
traces, warns, Format, MODE,async_traces,
|
||||
};
|
||||
use lazy_static::lazy_static;
|
||||
use std::{
|
||||
// fmt::format,
|
||||
borrow::{Borrow, BorrowMut}, sync::{Arc, Mutex}, thread::sleep
|
||||
};
|
||||
|
||||
struct LOGERME{
|
||||
LOGGER_RUST: Arc<Mutex<Logger>>,
|
||||
LOGGER_JS: Arc<Mutex<Logger>>,
|
||||
}
|
||||
lazy_static! {
|
||||
|
||||
static ref LOGERGloble: Arc<Mutex<LOGERME>> = Arc::new(Mutex::new(
|
||||
LOGERME{
|
||||
LOGGER_RUST:Arc::new( Mutex::new(Logger::new())),
|
||||
LOGGER_JS: Arc::new( Mutex::new(Logger::new())),
|
||||
}
|
||||
));
|
||||
|
||||
}
|
||||
// pub static LOGGER_RUST: Arc<Mutex<Logger>> =Arc::new( Mutex::new(Logger::new()));
|
||||
// pub static LOGGER_JS: Arc<Mutex<Logger>> = Arc::new(Mutex::new(Logger::new()));
|
||||
|
||||
|
||||
|
||||
|
||||
pub fn change_log_path(path: &str,String: &str) {
|
||||
if String=="RUST"{
|
||||
let mut loggerglobel = LOGERGloble.lock().unwrap();
|
||||
let mut log=loggerglobel.LOGGER_RUST.lock().unwrap();
|
||||
log.set_cutmode_by_time(path, MODE::DAY, 10, false);
|
||||
}else if String=="JS"{
|
||||
let mut loggerglobel=LOGERGloble.lock().unwrap();
|
||||
let mut log=loggerglobel.LOGGER_JS.lock().unwrap();
|
||||
log.set_cutmode_by_time(path, MODE::DAY, 10, false);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn initlog() {
|
||||
|
||||
//let mut logger = LOGERGloble.lock().unwrap().LOGGER_RUST;
|
||||
let mut loggerglobel = LOGERGloble.lock().unwrap();
|
||||
let mut log=loggerglobel.LOGGER_RUST.lock().unwrap();
|
||||
log.set_console(true).set_format(Format::Date|Format::Time).set_formatter("{time} {file}{level}:{message}\n")
|
||||
.set_cutmode_by_time("rust_log.log",MODE::DAY, 10, false);
|
||||
// let mut logger = LOGERGloble.lock().unwrap().LOGGER_JS;
|
||||
//let mut loggerglobel = LOGERGloble.lock().unwrap();
|
||||
let mut log=loggerglobel.LOGGER_JS.lock().unwrap();
|
||||
log.set_console(false).set_format(Format::Date|Format::Time).set_formatter("{time}:\t{message}\n")
|
||||
.set_cutmode_by_time("js_log.log",MODE::DAY, 10, false);
|
||||
|
||||
}
|
||||
|
||||
pub fn logtorust<T>(str:T)
|
||||
where T: std::fmt::Display
|
||||
{
|
||||
let mut loggerglobe=LOGERGloble.lock().unwrap();
|
||||
let mut log=Arc::clone(&loggerglobe.LOGGER_RUST);
|
||||
|
||||
let log1 = log.borrow_mut();
|
||||
infos!( log1, str);
|
||||
}
|
||||
|
||||
pub fn logtojs<T>(str:T)
|
||||
where T: std::fmt::Display
|
||||
{
|
||||
let mut loggerglobe=LOGERGloble.lock().unwrap();
|
||||
let mut log=Arc::clone(&loggerglobe.LOGGER_JS);
|
||||
|
||||
let log1 = log.borrow_mut();
|
||||
infos!( log1, str);
|
||||
}
|
||||
|
155
src-tauri/src/serport/iris_protool.rs
Normal file
155
src-tauri/src/serport/iris_protool.rs
Normal file
@ -0,0 +1,155 @@
|
||||
// use serialport::SerialPort;
|
||||
|
||||
|
||||
|
||||
pub fn _iris_protocol_pack(command: u8, length_of_in: u16, buffer_in: &[u8]) -> Option<Vec<u8>> {
|
||||
if length_of_in != 0 && buffer_in.is_empty() {
|
||||
return None;
|
||||
}
|
||||
let mut pack_data: Vec<u8> = vec![0u8; 5 ];
|
||||
pack_data[0] = 0x55;
|
||||
pack_data[1] = 0xAA;
|
||||
pack_data[2] = command;
|
||||
pack_data[3] = (length_of_in >> 8) as u8;
|
||||
pack_data[4] = (length_of_in & 0xFF) as u8;
|
||||
|
||||
let pack_crc: Vec<u8>=buffer_in.to_vec();
|
||||
let crc = iris_calc_crc(&pack_crc);
|
||||
pack_data.extend(pack_crc);
|
||||
pack_data.push((crc >> 8) as u8);
|
||||
pack_data.push(crc as u8);
|
||||
Some(pack_data)
|
||||
}
|
||||
|
||||
pub fn _iris_stm32_protocol_unpack(pack_data: &[u8]) -> Result<(u8, Vec<u8>), &'static str> {
|
||||
if pack_data.is_empty() {
|
||||
return Err("ERROR_INPUT");
|
||||
}
|
||||
if pack_data[0] != 0x55 || pack_data[1] != 0xAA {
|
||||
return Err("ERROR_HEADER");
|
||||
}
|
||||
//获取数据长度
|
||||
let length_of_data = (pack_data[4] as u16) + ((pack_data[3] as u16) << 8) ;
|
||||
//判断数据长度是否足够
|
||||
if length_of_data as usize > pack_data.len() - 7 {
|
||||
return Err("ERROR_NOT_ENOUGH_DATA");
|
||||
}
|
||||
//计算crc
|
||||
|
||||
let crc = iris_calc_crc(&pack_data[5..(length_of_data as usize) + 5]);
|
||||
let expected_crc = (pack_data[length_of_data as usize + 6] as u16) + ((pack_data[length_of_data as usize + 5] as u16) << 8);
|
||||
if crc != expected_crc {
|
||||
return Err("ERROR_CRC");
|
||||
}
|
||||
|
||||
let command = pack_data[2];
|
||||
let buffer_out = pack_data[5..(length_of_data as usize) + 5].to_vec();
|
||||
Ok((command, buffer_out))
|
||||
}
|
||||
|
||||
pub fn iris_protocol_unpack(pack_data: &[u8], command: u8) -> Result<Vec<u8>, &'static str> {
|
||||
if pack_data.is_empty() {
|
||||
return Err("ERROR_INPUT");
|
||||
}
|
||||
if pack_data[0] != 0x55 || pack_data[1] != 0xAA {
|
||||
return Err("ERROR_HEADER");
|
||||
}
|
||||
if pack_data[2] != command {
|
||||
if command != 0xff { return Err("ERROR_COMMAND"); }
|
||||
|
||||
}
|
||||
//获取数据长度
|
||||
let length_of_data = (pack_data[4] as u16) + ((pack_data[3] as u16) << 8) ;
|
||||
//判断数据长度是否足够
|
||||
if length_of_data as usize > pack_data.len() - 7 {
|
||||
return Err("ERROR_NOT_ENOUGH_DATA");
|
||||
}
|
||||
print!("length_of_data:{}",length_of_data);
|
||||
|
||||
// println!("{:?}", pack_data.iter().map(|&byte| format!("{:X}", byte)).collect::<Vec<String>>().join(" "));
|
||||
|
||||
let crc = iris_calc_crc(&pack_data[5..(length_of_data as usize) + 5]);
|
||||
let expected_crc: u16 = (pack_data[length_of_data as usize + 6] as u16) + ((pack_data[length_of_data as usize + 5] as u16) << 8);
|
||||
|
||||
println!("crc:{},expected_crc:{}",crc,expected_crc);
|
||||
// println!("{}:{}",pack_data[length_of_data as usize + 6],pack_data[length_of_data as usize + 5]);
|
||||
|
||||
|
||||
if crc != expected_crc {
|
||||
return Err("ERROR_CRC");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Ok(pack_data[2..(length_of_data as usize) + 5].to_vec())
|
||||
}
|
||||
|
||||
pub fn iris_cut_before_header(pack_data: &mut Vec<u8>) -> usize {
|
||||
|
||||
let mut i = 0;
|
||||
while i < pack_data.len() {
|
||||
if pack_data[i] == 0x55 && pack_data.get(i + 1) == Some(&0xAA) {
|
||||
break;
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
|
||||
if i == pack_data.len() {
|
||||
pack_data.clear();
|
||||
return 0;
|
||||
}
|
||||
|
||||
let length_of_data = pack_data.len() - i;
|
||||
pack_data.drain(0..i);
|
||||
length_of_data
|
||||
}
|
||||
|
||||
pub fn _iris_check_data_valid(pack_data: &[u8]) -> Result<(), &'static str> {
|
||||
if pack_data.is_empty() {
|
||||
return Err("ERROR_INPUT");
|
||||
}
|
||||
if pack_data.len() < 7 {
|
||||
return Err("ERROR_NOT_ENOUGH_DATA");
|
||||
}
|
||||
if pack_data[0] != 0x55 || pack_data[1] != 0xAA {
|
||||
return Err("ERROR_HEADER");
|
||||
}
|
||||
|
||||
let length_of_data = (pack_data[4] as u16) + ((pack_data[3] as u16) << 8);
|
||||
if length_of_data as usize > pack_data.len() - 7 {
|
||||
return Err("ERROR_NOT_ENOUGH_DATA");
|
||||
}
|
||||
|
||||
let crc = iris_calc_crc(&pack_data[5..(length_of_data as usize) + 5]);
|
||||
let expected_crc = (pack_data[length_of_data as usize + 6] as u16) + ((pack_data[length_of_data as usize + 5] as u16) << 8);
|
||||
// println!("crc:{},expected_crc:{}",crc,expected_crc);
|
||||
if crc != expected_crc {
|
||||
return Err("ERROR_CRC");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn iris_calc_crc(p_buffer: &[u8]) -> u16 {
|
||||
// println!("cut_before_header");
|
||||
// println!("{:?}", p_buffer.iter().map(|&byte| format!("{:X}", byte)).collect::<Vec<String>>().join(" "));
|
||||
let poly: u16 = 0x8408;
|
||||
let mut crc: u16 = 0;
|
||||
|
||||
for &byte in p_buffer {
|
||||
crc ^= byte as u16;
|
||||
for _ in 0..8 {
|
||||
let carry = crc & 1 != 0;
|
||||
crc >>= 1;
|
||||
if carry {
|
||||
crc ^= poly;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
crc
|
||||
}
|
||||
|
4
src-tauri/src/serport/mod.rs
Normal file
4
src-tauri/src/serport/mod.rs
Normal file
@ -0,0 +1,4 @@
|
||||
pub mod serport;
|
||||
pub mod iris_protool;
|
||||
|
||||
// remember to call `.manage(MyState::default())`
|
243
src-tauri/src/serport/serport.rs
Normal file
243
src-tauri/src/serport/serport.rs
Normal file
@ -0,0 +1,243 @@
|
||||
//静态变量 用来存储SerialPort对象
|
||||
use super::iris_protool::*;
|
||||
use lazy_static::lazy_static;
|
||||
use std::time::Duration;
|
||||
use std::{
|
||||
// fmt::format,
|
||||
sync::{Arc, Mutex},
|
||||
thread::sleep,
|
||||
};
|
||||
struct SeriesSettings {
|
||||
pub PortName: String,
|
||||
pub BaudRate: u32,
|
||||
pub port: Option<Box<dyn serialport::SerialPort>>,
|
||||
pub isopen: bool,
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
static ref PORT_INFO: Arc<Mutex<SeriesSettings>> = Arc::new(Mutex::new(SeriesSettings {
|
||||
PortName: String::from("NON"),
|
||||
BaudRate: 9600,
|
||||
port: None,
|
||||
isopen: false,
|
||||
}));
|
||||
}
|
||||
|
||||
pub fn tryuseport() -> String {
|
||||
let mut port_info = PORT_INFO.lock().unwrap();
|
||||
if port_info.PortName == "NON" {
|
||||
return format!("Port is not set");
|
||||
}
|
||||
if port_info.isopen {
|
||||
drop(port_info);
|
||||
closeport();
|
||||
port_info= PORT_INFO.lock().unwrap();
|
||||
}
|
||||
|
||||
|
||||
|
||||
port_info.port = match serialport::new(port_info.PortName.clone(), port_info.BaudRate).open() {
|
||||
Ok(p) => Some(p),
|
||||
Err(e) => {
|
||||
eprintln!("Failed to open Error: {}", e);
|
||||
return format!("Failed to open Error: {}", e);
|
||||
}
|
||||
};
|
||||
port_info.isopen = true;
|
||||
println!("Port is open");
|
||||
return String::from("Port is open");
|
||||
}
|
||||
|
||||
pub fn set_port_info(portname: &String, baudrate: u32) {
|
||||
let mut port_info = PORT_INFO.lock().unwrap();
|
||||
port_info.PortName = portname.to_string();
|
||||
port_info.BaudRate = baudrate;
|
||||
|
||||
}
|
||||
|
||||
pub fn get_port_name() -> Vec<String> {
|
||||
let ports = serialport::available_ports().expect("No ports found!");
|
||||
let mut portnames: Vec<String> = Vec::new();
|
||||
for p in ports {
|
||||
portnames.push(p.port_name);
|
||||
}
|
||||
return portnames;
|
||||
}
|
||||
|
||||
pub fn _reopenport() -> String {
|
||||
let mut port_info = PORT_INFO.lock().unwrap();
|
||||
if port_info.PortName == "NON" {
|
||||
return format!("Port is not set");
|
||||
}
|
||||
//关闭端口
|
||||
port_info.port = None;
|
||||
//重新打开端口
|
||||
port_info.port = match serialport::new(port_info.PortName.clone(), port_info.BaudRate).open() {
|
||||
Ok(p) => Some(p),
|
||||
Err(e) => {
|
||||
eprintln!("Failed to open Error: {}", e);
|
||||
return format!("Failed to open Error: {}", e);
|
||||
}
|
||||
};
|
||||
|
||||
String::from("Port is open")
|
||||
}
|
||||
|
||||
pub fn closeport() -> String {
|
||||
let mut port_info = PORT_INFO.lock().unwrap();
|
||||
if port_info.PortName == "NON" {
|
||||
return format!("Port is not set");
|
||||
}
|
||||
//关闭端口
|
||||
port_info.port = None;
|
||||
println!("Port is closed");
|
||||
String::from("Port is closed")
|
||||
}
|
||||
|
||||
pub fn sendtoprot(data: Vec<u8>) -> String {
|
||||
let mut port_info = PORT_INFO.lock().unwrap();
|
||||
if port_info.PortName == "NON" {
|
||||
return format!("Port is not set");
|
||||
}
|
||||
|
||||
match &mut port_info.port {
|
||||
Some(p) => match p.write(&data) {
|
||||
Ok(_) => {
|
||||
println!("Data sent");
|
||||
return String::from("Data sent");
|
||||
}
|
||||
Err(e) => {
|
||||
eprintln!("Failed to write to port: {}", e);
|
||||
return format!("Failed to write to port: {}", e);
|
||||
}
|
||||
},
|
||||
None => {
|
||||
return format!("Port is not open");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn clearserilport() -> String{
|
||||
let mut port_info = PORT_INFO.lock().unwrap();
|
||||
if port_info.PortName == "NON" {
|
||||
return "Port is not set".to_string();
|
||||
}
|
||||
let mut buf: Vec<u8> = vec![0; 1000];
|
||||
match &mut port_info.port {
|
||||
Some(p) => {
|
||||
p.set_timeout(Duration::from_millis(100)).unwrap();
|
||||
while true{
|
||||
let sizeread =match p.read(&mut buf){
|
||||
Ok(size)=>{size},
|
||||
Err(_e)=>{return "Port is not open".to_string()}
|
||||
};
|
||||
if sizeread==0 { return "OK".to_string(); }
|
||||
}
|
||||
}
|
||||
None => {
|
||||
port_info.isopen=false;
|
||||
return "Port is not open".to_string();
|
||||
}
|
||||
|
||||
}
|
||||
port_info.isopen=false;
|
||||
"OK".to_string()
|
||||
|
||||
}
|
||||
|
||||
|
||||
pub fn readdatafromport(waittime: u64, commanid: u8) -> Vec<u8> {
|
||||
let mut port_info = PORT_INFO.lock().unwrap();
|
||||
if port_info.PortName == "NON" {
|
||||
return "Port is not set".as_bytes().to_vec();
|
||||
}
|
||||
let mut buf: Vec<u8> = vec![0; 1000];
|
||||
let mut bufforrentrun: Vec<u8> = vec![0];
|
||||
match &mut port_info.port {
|
||||
Some(p) => {
|
||||
p.set_timeout(Duration::from_millis(100)).unwrap();
|
||||
let mut sizereadoftotal=0;
|
||||
let mut nowtimetry=0;
|
||||
while sizereadoftotal <5 {
|
||||
let sizeread =match p.read(&mut buf){
|
||||
Ok(size)=>{size},
|
||||
Err(_e)=>{0}
|
||||
};
|
||||
buf.truncate(sizeread);
|
||||
|
||||
bufforrentrun.extend_from_slice(&buf);
|
||||
//输出接收到的数据
|
||||
println!("{:?}:{}", buf.iter().map(|&byte| format!("{:02X}", byte)).collect::<Vec<String>>().join(" "),sizeread);
|
||||
sizereadoftotal =iris_cut_before_header(&mut bufforrentrun);
|
||||
nowtimetry+=1;
|
||||
if nowtimetry>waittime{
|
||||
return "long time no data retrun".as_bytes().to_vec();
|
||||
}
|
||||
sleep(Duration::from_millis(100));
|
||||
}
|
||||
|
||||
nowtimetry=0;
|
||||
// println!("{:?}", bufforrentrun);
|
||||
iris_cut_before_header(&mut bufforrentrun);
|
||||
|
||||
while match iris_protocol_unpack(&bufforrentrun, commanid) {
|
||||
Ok(buf) =>
|
||||
{
|
||||
return buf
|
||||
},
|
||||
Err(e) => {
|
||||
if e == "ERROR_NOT_ENOUGH_DATA" {
|
||||
true
|
||||
} else {
|
||||
println!("Error: {}", e.to_string());
|
||||
return e.to_string().as_bytes().to_vec();
|
||||
}
|
||||
}
|
||||
} {
|
||||
|
||||
let sizeread = match p.read(&mut buf) {
|
||||
Ok(size) => size,
|
||||
Err(msg) => {
|
||||
eprintln!("Failed to read from port: {}", msg);
|
||||
0
|
||||
}
|
||||
};
|
||||
buf.truncate(sizeread);
|
||||
bufforrentrun.extend_from_slice(&buf);
|
||||
//println!("{:?}", bufforrentrun.iter().map(|&byte| format!("{:X}", byte)).collect::<Vec<String>>().join(" "));
|
||||
nowtimetry+=1;
|
||||
if nowtimetry>waittime{
|
||||
return "long time no data retrun".as_bytes().to_vec();
|
||||
}
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
None => {
|
||||
return Vec::new();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn iris_calc_crc(p_buffer: &[u8]) -> u16 {
|
||||
let poly: u16 = 0x8408;
|
||||
let mut crc: u16 = 0;
|
||||
|
||||
for &byte in p_buffer {
|
||||
crc ^= u16::from(byte);
|
||||
for _ in 0..8 {
|
||||
let carry = crc & 1 != 0;
|
||||
crc >>= 1;
|
||||
if carry {
|
||||
crc ^= poly;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
crc
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test() {
|
||||
tryuseport();
|
||||
}
|
Reference in New Issue
Block a user