Kaynağa Gözat

Дополнительные параметры для Ai в modbus.

TelenkovDmitry 5 ay önce
ebeveyn
işleme
26c0d6a9b2

+ 2 - 1
fw/modules/io/analog_input.c

@@ -31,7 +31,8 @@ uint16_t ai_alarm;  // слово аварий входов
 
 uint16_t ai_gain[AI_COMMON_NUMBER]; // массив коэффициентов усиленя (modbus)
 
-uint16_t adc_com_raw_data[AI_COMMON_NUMBER];
+uint16_t adc_com_raw_data[AI_COMMON_NUMBER]; // сырые данные
+float adc_com_data[AI_COMMON_NUMBER];   // пересчитанные, фильтрованные данные
 
 uint16_t adc_com_fil_data[AI_COMMON_NUMBER];
 

+ 5 - 1
fw/modules/io/analog_input.h

@@ -8,8 +8,10 @@ typedef struct
 {
     uint8_t state;          // 0 - выкл, 1 - вкл
     uint8_t mode;           // режим измерения (0 - напряжение, 1 - ток)
+    uint8_t name;           // 
     uint8_t gain_factor;    // коэффициент усиления
-    uint8_t name;
+    float k_factor;         // 
+    float b_factor;         //
 } ai_t;
 
 
@@ -111,6 +113,8 @@ extern uint16_t ai_gain[];
 
 extern uint16_t adc_com_raw_data[];
 
+extern float adc_com_data[];
+
 extern uint16_t adc_com_fil_data[];
 
 extern uint16_t adc_add_raw_data[];

+ 52 - 4
fw/modules/modbus/modbus_ai_params.c

@@ -35,7 +35,7 @@ uint16_t mb_init_ai_params(uint16_t i)
     
     index++;
 
-    // Флаги аварий аналоговых входов
+    // Флаги аварий аналоговых входов. Определяется аппаратно.
     mb_param[index].reg = 0x0302;
 	mb_param[index].size = 1;
 	mb_param[index].param = (uint8_t*)&ai_alarm;
@@ -71,9 +71,41 @@ uint16_t mb_init_ai_params(uint16_t i)
     }
     
     // ---------------------------------------------------------------------- //
-    // Сырые данные каналов ADC
+    // Коэффициенты K
     addr = 0x0320;
     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.ai[i].k_factor;
+        mb_param[index].set = NULL;
+        mb_param[index].get = NULL;
+        mb_param[index].check_handler = mb_check_dummy;
+        
+        addr += 2;
+        index++;
+    }
+    
+    // ---------------------------------------------------------------------- //
+    // Коэффициенты B
+    addr = 0x0340;
+    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.ai[i].b_factor;
+        mb_param[index].set = NULL;
+        mb_param[index].get = NULL;
+        mb_param[index].check_handler = mb_check_dummy;
+        
+        addr += 2;
+        index++;
+    }
+        
+    // ---------------------------------------------------------------------- //
+    // Сырые данные каналов ADC
+    addr = 0x0360;
+    for (int i = 0; i < AI_COMMON_NUMBER; i++)
     {
         mb_param[index].reg = addr + i;
         mb_param[index].size = 1;
@@ -85,7 +117,7 @@ uint16_t mb_init_ai_params(uint16_t i)
         index++;
     }
     
-    addr = 0x032C;
+    addr = 0x036C;
     // V_ISO_CL, V_ISO, CRNT_LIM_U_BFR_R, CRNT_LIM_U_ABFR_R
     for (int i = 0; i < AI_ADD_NUMBER; i++)
     {
@@ -99,9 +131,25 @@ uint16_t mb_init_ai_params(uint16_t i)
         index++;
     }
 
+    // ---------------------------------------------------------------------- //
+    // Фильтрованные данные с учетом коэф-ов К, B
+    addr = 0x0380;
+    for (int i = 0; i < AI_COMMON_NUMBER; i++)
+    {
+        mb_param[index].reg = addr;
+        mb_param[index].size = 1;
+        mb_param[index].param = (uint8_t*)&adc_com_data[i];
+        mb_param[index].set = NULL;
+        mb_param[index].get = NULL;
+        mb_param[index].check_handler = mb_check_dummy;
+        
+        addr += 2;
+        index++;
+    }
+    
     // ---------------------------------------------------------------------- //
     // Фильтрованные значения 12-и основных каналов
-    addr = 0x0330;
+    addr = 0x03A0;
     for (int i = 0; i < AI_COMMON_NUMBER; i++)
     {
         mb_param[index].reg = addr + i;

+ 2 - 2
fw/modules/modbus/modbus_dio_params.c

@@ -195,7 +195,7 @@ uint16_t mb_init_dio_params(uint16_t i)
     {
         mb_param[index].reg = addr;
         mb_param[index].size = 1;
-        mb_param[index].param = (uint8_t*)&output_pwm_period[i];  // Счетчик ипульсов
+        mb_param[index].param = (uint8_t*)&output_pwm_period[i];
         mb_param[index].set = mb_set_do;
         mb_param[index].get = NULL;
         mb_param[index].check_handler = mb_check_dummy;
@@ -204,7 +204,7 @@ uint16_t mb_init_dio_params(uint16_t i)
         index++;
     }
     
-    // Период PWM. Регистры 0x0220 - 0x0227
+    // Период PWM в безопасном режиме. Регистры 0x0220 - 0x0227
     addr = 0x0240;
     for (int i = 0; i < DO_NUMBER; i++)
     {

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

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

+ 74 - 72
fw/modules/settings/settings_ai.c

@@ -1,73 +1,75 @@
-#include "at32f403a_407.h" 
-#include "settings_api.h"
-#include "settings_ai.h"
-#include "analog_input.h"
-
-#if defined (MAI_12)
-
-//
-void settings_ai_set_all_default(void)
-{
-    // Аналоговые входы
-    settings_ai_def(&settings);
-    
-    // Питание внешних датчиков
-    settings_ext_sens_power_def(&settings);
-}
-
-//
-void settings_ai_def(settings_t *settings)
-{
-    // Все входы выключены
-    settings->ai_state_bits = 0;
-    
-    // Режим измерения напряжения
-    settings->ai_mode_bits = 0;
-    
-    // Основные 12 каналов
-    for (int i = 0; i < AI_COMMON_NUMBER; i++) 
-    {  
-        settings->ai[i].state = 0;  // вход выключен
-        settings->ai[i].mode = 0;   // режим измерения напряжения
-        settings->ai[i].gain_factor = 1;    // коэф-т усиления внешнего ADC
-    }
-    
-    settings->ai[0].name = AN_INP_1;
-    settings->ai[1].name = AN_INP_2;
-    settings->ai[2].name = AN_INP_3;
-    settings->ai[3].name = AN_INP_4;
-    settings->ai[4].name = AN_INP_5;
-    settings->ai[5].name = AN_INP_6;
-    settings->ai[6].name = AN_INP_7;
-    settings->ai[7].name = AN_INP_8;
-    settings->ai[8].name = AN_INP_9;
-    settings->ai[9].name = AN_INP_10;
-    settings->ai[10].name = AN_INP_11;
-    settings->ai[11].name = AN_INP_12;
-
-    // Дополнительные 4 канала. Измерения происходят всегда.
-    for (int i = 0; i < AI_ADD_NUMBER; i++) 
-    {  
-        settings->ai_add[i].state = 1;  // вход включен
-        settings->ai_add[i].mode = 0;   // режим измерения напряжения
-        settings->ai_add[i].gain_factor = 1; // коэф-т усиления внешнего ADC
-    }
-    
-    settings->ai_add[0].name = V_ISO_CL;
-    settings->ai_add[1].name = V_ISO;
-    settings->ai_add[2].name = CRNT_LIM_U_BFR_R;
-    settings->ai_add[3].name = CRNT_LIM_U_ABFR_R;
-    
-    // Время ведения архива по каждому каналу (сек.)
-    for (uint8_t i = 0; i < ARCH_AI_CH_NUMBER; i++) {
-        settings->period_archive[i] = 3600;
-    }
-}
-
-//
-void settings_ext_sens_power_def(settings_t *settings)
-{
-    settings->ext_sens_power = 0;
-}
-
+#include "at32f403a_407.h" 
+#include "settings_api.h"
+#include "settings_ai.h"
+#include "analog_input.h"
+
+#if defined (MAI_12)
+
+//
+void settings_ai_set_all_default(void)
+{
+    // Аналоговые входы
+    settings_ai_def(&settings);
+    
+    // Питание внешних датчиков
+    settings_ext_sens_power_def(&settings);
+}
+
+//
+void settings_ai_def(settings_t *settings)
+{
+    // Все входы выключены
+    settings->ai_state_bits = 0;
+    
+    // Режим измерения напряжения
+    settings->ai_mode_bits = 0;
+    
+    // Основные 12 каналов
+    for (int i = 0; i < AI_COMMON_NUMBER; i++) 
+    {  
+        settings->ai[i].state = 0;  // вход выключен
+        settings->ai[i].mode = 0;   // режим измерения напряжения
+        settings->ai[i].gain_factor = 1;    // коэф-т усиления внешнего ADC
+        settings->ai[i].k_factor = i + 1.1;
+        settings->ai[i].b_factor = i + 10.1;
+    }
+    
+    settings->ai[0].name = AN_INP_1;
+    settings->ai[1].name = AN_INP_2;
+    settings->ai[2].name = AN_INP_3;
+    settings->ai[3].name = AN_INP_4;
+    settings->ai[4].name = AN_INP_5;
+    settings->ai[5].name = AN_INP_6;
+    settings->ai[6].name = AN_INP_7;
+    settings->ai[7].name = AN_INP_8;
+    settings->ai[8].name = AN_INP_9;
+    settings->ai[9].name = AN_INP_10;
+    settings->ai[10].name = AN_INP_11;
+    settings->ai[11].name = AN_INP_12;
+
+    // Дополнительные 4 канала. Измерения происходят всегда.
+    for (int i = 0; i < AI_ADD_NUMBER; i++) 
+    {  
+        settings->ai_add[i].state = 1;  // вход включен
+        settings->ai_add[i].mode = 0;   // режим измерения напряжения
+        settings->ai_add[i].gain_factor = 1; // коэф-т усиления внешнего ADC
+    }
+    
+    settings->ai_add[0].name = V_ISO_CL;
+    settings->ai_add[1].name = V_ISO;
+    settings->ai_add[2].name = CRNT_LIM_U_BFR_R;
+    settings->ai_add[3].name = CRNT_LIM_U_ABFR_R;
+    
+    // Время ведения архива по каждому каналу (сек.)
+    for (uint8_t i = 0; i < ARCH_AI_CH_NUMBER; i++) {
+        settings->period_archive[i] = 3600;
+    }
+}
+
+//
+void settings_ext_sens_power_def(settings_t *settings)
+{
+    settings->ext_sens_power = 0;
+}
+
 #endif

BIN
output/fw.bin


Dosya farkı çok büyük olduğundan ihmal edildi
+ 408 - 408
project/ewarm/iap/iap.dep


Dosya farkı çok büyük olduğundan ihmal edildi
+ 674 - 674
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>

BIN
tools/__pycache__/mb_registers.cpython-312.pyc


BIN
tools/__pycache__/modbus.cpython-312.pyc


+ 80 - 24
tools/analog_in.py

@@ -5,7 +5,7 @@ import colorama
 from colorama import Fore
 from time import sleep
 from serial import Serial
-from mb_registers import AI_REGS
+from mb_registers import AI_REGS, AiReg
 import matplotlib.pyplot as plt 
 import matplotlib.animation as animation 
 
@@ -37,51 +37,97 @@ class IO_AnalogInput(IO_Module):
         self.graph_input = ai_name['AIN_1']
         self.graph_input_func = 0
 
+    # Чтение параметров
 
-
-    '''Чтение параметров'''
-
-    # Значения состояний входов вкл./выкл. (битовое поле)
     def get_inputs_state(self):
-        data = self.modbus.read_holding_registers(AI_REGS['ain_state'], 1)
+        'Значения состояний входов вкл./выкл. (битовое поле)'
+        data = self.modbus.read_holding_registers(AiReg.IN_STATE.value, 1)
         return format(data[0], '012b')
 
-    # Режим измерения входов (0 - напряжение или 1 - ток. (битовое поле))
+
     def get_inputs_mode(self):
-        data = self.modbus.read_holding_registers(AI_REGS['ain_mode'], 1)
+        'Режим измерения входов (0 - напряжение или 1 - ток. (битовое поле))'
+        data = self.modbus.read_holding_registers(AiReg.IN_MODE.value , 1)
         return format(data[0], '012b')
 
-    def get_input_gain(self, input):
-        data = self.modbus.read_holding_registers(AI_REGS['ain_gain'] + input - 1, 1)
-        return data[0]
-
+    
     def get_inputs_alarm(self):
-        data = self.modbus.read_holding_registers(AI_REGS['ain_alarm'], 1)
+        'Аварии аналоговых входов (битовое поле)'
+        data = self.modbus.read_holding_registers(AiReg.IN_FAILURE.value, 1)
         return format(data[0], '012b')
 
+
+    def get_ext_sens_power(self):
+        'Состояние питания внешних датчиков (вкл./выкл.)'
+        data = self.modbus.read_holding_registers(AiReg.EXT_SENS_POWER.value, 1)
+
+
+    def get_input_gain(self, channel):
+        'Коэффициент усиления канала [1..12] (внутренний коэф-т ADC)'
+        data = self.modbus.read_holding_registers(AiReg.IN_GAINE_FACTOR.value + channel - 1, 1)
+        return data[0]
+
+
+    def get_k_factor(self, channel):
+        'Коэффициент пересчета K канала [1..12]'
+        return self.modbus.read_float_holding(AiReg.IN_K_FACTOR.value + 2*(channel - 1))
+        
+
+    def get_b_factor(self, channel):
+        'Коэффициент пересчета B канала [1..12]'
+        return self.modbus.read_float_holding(AiReg.IN_B_FACTOR.value + 2*(channel - 1))
+
+
+    def get_raw_input(self, channel):
+        'Сырые данные по отдельному каналу [1..12]'
+        return self.modbus.read_holding_registers(AiReg.IN_RAW.value + channel - 1, 1)[0]
+
+
+
     def get_raw_inputs(self):
-        data = self.modbus.read_holding_registers(AI_REGS['ain_raw'], 16)
+        data = self.modbus.read_holding_registers(AiReg.IN_RAW, 16)
         return data
 
     def get_fil_inputs(self):
         data = self.modbus.read_holding_registers(AI_REGS['ain_fil'], 12)
         return data
 
-    '''Установка параметров'''
+    # Установка параметров
 
     def set_inputs_state(self, val):
-        self.modbus.write_holding_register(AI_REGS['ain_state'], val)
+        'Значения состояний входов вкл./выкл. (битовое поле)'
+        self.modbus.write_holding_register(AiReg.IN_STATE.value , val)
+
 
     def set_inputs_mode(self, val):
-        self.modbus.write_holding_register(AI_REGS['ain_mode'], val)
+        'Режим измерения входов (0 - напряжение или 1 - ток. (битовое поле))'
+        self.modbus.write_holding_register(AiReg.IN_STATE.value, val)
 
-    def set_input_gain(self, input, value):
-        # if value not in (1, 2, 4, 8, 16, 32, 64, 128):
-        #     return None
-        self.modbus.write_holding_register(AI_REGS['ain_gain'] + input - 1, value)
 
     def set_ext_sens_power(self, val):
-        self.modbus.write_holding_register(AI_REGS['esens_pow'], val)
+        'Состояние питания внешних датчиков (вкл./выкл.)'
+        self.modbus.write_holding_register(AiReg.EXT_SENS_POWER.value , val)
+
+
+    def set_input_gain(self, input, value):
+        '''
+        Коэффициент усиления канала [1..12] (внутренний коэф-т ADC)
+        Допустимые значения: 1, 2, 4, 8, 16, 32, 64, 128
+        '''
+        if value not in (1, 2, 4, 8, 16, 32, 64, 128):
+            return None
+        self.modbus.write_holding_register(AiReg.IN_GAINE_FACTOR.value + input - 1, value)
+
+
+    def set_k_factor(self, channel, value):
+        'Коэффициент пересчета K канала [1..12]'
+        self.modbus.write_float(AiReg.IN_K_FACTOR.value + 2*(channel - 1), value)
+
+
+    def set_b_factor(self, channel, value):
+        'Коэффициент пересчета K канала [1..12]'
+        self.modbus.write_float(AiReg.IN_B_FACTOR.value + 2*(channel - 1), value)
+
 
     '''Настройки входов'''
     def print_inputs(self):
@@ -187,8 +233,13 @@ def main():
             sleep(1)
     '''
 
-    # ai.sys.get_system_vars()     
+    '''Коэффициенты K и B'''
+    # for i in range(1, 13):
+    #     ai.set_k_factor(i, i + 100)
+    #     ai.set_b_factor(i, i + 1000)
 
+
+    # ai.sys.get_system_vars()     
     
     # print(ai.get_inputs_state())
     # ai.set_inputs_state(0b1111_1111_1111)
@@ -220,6 +271,11 @@ def main():
     # ai.get_raw_inputs()
     # ai.print_raw_inputs()
 
+    '''Сырые данные'''
+    while True:
+        print(ai.get_raw_input(12))
+        sleep(1)
+
     '''Вывод на график. Сырые данные'''
     # ai.show_graph(ai.get_raw_inputs,  'AIN_7')
 
@@ -230,7 +286,7 @@ def main():
     # ai.sys.get_system_vars()
 
     '''Сохранение настроек'''
-    ai.sys.save_sattings()
+    # ai.sys.save_sattings()
 
     '''Обновление прошивки'''
     # serial_port.timeout = 1

+ 1 - 1
tools/digital_io.py

@@ -254,7 +254,7 @@ def main():
 
     '''Системные переменные и параметры'''
     # dio.sys.get_system_vars()
-    # print(dio.sys.get_bat_votage())
+    print(dio.sys.get_bat_votage())
 
     ''' Установить текущее время с учетом часового пояса'''
     # dev.sys.set_rtc()     

+ 15 - 2
tools/mb_registers.py

@@ -7,8 +7,7 @@ reg_table = {'out_cur': 0x0200, 'out_mode': 0x0202, 'out_mode_save': 0x0203, 'pw
 
 DIO_REGS = {'load_bits': 0x0130, 'cred_bits': 0x0131, 'out_cur': 0x0200}
 
-AI_REGS = {'ain_state': 0x0300, 'ain_mode': 0x0301, 'ain_alarm': 0x0302, 'esens_pow': 0x0303, 
-           'ain_gain': 0x0310, 'ain_raw': 0x0320, 'ain_fil': 0x0330}
+AI_REGS = {}
 
 LOG_REGS = {'log_info': 0x0900, 'log_ent': 0x0901, 'arch_cap': 0x0902, 'arch_ent': 0x0903, 'arch_per': 0x0904}
 
@@ -26,6 +25,20 @@ class DioReg(Enum):
     OUT_BITS        = 0x0201 # Текущее состояние выходов    
 
 
+class AiReg(Enum):
+
+    IN_STATE        = 0x0300 # Состояние входов (вкл./выкл.)
+    IN_MODE         = 0x0301 # Режим работы входов (битовое поле)
+    IN_FAILURE      = 0x0302 # Аварии аналоговых входов (битовое поле)
+
+    EXT_SENS_POWER  = 0x0303 # Питание внешних датчиков
+
+    IN_GAINE_FACTOR = 0x0310 # Коэффициент усиления канала
+    IN_K_FACTOR     = 0x0320 # Коэффициент пересчета K
+    IN_B_FACTOR     = 0x0340 # Коэффициент пересчета B
+    IN_RAW          = 0x0360 # Канал AN_INP_1 (сырые данные)
+
+
 class AoReg(Enum):
 
     OUT_STATE       = 0x0400 # статус выходов

+ 18 - 14
tools/modbus.py

@@ -158,6 +158,20 @@ class Modbus(ModbusMixin):
         """Read float integer from two holding registers"""
         return struct.unpack('>f', self.read_holding_registers_raw(address, 2))[0]
 
+    # 0x14
+    def read_file_record(self, rec_type: int, channel_number: int, rec_index: int, rec_num: int):
+        """Read file record
+        rec_type - код записи, 0x06 - архив, 0x07 - журнал
+        channel_number - номер канала архива (0 если это журнал)
+        rec_index - порядковый номер (индекс) записи
+        rec_num - количество записей
+        """
+        request = bytearray((self.address,  0x14, 7, rec_type))
+        request += rec_index.to_bytes(2, 'big')
+        request += channel_number.to_bytes(2, 'big')
+        request += rec_num.to_bytes(2, 'big')
+        return self.raw_communicate(request + self._crc(request))
+
     # 0x10
     def write_holding_registers_raw(self, address:int, values: bytes):
         """Write 16-bit integers to holding registers on device"""
@@ -177,20 +191,6 @@ class Modbus(ModbusMixin):
         if request != response:
             raise MBError('Incorrect response payload')
 
-    # 0x14
-    def read_file_record(self, rec_type: int, channel_number: int, rec_index: int, rec_num: int):
-        """Read file record
-        rec_type - код записи, 0x06 - архив, 0x07 - журнал
-        channel_number - номер канала архива (0 если это журнал)
-        rec_index - порядковый номер (индекс) записи
-        rec_num - количество записей
-        """
-        request = bytearray((self.address,  0x14, 7, rec_type))
-        request += rec_index.to_bytes(2, 'big')
-        request += channel_number.to_bytes(2, 'big')
-        request += rec_num.to_bytes(2, 'big')
-        return self.raw_communicate(request + self._crc(request))
-
     def write_uint32(self, address: int, value: int):
         """Write 32-bit integer to holding register"""
         self.write_holding_registers_raw(address, struct.pack('>I', value))
@@ -199,6 +199,10 @@ class Modbus(ModbusMixin):
         """Write 64-bit integer to holding register"""
         self.write_holding_registers_raw(address, struct.pack('>Q', value))
 
+    def write_float(self, address: int, value: float):
+        """Write float to two holding registers"""
+        self.write_holding_registers_raw(address, struct.pack('>f', value))
+
     def test_send(self, data: bytes):
         while True:
             self.serial.write(data)

Bu fark içinde çok fazla dosya değişikliği olduğu için bazı dosyalar gösterilmiyor