| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226 | from modbus import Modbusfrom analog_in import IO_AnalogInputfrom serial import Serialimport coloramafrom colorama import Forefrom mb_registers import *import inquirerfrom dataclasses import dataclassimport timeCALIBRATION_MODE = ['VOLT']@dataclass(frozen=True)class Const:    VOLTAGE_0_10 = 0    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:    CHANNEL_NUMBER = 12    def __init__(self, mb_port):        serial_port = Serial(mb_port, 115200, timeout=0.05, parity='N', xonxoff=False)        self.modbus = Modbus(serial_port, 1)        self.dut = IO_AnalogInput(self.modbus)        self.mid_point_factors = [0]*self.CHANNEL_NUMBER        self.first_point_data = [0]*self.CHANNEL_NUMBER        self.second_point_data = [0]*self.CHANNEL_NUMBER        self.k_factors = [0]*self.CHANNEL_NUMBER        self.b_factors = [0]*self.CHANNEL_NUMBER    def voltage_0_10(self):        print("Калибровка напряжения в режиме 0-10 В")        self.setup_module(Const.VOLTAGE_0_10)    def get_filtered_data(self, sample_count: int):        raw_data = []        for i in range(sample_count):            raw = self.dut.get_fil_inputs()            raw_data.append(raw)            time.sleep(0.5)        tmp_data = [0]*self.CHANNEL_NUMBER        for j in range(self.CHANNEL_NUMBER):            for i in range(sample_count):                tmp_data[j] += raw_data[i][j]/sample_count        return tmp_data    def middle_point(self, point: float):        """Расчет коэффициента средней точки"""        print(f"Установите значение напряжения {point} и нажмите 'Enter'")        input()        raw_data = self.get_filtered_data(10)        print(raw_data)        for i in range(self.CHANNEL_NUMBER):            self.mid_point_factors[i] = (point - raw_data[i])/10.0    def point(self, point: float):        """Расчет коэффициентов для точки"""        print(f"Установите значения напряжения {point} и назмите 'Enter'")        input()        return self.get_filtered_data(10)    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):        """Проверка коэффициентов"""        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            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 calibration_mode(self, mode: int):        # Настройка входов        self.setup_module(mode)        # Средняя точка 5 В        self.middle_point(Const.MIDLE_POINT_VOLTAGE)        # Первая точка 1 В        self.first_point_data = self.point(Const.FIRST_POINT_VOLTAGE)        # Вторая точка 10 В        self.second_point_data = self.point(Const.SECOND_POINT_VOLTAGE)        # Расчет коэффициентов уравнения прямой        for i in range(self.CHANNEL_NUMBER):            self.k_factors[i] = ((self.second_point_data[i] - self.first_point_data[i]) / \                                (Const.SECOND_POINT_VOLTAGE - Const.FIRST_POINT_VOLTAGE))            self.b_factors[i] = self.second_point_data[i] - self.k_factors[i]*Const.SECOND_POINT_VOLTAGE            self.k_factors[i] = 1.0/self.k_factors[i]        # print("K - factors:")        # print(self.k_factors)        # print("B - factors:")        # print(self.b_factors)        # Проверка коэффициентов        # 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)        # print("Secon point data")        # print(self.second_point_data)        # print("k, b factors")        # print(self.k_factors)        # print(self.b_factors)            def setup_module(self, channel_mode: int):        """Настройка измеретельных каналов модуля в нужном режиме"""        # Настройка каналов в режиме измерения напряжения 0 - 10 В        if channel_mode == Const.VOLTAGE_0_10:            print("Настройка модуля в режиме измерения напряжения 0 - 10 В...", end='')            self.dut.set_inputs_state(0b1111_1111_1111)            self.dut.set_inputs_mode(0b0000_0000_0000)            self.dut.set_voltage_range(0b0000_0000_0000)            for i in range(1, 13):                self.dut.set_k_factor(i, 1.0)                self.dut.set_b_factor(i, 0.0)            # self.dut.sys.save_settings()            # self.dut.print_inputs()            print('OK')    def menu(self):        menu_items = [        inquirer.List('action',                message="Калибровка MAI_12",                choices=['Калибровка напряжения 0-10 В',                         'Завершить'],            ),        ]        while True:            answers = inquirer.prompt(menu_items)            if answers['action'] == 'Калибровка напряжения 0-10 В':                self.calibration_mode(Const.VOLTAGE_0_10)            elif answers['action'] == 'Завершить':                returndef main():    colorama.init(autoreset=True)    calibration = Calibration_AI('COM12')    calibration.menu()if __name__ == '__main__':    main()
 |