Преглед изворни кода

Калибровочные коэффициенты в модуле и скрипт калибровки.

unknown пре 6 месеци
родитељ
комит
6f42d7c819

+ 8 - 2
fw/modules/calibration/factors.c

@@ -60,8 +60,14 @@ void factros_set_default(factors_t *factors)
 {
     for (int i = 0; i < AI_COMMON_NUMBER; i++)
     {
-        factors->factor_b[i] = 0.0;
-        factors->factor_k[i] = 1.0;
+        factors->factor_k_v10[i] = 1.0;
+        factors->factor_b_v10[i] = 0.0;
+        
+        factors->factor_k_v1[i] = 1.0;
+        factors->factor_b_v1[i] = 0.0;
+        
+        factors->factor_k_cur[i] = 1.0;
+        factors->factor_b_cur[i] = 0.0;
     }
     factors->control_word = SETTINGS_CONTROL_WORD;
 }

+ 9 - 2
fw/modules/calibration/factors.h

@@ -7,8 +7,15 @@
 
 typedef struct
 {
-    float factor_k[AI_COMMON_NUMBER];
-    float factor_b[AI_COMMON_NUMBER];
+    float factor_k_v10[AI_COMMON_NUMBER];   // диапазон измерения 0 - 10 В
+    float factor_b_v10[AI_COMMON_NUMBER];   // диапазон измерения 0 - 10 В
+    
+    float factor_k_v1[AI_COMMON_NUMBER];    // диапазон измерения 0 - 1 В
+    float factor_b_v1[AI_COMMON_NUMBER];    // диапазон измерения 0 - 1 В
+    
+    float factor_k_cur[AI_COMMON_NUMBER];   // режим измерения тока
+    float factor_b_cur[AI_COMMON_NUMBER];   // режим измерения тока
+    
     uint32_t control_word;
     
 } factors_t;

+ 5 - 0
fw/modules/modbus/modbus.c

@@ -15,6 +15,7 @@
 #include "log.h"
 #include "log_api.h"
 #include "settings_api.h"
+#include "factors.h"
 #include <stdio.h>
 #include <string.h>
 #include <stdbool.h>
@@ -199,6 +200,10 @@ void modbus_params(void *params)
                     
                 break;
                   
+                case MB_SAVE_CALIBRATION_SETTINGS:
+                  
+                    factors_save(&ai_factors);
+                
                 case MB_RESET :
                   
                     vTaskDelay(100);

+ 3 - 0
fw/modules/modbus/modbus.h

@@ -24,6 +24,8 @@ typedef enum
     MB_COM_ARCH_CLEAR_6 = 8,
     MB_COM_ARCH_CLEAR_7 = 9,
     MB_COM_ARCH_CLEAR_8 = 10,
+    
+    MB_COM_CALIBRATION_FACROTS_SAVE = 21,
       
 } mb_command_t;
 
@@ -45,6 +47,7 @@ typedef enum
     MB_PAS_ERR,
     MB_LOG_CLEAR,
     MB_ARCHIVE_CLEAR,
+    MB_SAVE_CALIBRATION_SETTINGS,
         
 } mb_delay_action_t ;
 

+ 98 - 5
fw/modules/modbus/modbus_ai_params.c

@@ -4,6 +4,7 @@
 #include "modbus_params.h"
 #include "analog_input.h"
 #include "preset_ai.h"
+#include "factors.h"
 
 
 extern mb_param_t mb_param[];
@@ -240,14 +241,70 @@ uint16_t mb_init_ai_params(uint16_t i)
         index++;
     }
     
-    // Набор калибровочных коэффициентов "K"
-/*    
-    addr = 0x0410;
+    // ---------------------------------------------------------------------- //
+    
+    // Набор калибровочных коэффициентов "K" 
+    // для диапазона измерения напряжения 0 - 10 В
+    
+    addr = 0x1410;
     for (int i = 0; i < AI_COMMON_NUMBER; i++)
     {
         mb_param[index].reg = addr;
         mb_param[index].size = 2;
-        mb_param[index].param = (uint8_t*)&settings.preset[i].hyst;
+        mb_param[index].param = (uint8_t*)&ai_factors.factor_k_v10[i];
+        mb_param[index].set = NULL;
+        mb_param[index].get = NULL;
+        mb_param[index].check_handler = mb_check_dummy;
+        
+        addr += 2;
+        index++;
+    }
+    
+    // Набор калибровочных коэффициентов "B" 
+    // для диапазона измерения напряжения 0 - 10 В
+    
+    addr = 0x1428;
+    for (int i = 0; i < AI_COMMON_NUMBER; i++)
+    {
+        mb_param[index].reg = addr;
+        mb_param[index].size = 2;
+        mb_param[index].param = (uint8_t*)&ai_factors.factor_b_v10[i];
+        mb_param[index].set = NULL;
+        mb_param[index].get = NULL;
+        mb_param[index].check_handler = mb_check_dummy;
+        
+        addr += 2;
+        index++;
+    }
+    
+    // ---------------------------------------------------------------------- //
+    
+    // Набор калибровочных коэффициентов "K" 
+    // для диапазона измерения напряжения 0 - 1 В
+    
+    addr = 0x1440;
+    for (int i = 0; i < AI_COMMON_NUMBER; i++)
+    {
+        mb_param[index].reg = addr;
+        mb_param[index].size = 2;
+        mb_param[index].param = (uint8_t*)&ai_factors.factor_k_v1[i];
+        mb_param[index].set = NULL;
+        mb_param[index].get = NULL;
+        mb_param[index].check_handler = mb_check_dummy;
+        
+        addr += 2;
+        index++;
+    }
+    
+    // Набор калибровочных коэффициентов "B" 
+    // для диапазона измерения напряжения 0 - 1 В
+    
+    addr = 0x1458;
+    for (int i = 0; i < AI_COMMON_NUMBER; i++)
+    {
+        mb_param[index].reg = addr;
+        mb_param[index].size = 2;
+        mb_param[index].param = (uint8_t*)&ai_factors.factor_b_v1[i];
         mb_param[index].set = NULL;
         mb_param[index].get = NULL;
         mb_param[index].check_handler = mb_check_dummy;
@@ -255,7 +312,43 @@ uint16_t mb_init_ai_params(uint16_t i)
         addr += 2;
         index++;
     }
-*/    
+    
+    // ---------------------------------------------------------------------- //
+    
+    // Набор калибровочных коэффициентов "K" 
+    // для режима измерения тока
+    
+    addr = 0x1470;
+    for (int i = 0; i < AI_COMMON_NUMBER; i++)
+    {
+        mb_param[index].reg = addr;
+        mb_param[index].size = 2;
+        mb_param[index].param = (uint8_t*)&ai_factors.factor_k_cur[i];
+        mb_param[index].set = NULL;
+        mb_param[index].get = NULL;
+        mb_param[index].check_handler = mb_check_dummy;
+        
+        addr += 2;
+        index++;
+    }
+    
+    // Набор калибровочных коэффициентов "B" 
+    // для режима измерения тока
+    
+    addr = 0x1488;
+    for (int i = 0; i < AI_COMMON_NUMBER; i++)
+    {
+        mb_param[index].reg = addr;
+        mb_param[index].size = 2;
+        mb_param[index].param = (uint8_t*)&ai_factors.factor_b_cur[i];
+        mb_param[index].set = NULL;
+        mb_param[index].get = NULL;
+        mb_param[index].check_handler = mb_check_dummy;
+        
+        addr += 2;
+        index++;
+    }
+    
     return index;
 }
 

+ 3 - 1
fw/modules/modbus/modbus_params.c

@@ -600,7 +600,9 @@ mb_delay_action_t mb_control(void)
     }
     else if (system_cmd == MB_COM_STOP_WDT)
         soft_wdt_dtop(true);
-      
+    else if (system_cmd == MB_COM_CALIBRATION_FACROTS_SAVE)
+        return MB_SAVE_CALIBRATION_SETTINGS;
+    
     return MB_NO_ACTION;
     
 #if 0

+ 1 - 1
fw/modules/modbus/modbus_params.h

@@ -16,7 +16,7 @@ extern "C" {
 #endif
 
 #if defined (MAI_12)  
-#define MB_PARAM_MAX			172
+#define MB_PARAM_MAX			234
 #endif
 
 #if defined (MAO_4)


Разлика између датотеке није приказан због своје велике величине
+ 428 - 396
project/ewarm/iap/iap.dep


Разлика између датотеке није приказан због своје велике величине
+ 1236 - 1233
project/ewarm/module_universal_io.dep


+ 1 - 1
project/ewarm/module_universal_io.ewp

@@ -225,7 +225,7 @@
                     <state>AT_START_F403A_V1</state>
                     <state>PRINTF_STDLIB</state>
                     <state>DEBUG</state>
-                    <state>MDIO_88</state>
+                    <state>MAI_12</state>
                 </option>
                 <option>
                     <name>CCPreprocFile</name>

+ 126 - 3
tools/analog_in.py

@@ -153,6 +153,34 @@ class IO_AnalogInput(IO_Module):
         return struct.unpack('>ffffffffffff', self.modbus.read_holding_registers_raw(AiReg.PR_HIST.value, 24))
 
     
+    def get_cal_k_v10(self):
+        """Калибровочные коэффициенты K (диапазон 0 - 10 В)"""
+        return struct.unpack('>ffffffffffff', self.modbus.read_holding_registers_raw(AiReg.CL_V10_K.value, 24))
+    
+
+    def get_cal_b_v10(self):
+        """Калибровочные коэффициенты B (диапазон 0 - 10 В)"""
+        return struct.unpack('>ffffffffffff', self.modbus.read_holding_registers_raw(AiReg.CL_V10_B.value, 24))
+
+
+    def get_cal_k_v1(self):
+        """Калибровочные коэффициенты K (диапазон 0 - 1 В)"""
+        return struct.unpack('>ffffffffffff', self.modbus.read_holding_registers_raw(AiReg.CL_V1_K.value, 24))
+    
+
+    def get_cal_b_v1(self):
+        """Калибровочные коэффициенты B (диапазон 0 - 1 В)"""
+        return struct.unpack('>ffffffffffff', self.modbus.read_holding_registers_raw(AiReg.CL_V1_B.value, 24))
+
+
+    def get_cal_k_cur(self):
+        """Калибровочные коэффициенты K (измерение тока)"""
+        return struct.unpack('>ffffffffffff', self.modbus.read_holding_registers_raw(AiReg.CL_CUR_K.value, 24))
+    
+
+    def get_cal_b_cur(self):
+        """Калибровочные коэффициенты B (измерение тока)"""
+        return struct.unpack('>ffffffffffff', self.modbus.read_holding_registers_raw(AiReg.CL_CUR_B.value, 24))
 
 
     # Установка параметров
@@ -207,18 +235,73 @@ class IO_AnalogInput(IO_Module):
         'Значения состояний входов вкл./выкл. (битовое поле)'
         self.modbus.write_holding_register(AiReg.PR_STATE.value , value)
 
+
     def set_preset_min(self, channel, value):
         'Минимальное значение уставки на отдельный канал'
         self.modbus.write_float(AiReg.PR_MIN.value + 2*(channel - 1), value)
 
+
     def set_preset_max(self, channel, value):
         'Максимальное значение уставки на отдельный канал'
         self.modbus.write_float(AiReg.PR_MAX.value + 2*(channel - 1), value)
 
+
     def set_preset_hyst(self, channel, value):
         'Значение гистерезиса уставки на отдельный канал'
         self.modbus.write_float(AiReg.PR_HIST.value + 2*(channel - 1), value)
 
+
+    def set_cal_k_v10(self, val:list[float]):
+        """Калибровочные коэффициенты K (диапазон 0 - 10 В)"""
+        self.modbus.write_holding_registers_raw(AiReg.CL_V10_K.value, 
+                                                struct.pack('>ffffffffffff', 
+                                                val[0], val[1], val[2], val[3],
+                                                val[4], val[5], val[6], val[7],
+                                                val[8], val[9], val[10], val[11]))
+
+    def set_cal_b_v10(self, val:list[float]):
+        """Калибровочные коэффициенты B (диапазон 0 - 10 В)"""
+        self.modbus.write_holding_registers_raw(AiReg.CL_V10_B.value, 
+                                                struct.pack('>ffffffffffff', 
+                                                val[0], val[1], val[2], val[3],
+                                                val[4], val[5], val[6], val[7],
+                                                val[8], val[9], val[10], val[11]))
+
+
+    def set_cal_k_v1(self, val:list[float]):
+        """Калибровочные коэффициенты K (диапазон 0 - 1 В)"""
+        self.modbus.write_holding_registers_raw(AiReg.CL_V1_K.value, 
+                                                struct.pack('>ffffffffffff', 
+                                                val[0], val[1], val[2], val[3],
+                                                val[4], val[5], val[6], val[7],
+                                                val[8], val[9], val[10], val[11]))
+
+    def set_cal_b_v1(self, val:list[float]):
+        """Калибровочные коэффициенты B (диапазон 0 - 1 В)"""
+        self.modbus.write_holding_registers_raw(AiReg.CL_V1_B.value, 
+                                                struct.pack('>ffffffffffff', 
+                                                val[0], val[1], val[2], val[3],
+                                                val[4], val[5], val[6], val[7],
+                                                val[8], val[9], val[10], val[11]))
+        
+
+    def set_cal_k_cur(self, val:list[float]):
+        """Калибровочные коэффициенты K (режим измерения тока)"""
+        self.modbus.write_holding_registers_raw(AiReg.CL_CUR_K.value, 
+                                                struct.pack('>ffffffffffff', 
+                                                val[0], val[1], val[2], val[3],
+                                                val[4], val[5], val[6], val[7],
+                                                val[8], val[9], val[10], val[11]))
+
+    def set_cal_b_cur(self, val:list[float]):
+        """Калибровочные коэффициенты B (режим зимерения тока)"""
+        self.modbus.write_holding_registers_raw(AiReg.CL_CUR_B.value, 
+                                                struct.pack('>ffffffffffff', 
+                                                val[0], val[1], val[2], val[3],
+                                                val[4], val[5], val[6], val[7],
+                                                val[8], val[9], val[10], val[11]))    
+
+
     '''Настройки входов'''
     def print_inputs(self):
         print(Fore.GREEN + '____________________________________________')
@@ -254,6 +337,35 @@ class IO_AnalogInput(IO_Module):
         print('Input preset hyst: ', Fore.GREEN + f'1: {data[0]}, 2: {data[1]}, 3: {data[2]}, 4: {data[3]}, 5: {data[4]}, 6: {data[5]}')
         print('Input preset hyst: ', Fore.GREEN + f'7: {data[6]}, 8: {data[7]}, 9: {data[8]}, 10: {data[9]}, 11: {data[10]}, 12: {data[11]}')
 
+        # Калибровочный коэф-т K (диапазон 0 - 10 В)
+        data = self.get_cal_k_v10()
+        print('Factors "K" in 0-10V mode: ', Fore.GREEN + f'1: {data[0]}, 2: {data[1]}, 3: {data[2]}, 4: {data[3]}, 5: {data[4]}, 6: {data[5]}')
+        print('Factors "K" in 0-10V mode: ', Fore.GREEN + f'7: {data[6]}, 8: {data[7]}, 9: {data[8]}, 10: {data[9]}, 11: {data[10]}, 12: {data[11]}')
+
+        # Калибровочный коэф-т B (диапазон 0 - 10 В)
+        data = self.get_cal_b_v10()
+        print('Factors "B" in 0-10V mode: ', Fore.GREEN + f'1: {data[0]}, 2: {data[1]}, 3: {data[2]}, 4: {data[3]}, 5: {data[4]}, 6: {data[5]}')
+        print('Factors "B" in 0-10V mode: ', Fore.GREEN + f'7: {data[6]}, 8: {data[7]}, 9: {data[8]}, 10: {data[9]}, 11: {data[10]}, 12: {data[11]}')
+
+        # Калибровочный коэф-т K (диапазон 0 - 1 В)
+        data = self.get_cal_k_v1()
+        print('Factors "K" in 0-1V mode: ', Fore.GREEN + f'1: {data[0]}, 2: {data[1]}, 3: {data[2]}, 4: {data[3]}, 5: {data[4]}, 6: {data[5]}')
+        print('Factors "K" in 0-1V mode: ', Fore.GREEN + f'7: {data[6]}, 8: {data[7]}, 9: {data[8]}, 10: {data[9]}, 11: {data[10]}, 12: {data[11]}')
+
+        # Калибровочный коэф-т B (диапазон 0 - 1 В)
+        data = self.get_cal_b_v1()
+        print('Factors "B" in 0-1V mode: ', Fore.GREEN + f'1: {data[0]}, 2: {data[1]}, 3: {data[2]}, 4: {data[3]}, 5: {data[4]}, 6: {data[5]}')
+        print('Factors "B" in 0-1V mode: ', Fore.GREEN + f'7: {data[6]}, 8: {data[7]}, 9: {data[8]}, 10: {data[9]}, 11: {data[10]}, 12: {data[11]}')
+
+        # Калибровочный коэф-т K (режим измерения тока)
+        data = self.get_cal_k_cur()
+        print('Factors "K" in current mode: ', Fore.GREEN + f'1: {data[0]}, 2: {data[1]}, 3: {data[2]}, 4: {data[3]}, 5: {data[4]}, 6: {data[5]}')
+        print('Factors "K" in current mode: ', Fore.GREEN + f'7: {data[6]}, 8: {data[7]}, 9: {data[8]}, 10: {data[9]}, 11: {data[10]}, 12: {data[11]}')
+
+        # Калибровочный коэф-т B (режим измерения тока)
+        data = self.get_cal_b_cur()
+        print('Factors "B" in current mode: ', Fore.GREEN + f'1: {data[0]}, 2: {data[1]}, 3: {data[2]}, 4: {data[3]}, 5: {data[4]}, 6: {data[5]}')
+        print('Factors "B" in current mode: ', Fore.GREEN + f'7: {data[6]}, 8: {data[7]}, 9: {data[8]}, 10: {data[9]}, 11: {data[10]}, 12: {data[11]}')
 
         # Коэффициенты усиления
         # for i in range(1, 13):
@@ -317,11 +429,22 @@ def main():
     ai = IO_AnalogInput(modbus_tester) 
 
     '''Режим работы аналоговых входов'''
-    ai.set_inputs_state(0b1111_1111_1111)
+    # ai.set_inputs_state(0b1111_1111_1111)
     # ai.set_voltage_range(0b1111_1111_1111)
-    ai.set_voltage_range(0b0000_0000_0000)
+    # ai.set_voltage_range(0b0000_0000_0000)
     ai.print_inputs()
         
+    
+    # ai.set_cal_k_v10([1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 1.10, 1.11, 1.12])
+    # ai.set_cal_b_v10([2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 2.8, 2.9, 2.10, 2.11, 2.12])
+
+    # ai.set_cal_k_v1([3.1, 3.2, 3.3, 3.4, 3.5, 3.6, 3.7, 3.8, 3.9, 3.10, 3.11, 3.12])
+    # ai.set_cal_b_v1([4.1, 4.2, 4.3, 4.4, 4.5, 4.6, 4.7, 4.8, 4.9, 4.10, 4.11, 4.12])
+
+    # ai.set_cal_k_cur([5.1, 5.2, 5.3, 5.4, 5.5, 5.6, 5.7, 5.8, 5.9, 5.10, 5.11, 5.12])
+    # ai.set_cal_b_cur([6.1, 6.2, 6.3, 6.4, 6.5, 6.6, 6.7, 6.8, 6.9, 6.10, 6.11, 6.12])
+
+
     # ai.show_graph(ai.get_fil_inputs, 'AIN_FIL_1')
 
     '''Уставки'''
@@ -343,7 +466,7 @@ def main():
 
     '''Системное'''
     # print(ai.sys.get_uptime())
-    ai.sys.save_settings()
+    # ai.sys.save_settings()
 
     '''Установка коэффициентов усиления. Канал, коэффициент'''
     '''

+ 62 - 10
tools/calibration_analog_in.py

@@ -1,6 +1,7 @@
 from modbus import Modbus
 from analog_in import IO_AnalogInput
 from serial import Serial
+import colorama
 from colorama import Fore
 from mb_registers import *
 import inquirer
@@ -13,12 +14,22 @@ CALIBRATION_MODE = ['VOLT']
 @dataclass(frozen=True)
 class Const:
     VOLTAGE_0_10 = 0
-    VOLTAGE_1_10 = 1
+    VOLTAGE_0_1 = 1
+    CURRENT_0_20 = 2
 
     FIRST_POINT_VOLTAGE = 1.0
     SECOND_POINT_VOLTAGE = 10.0
     MIDLE_POINT_VOLTAGE = 5.0
 
+    ACCURACY_THRESHOLD = 0.17
+
+    def print_mode(mode: int):
+        if mode == Const.VOLTAGE_0_10:
+            return "измерение напряжения 0 - 10 В"
+        elif mode == Const.VOLTAGE_0_1:
+            return "измерение напряжения 0 - 1 В"
+        elif mode == Const.CURRENT_0_20:
+            return "измерение напряжения 0 - 20 мА"
 
 class Calibration_AI:
 
@@ -75,15 +86,45 @@ class Calibration_AI:
         return self.get_filtered_data(10)
 
 
-    def test_factors(self, point:float):
+    def test_voltage_factors(self, point_voltage: float, mode: int):
+        """Проверка коэффициентов в режиме измерения напряжения"""
+        result = True
+        print(f"Установите значение напряжения {point_voltage} и назмите 'Enter'") 
+        input()
+
+        data = self.get_filtered_data(10)
+        for i in range(self.CHANNEL_NUMBER):
+            # data[i] = (point - (data[i]*self.k_factors[i] + self.b_factors[i]))/10.0
+            data[i] = 10*(point_voltage - (data[i]*self.k_factors[i] + self.b_factors[i]))
+            if abs(data[i]) > Const.ACCURACY_THRESHOLD:
+                result = False
+                print(Fore.RED + f"Канал {i + 1} точность: " + str(data[i]))
+            else:
+                print(Fore.GREEN + f"Канал {i + 1} точность: " + str(data[i]))
+
+        return result
+
+
+    def test_factors(self, point:float, mode: int):
         """Проверка коэффициентов"""
-        print(f"Установите значения напряжения {point} и назмите 'Enter'")
+        result = True
+        if mode in (Const.VOLTAGE_0_10, Const.VOLTAGE_1_10):
+            print(f"Установите значение напряжения {point} и назмите 'Enter'")
+        # elif mode in (Const.CURRENT_0_20):
+        #     print(f"Установите значение тока")
+
         input()
         data = self.get_filtered_data(10)
         for i in range(self.CHANNEL_NUMBER):
-            data[i] = (point - (data[i]*self.k_factors[i] + self.b_factors[i]))/10.0
+            # data[i] = (point - (data[i]*self.k_factors[i] + self.b_factors[i]))/10.0
+            data[i] = (point - (data[i]*self.k_factors[i] + self.b_factors[i]))*10.0
+            if abs(data[i]) > Const.ACCURACY_THRESHOLD:
+                result = False
+                print(Fore.RED + f"Канал {i + 1} точность: " + str(data[i]))
+            else:
+                print(Fore.GREEN + f"Канал {i + 1} точность: " + str(data[i]))
 
-        return data
+        return result
 
 
     def calibration_mode(self, mode: int):
@@ -105,13 +146,23 @@ class Calibration_AI:
 
             self.k_factors[i] = 1.0/self.k_factors[i]
 
-            # self.k_factors[i] = 1.0/((self.second_point_data[i] - self.first_point_data[i]) / \
-            #                     (Const.SECOND_POINT_VOLTAGE - Const.FIRST_POINT_VOLTAGE))
-            # self.b_factors[i] = Const.SECOND_POINT_VOLTAGE - self.second_point_data[i]
+        # print("K - factors:")
+        # print(self.k_factors)
+        # print("B - factors:")
+        # print(self.b_factors)
 
         # Проверка коэффициентов
-        print(self.mid_point_factors)
-        print(self.test_factors(5.0))
+        # print(self.mid_point_factors)
+        
+        mode_str = Const.print_mode(mode)
+
+        if self.test_voltage_factors(5.0, mode) == False:
+            print(Fore.RED + "Ошибка калибровки! в режиме - ", mode_str)
+        else:
+            print(Fore.GREEN + "Калибровка в режиме - ", mode_str, "успешно завершена.")        
+
+
+
 
         # print("First point data")
         # print(self.first_point_data)
@@ -166,6 +217,7 @@ class Calibration_AI:
 
 
 def main():
+    colorama.init(autoreset=True)
     calibration = Calibration_AI('COM12')
     calibration.menu()
 

+ 13 - 1
tools/mb_registers.py

@@ -56,6 +56,15 @@ class AiReg(Enum):
     PR_MAX          = 0x03D2 # Верхнее значение уставок
     PR_HIST         = 0x03EA # Значение гистерезиса
 
+    CL_V10_K        = 0x1410 # Калибровочный коэф-т K (диапазон 0 - 10 В)
+    CL_V10_B        = 0x1428 # Калибровочный коэф-т B (диапазон 0 - 10 В) 
+
+    CL_V1_K         = 0x1440 # Калибровочный коэф-т K (диапазон 1 - 10 В)
+    CL_V1_B         = 0x1458 # Калибровочный коэф-т B (диапазон 1 - 10 В) 
+
+    CL_CUR_K        = 0x1470 # Калибровочный коэф-т K (измерение тока)
+    CL_CUR_B        = 0x1488 # Калибровочный коэф-т B (измерение тока)
+    
 
 
 class AoReg(Enum):
@@ -94,9 +103,12 @@ class SysReg(Enum):
     SAVE_MODE   = 0x081B # Безопасный режим работы (0-выкл, 1-вкл)
     SAVE_DELAY  = 0x081C # Время до перехода в безопасный режим
 
+
+class Command(Enum):
+
     '''Команды'''
     WDT_STOP    = 0x0014 # Отключить watchdog (программно) 
-
+    SAVE_CALIBR = 0x0015 # Сохранить калибровочные коэффициенты
 
 class Log(Enum):
 

+ 21 - 1
tools/misc.py

@@ -1,4 +1,4 @@
-
+import struct
 
 
 def string_to_reg(value: str):
@@ -14,3 +14,23 @@ def string_to_reg(value: str):
     # print(ascii_data)
     print(b)
 
+
+def print_hex(start: int, count: int, step: int):
+    """Печатает hex в определенном формате"""
+    value = start
+    for _ in range(count):
+        print('0x' + format(value, 'X'))
+        value += step
+
+
+def test_struct(lst: list[float]):
+    print(struct.pack('>ff', lst[0], lst[1]))
+
+
+def main():
+    # print_hex(0x1488, 12, 2)
+    test_struct([1.2, 1.3])
+
+
+if __name__ == '__main__':
+    main()

+ 5 - 2
tools/sys_params.py

@@ -1,5 +1,5 @@
 from modbus import Modbus
-from mb_registers import SysReg
+from mb_registers import SysReg, Command
 from colorama import Fore
 import time
 import random
@@ -107,6 +107,9 @@ class IO_SysParams:
     def save_settings(self):
         self.modbus.write_holding_register(SysReg.COMMAND.value, self.SAVE_SETTIGNS)
 
+    def save_cilibration_factors(self):
+        self.modbus.write_holding_register(SysReg.COMMAND.value, Command.value)
+
     def get_uptime(self):
         return self.modbus.read_uint32_holding(SysReg.UPTIME.value)
 
@@ -151,7 +154,7 @@ class IO_SysParams:
 
     def wdt_stop(self):
         """Программно отключает watchdog"""
-        self.modbus.write_holding_register(SysReg.COMMAND.value, SysReg.WDT_STOP.value)
+        self.modbus.write_holding_register(SysReg.COMMAND.value, Command.WDT_STOP.value)
 
 
 # def set_manager_register(dev: IO_Module, commands: list):

Неке датотеке нису приказане због велике количине промена