| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226 |
- 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
- from dataclasses import dataclass
- import time
- CALIBRATION_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'] == 'Завершить':
- return
- def main():
- colorama.init(autoreset=True)
- calibration = Calibration_AI('COM12')
- calibration.menu()
- if __name__ == '__main__':
- main()
|