analog_in.py 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  1. from io_module import IO_Module
  2. from modbus import Modbus
  3. from log_reader import AnalogInputLogReader
  4. import colorama
  5. from colorama import Fore
  6. from time import sleep
  7. from serial import Serial
  8. import matplotlib.pyplot as plt
  9. import matplotlib.animation as animation
  10. from mb_registers import SysReg, AiReg
  11. ai_name = {'AIN_1': 0, 'AIN_2': 1, 'AIN_3': 2, 'AIN_4': 3, 'AIN_5': 4,
  12. 'AIN_6': 5, 'AIN_7': 6, 'AIN_8': 7, 'AIN_9': 8, 'AIN_10': 9,
  13. 'AIN_11': 10, 'AIN_12': 11, 'V_ISO_CL': 12, 'V_ISO': 13,
  14. 'CRNT_LIM_U_BFR_R': 14, 'CRNT_LIM_U_ABFR_R': 15,
  15. 'AIN_FIL_1': 0, 'AIN_FIL_2': 1, 'AIN_FIL_3': 2, 'AIN_FIL_4': 3,
  16. 'AIN_FIL_5': 4, 'AIN_FIL_6': 5, 'AIN_FIL_7': 6, 'AIN_FIL_8': 7,
  17. 'AIN_FIL_9': 8, 'AIN_FIL_10': 9, 'AIN_FIL_11': 10, 'AIN_FIL_12': 11
  18. }
  19. class IO_AnalogInput(IO_Module):
  20. GRAPTH_LEN = 100
  21. def __init__(self, modbus: Modbus):
  22. self.modbus = modbus
  23. super().__init__(self.modbus)
  24. self.log = AnalogInputLogReader(self.modbus)
  25. self.fig = plt.figure(1)
  26. self.input = self.fig.add_subplot(1, 1, 1)
  27. self.input.set_title('input_1')
  28. self.x = [0]
  29. self.data = []
  30. self.graph_input = ai_name['AIN_1']
  31. self.graph_input_func = 0
  32. # Чтение параметров
  33. def get_inputs_state(self):
  34. 'Значения состояний входов вкл./выкл. (битовое поле)'
  35. data = self.modbus.read_holding_registers(AiReg.IN_STATE.value, 1)
  36. return format(data[0], '012b')
  37. def get_inputs_mode(self):
  38. 'Режим измерения входов (0 - напряжение или 1 - ток. (битовое поле))'
  39. data = self.modbus.read_holding_registers(AiReg.IN_MODE.value , 1)
  40. return format(data[0], '012b')
  41. def get_inputs_alarm(self):
  42. 'Аварии аналоговых входов (битовое поле)'
  43. data = self.modbus.read_holding_registers(AiReg.IN_FAILURE.value, 1)
  44. return format(data[0], '012b')
  45. def get_ext_sens_power(self):
  46. 'Состояние питания внешних датчиков (вкл./выкл.)'
  47. data = self.modbus.read_holding_registers(AiReg.EXT_SENS_POWER.value, 1)
  48. def get_input_gain(self, channel):
  49. 'Коэффициент усиления канала [1..12] (внутренний коэф-т ADC)'
  50. data = self.modbus.read_holding_registers(AiReg.IN_GAINE_FACTOR.value + channel - 1, 1)
  51. return data[0]
  52. def get_k_factor(self, channel):
  53. 'Коэффициент пересчета K канала [1..12]'
  54. return self.modbus.read_float_holding(AiReg.IN_K_FACTOR.value + 2*(channel - 1))
  55. def get_b_factor(self, channel):
  56. 'Коэффициент пересчета B канала [1..12]'
  57. return self.modbus.read_float_holding(AiReg.IN_B_FACTOR.value + 2*(channel - 1))
  58. def get_raw_input(self, channel):
  59. 'Сырые данные по отдельному каналу [1..12]'
  60. return self.modbus.read_holding_registers(AiReg.IN_RAW.value + channel - 1, 1)[0]
  61. def get_raw_inputs(self):
  62. 'Сырые данные по всем каналам'
  63. data = self.modbus.read_holding_registers(AiReg.IN_RAW.value, 16)
  64. return data
  65. def get_fil_inputs(self):
  66. 'Фильтрованные данные'
  67. data = []
  68. for i in range(12):
  69. data.append(self.modbus.read_float_holding(AiReg.IN_FILTER.value + i*2))
  70. return data
  71. def get_presets_state(self):
  72. 'Значения состояний уставок вкл./выкл. (битовое поле)'
  73. data = self.modbus.read_holding_registers(AiReg.PR_STATE.value, 1)
  74. return format(data[0], '012b')
  75. def get_preset_min(self, channel):
  76. 'Минимальное значение уставки'
  77. return self.modbus.read_float_holding(AiReg.PR_MIN.value + 2*(channel - 1))
  78. def get_presets_min(self):
  79. 'Минимальное значение уставок по всем каналам'
  80. data = []
  81. for i in range(12):
  82. data.append(self.modbus.read_float_holding(AiReg.PR_MIN.value + i*2))
  83. return data
  84. def get_preset_max(self, channel):
  85. 'Маскимальное значение уставки'
  86. return self.modbus.read_float_holding(AiReg.PR_MAX.value + 2*(channel - 1))
  87. def get_presets_max(self):
  88. 'Максимальное значение уставок по все каналам'
  89. data = []
  90. for i in range(12):
  91. data.append(self.modbus.read_float_holding(AiReg.PR_MAX.value + i*2))
  92. return data
  93. def get_preset_hist(self, channel):
  94. 'Значение гистерезиса уставки'
  95. return self.modbus.read_float_holding(AiReg.PR_HIST.value + 2*(channel - 1))
  96. def get_presets_hist(self):
  97. 'Максимальное значение уставок по все каналам'
  98. data = []
  99. for i in range(12):
  100. data.append(self.modbus.read_float_holding(AiReg.PR_HIST.value + i*2))
  101. return data
  102. # Установка параметров
  103. def set_inputs_state(self, val):
  104. 'Значения состояний входов вкл./выкл. (битовое поле)'
  105. self.modbus.write_holding_register(AiReg.IN_STATE.value , val)
  106. def set_inputs_mode(self, val):
  107. 'Режим измерения входов (0 - напряжение или 1 - ток. (битовое поле))'
  108. self.modbus.write_holding_register(AiReg.IN_STATE.value, val)
  109. def set_ext_sens_power(self, val):
  110. 'Состояние питания внешних датчиков (вкл./выкл.)'
  111. self.modbus.write_holding_register(AiReg.EXT_SENS_POWER.value , val)
  112. def set_input_gain(self, input, value):
  113. '''
  114. Коэффициент усиления канала [1..12] (внутренний коэф-т ADC)
  115. Допустимые значения: 1, 2, 4, 8, 16, 32, 64, 128
  116. '''
  117. if value not in (1, 2, 4, 8, 16, 32, 64, 128):
  118. return None
  119. self.modbus.write_holding_register(AiReg.IN_GAINE_FACTOR.value + input - 1, value)
  120. def set_k_factor(self, channel, value):
  121. 'Коэффициент пересчета K канала [1..12]'
  122. self.modbus.write_float(AiReg.IN_K_FACTOR.value + 2*(channel - 1), value)
  123. def set_b_factor(self, channel, value):
  124. 'Коэффициент пересчета K канала [1..12]'
  125. self.modbus.write_float(AiReg.IN_B_FACTOR.value + 2*(channel - 1), value)
  126. def set_presets_state(self, val):
  127. 'Значения состояний входов вкл./выкл. (битовое поле)'
  128. self.modbus.write_holding_register(AiReg.PR_STATE.value , val)
  129. '''Настройки входов'''
  130. def print_inputs(self):
  131. print(Fore.GREEN + '____________________________________________')
  132. print(Fore.GREEN + 'Analog inputs settings:')
  133. # Значения состояний входов вкл./выкл. (битовое поле)
  134. print('Inputs state [bit field] :', Fore.GREEN + self.get_inputs_state())
  135. # Режим измерения входов напряжение или ток. (битовое поле)
  136. print('Inputs mode [bit field] :', Fore.GREEN + self.get_inputs_mode())
  137. # Коэффициенты усиления
  138. for i in range(1, 13):
  139. print(f'Gain factor channel {i} : ', end='')
  140. print(Fore.GREEN + str(self.get_input_gain(i)))
  141. '''Вывод параметров. Сырые данные 16 входов'''
  142. def print_raw_inputs(self):
  143. data = self.get_raw_inputs()
  144. print(f"[ADC raw] IN_1: {data[0]}, IN_2: {data[1]}, IN_3: {data[2]}, IN_4: {data[3]}")
  145. print(f"[ADC raw] IN_5: {data[4]}, IN_6: {data[5]}, IN_7: {data[6]}, IN_8: {data[7]}")
  146. print(f"[ADC raw] IN_9: {data[8]}, IN_10: {data[9]}, IN_11: {data[10]}, IN_12: {data[11]}")
  147. print(f"[ADC raw] V_ISO_CL: {data[12]}, V_ISO: {data[13]}")
  148. print(f"[ADC raw] CRNT_LIM_U_BFR_R: {data[14]}, CRNT_LIM_U_ABFR_R: {data[15]}")
  149. '''Вывод параметров. Фильтрованные данные 12 входов'''
  150. def print_filtered_inputs(self):
  151. data = self.get_fil_inputs()
  152. print(f"[ADC fil] IN_1: {data[0]}, IN_2: {data[1]}, IN_3: {data[2]}, IN_4: {data[3]}")
  153. print(f"[ADC fil] IN_5: {data[4]}, IN_6: {data[5]}, IN_7: {data[6]}, IN_8: {data[7]}")
  154. print(f"[ADC fil] IN_9: {data[8]}, IN_10: {data[9]}, IN_11: {data[10]}, IN_12: {data[11]}")
  155. '''Вывод данных на график'''
  156. def show_graph(self, func, channel: str):
  157. self.graph_input_func = func
  158. self.graph_input = ai_name[channel]
  159. ani = animation.FuncAnimation(self.fig, self.draw, interval=50)
  160. plt.show()
  161. def show_graph_filtered(self, channel: str):
  162. self.graph_input = ai_name[channel]
  163. def draw(self, i):
  164. data = self.graph_input_func()
  165. self.data.append(data[self.graph_input])
  166. self.input.clear()
  167. self.input.plot(self.x, self.data)
  168. if len(self.data) == self.GRAPTH_LEN:
  169. self.data.pop(0)
  170. self.x.pop(0)
  171. self.x.append(self.x[-1] + 1)
  172. # print(self.in1)
  173. # print(self.x)
  174. def main():
  175. colorama.init(autoreset=True)
  176. serial_port = Serial('COM7', 115200, timeout=0.05, parity='N', xonxoff=False)
  177. modbus_tester = Modbus(serial_port, 1)
  178. modbus_tester.MB_DEBUG = False
  179. # modbus_tester.MB_DEBUG = True
  180. # dev_tester = IO_Digital(modbus_tester)
  181. ai = IO_AnalogInput(modbus_tester)
  182. '''Режим работы аналоговых входов'''
  183. # ai.print_inputs()
  184. '''Установка коэффициентов усиления. Канал, коэффициент'''
  185. '''
  186. for channel in range(1, 13):
  187. ai.set_input_gain(channel, 8)
  188. for channel in range(1, 13):
  189. print(ai.get_input_gain(channel))
  190. '''
  191. '''Коэффициенты K и B'''
  192. # for i in range(1, 13):
  193. # ai.set_k_factor(i, 1.0)
  194. # ai.set_b_factor(i, 0.0)
  195. '''Последовательное включение входов по одному.'''
  196. '''
  197. while True:
  198. for i in range(12):
  199. ai.set_inputs_state(1 << i)
  200. print(ai.get_inputs_state())
  201. sleep(1)
  202. '''
  203. '''Настройка режима измерения'''
  204. '''
  205. while True:
  206. for i in range(12):
  207. ai.set_inputs_mode(1 << i)
  208. print(ai.get_inputs_mode())
  209. sleep(1)
  210. '''
  211. # ai.sys.set_system_vars(1234)
  212. # ai.sys.get_system_vars()
  213. # print(ai.sys.get_bat_votage())
  214. # ai.sys.set_rtc()
  215. # ai.sys.set_system_vars(1234)
  216. # ai.sys.get_system_vars()
  217. # print(ai.sys.get_rtc())
  218. # print(ai.get_inputs_state())
  219. # ai.set_inputs_state(0b1111_1111_1111)
  220. # print(ai.sys.get_module_state())
  221. # ai.set_inputs_state(0b0000_0000_0000)
  222. # ai.set_inputs_state(0b1111_1111_1111)
  223. # print(ai.get_inputs_state())
  224. # sleep(1)
  225. # ai.set_inputs_state(0b0)
  226. # print(ai.get_inputs_mode())
  227. # ai.set_inputs_mode(0b0000_0000_0000)
  228. # print(ai.get_inputs_mode())
  229. '''Питание внешних датчиков'''
  230. # ai.set_ext_sens_power(0)
  231. '''Аварии аналоговых входов'''
  232. # for i in range(100):
  233. # print(ai.get_inputs_alarm())
  234. # sleep(1)
  235. '''Данные каналов'''
  236. # while True:
  237. # ai.print_raw_inputs()
  238. # ai.print_filtered_inputs()
  239. # sleep(1)
  240. # ai.get_raw_inputs()
  241. # ai.print_raw_inputs()
  242. '''Сырые данные'''
  243. # while True:
  244. # print(ai.get_raw_input(12))
  245. # sleep(1)
  246. '''Вывод на график. Сырые данные'''
  247. # ai.show_graph(ai.get_raw_inputs, 'AIN_1')
  248. '''Вывод на график. Фильтрованные данные'''
  249. # ai.show_graph(ai.get_fil_inputs, 'AIN_FIL_12')
  250. '''Системные настройки'''
  251. # ai.sys.get_system_vars()
  252. '''Сохранение настроек'''
  253. # ai.sys.save_sattings()
  254. '''Обновление прошивки'''
  255. # serial_port.timeout = 1
  256. # modbus_tester.MB_DEBUG = True
  257. # ai.updater.update('fw.bin', 'MAI_12')
  258. if __name__ == '__main__':
  259. main()