use std::io::Write;
use log::{debug, info};
use crate::IInstr;
#[derive(Default, Debug)]
pub struct CurrentData {
pub avgCurr: f64,
pub highCuur: f64,
pub lowCurr: f64,
pub maxCurr: f64,
pub minCurr: f64,
}
impl CurrentData {
pub fn new() -> Self {
Self {
..Default::default()
}
}
pub fn to_tb(&self) -> String {
format!(
"{},{},{},{},{}",
self.avgCurr, self.maxCurr, self.minCurr, self.highCuur, self.lowCurr
)
}
}
impl std::fmt::Display for CurrentData {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"avg:{}, max:{}, min:{} ,high:{} ,low:{}",
self.avgCurr, self.maxCurr, self.minCurr, self.highCuur, self.lowCurr
)
}
}
pub struct P66319D {
pub instr: visa_rs::Instrument,
pub datafile: Option<std::fs::File>,
}
impl P66319D {
pub fn new(instr: visa_rs::Instrument) -> Self {
Self {
instr,
datafile: None,
}
}
pub fn m_init(&mut self) -> std::io::Result<()> {
self.instr.m_send("*RST; *OPC?")
}
pub fn m_set_volt(&mut self, channel: u64, volt: f64) -> std::io::Result<()> {
self.instr
.m_send(&format!("SOUR{}:VOLT {:.2}", channel, volt))
}
pub fn m_set_poweron(&mut self, channel: u64, on: bool) -> std::io::Result<()> {
self.instr.m_send(&format!(
"OUTP{} {}",
channel,
if on { "ON" } else { "OFF" }
))
}
pub fn m_set_test_accur(&mut self, accur: &str) -> std::io::Result<()> {
match accur {
"100.us/div" => self
.instr
.m_send("SENS:SWE:TINT 1.56E-005;POIN 38;OFFS:POIN 0"),
"200.us/div" => self
.instr
.m_send("SENS:SWE:TINT 1.56E-005;POIN 76;OFFS:POIN 0"),
"500.us/div" => self
.instr
.m_send("SENS:SWE:TINT 1.56E-005;POIN 192;OFFS:POIN 0"),
"1.ms/div" => self
.instr
.m_send("SENS:SWE:TINT 1.56E-005;POIN 384;OFFS:POIN 0"),
"2.ms/div" => self
.instr
.m_send("SENS:SWE:TINT 1.56E-005;POIN 769;OFFS:POIN 0"),
"5.ms/div" => self
.instr
.m_send("SENS:SWE:TINT 1.56E-005;POIN 1923;OFFS:POIN 0"),
"10.ms/div" => self
.instr
.m_send("SENS:SWE:TINT 1.56E-005;POIN 3846;OFFS:POIN 0"),
"20.ms/div" => self
.instr
.m_send("SENS:SWE:TINT 3.12E-005;POIN 3846;OFFS:POIN 0"),
"50.ms/div" => self
.instr
.m_send("SENS:SWE:TINT 7.8E-005;POIN 3846;OFFS:POIN 0"),
"100.ms/div" => self
.instr
.m_send("SENS:SWE:TINT 0.000156;POIN 3846;OFFS:POIN 0"),
"200.ms/div" => self
.instr
.m_send("SENS:SWE:TINT 0.0002964;POIN 4048;OFFS:POIN 0"),
"500.ms/div" => self
.instr
.m_send("SENS:SWE:TINT 0.0007332;POIN 4091;OFFS:POIN 0"),
"1.s/div" => self
.instr
.m_send("SENS:SWE:TINT 0.0014664;POIN 4091;OFFS:POIN 0"),
"2.s/div" => self
.instr
.m_send("SENS:SWE:TINT 0.0029328;POIN 4091;OFFS:POIN 0"),
"4.s/div" => self
.instr
.m_send("SENS:SWE:TINT 0.0058656;POIN 4091;OFFS:POIN 0"),
_ => Err(std::io::Error::from_raw_os_error(233)),
}
}
pub fn m_set_ps_mode(&mut self, mode: bool) -> std::io::Result<()> {
self.instr.m_send(&format!(
"OUTP:COMP:MODE {}",
if mode { "HLOCAL" } else { "LLOCAL" }
))?;
self.instr
.m_send("SENS:SWE:TINT 0.0001;POIN 512;OFFS:POIN 0")
}
pub fn m_measure_current(&mut self) -> Option<CurrentData> {
let mut curdata = CurrentData::new();
self.read_esr_state();
let ss = self.instr.m_query("MEAS:ARR:CURR?")?;
let mut data = Vec::new();
debug!("{ss}");
if let Some(dfile) = &mut self.datafile {
dfile.write(ss.as_bytes());
}
for idx in ss.trim().split(",") {
match idx.parse::<f64>() {
Ok(vl) => {
data.push(vl);
}
Err(_) => {}
}
}
debug!("count:{}", data.len());
debug!("avgcurr:{}", data.iter().sum::<f64>() / data.len() as f64);
self.read_esr_state();
let ss = self.instr.m_query("FETC:CURR?")?;
let ss_v = ss.trim().parse::<f64>().ok()?;
curdata.avgCurr = ss_v;
self.read_esr_state();
let ss = self.instr.m_query("FETC:CURR:MAX?")?;
let ss_v = ss.trim().parse::<f64>().ok()?;
curdata.maxCurr = ss_v;
self.read_esr_state();
let ss = self.instr.m_query("FETC:CURR:MIN?")?;
let ss_v = ss.trim().parse::<f64>().ok()?;
curdata.minCurr = ss_v;
self.read_esr_state();
let ss = self.instr.m_query("FETC:CURR:HIGH?")?;
let ss_v = ss.trim().parse::<f64>().ok()?;
curdata.highCuur = ss_v;
self.read_esr_state();
let ss = self.instr.m_query("FETC:CURR:LOW?")?;
let ss_v = ss.trim().parse::<f64>().ok()?;
curdata.lowCurr = ss_v;
self.read_esr_state();
Some(curdata)
}
fn read_esr_state(&mut self) {
loop {
if let Some(ss) = self.instr.m_query("*ESR?") {
if let Some(_) = ss.find("+0") {
break;
}
}
}
}
}