st-ten-1/src/components/usb_586x.py

225 lines
8.4 KiB
Python
Raw Normal View History

2022-12-31 13:00:23 +00:00
import ctypes
import sys
2023-01-03 09:22:54 +00:00
import platform
2022-12-31 13:00:23 +00:00
import time
from enum import Enum
2023-01-31 15:03:46 +00:00
from PyQt5.QtCore import QMutex, Qt, QTimer, pyqtSlot, pyqtSignal
2022-12-31 13:00:23 +00:00
from .component import Component
2023-01-30 15:50:02 +00:00
is_win = platform.system() == "Windows"
2022-12-31 13:00:23 +00:00
if "--sim-io" not in sys.argv:
2023-01-30 15:50:02 +00:00
if is_win:
2023-02-17 20:19:30 +00:00
from components.Automation.BDaq import *
from components.Automation.BDaq.InstantDoCtrl import InstantDoCtrl
from components.Automation.BDaq.InstantDiCtrl import InstantDiCtrl
2023-01-03 09:22:54 +00:00
else:
libbiodaq = ctypes.CDLL("/opt/advantech/libs/libbiodaq.so")
2022-12-31 13:00:23 +00:00
else:
2023-03-25 14:13:09 +00:00
from components.dummies.Automation.BDaq import *
from components.dummies.Automation.BDaq.InstantDoCtrl import InstantDoCtrl
from components.dummies.Automation.BDaq.InstantDiCtrl import InstantDiCtrl
#is_win=False
#import components.dummies.libbiodaq as libbiodaq
2023-03-03 17:51:35 +00:00
from components.dummies.libbiodaq import ErrorCode
2022-12-31 13:00:23 +00:00
2023-01-03 16:57:14 +00:00
class USB_586x(Component):
2022-12-31 13:00:23 +00:00
class DeviceInformation(ctypes.Structure):
_fields_ = [
('DeviceNumber', ctypes.c_uint32),
('DeviceMode', ctypes.c_uint32),
('ModuleIndex', ctypes.c_uint32),
('Description', ctypes.c_wchar_p)
]
2023-01-31 15:03:46 +00:00
update=pyqtSignal(object)
2023-02-01 10:51:57 +00:00
masks = [1 << n for n in range(8)]
2022-12-31 13:00:23 +00:00
2023-01-31 14:51:41 +00:00
def __init__(self, config=None, name=None, period=1, lazy=True, paused=False, threaded=True):
super().__init__(config=config, name=name, period=period, lazy=lazy, paused=paused, threaded=threaded)
2022-12-31 13:00:23 +00:00
self.mutex = QMutex()
2023-02-17 17:41:45 +00:00
self.simulate="--sim-io" in sys.argv
2022-12-31 13:00:23 +00:00
# DEVICE INFORMATION
2023-01-31 14:51:41 +00:00
self.id=config["digital_io"]["id"]
2023-01-03 16:57:14 +00:00
if "5860" in self.id:
self.type = "5860"
self.in_size = 1
self.out_size = 1
if "5862" in self.id:
self.type = "5862"
self.in_size = 2
self.out_size = 2
2022-12-31 13:00:23 +00:00
self.info = self.DeviceInformation()
2023-01-31 14:51:41 +00:00
self.info.Description = self.id
2023-01-03 16:57:14 +00:00
# self.info.DeviceNumber = -1
2022-12-31 13:00:23 +00:00
self.info.DeviceMode = 1
self.info.ModuleIndex = 0
2023-02-16 14:58:09 +00:00
self.open_device()
# SET ALL RELAYS OFF
for bit in range(0, self.out_size*8):
self.set_bit(int(bit/8), bit%8, False)
self.state_delay = 1
self.last_get = None
self.state_count = None
self.last_out = None
def open_device(self):
2022-12-31 13:00:23 +00:00
# DIGITAL INPUTS CLASS
2023-03-30 10:06:45 +00:00
if not self.simulate:
if is_win:
self.di_ctrl = InstantDiCtrl(self.info.Description)
self.do_ctrl = InstantDoCtrl(self.info.Description)
self.di_read = self.di_ctrl.readAny
self.do_write_bit = self.do_ctrl.writeBit
self.buffer = ctypes.create_string_buffer(2)
else:
self.di_create = libbiodaq.AdxInstantDiCtrlCreate
self.di_create.restype = ctypes.c_void_p
self.di_setSelectedDevice = libbiodaq.InstantDiCtrl_setSelectedDevice
self.di_setSelectedDevice.argtypes = [ctypes.c_void_p, ctypes.POINTER(self.DeviceInformation)]
self.di_setSelectedDevice.restype = ctypes.c_uint32
# DIGITAL INPUTS READ FUNCTION
self.di_read = libbiodaq.InstantDiCtrl_ReadAny
self.di_read.argtypes = [ctypes.c_void_p, ctypes.c_int32, ctypes.c_int32, ctypes.c_char_p]
self.di_read.restype = ctypes.c_int32
# DIGITAL OUTPUTS CLASS
self.do_create = libbiodaq.AdxInstantDoCtrlCreate
self.do_create.restype = ctypes.c_void_p
# SET SELECTED DEVICE
self.do_setSelectedDevice = libbiodaq.InstantDoCtrl_setSelectedDevice
self.do_setSelectedDevice.argtypes = [ctypes.c_void_p, ctypes.POINTER(self.DeviceInformation)]
self.do_setSelectedDevice.restype = ctypes.c_uint32
# get ports
self.get_ports = libbiodaq.InstantDoCtrl_getPortDirection
self.get_ports.argtypes = [ctypes.c_void_p]
self.get_ports.restype = ctypes.POINTER(ctypes.c_void_p)
# DIGITAL OUTPUTS WRITE FUNCTION
self.do_write_bit = libbiodaq.InstantDoCtrl_WriteBit
self.do_write_bit.argtypes = [ctypes.c_void_p, ctypes.c_int32, ctypes.c_int32, ctypes.c_char]
self.do_write_bit.restype = ctypes.c_int32
self.buffer = ctypes.create_string_buffer(2)
# INIT OBJECTS
self.di_ctrl = self.di_create()
self.do_ctrl = self.do_create()
self.di_init_status = self.di_setSelectedDevice(self.di_ctrl, ctypes.byref(self.info))
self.do_init_status = self.do_setSelectedDevice(self.do_ctrl, ctypes.byref(self.info))
else:
2023-01-03 09:22:54 +00:00
self.di_ctrl = InstantDiCtrl(self.info.Description)
self.do_ctrl = InstantDoCtrl(self.info.Description)
self.di_read = self.di_ctrl.readAny
self.do_write_bit = self.do_ctrl.writeBit
2023-02-01 10:51:57 +00:00
self.buffer = ctypes.create_string_buffer(2)
2023-03-30 10:06:45 +00:00
2023-02-16 14:58:09 +00:00
def close_device(self):
pass
2022-12-31 13:00:23 +00:00
@pyqtSlot()
def start(self):
# ACQUISITION TIMER
self.timer = QTimer()
self.timer.setTimerType(Qt.PreciseTimer)
self.timer.setInterval(int(1000 / 20))
self.timer.timeout.connect(self._get)
self.timer.start()
super().start()
# Read data for buffer
@pyqtSlot()
def _get(self):
get = self.get()
# print(self.last_get)
if self.state_count is None or self.last_get is None:
self.last_out = get
self.state_count = [[1 for bit in byte] for byte in get]
else:
for byte_n, byte in enumerate(get):
for bit_n, bit in enumerate(byte):
if bit == self.last_get[byte_n][bit_n]:
self.state_count[byte_n][bit_n] += 1
else:
self.state_count[byte_n][bit_n] = 1
if self.state_count[byte_n][bit_n] > self.state_delay:
self.last_out[byte_n][bit_n] = bit
self.last_get = get
2023-02-01 10:51:57 +00:00
#self.update.emit([time.time(), self.last_out])
super()._get([self.last_out])
2022-12-31 13:00:23 +00:00
def get_all(self):
return self.get()
2023-01-06 13:06:27 +00:00
# Read input bytes
2022-12-31 13:00:23 +00:00
def get(self):
self.mutex.lock()
read = []
2023-03-30 10:06:45 +00:00
if is_win or self.simulate:
2023-03-25 14:13:09 +00:00
if self.simulate:
2023-04-11 15:01:17 +00:00
read=[1,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0]
2023-01-03 09:22:54 +00:00
else:
2023-03-25 14:13:09 +00:00
ret = self.di_read(0, self.in_size)
if ret[0].value == ErrorCode.Success.value:
self.buffer = ret[1]
for byte_num in range(len(self.buffer)):
byte = self.buffer[byte_num]
read.append([bool(byte & m) for m in self.masks])
else:
self.buffer = None
2023-01-03 09:22:54 +00:00
else:
2023-01-06 13:06:27 +00:00
self.di_read(self.di_ctrl, 0, self.in_size, self.buffer)
2023-01-03 09:22:54 +00:00
2023-01-03 16:57:14 +00:00
for byte_num in range(len(self.buffer)):
byte = int.from_bytes(self.buffer[byte_num], "little")
2023-01-03 09:22:54 +00:00
read.append([bool(byte & m) for m in self.masks])
2022-12-31 13:00:23 +00:00
self.mutex.unlock()
return read
# Read data bit
def get_bit(self, byte, bit):
return self.get()[byte][bit]
# Send data byte
def set(self, start_byte, val):
for byte, v in enumerate(val, start=start_byte):
for bit, bv in enumerate([bool(v & m) for m in self.masks]):
self.set_bit(byte, bit, bv)
# Write single bit
def set_bit(self, byte, bit, val):
self.mutex.lock()
# print("set", byte, bit, not val, flush=True)
2023-03-03 17:51:35 +00:00
if not self.simulate:
if is_win:
ret=self.do_write_bit(byte, bit, int(val))
else:
ret=self.do_write_bit(self.do_ctrl, byte, bit, int(val))
2023-01-03 09:22:54 +00:00
else:
2023-03-03 17:51:35 +00:00
ret = ErrorCode.Success
2022-12-31 13:00:23 +00:00
self.mutex.unlock()
2023-02-16 14:58:09 +00:00
return ret
def set_bit_verify(self, byte, bit, val):
ok = False
retry=0
max_retry = 3
while not ok and retry <max_retry:
2023-02-16 16:26:17 +00:00
ret = self.set_bit(byte, bit, val)
2023-02-21 08:26:43 +00:00
if ret.value != ErrorCode.Success.value and not self.simulate:
2023-02-16 14:58:09 +00:00
self.log.error(f"SET BIT ERROR")
self.open_device()
retry+=1
else:
ok = True
return ok
2022-12-31 13:00:23 +00:00
# val from buffer channel
def vfbc(self, buffer, channel):
return buffer[channel[0]][channel[1]]