calibration_analog_in.py 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. from modbus import Modbus
  2. from analog_in import IO_AnalogInput
  3. from serial import Serial
  4. import colorama
  5. from colorama import Fore
  6. from mb_registers import *
  7. import inquirer
  8. from dataclasses import dataclass
  9. import time
  10. CALIBRATION_MODE = ['VOLT']
  11. @dataclass(frozen=True)
  12. class Const:
  13. VOLTAGE_0_10 = 0
  14. VOLTAGE_0_1 = 1
  15. CURRENT_0_20 = 2
  16. FIRST_POINT_VOLTAGE = 1.0
  17. SECOND_POINT_VOLTAGE = 10.0
  18. MIDLE_POINT_VOLTAGE = 5.0
  19. ACCURACY_THRESHOLD = 0.17
  20. def print_mode(mode: int):
  21. if mode == Const.VOLTAGE_0_10:
  22. return "измерение напряжения 0 - 10 В"
  23. elif mode == Const.VOLTAGE_0_1:
  24. return "измерение напряжения 0 - 1 В"
  25. elif mode == Const.CURRENT_0_20:
  26. return "измерение напряжения 0 - 20 мА"
  27. class Calibration_AI:
  28. CHANNEL_NUMBER = 12
  29. def __init__(self, mb_port):
  30. serial_port = Serial(mb_port, 115200, timeout=0.05, parity='N', xonxoff=False)
  31. self.modbus = Modbus(serial_port, 1)
  32. self.dut = IO_AnalogInput(self.modbus)
  33. self.mid_point_factors = [0]*self.CHANNEL_NUMBER
  34. self.first_point_data = [0]*self.CHANNEL_NUMBER
  35. self.second_point_data = [0]*self.CHANNEL_NUMBER
  36. self.k_factors = [0]*self.CHANNEL_NUMBER
  37. self.b_factors = [0]*self.CHANNEL_NUMBER
  38. def voltage_0_10(self):
  39. print("Калибровка напряжения в режиме 0-10 В")
  40. self.setup_module(Const.VOLTAGE_0_10)
  41. def get_filtered_data(self, sample_count: int):
  42. raw_data = []
  43. for i in range(sample_count):
  44. raw = self.dut.get_fil_inputs()
  45. raw_data.append(raw)
  46. time.sleep(0.5)
  47. tmp_data = [0]*self.CHANNEL_NUMBER
  48. for j in range(self.CHANNEL_NUMBER):
  49. for i in range(sample_count):
  50. tmp_data[j] += raw_data[i][j]/sample_count
  51. return tmp_data
  52. def middle_point(self, point: float):
  53. """Расчет коэффициента средней точки"""
  54. print(f"Установите значение напряжения {point} и нажмите 'Enter'")
  55. input()
  56. raw_data = self.get_filtered_data(10)
  57. print(raw_data)
  58. for i in range(self.CHANNEL_NUMBER):
  59. self.mid_point_factors[i] = (point - raw_data[i])/10.0
  60. def point(self, point: float):
  61. """Расчет коэффициентов для точки"""
  62. print(f"Установите значения напряжения {point} и назмите 'Enter'")
  63. input()
  64. return self.get_filtered_data(10)
  65. def test_voltage_factors(self, point_voltage: float, mode: int):
  66. """Проверка коэффициентов в режиме измерения напряжения"""
  67. result = True
  68. print(f"Установите значение напряжения {point_voltage} и назмите 'Enter'")
  69. input()
  70. data = self.get_filtered_data(10)
  71. for i in range(self.CHANNEL_NUMBER):
  72. # data[i] = (point - (data[i]*self.k_factors[i] + self.b_factors[i]))/10.0
  73. data[i] = 10*(point_voltage - (data[i]*self.k_factors[i] + self.b_factors[i]))
  74. if abs(data[i]) > Const.ACCURACY_THRESHOLD:
  75. result = False
  76. print(Fore.RED + f"Канал {i + 1} точность: " + str(data[i]))
  77. else:
  78. print(Fore.GREEN + f"Канал {i + 1} точность: " + str(data[i]))
  79. return result
  80. def test_factors(self, point:float, mode: int):
  81. """Проверка коэффициентов"""
  82. result = True
  83. if mode in (Const.VOLTAGE_0_10, Const.VOLTAGE_1_10):
  84. print(f"Установите значение напряжения {point} и назмите 'Enter'")
  85. # elif mode in (Const.CURRENT_0_20):
  86. # print(f"Установите значение тока")
  87. input()
  88. data = self.get_filtered_data(10)
  89. for i in range(self.CHANNEL_NUMBER):
  90. # data[i] = (point - (data[i]*self.k_factors[i] + self.b_factors[i]))/10.0
  91. data[i] = (point - (data[i]*self.k_factors[i] + self.b_factors[i]))*10.0
  92. if abs(data[i]) > Const.ACCURACY_THRESHOLD:
  93. result = False
  94. print(Fore.RED + f"Канал {i + 1} точность: " + str(data[i]))
  95. else:
  96. print(Fore.GREEN + f"Канал {i + 1} точность: " + str(data[i]))
  97. return result
  98. def calibration_mode(self, mode: int):
  99. # Настройка входов
  100. self.setup_module(mode)
  101. # Средняя точка 5 В
  102. self.middle_point(Const.MIDLE_POINT_VOLTAGE)
  103. # Первая точка 1 В
  104. self.first_point_data = self.point(Const.FIRST_POINT_VOLTAGE)
  105. # Вторая точка 10 В
  106. self.second_point_data = self.point(Const.SECOND_POINT_VOLTAGE)
  107. # Расчет коэффициентов уравнения прямой
  108. for i in range(self.CHANNEL_NUMBER):
  109. self.k_factors[i] = ((self.second_point_data[i] - self.first_point_data[i]) / \
  110. (Const.SECOND_POINT_VOLTAGE - Const.FIRST_POINT_VOLTAGE))
  111. self.b_factors[i] = self.second_point_data[i] - self.k_factors[i]*Const.SECOND_POINT_VOLTAGE
  112. self.k_factors[i] = 1.0/self.k_factors[i]
  113. # print("K - factors:")
  114. # print(self.k_factors)
  115. # print("B - factors:")
  116. # print(self.b_factors)
  117. # Проверка коэффициентов
  118. # print(self.mid_point_factors)
  119. mode_str = Const.print_mode(mode)
  120. if self.test_voltage_factors(5.0, mode) == False:
  121. print(Fore.RED + "Ошибка калибровки! в режиме - ", mode_str)
  122. else:
  123. print(Fore.GREEN + "Калибровка в режиме - ", mode_str, "успешно завершена.")
  124. # print("First point data")
  125. # print(self.first_point_data)
  126. # print("Secon point data")
  127. # print(self.second_point_data)
  128. # print("k, b factors")
  129. # print(self.k_factors)
  130. # print(self.b_factors)
  131. def setup_module(self, channel_mode: int):
  132. """Настройка измеретельных каналов модуля в нужном режиме"""
  133. # Настройка каналов в режиме измерения напряжения 0 - 10 В
  134. if channel_mode == Const.VOLTAGE_0_10:
  135. print("Настройка модуля в режиме измерения напряжения 0 - 10 В...", end='')
  136. self.dut.set_inputs_state(0b1111_1111_1111)
  137. self.dut.set_inputs_mode(0b0000_0000_0000)
  138. self.dut.set_voltage_range(0b0000_0000_0000)
  139. for i in range(1, 13):
  140. self.dut.set_k_factor(i, 1.0)
  141. self.dut.set_b_factor(i, 0.0)
  142. # self.dut.sys.save_settings()
  143. # self.dut.print_inputs()
  144. print('OK')
  145. def menu(self):
  146. menu_items = [
  147. inquirer.List('action',
  148. message="Калибровка MAI_12",
  149. choices=['Калибровка напряжения 0-10 В',
  150. 'Завершить'],
  151. ),
  152. ]
  153. while True:
  154. answers = inquirer.prompt(menu_items)
  155. if answers['action'] == 'Калибровка напряжения 0-10 В':
  156. self.calibration_mode(Const.VOLTAGE_0_10)
  157. elif answers['action'] == 'Завершить':
  158. return
  159. def main():
  160. colorama.init(autoreset=True)
  161. calibration = Calibration_AI('COM12')
  162. calibration.menu()
  163. if __name__ == '__main__':
  164. main()