mirror of
https://github.com/italicsjenga/mppt-modbus.git
synced 2025-01-27 01:26:50 +11:00
things
This commit is contained in:
parent
d590bb459f
commit
fd4747c15d
4 changed files with 382 additions and 113 deletions
31
Cargo.lock
generated
31
Cargo.lock
generated
|
@ -67,6 +67,15 @@ dependencies = [
|
|||
"rustc-demangle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bincode"
|
||||
version = "1.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bindgen"
|
||||
version = "0.31.3"
|
||||
|
@ -376,8 +385,10 @@ dependencies = [
|
|||
name = "modbus-test"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"clap 3.2.20",
|
||||
"libmodbus-rs",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -535,6 +546,26 @@ version = "0.1.21"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.144"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0f747710de3dcd43b88c9168773254e809d8ddbdf9653b84e2554ab219f17860"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.144"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94ed3a816fb1d101812f83e789f888322c34e291f894f19590dc310963e87a00"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote 1.0.21",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.8.0"
|
||||
|
|
|
@ -7,4 +7,6 @@ edition = "2021"
|
|||
|
||||
[dependencies]
|
||||
libmodbus-rs = "0.8.3"
|
||||
clap = { version = "3.1", features = ["derive"] }
|
||||
clap = { version = "3.1", features = ["derive"] }
|
||||
bincode = "1.3"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
354
src/main.rs
354
src/main.rs
|
@ -1,81 +1,117 @@
|
|||
use clap::Parser;
|
||||
use libmodbus_rs::{Modbus, ModbusClient, ModbusRTU};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
mod offsets;
|
||||
use crate::offsets::{OffsetsEeprom, OffsetsRam};
|
||||
|
||||
const DEVICE_ID: u8 = 0x01;
|
||||
const RAM_DATA_SIZE: u16 = 0x005B;
|
||||
const EEPROM_BEGIN: u16 = 0xE000;
|
||||
const EEPROM_DATA_SIZE: u16 = 0xE021 - EEPROM_BEGIN;
|
||||
// const EEPROM_DATA_SIZE: u16 = 0xE0CD - EEPROM_BEGIN;
|
||||
|
||||
struct Offsets {}
|
||||
|
||||
impl Offsets {
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
struct MpptRam {
|
||||
// scaling values
|
||||
const V_PU_HI: u16 = 0x0000;
|
||||
const V_PU_LO: u16 = 0x0001;
|
||||
const I_PU_HI: u16 = 0x0002;
|
||||
const I_PU_LO: u16 = 0x0003;
|
||||
const VER_SW: u16 = 0x0004;
|
||||
V_PU: f32,
|
||||
I_PU: f32,
|
||||
VER_SW: u16,
|
||||
// filtered ADC
|
||||
const ADC_VB_F_MED: u16 = 0x0018;
|
||||
const ADC_VBTERM_F: u16 = 0x0019;
|
||||
const ADC_VBS_F: u16 = 0x001A;
|
||||
const ADC_VA_F: u16 = 0x001B;
|
||||
const ADC_IB_F_SHADOW: u16 = 0x001C;
|
||||
const ADC_IA_F_SHADOW: u16 = 0x001D;
|
||||
const ADC_P12_F: u16 = 0x001E;
|
||||
const ADC_P3_F: u16 = 0x001F;
|
||||
const ADC_PMETER_F: u16 = 0x0020;
|
||||
const ADC_P18_F: u16 = 0x0021;
|
||||
const ADC_V_REF: u16 = 0x0022;
|
||||
ADC_VB_F_MED: f32,
|
||||
ADC_VBTERM_F: f32,
|
||||
ADC_VBS_F: f32,
|
||||
ADC_VA_F: f32,
|
||||
ADC_IB_F_SHADOW: f32,
|
||||
ADC_IA_F_SHADOW: f32,
|
||||
ADC_P12_F: f32,
|
||||
ADC_P3_F: f32,
|
||||
ADC_PMETER_F: f32,
|
||||
ADC_P18_F: f32,
|
||||
ADC_V_REF: f32,
|
||||
// temperatures
|
||||
const T_HS: u16 = 0x0023;
|
||||
const T_RTS: u16 = 0x0024;
|
||||
const T_BATT: u16 = 0x0025;
|
||||
T_HS: u16,
|
||||
T_RTS: u16,
|
||||
T_BATT: u16,
|
||||
// status
|
||||
const ADC_VB_F_1M: u16 = 0x0026;
|
||||
const ADC_IB_F_1M: u16 = 0x0027;
|
||||
const VB_MIN: u16 = 0x0028;
|
||||
const VB_MAX: u16 = 0x0029;
|
||||
const HOURMETER_HI: u16 = 0x002A;
|
||||
const HOURMETER_LO: u16 = 0x002B;
|
||||
const FAULT_ALL: u16 = 0x002C;
|
||||
const ALARM_HI: u16 = 0x002E;
|
||||
const ALARM_LO: u16 = 0x002F;
|
||||
const DIP_ALL: u16 = 0x0030;
|
||||
const LED_STATE: u16 = 0x0031;
|
||||
ADC_VB_F_1M: f32,
|
||||
ADC_IB_F_1M: f32,
|
||||
VB_MIN: f32,
|
||||
VB_MAX: f32,
|
||||
HOURMETER_HI: u16,
|
||||
HOURMETER_LO: u16,
|
||||
FAULT_ALL: u16,
|
||||
ALARM_HI: u16,
|
||||
ALARM_LO: u16,
|
||||
DIP_ALL: u16,
|
||||
LED_STATE: u16,
|
||||
// charger
|
||||
const CHARGE_STATE: u16 = 0x0032;
|
||||
const VB_REF: u16 = 0x0033;
|
||||
const AHC_R_HI: u16 = 0x0034;
|
||||
const AHC_R_LO: u16 = 0x0035;
|
||||
const AHC_T_HI: u16 = 0x0036;
|
||||
const AHC_T_LO: u16 = 0x0037;
|
||||
const KWHC_R: u16 = 0x0038;
|
||||
const KWHC_T: u16 = 0x0039;
|
||||
// MPPT
|
||||
const POWER_OUT_SHADOW: u16 = 0x003A;
|
||||
const POWER_IN_SHADOW: u16 = 0x003B;
|
||||
const SWEEP_PIN_MAX: u16 = 0x003C;
|
||||
const SWEEP_VMP: u16 = 0x003D;
|
||||
const SWEEP_VOC: u16 = 0x003E;
|
||||
CHARGE_STATE: u16,
|
||||
VB_REF: f32,
|
||||
AHC_R_HI: u16,
|
||||
AHC_R_LO: u16,
|
||||
AHC_T_HI: u16,
|
||||
AHC_T_LO: u16,
|
||||
KWHC_R: u16,
|
||||
KWHC_T: u16,
|
||||
// MpptRam
|
||||
POWER_OUT_SHADOW: f32,
|
||||
POWER_IN_SHADOW: f32,
|
||||
SWEEP_PIN_MAX: f32,
|
||||
SWEEP_VMP: f32,
|
||||
SWEEP_VOC: f32,
|
||||
// logger - today's values
|
||||
const VB_MIN_DAILY: u16 = 0x0040;
|
||||
const VB_MAX_DAILY: u16 = 0x0041;
|
||||
const VA_MAX_DAILY: u16 = 0x0042;
|
||||
const AHC_DAILY: u16 = 0x0043;
|
||||
const WHC_DAILY: u16 = 0x0044;
|
||||
const FLAGS_DAILY: u16 = 0x0045;
|
||||
const POUT_MAX_DAILY: u16 = 0x0046;
|
||||
const TB_MIN_DAILY: u16 = 0x0047;
|
||||
const TB_MAX_DAILY: u16 = 0x0048;
|
||||
const FAULT_DAILY: u16 = 0x0049;
|
||||
const ALARM_DAILY_HI: u16 = 0x004B;
|
||||
const ALARM_DAILY_LO: u16 = 0x004C;
|
||||
const TIME_AB_DAILY: u16 = 0x004D;
|
||||
const TIME_EQ_DAILY: u16 = 0x004E;
|
||||
const FIME_FL_DAILY: u16 = 0x004F;
|
||||
VB_MIN_DAILY: f32,
|
||||
VB_MAX_DAILY: f32,
|
||||
VA_MAX_DAILY: f32,
|
||||
AHC_DAILY: f32,
|
||||
WHC_DAILY: u16,
|
||||
FLAGS_DAILY: u16,
|
||||
POUT_MAX_DAILY: f32,
|
||||
TB_MIN_DAILY: u16,
|
||||
TB_MAX_DAILY: u16,
|
||||
FAULT_DAILY: u16,
|
||||
ALARM_DAILY_HI: u16,
|
||||
ALARM_DAILY_LO: u16,
|
||||
TIME_AB_DAILY: u16,
|
||||
TIME_EQ_DAILY: u16,
|
||||
TIME_FL_DAILY: u16,
|
||||
// manual control
|
||||
const IB_REF_SLAVE: u16 = 0x0058;
|
||||
const VB_REF_SLAVE: u16 = 0x0059;
|
||||
const VA_REF_FIXED: u16 = 0x005A;
|
||||
const VA_REF_FIXED_PCT: u16 = 0x005B;
|
||||
IB_REF_SLAVE: f32,
|
||||
VB_REF_SLAVE: f32,
|
||||
VA_REF_FIXED: f32,
|
||||
VA_REF_FIXED_PCT: f32,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
struct MpptEeprom {
|
||||
EV_absorp: f32,
|
||||
EV_float: f32,
|
||||
Et_absorp: u16,
|
||||
Et_absorp_ext: u16,
|
||||
EV_absorp_ext: f32,
|
||||
EV_float_cancel: f32,
|
||||
Et_float_exit_cum: u16,
|
||||
EV_eq: f32,
|
||||
Et_eqcalendar: u16,
|
||||
Et_eq_above: u16,
|
||||
Et_eq_reg: u16,
|
||||
Et_batt_service: u16,
|
||||
EV_tempcomp: f32,
|
||||
EV_hvd: f32,
|
||||
EV_hvr: f32,
|
||||
Evb_ref_lim: f32,
|
||||
ETb_max: u16,
|
||||
ETb_min: u16,
|
||||
EV_soc_g_gy: f32,
|
||||
EV_soc_gy_g: f32,
|
||||
EV_soc_y_yr: f32,
|
||||
EV_soc_yr_r: f32,
|
||||
Emodbus_id: u16,
|
||||
Emeterbus_id: u16,
|
||||
EIb_lim: f32,
|
||||
EVa_ref_fixed_init: f32,
|
||||
EVa_ref_fixed_pct_init: f32,
|
||||
}
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
|
@ -85,6 +121,34 @@ struct Args {
|
|||
serial_port: String,
|
||||
}
|
||||
|
||||
struct Info {
|
||||
v_scale: f32,
|
||||
i_scale: f32,
|
||||
}
|
||||
impl Info {
|
||||
pub fn from(data: &[u16]) -> Self {
|
||||
Self {
|
||||
v_scale: data[0] as f32 + (data[1] as f32 / f32::powf(2., 16.)),
|
||||
i_scale: data[2] as f32 + (data[3] as f32 / f32::powf(2., 16.)),
|
||||
}
|
||||
}
|
||||
pub fn scale_power(&self, p: &u16) -> f32 {
|
||||
*p as f32 * self.v_scale * self.i_scale * f32::powf(2., -17.)
|
||||
}
|
||||
pub fn scale_voltage(&self, v: &u16) -> f32 {
|
||||
*v as f32 * self.v_scale * f32::powf(2., -15.)
|
||||
}
|
||||
pub fn scale_current(&self, i: &u16) -> f32 {
|
||||
*i as f32 * self.i_scale * f32::powf(2., -15.)
|
||||
}
|
||||
pub fn scale_voltage_f(&self, v: f32) -> f32 {
|
||||
v * self.v_scale * f32::powf(2., -15.)
|
||||
}
|
||||
pub fn scale_current_f(&self, i: f32) -> f32 {
|
||||
i * self.i_scale * f32::powf(2., -15.)
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let args = Args::parse();
|
||||
let baud = 9600;
|
||||
|
@ -100,53 +164,119 @@ fn main() {
|
|||
modbus
|
||||
.connect()
|
||||
.expect("Could not connect to client device");
|
||||
let mut scaling_data: [u16; 4] = [0; 4];
|
||||
let mut data_in: [u16; RAM_DATA_SIZE as usize + 1] = [0; RAM_DATA_SIZE as usize + 1];
|
||||
modbus
|
||||
.read_registers(0x0000, 4, &mut scaling_data)
|
||||
.read_registers(0x0000, RAM_DATA_SIZE + 1, &mut data_in)
|
||||
.expect("couldnt");
|
||||
let v_scale = scaling_data[0] as f32 + (scaling_data[1] as f32 / f32::powf(2., 16.));
|
||||
let i_scale = scaling_data[2] as f32 + (scaling_data[3] as f32 / f32::powf(2., 16.));
|
||||
let mut data: [u16; 1] = [0; 1];
|
||||
modbus
|
||||
.read_registers(Offsets::T_BATT, 1, &mut data)
|
||||
.expect("couldnt");
|
||||
// println!("d: {}", (data[0] as f32 * v_scale) / 32768.);
|
||||
println!("battery temp: {}", data[0]);
|
||||
modbus
|
||||
.read_registers(Offsets::CHARGE_STATE, 1, &mut data)
|
||||
.expect("couldnt");
|
||||
println!("charge state: {}", data[0]);
|
||||
modbus
|
||||
.read_registers(Offsets::ADC_IB_F_1M, 1, &mut data)
|
||||
.expect("couldnt");
|
||||
println!(
|
||||
"current (1 min avg): {}",
|
||||
data[0] as f32 * i_scale * f32::powf(2., -15.)
|
||||
);
|
||||
modbus
|
||||
.read_registers(Offsets::ADC_VB_F_1M, 1, &mut data)
|
||||
.expect("couldnt");
|
||||
println!(
|
||||
"voltage (1 min avg): {}",
|
||||
data[0] as f32 * v_scale * f32::powf(2., -15.)
|
||||
);
|
||||
// let mut data: [u16; 5] = [0; 5];
|
||||
// modbus
|
||||
// .read_registers(0x0000, 5, &mut data)
|
||||
// .expect("Could not read registers");
|
||||
// println!("voltage scaling (whole term): {}", get_floating(data[0]));
|
||||
// println!(
|
||||
// "voltage scaling (fractional term): {}",
|
||||
// get_floating(data[1])
|
||||
// );
|
||||
// println!("current scaling (whole term): {}", get_floating(data[2]));
|
||||
// println!(
|
||||
// "current scaling (fractional term): {}",
|
||||
// get_floating(data[3])
|
||||
// );
|
||||
// println!("software version: {}", data[4]);
|
||||
}
|
||||
let info = Info::from(&data_in);
|
||||
let ram_data = MpptRam {
|
||||
V_PU: info.scale_voltage_f(
|
||||
data_in[OffsetsRam::V_PU_HI] as f32
|
||||
+ (data_in[OffsetsRam::V_PU_LO] as f32 / f32::powf(2., 16.)),
|
||||
),
|
||||
I_PU: info.scale_current_f(
|
||||
data_in[OffsetsRam::I_PU_HI] as f32
|
||||
+ (data_in[OffsetsRam::I_PU_LO] as f32 / f32::powf(2., 16.)),
|
||||
),
|
||||
VER_SW: data_in[OffsetsRam::VER_SW],
|
||||
ADC_VB_F_MED: info.scale_voltage(&data_in[OffsetsRam::ADC_VB_F_MED]),
|
||||
ADC_VBTERM_F: info.scale_voltage(&data_in[OffsetsRam::ADC_VBTERM_F]),
|
||||
ADC_VBS_F: info.scale_voltage(&data_in[OffsetsRam::ADC_VBS_F]),
|
||||
ADC_VA_F: info.scale_voltage(&data_in[OffsetsRam::ADC_VA_F]),
|
||||
ADC_IB_F_SHADOW: info.scale_current(&data_in[OffsetsRam::ADC_IB_F_SHADOW]),
|
||||
ADC_IA_F_SHADOW: info.scale_current(&data_in[OffsetsRam::ADC_IA_F_SHADOW]),
|
||||
ADC_P12_F: data_in[OffsetsRam::ADC_P12_F] as f32 * 18.618 * f32::powf(2., -15.),
|
||||
ADC_P3_F: data_in[OffsetsRam::ADC_P3_F] as f32 * 6.6 * f32::powf(2., -15.),
|
||||
ADC_PMETER_F: data_in[OffsetsRam::ADC_PMETER_F] as f32 * 18.618 * f32::powf(2., -15.),
|
||||
ADC_P18_F: data_in[OffsetsRam::ADC_P18_F] as f32 * 3. * f32::powf(2., -15.),
|
||||
ADC_V_REF: data_in[OffsetsRam::ADC_V_REF] as f32 * 3. * f32::powf(2., -15.),
|
||||
T_HS: data_in[OffsetsRam::T_HS],
|
||||
T_RTS: data_in[OffsetsRam::T_RTS],
|
||||
T_BATT: data_in[OffsetsRam::T_BATT],
|
||||
ADC_VB_F_1M: info.scale_voltage(&data_in[OffsetsRam::ADC_VB_F_1M]),
|
||||
ADC_IB_F_1M: info.scale_current(&data_in[OffsetsRam::ADC_IB_F_1M]),
|
||||
VB_MIN: info.scale_voltage(&data_in[OffsetsRam::VB_MIN]),
|
||||
VB_MAX: info.scale_voltage(&data_in[OffsetsRam::VB_MAX]),
|
||||
HOURMETER_HI: data_in[OffsetsRam::HOURMETER_HI],
|
||||
HOURMETER_LO: data_in[OffsetsRam::HOURMETER_LO],
|
||||
FAULT_ALL: data_in[OffsetsRam::FAULT_ALL],
|
||||
ALARM_HI: data_in[OffsetsRam::ALARM_HI],
|
||||
ALARM_LO: data_in[OffsetsRam::ALARM_LO],
|
||||
DIP_ALL: data_in[OffsetsRam::DIP_ALL],
|
||||
LED_STATE: data_in[OffsetsRam::LED_STATE],
|
||||
CHARGE_STATE: data_in[OffsetsRam::CHARGE_STATE],
|
||||
VB_REF: info.scale_voltage(&data_in[OffsetsRam::VB_REF]),
|
||||
AHC_R_HI: data_in[OffsetsRam::AHC_R_HI],
|
||||
AHC_R_LO: data_in[OffsetsRam::AHC_R_LO],
|
||||
AHC_T_HI: data_in[OffsetsRam::AHC_T_HI],
|
||||
AHC_T_LO: data_in[OffsetsRam::AHC_T_LO],
|
||||
KWHC_R: data_in[OffsetsRam::KWHC_R],
|
||||
KWHC_T: data_in[OffsetsRam::KWHC_T],
|
||||
POWER_OUT_SHADOW: info.scale_power(&data_in[OffsetsRam::AHC_R_HI]),
|
||||
POWER_IN_SHADOW: info.scale_power(&data_in[OffsetsRam::POWER_IN_SHADOW]),
|
||||
SWEEP_PIN_MAX: info.scale_power(&data_in[OffsetsRam::SWEEP_PIN_MAX]),
|
||||
SWEEP_VMP: info.scale_voltage(&data_in[OffsetsRam::SWEEP_VMP]),
|
||||
SWEEP_VOC: info.scale_voltage(&data_in[OffsetsRam::SWEEP_VOC]),
|
||||
VB_MIN_DAILY: info.scale_voltage(&data_in[OffsetsRam::VB_MIN_DAILY]),
|
||||
VB_MAX_DAILY: info.scale_voltage(&data_in[OffsetsRam::VB_MAX_DAILY]),
|
||||
VA_MAX_DAILY: info.scale_voltage(&data_in[OffsetsRam::VA_MAX_DAILY]),
|
||||
AHC_DAILY: data_in[OffsetsRam::AHC_DAILY] as f32 * 0.1,
|
||||
WHC_DAILY: data_in[OffsetsRam::WHC_DAILY],
|
||||
FLAGS_DAILY: data_in[OffsetsRam::FLAGS_DAILY],
|
||||
POUT_MAX_DAILY: info.scale_power(&data_in[OffsetsRam::POUT_MAX_DAILY]),
|
||||
TB_MIN_DAILY: data_in[OffsetsRam::TB_MIN_DAILY],
|
||||
TB_MAX_DAILY: data_in[OffsetsRam::TB_MAX_DAILY],
|
||||
FAULT_DAILY: data_in[OffsetsRam::FAULT_DAILY],
|
||||
ALARM_DAILY_HI: data_in[OffsetsRam::ALARM_DAILY_HI],
|
||||
ALARM_DAILY_LO: data_in[OffsetsRam::ALARM_DAILY_LO],
|
||||
TIME_AB_DAILY: data_in[OffsetsRam::TIME_AB_DAILY],
|
||||
TIME_EQ_DAILY: data_in[OffsetsRam::TIME_EQ_DAILY],
|
||||
TIME_FL_DAILY: data_in[OffsetsRam::TIME_FL_DAILY],
|
||||
IB_REF_SLAVE: data_in[OffsetsRam::IB_REF_SLAVE] as f32 * 80. * f32::powf(2., -15.),
|
||||
VB_REF_SLAVE: info.scale_voltage(&data_in[OffsetsRam::VB_REF_SLAVE]),
|
||||
VA_REF_FIXED: info.scale_voltage(&data_in[OffsetsRam::VA_REF_FIXED]),
|
||||
VA_REF_FIXED_PCT: data_in[OffsetsRam::VA_REF_FIXED_PCT] as f32 * 100. * f32::powf(2., -16.),
|
||||
};
|
||||
println!("ram: {:#?}", ram_data);
|
||||
|
||||
fn get_floating(num: u16) -> f32 {
|
||||
num as f32 * 16.92 / 65536.0
|
||||
let mut data_in: [u16; EEPROM_DATA_SIZE as usize + 1] = [0; EEPROM_DATA_SIZE as usize + 1];
|
||||
modbus
|
||||
.read_registers(EEPROM_BEGIN, EEPROM_DATA_SIZE + 1, &mut data_in)
|
||||
.expect("could not get eeprom data");
|
||||
|
||||
let eeprom_data = MpptEeprom {
|
||||
EV_absorp: info.scale_voltage(&data_in[OffsetsEeprom::EV_absorp]),
|
||||
EV_float: info.scale_voltage(&data_in[OffsetsEeprom::EV_float]),
|
||||
Et_absorp: data_in[OffsetsEeprom::Et_absorp],
|
||||
Et_absorp_ext: data_in[OffsetsEeprom::Et_absorp_ext],
|
||||
EV_absorp_ext: info.scale_voltage(&data_in[OffsetsEeprom::EV_absorp_ext]),
|
||||
EV_float_cancel: info.scale_voltage(&data_in[OffsetsEeprom::EV_float_cancel]),
|
||||
Et_float_exit_cum: data_in[OffsetsEeprom::Et_float_exit_cum],
|
||||
EV_eq: info.scale_voltage(&data_in[OffsetsEeprom::EV_eq]),
|
||||
Et_eqcalendar: data_in[OffsetsEeprom::Et_eqcalendar],
|
||||
Et_eq_above: data_in[OffsetsEeprom::Et_eq_above],
|
||||
Et_eq_reg: data_in[OffsetsEeprom::Et_eq_reg],
|
||||
Et_batt_service: data_in[OffsetsEeprom::Et_batt_service],
|
||||
EV_tempcomp: data_in[OffsetsEeprom::EV_tempcomp] as f32
|
||||
* info.v_scale
|
||||
* f32::powf(2., -16.),
|
||||
EV_hvd: info.scale_voltage(&data_in[OffsetsEeprom::EV_hvd]),
|
||||
EV_hvr: info.scale_voltage(&data_in[OffsetsEeprom::EV_hvr]),
|
||||
Evb_ref_lim: info.scale_voltage(&data_in[OffsetsEeprom::Evb_ref_lim]),
|
||||
ETb_max: data_in[OffsetsEeprom::ETb_max],
|
||||
ETb_min: data_in[OffsetsEeprom::ETb_min],
|
||||
EV_soc_g_gy: info.scale_voltage(&data_in[OffsetsEeprom::EV_soc_g_gy]),
|
||||
EV_soc_gy_g: info.scale_voltage(&data_in[OffsetsEeprom::EV_soc_gy_g]),
|
||||
EV_soc_y_yr: info.scale_voltage(&data_in[OffsetsEeprom::EV_soc_y_yr]),
|
||||
EV_soc_yr_r: info.scale_voltage(&data_in[OffsetsEeprom::EV_soc_yr_r]),
|
||||
Emodbus_id: data_in[OffsetsEeprom::Emodbus_id],
|
||||
Emeterbus_id: data_in[OffsetsEeprom::Emeterbus_id],
|
||||
EIb_lim: info.scale_current(&data_in[OffsetsEeprom::EIb_lim]),
|
||||
EVa_ref_fixed_init: info.scale_voltage(&data_in[OffsetsEeprom::EVa_ref_fixed_init]),
|
||||
EVa_ref_fixed_pct_init: data_in[OffsetsEeprom::EVa_ref_fixed_pct_init] as f32
|
||||
* 100.
|
||||
* f32::powf(2., -16.),
|
||||
};
|
||||
|
||||
println!("eeprom: {:#?}", eeprom_data);
|
||||
}
|
||||
|
|
106
src/offsets.rs
Normal file
106
src/offsets.rs
Normal file
|
@ -0,0 +1,106 @@
|
|||
pub struct OffsetsRam {}
|
||||
|
||||
impl OffsetsRam {
|
||||
// scaling values
|
||||
pub const V_PU_HI: usize = 0x0000;
|
||||
pub const V_PU_LO: usize = 0x0001;
|
||||
pub const I_PU_HI: usize = 0x0002;
|
||||
pub const I_PU_LO: usize = 0x0003;
|
||||
pub const VER_SW: usize = 0x0004;
|
||||
// filtered ADC
|
||||
pub const ADC_VB_F_MED: usize = 0x0018;
|
||||
pub const ADC_VBTERM_F: usize = 0x0019;
|
||||
pub const ADC_VBS_F: usize = 0x001A;
|
||||
pub const ADC_VA_F: usize = 0x001B;
|
||||
pub const ADC_IB_F_SHADOW: usize = 0x001C;
|
||||
pub const ADC_IA_F_SHADOW: usize = 0x001D;
|
||||
pub const ADC_P12_F: usize = 0x001E;
|
||||
pub const ADC_P3_F: usize = 0x001F;
|
||||
pub const ADC_PMETER_F: usize = 0x0020;
|
||||
pub const ADC_P18_F: usize = 0x0021;
|
||||
pub const ADC_V_REF: usize = 0x0022;
|
||||
// temperatures
|
||||
pub const T_HS: usize = 0x0023;
|
||||
pub const T_RTS: usize = 0x0024;
|
||||
pub const T_BATT: usize = 0x0025;
|
||||
// status
|
||||
pub const ADC_VB_F_1M: usize = 0x0026;
|
||||
pub const ADC_IB_F_1M: usize = 0x0027;
|
||||
pub const VB_MIN: usize = 0x0028;
|
||||
pub const VB_MAX: usize = 0x0029;
|
||||
pub const HOURMETER_HI: usize = 0x002A;
|
||||
pub const HOURMETER_LO: usize = 0x002B;
|
||||
pub const FAULT_ALL: usize = 0x002C;
|
||||
pub const ALARM_HI: usize = 0x002E;
|
||||
pub const ALARM_LO: usize = 0x002F;
|
||||
pub const DIP_ALL: usize = 0x0030;
|
||||
pub const LED_STATE: usize = 0x0031;
|
||||
// charger
|
||||
pub const CHARGE_STATE: usize = 0x0032;
|
||||
pub const VB_REF: usize = 0x0033;
|
||||
pub const AHC_R_HI: usize = 0x0034;
|
||||
pub const AHC_R_LO: usize = 0x0035;
|
||||
pub const AHC_T_HI: usize = 0x0036;
|
||||
pub const AHC_T_LO: usize = 0x0037;
|
||||
pub const KWHC_R: usize = 0x0038;
|
||||
pub const KWHC_T: usize = 0x0039;
|
||||
// MPPT
|
||||
pub const POWER_OUT_SHADOW: usize = 0x003A;
|
||||
pub const POWER_IN_SHADOW: usize = 0x003B;
|
||||
pub const SWEEP_PIN_MAX: usize = 0x003C;
|
||||
pub const SWEEP_VMP: usize = 0x003D;
|
||||
pub const SWEEP_VOC: usize = 0x003E;
|
||||
// logger - today's values
|
||||
pub const VB_MIN_DAILY: usize = 0x0040;
|
||||
pub const VB_MAX_DAILY: usize = 0x0041;
|
||||
pub const VA_MAX_DAILY: usize = 0x0042;
|
||||
pub const AHC_DAILY: usize = 0x0043;
|
||||
pub const WHC_DAILY: usize = 0x0044;
|
||||
pub const FLAGS_DAILY: usize = 0x0045;
|
||||
pub const POUT_MAX_DAILY: usize = 0x0046;
|
||||
pub const TB_MIN_DAILY: usize = 0x0047;
|
||||
pub const TB_MAX_DAILY: usize = 0x0048;
|
||||
pub const FAULT_DAILY: usize = 0x0049;
|
||||
pub const ALARM_DAILY_HI: usize = 0x004B;
|
||||
pub const ALARM_DAILY_LO: usize = 0x004C;
|
||||
pub const TIME_AB_DAILY: usize = 0x004D;
|
||||
pub const TIME_EQ_DAILY: usize = 0x004E;
|
||||
pub const TIME_FL_DAILY: usize = 0x004F;
|
||||
// manual control
|
||||
pub const IB_REF_SLAVE: usize = 0x0058;
|
||||
pub const VB_REF_SLAVE: usize = 0x0059;
|
||||
pub const VA_REF_FIXED: usize = 0x005A;
|
||||
pub const VA_REF_FIXED_PCT: usize = 0x005B;
|
||||
}
|
||||
|
||||
pub struct OffsetsEeprom {}
|
||||
|
||||
impl OffsetsEeprom {
|
||||
pub const EV_absorp: usize = 0xE000;
|
||||
pub const EV_float: usize = 0xE001;
|
||||
pub const Et_absorp: usize = 0xE002;
|
||||
pub const Et_absorp_ext: usize = 0xE003;
|
||||
pub const EV_absorp_ext: usize = 0xE004;
|
||||
pub const EV_float_cancel: usize = 0xE005;
|
||||
pub const Et_float_exit_cum: usize = 0xE006;
|
||||
pub const EV_eq: usize = 0xE007;
|
||||
pub const Et_eqcalendar: usize = 0xE008;
|
||||
pub const Et_eq_above: usize = 0xE009;
|
||||
pub const Et_eq_reg: usize = 0xE00A;
|
||||
pub const Et_batt_service: usize = 0xE00B;
|
||||
pub const EV_tempcomp: usize = 0xE00D;
|
||||
pub const EV_hvd: usize = 0xE00E;
|
||||
pub const EV_hvr: usize = 0xE00F;
|
||||
pub const Evb_ref_lim: usize = 0xE010;
|
||||
pub const ETb_max: usize = 0xE011;
|
||||
pub const ETb_min: usize = 0xE012;
|
||||
pub const EV_soc_g_gy: usize = 0xE015;
|
||||
pub const EV_soc_gy_g: usize = 0xE016;
|
||||
pub const EV_soc_y_yr: usize = 0xE017;
|
||||
pub const EV_soc_yr_r: usize = 0xE018;
|
||||
pub const Emodbus_id: usize = 0xE019;
|
||||
pub const Emeterbus_id: usize = 0xE01A;
|
||||
pub const EIb_lim: usize = 0xE01D;
|
||||
pub const EVa_ref_fixed_init: usize = 0xE020;
|
||||
pub const EVa_ref_fixed_pct_init: usize = 0xE021;
|
||||
}
|
Loading…
Add table
Reference in a new issue