add i2c initial and pull configs

This commit is contained in:
Empire 2024-01-17 21:25:01 +01:00
parent 9473466feb
commit 12463c557b
8 changed files with 7042 additions and 6103 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
{
"board": {
"active_layer": 0,
"active_layer": 44,
"active_layer_preset": "",
"auto_track_width": false,
"hidden_netclasses": [],

View File

@ -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)

View File

@ -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]

View File

@ -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
View 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;
}

View File

@ -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<()> {
,
}
/*
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
//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

View File

@ -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 clock = PinDriver::output(peripherals.pins.gpio21)?;
let latch = PinDriver::output(peripherals.pins.gpio22)?;
let data = PinDriver::output(peripherals.pins.gpio19)?;
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 one_wire_pin = PinDriver::input_output_od(peripherals.pins.gpio4)?;
let driver = I2cDriver::new(i2c, sda, scl, &config).unwrap();
let mut battery_driver :Bq34z100g1Driver<I2cDriver> = Bq34z100g1Driver{
i2c :driver,
flash_block_data : [0;32],
};
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) })?;