Compare commits
No commits in common. "11f2ebe9614b31bd1436b3b23cb2fbcacb3c1c08" and "97490e5e1b5b49575a3020eb1171912f50d9d9ed" have entirely different histories.
11f2ebe961
...
97490e5e1b
|
@ -28,7 +28,6 @@ series = {
|
||||||
'sens': Series(0.0001),
|
'sens': Series(0.0001),
|
||||||
'temperature': Series(),
|
'temperature': Series(),
|
||||||
'i_set': Series(),
|
'i_set': Series(),
|
||||||
'pid_output': Series(),
|
|
||||||
'vref': Series(),
|
'vref': Series(),
|
||||||
'dac_feedback': Series(),
|
'dac_feedback': Series(),
|
||||||
'i_tec': Series(),
|
'i_tec': Series(),
|
||||||
|
@ -40,6 +39,7 @@ series_lock = Lock()
|
||||||
quit = False
|
quit = False
|
||||||
|
|
||||||
def recv_data(tec):
|
def recv_data(tec):
|
||||||
|
print("reporting")
|
||||||
for data in tec.report_mode():
|
for data in tec.report_mode():
|
||||||
if data['channel'] == 0:
|
if data['channel'] == 0:
|
||||||
series_lock.acquire()
|
series_lock.acquire()
|
||||||
|
@ -56,6 +56,7 @@ def recv_data(tec):
|
||||||
break
|
break
|
||||||
|
|
||||||
tec = Client()
|
tec = Client()
|
||||||
|
print("connected")
|
||||||
thread = Thread(target=recv_data, args=(tec,))
|
thread = Thread(target=recv_data, args=(tec,))
|
||||||
thread.start()
|
thread.start()
|
||||||
|
|
||||||
|
@ -63,17 +64,15 @@ fig, ax = plt.subplots()
|
||||||
|
|
||||||
for k, s in series.iteritems():
|
for k, s in series.iteritems():
|
||||||
s.plot, = ax.plot([], [], label=k)
|
s.plot, = ax.plot([], [], label=k)
|
||||||
legend = ax.legend()
|
ax.legend()
|
||||||
|
|
||||||
def animate(i):
|
def animate(i):
|
||||||
min_x, max_x, min_y, max_y = None, None, None, None
|
min_x, max_x, min_y, max_y = None, None, None, None
|
||||||
|
|
||||||
series_lock.acquire()
|
series_lock.acquire()
|
||||||
try:
|
try:
|
||||||
for k, s in series.iteritems():
|
for s in series.itervalues():
|
||||||
s.plot.set_data(s.x_data, s.y_data)
|
s.plot.set_data(s.x_data, s.y_data)
|
||||||
if len(s.y_data) > 0:
|
|
||||||
s.plot.set_label("{}: {:.3f}".format(k, s.y_data[-1]))
|
|
||||||
|
|
||||||
if len(s.x_data) > 0:
|
if len(s.x_data) > 0:
|
||||||
min_x_ = min(s.x_data)
|
min_x_ = min(s.x_data)
|
||||||
|
@ -108,13 +107,21 @@ def animate(i):
|
||||||
ax.set_xlim(min_x, max_x)
|
ax.set_xlim(min_x, max_x)
|
||||||
ax.set_ylim(min_y - margin_y, max_y + margin_y)
|
ax.set_ylim(min_y - margin_y, max_y + margin_y)
|
||||||
|
|
||||||
global legend
|
|
||||||
legend.remove()
|
|
||||||
legend = ax.legend()
|
|
||||||
|
|
||||||
ani = animation.FuncAnimation(
|
ani = animation.FuncAnimation(
|
||||||
fig, animate, interval=1, blit=False, save_count=50)
|
fig, animate, interval=1, blit=False, save_count=50)
|
||||||
|
|
||||||
|
# To save the animation, use e.g.
|
||||||
|
#
|
||||||
|
# ani.save("movie.mp4")
|
||||||
|
#
|
||||||
|
# or
|
||||||
|
#
|
||||||
|
# writer = animation.FFMpegWriter(
|
||||||
|
# fps=15, metadata=dict(artist='Me'), bitrate=1800)
|
||||||
|
# ani.save("movie.mp4", writer=writer)
|
||||||
|
|
||||||
|
print("show")
|
||||||
plt.show()
|
plt.show()
|
||||||
quit = True
|
quit = True
|
||||||
thread.join()
|
thread.join()
|
||||||
|
|
|
@ -91,19 +91,6 @@ impl Channels {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// calculate the TEC i_set centerpoint
|
|
||||||
pub fn get_center(&mut self, channel: usize) -> ElectricPotential {
|
|
||||||
match self.channel_state(channel).center {
|
|
||||||
CenterPoint::Vref => {
|
|
||||||
let vref = self.read_vref(channel);
|
|
||||||
self.channel_state(channel).vref = vref;
|
|
||||||
vref
|
|
||||||
},
|
|
||||||
CenterPoint::Override(center_point) =>
|
|
||||||
ElectricPotential::new::<volt>(center_point.into()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// i_set DAC
|
/// i_set DAC
|
||||||
fn get_dac(&mut self, channel: usize) -> (ElectricPotential, ElectricPotential) {
|
fn get_dac(&mut self, channel: usize) -> (ElectricPotential, ElectricPotential) {
|
||||||
let dac_factor = match channel.into() {
|
let dac_factor = match channel.into() {
|
||||||
|
@ -117,7 +104,13 @@ impl Channels {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_i(&mut self, channel: usize) -> (ElectricCurrent, ElectricCurrent) {
|
pub fn get_i(&mut self, channel: usize) -> (ElectricCurrent, ElectricCurrent) {
|
||||||
let center_point = self.get_center(channel);
|
let state = self.channel_state(channel);
|
||||||
|
let center_point = match state.center {
|
||||||
|
CenterPoint::Vref =>
|
||||||
|
state.vref,
|
||||||
|
CenterPoint::Override(center_point) =>
|
||||||
|
ElectricPotential::new::<volt>(center_point.into()),
|
||||||
|
};
|
||||||
let r_sense = ElectricalResistance::new::<ohm>(R_SENSE);
|
let r_sense = ElectricalResistance::new::<ohm>(R_SENSE);
|
||||||
let (voltage, max) = self.get_dac(channel);
|
let (voltage, max) = self.get_dac(channel);
|
||||||
let i_tec = (voltage - center_point) / (10.0 * r_sense);
|
let i_tec = (voltage - center_point) / (10.0 * r_sense);
|
||||||
|
@ -145,7 +138,13 @@ impl Channels {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_i(&mut self, channel: usize, i_tec: ElectricCurrent) -> (ElectricCurrent, ElectricCurrent) {
|
pub fn set_i(&mut self, channel: usize, i_tec: ElectricCurrent) -> (ElectricCurrent, ElectricCurrent) {
|
||||||
let center_point = self.get_center(channel);
|
let state = self.channel_state(channel);
|
||||||
|
let center_point = match state.center {
|
||||||
|
CenterPoint::Vref =>
|
||||||
|
state.vref,
|
||||||
|
CenterPoint::Override(center_point) =>
|
||||||
|
ElectricPotential::new::<volt>(center_point.into()),
|
||||||
|
};
|
||||||
let r_sense = ElectricalResistance::new::<ohm>(R_SENSE);
|
let r_sense = ElectricalResistance::new::<ohm>(R_SENSE);
|
||||||
let voltage = i_tec * 10.0 * r_sense + center_point;
|
let voltage = i_tec * 10.0 * r_sense + center_point;
|
||||||
let (voltage, max) = self.set_dac(channel, voltage);
|
let (voltage, max) = self.set_dac(channel, voltage);
|
||||||
|
@ -418,9 +417,6 @@ impl Channels {
|
||||||
let i_tec = self.read_itec(channel);
|
let i_tec = self.read_itec(channel);
|
||||||
let tec_i = (i_tec - vref) / ElectricalResistance::new::<ohm>(0.4);
|
let tec_i = (i_tec - vref) / ElectricalResistance::new::<ohm>(0.4);
|
||||||
let state = self.channel_state(channel);
|
let state = self.channel_state(channel);
|
||||||
let pid_output = state.pid.last_output.map(|last_output|
|
|
||||||
ElectricCurrent::new::<ampere>(last_output)
|
|
||||||
);
|
|
||||||
Report {
|
Report {
|
||||||
channel,
|
channel,
|
||||||
time: state.adc_time.total_millis(),
|
time: state.adc_time.total_millis(),
|
||||||
|
@ -435,7 +431,6 @@ impl Channels {
|
||||||
i_tec,
|
i_tec,
|
||||||
tec_i,
|
tec_i,
|
||||||
tec_u_meas: self.read_tec_u_meas(channel),
|
tec_u_meas: self.read_tec_u_meas(channel),
|
||||||
pid_output,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -454,41 +449,12 @@ pub struct Report {
|
||||||
i_tec: ElectricPotential,
|
i_tec: ElectricPotential,
|
||||||
tec_i: ElectricCurrent,
|
tec_i: ElectricCurrent,
|
||||||
tec_u_meas: ElectricPotential,
|
tec_u_meas: ElectricPotential,
|
||||||
pid_output: Option<ElectricCurrent>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type JsonBuffer = heapless::Vec<u8, heapless::consts::U360>;
|
type JsonBuffer = heapless::Vec<u8, heapless::consts::U320>;
|
||||||
|
|
||||||
impl Report {
|
impl Report {
|
||||||
pub fn to_json(&self) -> Result<JsonBuffer, serde_json_core::ser::Error> {
|
pub fn to_json(&self) -> Result<JsonBuffer, serde_json_core::ser::Error> {
|
||||||
serde_json_core::to_vec(self)
|
serde_json_core::to_vec(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod test {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn report_to_json() {
|
|
||||||
// `/ 1.1` results in values with a really long serialization
|
|
||||||
let report = Report {
|
|
||||||
channel: 0,
|
|
||||||
time: 3200,
|
|
||||||
adc: Some(ElectricPotential::new::<volt>(0.65 / 1.1)),
|
|
||||||
sens: Some(ElectricalResistance::new::<ohm>(10000.0 / 1.1)),
|
|
||||||
temperature: Some(30.0 / 1.1),
|
|
||||||
pid_engaged: false,
|
|
||||||
i_set: ElectricCurrent::new::<ampere>(0.5 / 1.1),
|
|
||||||
vref: ElectricPotential::new::<volt>(1.5 / 1.1),
|
|
||||||
dac_feedback: ElectricPotential::new::<volt>(2.0 / 1.1),
|
|
||||||
i_tec: ElectricPotential::new::<volt>(2.0 / 1.1),
|
|
||||||
tec_i: ElectricCurrent::new::<ampere>(0.2 / 1.1),
|
|
||||||
tec_u_meas: ElectricPotential::new::<volt>(2.0 / 1.1),
|
|
||||||
pid_output: Some(ElectricCurrent::new::<ampere>(0.5 / 1.1)),
|
|
||||||
};
|
|
||||||
let buf = report.to_json().unwrap();
|
|
||||||
assert_eq!(buf[0], b'{');
|
|
||||||
assert_eq!(buf[buf.len() - 1], b'}');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ use crate::usb;
|
||||||
pub fn init_log() {
|
pub fn init_log() {
|
||||||
static USB_LOGGER: usb::Logger = usb::Logger;
|
static USB_LOGGER: usb::Logger = usb::Logger;
|
||||||
let _ = log::set_logger(&USB_LOGGER);
|
let _ = log::set_logger(&USB_LOGGER);
|
||||||
log::set_max_level(log::LevelFilter::Trace);
|
log::set_max_level(log::LevelFilter::Info);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "semihosting")]
|
#[cfg(feature = "semihosting")]
|
||||||
|
|
Loading…
Reference in New Issue