add i2c initial and pull configs
This commit is contained in:
parent
9473466feb
commit
12463c557b
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
||||
{
|
||||
"board": {
|
||||
"active_layer": 0,
|
||||
"active_layer": 44,
|
||||
"active_layer_preset": "",
|
||||
"auto_track_width": false,
|
||||
"hidden_netclasses": [],
|
||||
|
@ -11041,10 +11041,10 @@
|
||||
(effects (font (size 1.27 1.27)) (justify left) hide)
|
||||
)
|
||||
)
|
||||
(global_label "IsDay" (shape input) (at 107.696 117.602 0) (fields_autoplaced)
|
||||
(global_label "IsDay" (shape input) (at 115.316 117.602 0) (fields_autoplaced)
|
||||
(effects (font (size 1.27 1.27)) (justify left))
|
||||
(uuid f9414b76-a92a-468b-b946-a220ff9116fe)
|
||||
(property "Intersheetrefs" "${INTERSHEET_REFS}" (at 114.9671 117.602 0)
|
||||
(property "Intersheetrefs" "${INTERSHEET_REFS}" (at 122.5871 117.602 0)
|
||||
(effects (font (size 1.27 1.27)) (justify left) hide)
|
||||
)
|
||||
)
|
||||
@ -21854,6 +21854,32 @@
|
||||
)
|
||||
)
|
||||
|
||||
(symbol (lib_id "Device:R") (at 111.506 117.602 90) (unit 1)
|
||||
(in_bom yes) (on_board yes) (dnp no)
|
||||
(uuid cf61d446-6821-4eb1-853c-956de372075a)
|
||||
(property "Reference" "R45" (at 111.506 112.522 90)
|
||||
(effects (font (size 1.27 1.27)))
|
||||
)
|
||||
(property "Value" "1k ? unclear if required" (at 134.874 115.062 90)
|
||||
(effects (font (size 1.27 1.27)))
|
||||
)
|
||||
(property "Footprint" "Resistor_SMD:R_0603_1608Metric" (at 111.506 119.38 90)
|
||||
(effects (font (size 1.27 1.27)) hide)
|
||||
)
|
||||
(property "Datasheet" "~" (at 111.506 117.602 0)
|
||||
(effects (font (size 1.27 1.27)) hide)
|
||||
)
|
||||
(pin "1" (uuid 965529aa-0bae-4e1a-bac1-72c5adfd81aa))
|
||||
(pin "2" (uuid 490001cc-f9a7-4b11-a1b5-b95679c0e8f6))
|
||||
(instances
|
||||
(project "PlantCtrlESP32"
|
||||
(path "/c26e8d55-0b6e-4c4e-b7c8-b1fed973201c"
|
||||
(reference "R45") (unit 1)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
(symbol (lib_id "Device:LED") (at 602.996 104.394 180) (unit 1)
|
||||
(in_bom yes) (on_board yes) (dnp no) (fields_autoplaced)
|
||||
(uuid cf7c9688-c042-4127-845f-a77e26e24ea9)
|
||||
|
@ -77,6 +77,7 @@ heapless = { version = "0.7", features = ["serde"] }
|
||||
serde_json = "1.0.108"
|
||||
strum = { version = "0.25.0", features = ["derive"] }
|
||||
once_cell = "1.19.0"
|
||||
measurements = "0.11.0"
|
||||
#?bq34z100 required
|
||||
|
||||
[build-dependencies]
|
||||
|
@ -5,6 +5,4 @@ CONFIG_ESP_MAIN_TASK_STACK_SIZE=20000
|
||||
# This allows to use 1 ms granuality for thread sleeps (10 ms by default).
|
||||
CONFIG_FREERTOS_HZ=1000
|
||||
|
||||
# Workaround for https://github.com/espressif/esp-idf/issues/7631
|
||||
#CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=n
|
||||
#CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=n
|
||||
CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE=true
|
452
rust/src/bq34z100.rs
Normal file
452
rust/src/bq34z100.rs
Normal file
@ -0,0 +1,452 @@
|
||||
use embedded_hal::blocking::i2c::{WriteRead, Write, Read};
|
||||
|
||||
const BQ34Z100_G1_ADDRESS:u8 = 0x55;
|
||||
|
||||
//
|
||||
// bq34z100g1.cpp
|
||||
// SMC
|
||||
//
|
||||
// Created by Empire-Phoenix,
|
||||
// directly ported from
|
||||
// https://github.com/xkam1x/BQ34Z100G1/blob/master/bq34z100g1.cpp by Kamran Ahmad on 08/05/2019.
|
||||
//
|
||||
|
||||
impl <I2C, E: std::fmt::Debug> Bq34z100g1 for Bq34z100g1Driver<I2C> where I2C: WriteRead<Error = E> + Write<Error = E> + Read<Error = E> {
|
||||
fn read_register(&mut self, address:u8 , length:u8) -> u16 {
|
||||
let data: [u8;1] = [address];
|
||||
self.i2c.write(BQ34Z100_G1_ADDRESS, &data).unwrap();
|
||||
if length != 1 && length != 2{
|
||||
todo!();
|
||||
}
|
||||
if length == 2 {
|
||||
let mut buffer : [u8;2] = [0_u8,0_u8];
|
||||
let _ = self.i2c.read(BQ34Z100_G1_ADDRESS, &mut buffer);
|
||||
return ((buffer[1] as u16) << 8) | buffer[0] as u16;
|
||||
} else {
|
||||
let mut buffer : [u8;1] = [0_u8];
|
||||
let _ = self.i2c.read(BQ34Z100_G1_ADDRESS, &mut buffer);
|
||||
return buffer[0] as u16;
|
||||
}
|
||||
|
||||
// Wire.beginTransmission(BQ34Z100_G1_ADDRESS);
|
||||
// Wire.write(address);
|
||||
// Wire.endTransmission(false);
|
||||
// Wire.requestFrom(BQ34Z100_G1_ADDRESS, length, true);
|
||||
|
||||
// uint16_t temp = 0;
|
||||
// for (uint8_t i = 0; i < length; i++) {
|
||||
// temp |= Wire.read() << (8 * i);
|
||||
// }
|
||||
// return temp;
|
||||
}
|
||||
|
||||
fn read_control(&mut self,address_lsb:u8, address_msb: u8) -> u16 {
|
||||
let data: [u8;3] = [0x00_u8, address_lsb, address_msb];
|
||||
self.i2c.write(BQ34Z100_G1_ADDRESS, &data).unwrap();
|
||||
return self.read_register(0x00, 2);
|
||||
// Wire.beginTransmission(BQ34Z100_G1_ADDRESS);
|
||||
// Wire.write(0x00);
|
||||
// Wire.write(address_lsb);
|
||||
// Wire.write(address_msb);
|
||||
// Wire.endTransmission(true);
|
||||
// return read_register(0x00, 2);
|
||||
}
|
||||
|
||||
fn read_flash_block(sub_class:u8, offset:u8) {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn write_reg(address:u8, value:u8 ) {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn write_flash_block(sub_class:u8 , offset:u8) {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn flash_block_checksum() -> u8 {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn xemics_to_f64( value: u32) -> f64 {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn f64_to_xemics( value:f64) -> u32 {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn unsealed() {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn enter_calibration() {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn exit_calibration() {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn update_design_capacity(capacity:u16) -> bool {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn update_q_max(capacity:i16) -> bool {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn update_design_energy(energy:i16) -> bool {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn update_cell_charge_voltage_range(t1_t2:u16, t2_t3:u16, t3_t4:u16)-> bool {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn update_number_of_series_cells(cells:u8)-> bool {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn update_pack_configuration(config:u16) -> bool {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn update_charge_termination_parameters(taper_current:i16, min_taper_capacity:i16, cell_taper_voltage:i16,
|
||||
taper_window:u8, tca_set:i8, tca_clear:i8, fc_set:i8, fc_clear:i8) -> bool {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn calibrate_cc_offset() {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn calibrate_board_offset() {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn calibrate_voltage_divider(applied_voltage:u16, cells_count:u8) {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn calibrate_sense_resistor(applied_current:i16) {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn set_current_deadband( deadband:u8) {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn ready() {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn control_status() -> u16 {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn device_type() ->u16 {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn fw_version(&mut self)->u16 {
|
||||
return self.read_control(0x02, 0x00);
|
||||
}
|
||||
|
||||
fn hw_version()->u16 {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn reset_data() -> u16 {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn prev_macwrite() -> u16 {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn chem_id() -> u16 {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn board_offset() -> u16 {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn cc_offset() -> u16 {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn cc_offset_save() -> u16 {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn df_version() -> u16 {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn set_fullsleep() -> u16 {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn static_chem_chksum() -> u16 {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn sealed() -> u16 {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn it_enable() -> u16 {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn cal_enable() -> u16 {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn reset() -> u16 {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn exit_cal() -> u16 {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn enter_cal() -> u16 {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn offset_cal() -> u16 {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn state_of_charge() -> u8 {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn state_of_charge_max_error() -> u8 {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn remaining_capacity() -> u16 {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn full_charge_capacity() -> u16 {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn voltage() -> u16 {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn average_current() -> i16 {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn temperature() -> u16 {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn flags() -> u16 {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn flags_b() -> u16 {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn current() -> i16 {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn average_time_to_empty() -> u16 {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn average_time_to_full() -> u16 {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn passed_charge() -> i16 {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn do_d0_time() -> u16 {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn available_energy() -> u16 {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn average_power() -> u16 {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn serial_number() -> u16 {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn internal_temperature(&mut self) -> u16 {
|
||||
return self.read_register(0x2a, 2);
|
||||
}
|
||||
|
||||
fn cycle_count() -> u16 {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn state_of_health() -> u16 {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn charge_voltage() -> u16 {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn charge_current() -> u16 {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn pack_configuration() -> u16 {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn design_capacity() -> u16 {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn grid_number() -> u8 {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn learned_status() -> u8 {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn dod_at_eoc() -> u16 {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn q_start() -> u16 {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn true_fcc() -> u16 {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn state_time() -> u16 {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn q_max_passed_q() -> u16 {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn dod_0() -> u16 {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn q_max_dod_0() -> u16 {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn q_max_time() -> u16 {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Bq34z100g1Driver<I2C>{
|
||||
pub i2c: I2C,
|
||||
pub flash_block_data: [u8;32],
|
||||
}
|
||||
pub trait Bq34z100g1 {
|
||||
fn read_register(&mut self, address:u8 , length:u8) -> u16;
|
||||
fn read_control(&mut self, address_lsb:u8, address_msb: u8) -> u16;
|
||||
fn read_flash_block(sub_class:u8, offset:u8);
|
||||
fn write_reg(address:u8, value:u8 );
|
||||
fn write_flash_block(sub_class:u8 , offset:u8);
|
||||
|
||||
fn flash_block_checksum() -> u8;
|
||||
|
||||
fn xemics_to_f64( value: u32) -> f64 ;
|
||||
fn f64_to_xemics( value:f64) -> u32 ;
|
||||
|
||||
fn unsealed();
|
||||
fn enter_calibration();
|
||||
fn exit_calibration();
|
||||
|
||||
fn update_design_capacity(capacity:u16) -> bool;
|
||||
fn update_q_max(capacity:i16) -> bool ;
|
||||
fn update_design_energy(energy:i16) -> bool ;
|
||||
fn update_cell_charge_voltage_range(t1_t2:u16, t2_t3:u16, t3_t4:u16)-> bool ;
|
||||
fn update_number_of_series_cells(cells:u8)-> bool ;
|
||||
fn update_pack_configuration(config:u16) -> bool ;
|
||||
fn update_charge_termination_parameters(taper_current:i16, min_taper_capacity:i16, cell_taper_voltage:i16,
|
||||
taper_window:u8, tca_set:i8, tca_clear:i8, fc_set:i8, fc_clear:i8) -> bool ;
|
||||
fn calibrate_cc_offset();
|
||||
fn calibrate_board_offset();
|
||||
fn calibrate_voltage_divider(applied_voltage:u16, cells_count:u8);
|
||||
fn calibrate_sense_resistor(applied_current:i16);
|
||||
fn set_current_deadband( deadband:u8);
|
||||
fn ready();
|
||||
|
||||
fn control_status() -> u16;
|
||||
fn device_type() ->u16;
|
||||
fn fw_version(&mut self)->u16;
|
||||
fn hw_version()->u16;
|
||||
fn reset_data() -> u16 ;
|
||||
fn prev_macwrite() -> u16 ;
|
||||
fn chem_id() -> u16 ;
|
||||
fn board_offset() -> u16 ;
|
||||
fn cc_offset() -> u16 ;
|
||||
fn cc_offset_save() -> u16 ;
|
||||
fn df_version() -> u16 ;
|
||||
fn set_fullsleep() -> u16 ;
|
||||
fn static_chem_chksum() -> u16 ;
|
||||
fn sealed() -> u16 ;
|
||||
fn it_enable() -> u16 ;
|
||||
fn cal_enable() -> u16 ;
|
||||
fn reset() -> u16 ;
|
||||
fn exit_cal() -> u16 ;
|
||||
fn enter_cal() -> u16 ;
|
||||
fn offset_cal() -> u16 ;
|
||||
|
||||
fn state_of_charge() -> u8 ; // 0 to 100%
|
||||
fn state_of_charge_max_error() -> u8 ; // 1 to 100%
|
||||
fn remaining_capacity() -> u16 ; // mAh
|
||||
fn full_charge_capacity() -> u16 ; // mAh
|
||||
fn voltage() -> u16 ; // mV
|
||||
fn average_current() -> i16; // mA
|
||||
fn temperature() -> u16 ; // Unit of x10 K
|
||||
fn flags() -> u16 ;
|
||||
fn flags_b() -> u16 ;
|
||||
fn current() -> i16; // mA
|
||||
|
||||
fn average_time_to_empty() -> u16; // Minutes
|
||||
fn average_time_to_full() -> u16; // Minutes
|
||||
fn passed_charge() -> i16; // mAh
|
||||
fn do_d0_time() -> u16 ; // Minutes
|
||||
fn available_energy() -> u16 ; // 10 mWh
|
||||
fn average_power() -> u16 ; // 10 mW
|
||||
fn serial_number() -> u16 ;
|
||||
fn internal_temperature(&mut self) -> u16 ; // Unit of x10 K
|
||||
fn cycle_count() -> u16 ; // Counts
|
||||
fn state_of_health() -> u16 ; // 0 to 100%
|
||||
fn charge_voltage() -> u16 ; // mV
|
||||
fn charge_current() -> u16; // mA
|
||||
fn pack_configuration() -> u16 ;
|
||||
fn design_capacity() -> u16 ; // mAh
|
||||
fn grid_number() -> u8 ;
|
||||
fn learned_status() -> u8 ;
|
||||
fn dod_at_eoc() -> u16 ;
|
||||
fn q_start() -> u16; // mAh
|
||||
fn true_fcc() -> u16; // mAh
|
||||
fn state_time() -> u16 ; // s
|
||||
fn q_max_passed_q() -> u16; // mAh
|
||||
fn dod_0() -> u16;
|
||||
fn q_max_dod_0() -> u16;
|
||||
fn q_max_time() -> u16;
|
||||
}
|
@ -18,6 +18,7 @@ use crate::{
|
||||
config::{Config, WifiConfig},
|
||||
webserver::webserver::{httpd, httpd_initial},
|
||||
};
|
||||
pub mod bq34z100;
|
||||
mod config;
|
||||
pub mod plant_hal;
|
||||
|
||||
@ -49,6 +50,14 @@ enum WaitType {
|
||||
StayAlive,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Copy, Clone, Debug, PartialEq, Default)]
|
||||
struct LightState{
|
||||
active: bool,
|
||||
out_of_work_hour: bool,
|
||||
battery_low: bool,
|
||||
is_day: bool
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Copy, Clone, Debug, PartialEq, Default)]
|
||||
struct PlantState {
|
||||
a: Option<u8>,
|
||||
@ -134,11 +143,11 @@ fn map_range_moisture(s: f32) -> Result<u8> {
|
||||
fn in_time_range(cur: DateTime<Tz>, start:u8, end:u8) -> bool{
|
||||
let curhour = cur.hour() as u8;
|
||||
//eg 10-14
|
||||
if(start < end){
|
||||
if start < end {
|
||||
return curhour > start && curhour < end;
|
||||
} else {
|
||||
//eg 20-05
|
||||
return curhour > start || curhour < end;;
|
||||
return curhour > start || curhour < end;
|
||||
}
|
||||
}
|
||||
|
||||
@ -188,7 +197,7 @@ fn determine_next_plant(plantstate: &mut [PlantState;PLANT_COUNT],cur: DateTime<
|
||||
state.out_of_work_hour = true;
|
||||
}
|
||||
|
||||
if(state.dry && !state.no_water && !state.cooldown && !state.out_of_work_hour){
|
||||
if state.dry && !state.no_water && !state.cooldown && !state.out_of_work_hour {
|
||||
state.do_water = true;
|
||||
}
|
||||
},
|
||||
@ -210,7 +219,7 @@ fn determine_next_plant(plantstate: &mut [PlantState;PLANT_COUNT],cur: DateTime<
|
||||
if !in_time_range(cur, plant_config.pump_hour_start, plant_config.pump_hour_end) {
|
||||
state.out_of_work_hour = true;
|
||||
}
|
||||
if(!state.cooldown && !state.out_of_work_hour){
|
||||
if !state.cooldown && !state.out_of_work_hour {
|
||||
state.do_water = true;
|
||||
}
|
||||
},
|
||||
@ -237,7 +246,7 @@ fn determine_next_plant(plantstate: &mut [PlantState;PLANT_COUNT],cur: DateTime<
|
||||
return None
|
||||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
fn safe_main() -> Result<()> {
|
||||
// It is necessary to call this function once. Otherwise some patches to the runtime
|
||||
// implemented by esp-idf-sys might not link properly. See https://github.com/esp-rs/esp-idf-template/issues/71
|
||||
esp_idf_svc::sys::link_patches();
|
||||
@ -261,18 +270,18 @@ fn main() -> Result<()> {
|
||||
let mut partition_state: embedded_svc::ota::SlotState = embedded_svc::ota::SlotState::Unknown;
|
||||
match esp_idf_svc::ota::EspOta::new() {
|
||||
Ok(ota) => {
|
||||
// match ota.get_running_slot(){
|
||||
// Ok(slot) => {
|
||||
//match ota.get_running_slot(){
|
||||
// Ok(slot) => {
|
||||
// partition_state = slot.state;
|
||||
// println!(
|
||||
// "Booting from {} with state {:?}",
|
||||
// slot.label, partition_state
|
||||
// );
|
||||
// },
|
||||
// Err(err) => {
|
||||
// println!("Error getting running slot {}", err);
|
||||
// },
|
||||
// }
|
||||
//},
|
||||
// Err(err) => {
|
||||
// println!("Error getting running slot {}", err);
|
||||
// },
|
||||
//}
|
||||
},
|
||||
Err(err) => {
|
||||
println!("Error obtaining ota info {}", err);
|
||||
@ -281,7 +290,7 @@ fn main() -> Result<()> {
|
||||
|
||||
println!("Board hal init");
|
||||
let mut board: std::sync::MutexGuard<'_, PlantCtrlBoard<'_>> = BOARD_ACCESS.lock().unwrap();
|
||||
board.disable_all()?;
|
||||
|
||||
println!("Mounting filesystem");
|
||||
board.mount_file_system()?;
|
||||
let free_space = board.file_system_size()?;
|
||||
@ -475,7 +484,7 @@ fn main() -> Result<()> {
|
||||
Ok(temp) => {
|
||||
//FIXME mqtt here
|
||||
println!("Water temp is {}", temp);
|
||||
if(temp < 4_f32){
|
||||
if temp < 4_f32 {
|
||||
water_frozen = true;
|
||||
}
|
||||
break;
|
||||
@ -533,9 +542,23 @@ fn main() -> Result<()> {
|
||||
,
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
//check if during light time
|
||||
let mut light_state = LightState{ ..Default::default() };
|
||||
light_state.is_day = board.is_day();
|
||||
light_state.out_of_work_hour = !in_time_range(europe_time, config.night_lamp_hour_start, config.night_lamp_hour_end);
|
||||
if !light_state.out_of_work_hour {
|
||||
if config.night_lamp_only_when_dark {
|
||||
if !light_state.is_day {
|
||||
board.light(true).unwrap();
|
||||
}
|
||||
}else {
|
||||
board.light(true).unwrap();
|
||||
}
|
||||
} else {
|
||||
board.light(false).unwrap();
|
||||
}
|
||||
println!("Lightstate is {:?}", light_state);
|
||||
|
||||
//check if during light time
|
||||
//lightstate += out of worktime
|
||||
//check battery level
|
||||
//lightstate += battery empty
|
||||
@ -544,19 +567,14 @@ fn main() -> Result<()> {
|
||||
//if no preventing lightstate, enable light
|
||||
//lightstate = active
|
||||
|
||||
//keep webserver in scope
|
||||
let webserver = httpd(true);
|
||||
let delay = Delay::new_default();
|
||||
loop {
|
||||
//let freertos do shit
|
||||
delay.delay_ms(1001);
|
||||
}
|
||||
*/
|
||||
//deepsleep here?
|
||||
unsafe { esp_deep_sleep(1000*1000*10) };
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn main(){
|
||||
let result = safe_main();
|
||||
result.unwrap();
|
||||
}
|
||||
//error codes
|
||||
//error_reading_config_after_upgrade
|
||||
//error_no_config_after_upgrade
|
||||
|
@ -1,15 +1,19 @@
|
||||
//mod config;
|
||||
|
||||
use embedded_hal::blocking::i2c::Operation;
|
||||
use embedded_svc::wifi::{
|
||||
AccessPointConfiguration, AccessPointInfo, AuthMethod, ClientConfiguration, Configuration,
|
||||
};
|
||||
|
||||
use esp_idf_hal::i2c::{I2cConfig, I2cDriver, APBTickType};
|
||||
use esp_idf_hal::units::FromValueType;
|
||||
use esp_idf_svc::eventloop::EspSystemEventLoop;
|
||||
use esp_idf_svc::mqtt::client::QoS::ExactlyOnce;
|
||||
use esp_idf_svc::mqtt::client::{EspMqttClient, MqttClientConfiguration};
|
||||
use esp_idf_svc::nvs::EspDefaultNvsPartition;
|
||||
use esp_idf_svc::wifi::config::{ScanConfig, ScanType};
|
||||
use esp_idf_svc::wifi::EspWifi;
|
||||
use measurements::{Measurement, Temperature};
|
||||
use plant_ctrl2::sipo::ShiftRegister40;
|
||||
|
||||
use anyhow::anyhow;
|
||||
@ -29,7 +33,7 @@ use ds18b20::Ds18b20;
|
||||
use embedded_hal::digital::v2::OutputPin;
|
||||
use esp_idf_hal::adc::{attenuation, AdcChannelDriver, AdcDriver};
|
||||
use esp_idf_hal::delay::Delay;
|
||||
use esp_idf_hal::gpio::{AnyInputPin, Gpio39, Gpio4, Level, PinDriver};
|
||||
use esp_idf_hal::gpio::{AnyInputPin, Gpio39, Gpio4, Level, PinDriver, Pull, InputOutput};
|
||||
use esp_idf_hal::pcnt::{
|
||||
PcntChannel, PcntChannelConfig, PcntControlMode, PcntCountMode, PcntDriver, PinIndex,
|
||||
};
|
||||
@ -42,6 +46,7 @@ use one_wire_bus::OneWire;
|
||||
|
||||
use crate::config::{self, Config, WifiConfig};
|
||||
use crate::STAY_ALIVE;
|
||||
use crate::bq34z100::{Bq34z100g1Driver, Bq34z100g1};
|
||||
|
||||
pub const PLANT_COUNT: usize = 8;
|
||||
const PINS_PER_PLANT: usize = 5;
|
||||
@ -163,7 +168,6 @@ pub trait PlantCtrlBoardInteraction {
|
||||
fn test(&mut self) -> Result<()>;
|
||||
fn is_wifi_config_file_existant(&mut self) -> bool;
|
||||
fn mqtt(&mut self, config: &Config) -> Result<()>;
|
||||
fn disable_all(&mut self) -> Result<()>;
|
||||
}
|
||||
|
||||
pub trait CreatePlantHal<'a> {
|
||||
@ -174,9 +178,9 @@ pub struct PlantHal {}
|
||||
|
||||
pub struct PlantCtrlBoard<'a> {
|
||||
shift_register: ShiftRegister40<
|
||||
PinDriver<'a, esp_idf_hal::gpio::Gpio21, esp_idf_hal::gpio::Output>,
|
||||
PinDriver<'a, esp_idf_hal::gpio::Gpio22, esp_idf_hal::gpio::Output>,
|
||||
PinDriver<'a, esp_idf_hal::gpio::Gpio19, esp_idf_hal::gpio::Output>,
|
||||
PinDriver<'a, esp_idf_hal::gpio::Gpio21, InputOutput>,
|
||||
PinDriver<'a, esp_idf_hal::gpio::Gpio22, InputOutput>,
|
||||
PinDriver<'a, esp_idf_hal::gpio::Gpio19, InputOutput>,
|
||||
>,
|
||||
consecutive_watering_plant: Mutex<[u32; PLANT_COUNT]>,
|
||||
last_watering_timestamp: Mutex<[i64; PLANT_COUNT]>,
|
||||
@ -186,10 +190,10 @@ pub struct PlantCtrlBoard<'a> {
|
||||
solar_is_day: PinDriver<'a, esp_idf_hal::gpio::Gpio25, esp_idf_hal::gpio::Input>,
|
||||
boot_button: PinDriver<'a, esp_idf_hal::gpio::Gpio0, esp_idf_hal::gpio::Input>,
|
||||
signal_counter: PcntDriver<'a>,
|
||||
light: PinDriver<'a, esp_idf_hal::gpio::Gpio26, esp_idf_hal::gpio::Output>,
|
||||
main_pump: PinDriver<'a, esp_idf_hal::gpio::Gpio23, esp_idf_hal::gpio::Output>,
|
||||
tank_power: PinDriver<'a, esp_idf_hal::gpio::Gpio27, esp_idf_hal::gpio::Output>,
|
||||
general_fault: PinDriver<'a, esp_idf_hal::gpio::Gpio13, esp_idf_hal::gpio::Output>,
|
||||
light: PinDriver<'a, esp_idf_hal::gpio::Gpio26, InputOutput>,
|
||||
main_pump: PinDriver<'a, esp_idf_hal::gpio::Gpio23, InputOutput>,
|
||||
tank_power: PinDriver<'a, esp_idf_hal::gpio::Gpio27, InputOutput>,
|
||||
general_fault: PinDriver<'a, esp_idf_hal::gpio::Gpio13, InputOutput>,
|
||||
pub wifi_driver: EspWifi<'a>,
|
||||
one_wire_bus: OneWire<PinDriver<'a, Gpio4, esp_idf_hal::gpio::InputOutput>>,
|
||||
mqtt_client: Option<EspMqttClient<'a>>,
|
||||
@ -660,26 +664,54 @@ impl PlantCtrlBoardInteraction for PlantCtrlBoard<'_> {
|
||||
}
|
||||
bail!("Mqtt did not complete roundtrip in time");
|
||||
}
|
||||
|
||||
fn disable_all(&mut self) -> Result<()> {
|
||||
for mut pin in self.shift_register.decompose() {
|
||||
pin.set_low().unwrap();
|
||||
}
|
||||
self.general_fault(false);
|
||||
self.any_pump(false)?;
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
||||
impl CreatePlantHal<'_> for PlantHal {
|
||||
fn create() -> Result<Mutex<PlantCtrlBoard<'static>>> {
|
||||
let peripherals = Peripherals::take()?;
|
||||
|
||||
let i2c = peripherals.i2c1;
|
||||
let config = I2cConfig::new()
|
||||
.scl_enable_pullup(false)
|
||||
.sda_enable_pullup(false)
|
||||
.timeout(Duration::from_millis(10).into())
|
||||
.baudrate(10_u32.kHz().into());
|
||||
let scl = peripherals.pins.gpio16;
|
||||
let sda = peripherals.pins.gpio17;
|
||||
|
||||
|
||||
let clock = PinDriver::output(peripherals.pins.gpio21)?;
|
||||
let latch = PinDriver::output(peripherals.pins.gpio22)?;
|
||||
let data = PinDriver::output(peripherals.pins.gpio19)?;
|
||||
let driver = I2cDriver::new(i2c, sda, scl, &config).unwrap();
|
||||
let mut battery_driver :Bq34z100g1Driver<I2cDriver> = Bq34z100g1Driver{
|
||||
i2c :driver,
|
||||
flash_block_data : [0;32],
|
||||
};
|
||||
|
||||
let one_wire_pin = PinDriver::input_output_od(peripherals.pins.gpio4)?;
|
||||
let fwversion = battery_driver.fw_version();
|
||||
println!("fw version is {}", fwversion);
|
||||
loop {
|
||||
let bat_temp = battery_driver.internal_temperature();
|
||||
let temp_c = Temperature::from_kelvin(bat_temp as f64/10_f64).as_celsius();
|
||||
println!("bat int temp is is {}", temp_c);
|
||||
unsafe{
|
||||
vTaskDelay(1000);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
let mut clock = PinDriver::input_output(peripherals.pins.gpio21)?;
|
||||
clock.set_pull(Pull::Floating);
|
||||
let mut latch = PinDriver::input_output(peripherals.pins.gpio22)?;
|
||||
latch.set_pull(Pull::Floating);
|
||||
let mut data = PinDriver::input_output(peripherals.pins.gpio19)?;
|
||||
data.set_pull(Pull::Floating);
|
||||
let shift_register = ShiftRegister40::new(clock.into(), latch.into(), data.into());
|
||||
for mut pin in shift_register.decompose() {
|
||||
pin.set_low().unwrap();
|
||||
}
|
||||
|
||||
let mut one_wire_pin = PinDriver::input_output_od(peripherals.pins.gpio4)?;
|
||||
one_wire_pin.set_pull(Pull::Floating);
|
||||
//TODO make to none if not possible to init
|
||||
|
||||
//init,reset rtc memory depending on cause
|
||||
@ -744,7 +776,7 @@ impl CreatePlantHal<'_> for PlantHal {
|
||||
let nvs = EspDefaultNvsPartition::take()?;
|
||||
let wifi_driver = EspWifi::new(peripherals.modem, sys_loop, Some(nvs))?;
|
||||
|
||||
let shift_register = ShiftRegister40::new(clock, latch, data);
|
||||
|
||||
let last_watering_timestamp = Mutex::new(unsafe { LAST_WATERING_TIMESTAMP });
|
||||
let consecutive_watering_plant = Mutex::new(unsafe { CONSECUTIVE_WATERING_PLANT });
|
||||
let low_voltage_detected = Mutex::new(unsafe { LOW_VOLTAGE_DETECTED });
|
||||
@ -752,12 +784,22 @@ impl CreatePlantHal<'_> for PlantHal {
|
||||
AdcDriver::new(peripherals.adc1, &esp_idf_hal::adc::config::Config::new())?;
|
||||
let tank_channel: AdcChannelDriver<'_, { attenuation::DB_11 }, Gpio39> =
|
||||
AdcChannelDriver::new(peripherals.pins.gpio39)?;
|
||||
let solar_is_day = PinDriver::input(peripherals.pins.gpio25)?;
|
||||
let boot_button = PinDriver::input(peripherals.pins.gpio0)?;
|
||||
let light = PinDriver::output(peripherals.pins.gpio26)?;
|
||||
let main_pump = PinDriver::output(peripherals.pins.gpio23)?;
|
||||
let tank_power = PinDriver::output(peripherals.pins.gpio27)?;
|
||||
let general_fault = PinDriver::output(peripherals.pins.gpio13)?;
|
||||
|
||||
let mut solar_is_day = PinDriver::input(peripherals.pins.gpio25)?;
|
||||
solar_is_day.set_pull(Pull::Floating)?;
|
||||
|
||||
let mut boot_button = PinDriver::input(peripherals.pins.gpio0)?;
|
||||
boot_button.set_pull(Pull::Floating)?;
|
||||
let mut light = PinDriver::input_output(peripherals.pins.gpio26)?;
|
||||
light.set_pull(Pull::Floating)?;
|
||||
let mut main_pump = PinDriver::input_output(peripherals.pins.gpio23)?;
|
||||
main_pump.set_pull(Pull::Floating)?;
|
||||
main_pump.set_low()?;
|
||||
let mut tank_power = PinDriver::input_output(peripherals.pins.gpio27)?;
|
||||
tank_power.set_pull(Pull::Floating)?;
|
||||
let mut general_fault = PinDriver::input_output(peripherals.pins.gpio13)?;
|
||||
general_fault.set_pull(Pull::Floating)?;
|
||||
general_fault.set_low()?;
|
||||
let one_wire_bus = OneWire::new(one_wire_pin)
|
||||
.map_err(|err| -> anyhow::Error { anyhow!("Missing attribute: {:?}", err) })?;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user