Forráskód Böngészése

Calculate values.

Vladimir N. Shilov 5 éve
szülő
commit
0eab24f2e2
3 módosított fájl, 111 hozzáadás és 40 törlés
  1. 12 25
      lib/ina219.c
  2. 13 0
      lib/ina219.h
  3. 86 15
      src/main.c

+ 12 - 25
lib/ina219.c

@@ -21,7 +21,6 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #include "INA219.h"
 #include "i2c.h"
 
-static uint16_t currentLSB, powerLSB;
 static uint16_t vShuntMax; // millivolt
 static uint16_t vBusMax; // millivolt
 static uint16_t rShunt; // milliohms
@@ -36,7 +35,6 @@ static t_i2c_status status = I2C_SUCCESS;
   */
 void INA219_Config(void) {
   uint16_t config;
-  uint16_t calibrationValue;
 
   vBusMax = 32000; // !!! Maximum input voltage only 26V !!!
   vShuntMax = 80; // !! for shunt 10 mOhm and maximum 8A input current
@@ -52,18 +50,7 @@ void INA219_Config(void) {
 
   i2c_wr_reg(INA219_ADDRESS, INA219_REG_CONFIG, config);
 
-  /**
-   * ôîðìóëû èç ìàíóàëà:
-   * Current_LSB = Maximum Expected Current / 2^15
-   * Power_LSB = 20 * Current_LSB
-   * Calibration_Value = trunc( 0.04096 / (Current_LSB * Rshunt) )
-   */
-  currentLSB = 244; // 8000000 uA / 32768
-  powerLSB = 4880;
-
-  calibrationValue = 16777; // 0.04096 / ((8/32768) * 0.01)
-
-  i2c_wr_reg(INA219_ADDRESS, INA219_REG_CALIBRATION, calibrationValue);
+  i2c_wr_reg(INA219_ADDRESS, INA219_REG_CALIBRATION, CALIBRATION_VALUE);
 }
 
 /** */
@@ -73,7 +60,7 @@ uint16_t getMaxPossibleCurrent(void) {
 
 /** */
 uint16_t getMaxCurrent(void) {
-  uint16_t maxCurrent = ((currentLSB * 32767) + 500) / 1000;
+  uint16_t maxCurrent = ((CURRENT_LSB * 32767) + 500) / 1000;
   uint16_t maxPossible = getMaxPossibleCurrent();
 
   if (maxCurrent > maxPossible) {
@@ -113,7 +100,7 @@ uint16_t readBusCurrent(void) {
     tmp = - tmp;
   }
   current = tmp;
-  current *= currentLSB;
+  current *= CURRENT_LSB;
   current += 500;
   current /= 1000;
 
@@ -122,15 +109,15 @@ uint16_t readBusCurrent(void) {
 
 /** */
 uint32_t readBusPower(void) {
-  uint16_t power;
-  uint32_t tmp;
-
-  i2c_rd_reg(INA219_ADDRESS, INA219_REG_POWER, &power);
-  tmp = power;
-  tmp *= powerLSB;
-  tmp += 500;
-  tmp /= 1000;
-  return (uint16_t)tmp;
+  uint32_t power;
+  uint16_t tmp;
+
+  i2c_rd_reg(INA219_ADDRESS, INA219_REG_POWER, &tmp);
+  power = tmp;
+  power *= POWER_LSB;
+  power += 500;
+  power /= 1000;
+  return power;
 }
 
 /**

+ 13 - 0
lib/ina219.h

@@ -27,6 +27,19 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #define INA219_ADDRESS              (uint8_t)(0x40 << 1)
 #define INA219_ADDR_RD              (INA219_ADDRESS | 0x01)
 
+/**
+ * Calibration value -- ôîðìóëû èç ìàíóàëà:
+ * Current_LSB = Maximum Expected Current / 2^15
+ * Power_LSB = 20 * Current_LSB
+ * Calibration_Value = trunc( 0.04096 / (Current_LSB * Rshunt) )
+ */
+// 8000000 uA / 32768
+#define CURRENT_LSB                 244
+#define POWER_LSB                   4880
+// 0.04096 / ((8 A/32768) * 0.01 Ohm)
+#define CALIBRATION_VALUE           16777
+
+
 /* INA219 Registers */
 #define INA219_REG_CONFIG           0x00
 #define INA219_REG_SHUNTVOLTAGE     0x01

+ 86 - 15
src/main.c

@@ -38,6 +38,7 @@ typedef enum _mode_led {
   displayP,
   displayCI,
   displayCP,
+  displaySh,
   displayT
 } mode_led_t;
 
@@ -76,6 +77,7 @@ const static button_t Button[BUTTON_NUM] = {
 
 /* Private variables ---------------------------------------------------------*/
 static uint16_t Voltage;
+static int16_t  ShuntV;
 static uint16_t Current;
 static uint32_t Power;
 static uint32_t CapacityAH = 0;
@@ -100,6 +102,7 @@ static void showI(uint8_t pos);
 static void showP(uint8_t pos);
 static void showCI(uint8_t pos);
 static void showCP(uint8_t pos);
+static void showSH(uint8_t pos);
 static void showT(uint8_t pos);
 
 static void showLabelU(uint8_t pos);
@@ -107,6 +110,7 @@ static void showLabelI(uint8_t pos);
 static void showLabelP(uint8_t pos);
 static void showLabelAH(uint8_t pos);
 static void showLabelWH(uint8_t pos);
+static void showLabelSH(uint8_t pos);
 static void showLabelT(uint8_t pos);
 
 static void displayMode(mode_led_t * disp, event_t event, uint8_t pos);
@@ -115,17 +119,20 @@ static void blankLine(uint8_t pos);
 
 /* RTOS function prototypes -----------------------------------------------*/
 static void readINAValues(void);
+static void calculateValues(void);
 static void showTopLineU(void);
 static void showTopLineI(void);
 static void showTopLineP(void);
 static void showTopLineAH(void);
 static void showTopLineWH(void);
+static void showTopLineSH(void);
 static void showTopLineT(void);
 static void showBotLineU(void);
 static void showBotLineI(void);
 static void showBotLineP(void);
 static void showBotLineAH(void);
 static void showBotLineWH(void);
+static void showBotLineSH(void);
 static void showBotLineT(void);
 
 static void blankTopLine(void);
@@ -160,7 +167,8 @@ void main(void)
 
   /* ROTS tasks */
   RTOS_SetTask(btnScan, 0, BTN_SCAN_PERIOD);
-  RTOS_SetTask(readINAValues, 70, 250);
+  RTOS_SetTask(readINAValues, 69, 250);
+  RTOS_SetTask(calculateValues, 70, 1000);
   RTOS_SetTask(showTopLineU, 71, 250);
   RTOS_SetTask(showBotLineI, 72, 250);
 
@@ -323,9 +331,20 @@ static void displayMode(mode_led_t * disp, event_t event, uint8_t pos) {
     case displayCP:
       if (pos == 0) {
         RTOS_DeleteTask(showTopLineWH);
-        RTOS_SetTask(showTopLineT, 1000, 250);
+        RTOS_SetTask(showTopLineSH, 1000, 250);
       } else {
         RTOS_DeleteTask(showBotLineWH);
+        RTOS_SetTask(showBotLineSH, 1000, 250);
+      }
+      showLabelSH(pos);
+      *disp = displaySh;
+      break;
+    case displaySh:
+      if (pos == 0) {
+        RTOS_DeleteTask(showTopLineSH);
+        RTOS_SetTask(showTopLineT, 1000, 250);
+      } else {
+        RTOS_DeleteTask(showBotLineSH);
         RTOS_SetTask(showBotLineT, 1000, 250);
       }
       showLabelT(pos);
@@ -408,10 +427,36 @@ static void btn2Long(void) {
 /** Get values from INA219 and store to local variables. */
 static void readINAValues(void) {
   Voltage = readBusVoltage();
+  ShuntV = readShuntVoltage();
   Current = readBusCurrent();
   Power = readBusPower();
 }
 
+/**
+  * Calculate Time, Capacitance AH and WH.
+  */
+static void calculateValues(void) {
+  if (Current != 0) {
+
+    // millivolt * milliamper = microwatt, convert it to milliwatt
+    //Power = ((uint32_t)(v * c) + 500) / 1000;
+
+    CapacityAH += Current;
+    CapacityWH += Power;
+
+    Timer.ss ++;
+    if (Timer.ss > 59) {
+      Timer.ss = 0;
+      Timer.mm ++;
+      if (Timer.mm > 59) {
+        Timer.mm = 0;
+        Timer.hh ++;
+      }
+    }
+  }
+
+}
+
 /**
   * âûâîä èíôû íà âåðõíåì èíäèêàòîðå
   */
@@ -435,6 +480,10 @@ static void showTopLineWH(void) {
   showCP(0);
 }
 
+static void showTopLineSH(void) {
+  showSH(0);
+}
+
 static void showTopLineT(void) {
   showT(0);
 }
@@ -466,6 +515,10 @@ static void showBotLineWH(void) {
   showCP(4);
 }
 
+static void showBotLineSH(void) {
+  showSH(4);
+}
+
 static void showBotLineT(void) {
   showT(4);
 }
@@ -483,10 +536,6 @@ static void blankBotLine(void) {
 static void showValue(uint32_t val, uint8_t pos) {
   uint8_t tmp;
 
-  if (pos != 0) {
-    pos = 4;
-  }
-
   if (val >= 100000) { // 000.0
     tmp = (uint8_t)(val / 100000);
     val %= 100000;
@@ -563,7 +612,6 @@ void blankLine(uint8_t pos) {
   * any other for bottom.
   */
 static void showU(uint8_t pos) {
-  //showValue(slowBuf.Voltage[slowBuf.idx], pos);
   showValue(Voltage, pos);
 }
 
@@ -573,7 +621,6 @@ static void showU(uint8_t pos) {
   * any other for bottom.
   */
 static void showI(uint8_t pos) {
-  //showValue(slowBuf.Current[slowBuf.idx], pos);
   showValue(Current, pos);
 }
 
@@ -604,13 +651,31 @@ static void showCP(uint8_t pos) {
   showValue(((CapacityWH + 1800) / 3600), pos);
 }
 
+/**
+  * Output shunt voltage values to given indicator
+  * param: starting position -- 0 for top
+  * any other for bottom.
+  * LSB = 10 uV, may be negative!!!
+  */
+static void showSH(uint8_t pos) {
+  uint16_t val;
+
+  if (ShuntV < 0) {
+    val = - ShuntV;
+  } else {
+    val = ShuntV;
+  }
+
+  showValue(val, pos);
+}
+
 /**
   * Output time values to given indicator
   * param: starting position -- 0 for top
   * any other for bottom.
   */
 static void showT(uint8_t pos) {
-  static uint8_t halfsek = 0;
+  static uint8_t old_sek = 0;
   uint8_t tmp;
 
   if (Timer.hh > 0) {
@@ -618,7 +683,7 @@ static void showT(uint8_t pos) {
     MAX7219_WriteData(digitPosition[pos], digitValue[tmp]);
     pos ++;
     tmp = Timer.hh % 10;
-    if (halfsek == 0) {
+    if (old_sek == Timer.ss) {
       MAX7219_WriteData(digitPosition[pos], digitValue[tmp]);
     } else {
       MAX7219_WriteData(digitPosition[pos], (digitValue[tmp] | Sym_Dot));
@@ -643,11 +708,7 @@ static void showT(uint8_t pos) {
     MAX7219_WriteData(digitPosition[pos], digitValue[tmp]);
   }
 
-  if (halfsek == 0) {
-    halfsek = 1;
-  } else {
-    halfsek = 0;
-  }
+  old_sek = Timer.ss;
 }
 
 /**
@@ -703,6 +764,16 @@ static void showLabelWH(uint8_t pos) {
   MAX7219_WriteData(digitPosition[pos], Sym_Minus);
 }
 
+static void showLabelSH(uint8_t pos) {
+  MAX7219_WriteData(digitPosition[pos], Sym_Minus);
+  pos ++;
+  MAX7219_WriteData(digitPosition[pos], Sym_5);
+  pos ++;
+  MAX7219_WriteData(digitPosition[pos], Sym_h);
+  pos ++;
+  MAX7219_WriteData(digitPosition[pos], Sym_Minus);
+}
+
 static void showLabelT(uint8_t pos) {
   MAX7219_WriteData(digitPosition[pos], Sym_Minus);
   pos ++;