mppt-modbus/src/main.rs

153 lines
4.9 KiB
Rust
Raw Normal View History

2022-09-03 12:45:33 +10:00
use clap::Parser;
2022-09-02 20:34:28 +10:00
use libmodbus_rs::{Modbus, ModbusClient, ModbusRTU};
2022-09-02 19:07:04 +10:00
const DEVICE_ID: u8 = 0x01;
2022-09-02 20:34:28 +10:00
struct Offsets {}
impl Offsets {
// 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;
// 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;
// temperatures
const T_HS: u16 = 0x0023;
const T_RTS: u16 = 0x0024;
const T_BATT: u16 = 0x0025;
// 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;
// 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;
// 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;
// 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;
}
2022-09-03 12:45:33 +10:00
#[derive(Parser, Debug)]
#[clap(author, version, about, long_about = None)]
struct Args {
#[clap(short, long, default_value = "/dev/ttyUSB0")]
serial_port: String,
}
2022-09-02 19:07:04 +10:00
fn main() {
2022-09-03 12:45:33 +10:00
let args = Args::parse();
2022-09-02 19:07:04 +10:00
let baud = 9600;
let parity = 'N';
let data_bit = 8;
let stop_bit = 2;
2022-09-03 12:48:09 +10:00
println!("Connecting to device on {}", args.serial_port);
2022-09-03 12:45:33 +10:00
let mut modbus = Modbus::new_rtu(&args.serial_port, baud, parity, data_bit, stop_bit)
2022-09-03 12:48:09 +10:00
.expect("Could not create modbus device");
2022-09-02 19:07:04 +10:00
modbus
.set_slave(DEVICE_ID)
2022-09-03 12:48:09 +10:00
.expect("Could not set client device");
modbus
.connect()
.expect("Could not connect to client device");
2022-09-03 14:43:17 +10:00
let mut scaling_data: [u16; 4] = [0; 4];
2022-09-02 20:34:28 +10:00
modbus
2022-09-03 14:43:17 +10:00
.read_registers(0x0000, 4, &mut scaling_data)
.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");
2022-09-02 20:34:28 +10:00
println!(
2022-09-03 14:43:17 +10:00
"current (1 min avg): {}",
data[0] as f32 * i_scale * f32::powf(2., -15.)
2022-09-02 20:34:28 +10:00
);
2022-09-03 14:43:17 +10:00
modbus
.read_registers(Offsets::ADC_VB_F_1M, 1, &mut data)
.expect("couldnt");
2022-09-02 20:34:28 +10:00
println!(
2022-09-03 14:43:17 +10:00
"voltage (1 min avg): {}",
data[0] as f32 * v_scale * f32::powf(2., -15.)
2022-09-02 20:34:28 +10:00
);
2022-09-03 14:43:17 +10:00
// 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]);
2022-09-02 20:34:28 +10:00
}
fn get_floating(num: u16) -> f32 {
2022-09-03 14:43:17 +10:00
num as f32 * 16.92 / 65536.0
2022-09-02 19:07:04 +10:00
}