Browse Source

PWM Control-loop gefixt. Stromoffset-Problem der High-Side besteht noch.

Heinrich Blatt 7 months ago
parent
commit
8ba47ea719
2 changed files with 22 additions and 20 deletions
  1. 15 15
      src/battery_data/battery.c
  2. 7 5
      src/interfaces/i2c_target.c

+ 15 - 15
src/battery_data/battery.c

@@ -1,5 +1,6 @@
 #include "battery.h"
 #include "ti/driverlib/dl_i2c.h"
+#include "ti/driverlib/dl_timerg.h"
 #include "ti_msp_dl_config.h"
 #include "src/peripherals/dac/dac.h"
 #include "src/peripherals/adc/adc.h"
@@ -52,11 +53,13 @@ static void batteryslots_init() {
         battery_slots[i].measurement.temperature = 0;
         battery_slots[i].set_current = 0;
 
+        DL_TimerG_startCounter(battery_slots[i].timer);
         set_pwm(i, 0);
+        delay_cycles(PWM_INITIALIZATION_DELAY);
     }
 
     
-    if (!i2c_discover(DAC_TARGET_ADDRESS)) {
+    /*if (!i2c_discover(DAC_TARGET_ADDRESS)) {
         // there is only 1 DAC for all 4 slots
         for(uint8_t i=0; i< NUM_SLOTS; i++) {
             *battery_slots[i].state = SLOT_ERR_NO_DAC;
@@ -68,12 +71,12 @@ static void batteryslots_init() {
     for(uint8_t i=0; i< NUM_SLOTS; i++){
 
         set_dac(i, 0);
-
+        
         if (!i2c_discover(ADC_TARGET_BASE_ADDRESS+i)) {
             // this automatically translates to the other addresses
             *battery_slots[i].state = SLOT_ERR_NO_ADC1+i;
         }
-    }
+    }*/
 }
 static void batteryslots_read_state(uint8_t slot) {
     /*
@@ -86,7 +89,7 @@ static void batteryslots_read_state(uint8_t slot) {
  
     // step 1: read channel 0 (voltage reading of the cell)
     uint16_t bare_voltage = read_adc_channel(slot, 0);
-    battery_slots[slot].measurement.voltage = (100.0/56+1)*bare_voltage; // We have that voltage divider
+    battery_slots[slot].measurement.voltage = bare_voltage*(56+100)/56; // We have that voltage divider
 
     // DAC branch: we can calculate the current based on the shunt
     if (battery_slots[slot].set_current >= 0) {
@@ -99,13 +102,15 @@ static void batteryslots_read_state(uint8_t slot) {
     } else {
         // we are in PWM mode, the shunt is on the high side
         // read channel 2 (voltage reading on 5V side)
-        int16_t shunt_current = read_adc_channel(slot, 2)*10;
+        uint16_t shunt_current = 10*read_adc_channel(slot, 2)/1000;
 
         // read channel 3 (current reading after step conversion, 5V side)
-        int16_t hi_voltage = read_adc_channel(slot, 3)*100/56;
+        uint16_t hi_voltage = read_adc_channel(slot, 3)*(56+100)/56;
+
+        uint32_t hi_power = shunt_current*hi_voltage;
 
         // calculate the result
-        battery_slots[slot].measurement.current = -1*shunt_current*hi_voltage/battery_slots[slot].measurement.voltage;
+        battery_slots[slot].measurement.current = (int16_t)(hi_power/battery_slots[slot].measurement.voltage)*-1;
 #ifdef DEBUG_TRACE_CTRL
         printf("Slot %d voltage: %d mV and %d mA (pwm shunt) (hi side voltage: %d mV, hi side current: %d mA)\n", slot, battery_slots[slot].measurement.voltage, battery_slots[slot].measurement.current, hi_voltage, shunt_current);
 #endif
@@ -180,17 +185,12 @@ static void batteryslots_adjust_current(uint8_t slot) {
             set_dac(slot, 0);
         }
 
-        if (battery_slots[slot].set_current + BATTERY_CURRENT_THRESHOLD > battery_slots[slot].measurement.current) {
+        if (battery_slots[slot].set_current + BATTERY_CURRENT_THRESHOLD < battery_slots[slot].measurement.current) {
             // we are outside of the tolerance band
             // exceeded to the upper limit
             // -> update pwm value, decrease the voltage
-            
-            // @todo debugging & validation: ensure that this directive works
-#ifdef DEBUG_CTRL
-            printf("timer count: %d\n", DL_Timer_getTimerCount(battery_slots[0].timer));
-#endif
 
-            if (battery_slots[slot].pwm_value+1 <= DL_Timer_getTimerCount(battery_slots[0].timer)) {
+            if (battery_slots[slot].pwm_value+1 <= MAX_PWM_CYCLE) {
                 // pwm is inverse to the DAC since dragging more current means more negative
 #ifdef DEBUG_TRACE_CTRL
                 printf("Ctrl: Increasing PWM to %d\n", battery_slots[slot].pwm_value+1);
@@ -204,7 +204,7 @@ static void batteryslots_adjust_current(uint8_t slot) {
 #endif
                 *battery_slots[slot].state = SLOT_WARN_HIGHER_PWM_NOT_POSSIBLE;
             }
-        } else if (battery_slots[slot].set_current - BATTERY_CURRENT_THRESHOLD < battery_slots[slot].measurement.current) {
+        } else if (battery_slots[slot].set_current - BATTERY_CURRENT_THRESHOLD > battery_slots[slot].measurement.current) {
             // we are outside of the tolerance band
             // exceeded to the upplowerer limit
             // -> update pwm value, increase the voltage

+ 7 - 5
src/interfaces/i2c_target.c

@@ -84,16 +84,18 @@ void mcu_i2c_handle(I2C_Regs *i2c) {
             return;
         }
         uint8_t slot = rx_buffer[1]; // first byte is the slot id (0..3)
-        battery_slots[slot].set_current = *((rx_buffer)+2); // byte 3+4 is the current
+        battery_slots[slot].set_current = *((int16_t*)(&rx_buffer[2])); // byte 3+4 is the current
+        
 #ifdef DEBUG_TARGET
         printf("Slot id: %d, Current: %" SCNd16 "\n", slot, battery_slots[slot].set_current);
 #endif
+        /*
+        // This code is for debugging:
+        // you can shoot directly code to the DAC / PWM for debugging
         if (battery_slots[slot].set_current >= 0) {
             DAC_SingleWrite(slot, battery_slots[slot].set_current);
         } else if (battery_slots[slot].set_current < 0) {
-            
-            DL_TimerG_startCounter(PWM_0_INST);
-            DL_TimerG_setCaptureCompareValue(PWM_0_INST, -1*battery_slots[slot].set_current, DL_TIMER_CC_0_INDEX); // update ccr0 value
+            DL_TimerG_setCaptureCompareValue(PWM_0_INST, -1*battery_slots[slot].set_current, DL_TIMER_CC_1_INDEX);
 
         } else {
             // do nothing, charge or discharge
@@ -102,7 +104,7 @@ void mcu_i2c_handle(I2C_Regs *i2c) {
 #else
             ;
 #endif
-        }
+        } */
     } else if (receivedCommand == CMD_CELAR_ERR) {
         uint8_t slot = receivedCommand & 0xF0;
         if (slot > NUM_SLOTS) {