Skip to content

Commit aa29e0e

Browse files
author
andy
committed
read z-stage
1 parent 3ac3f32 commit aa29e0e

File tree

11 files changed

+372
-40
lines changed

11 files changed

+372
-40
lines changed

devices/amsamotion_sensor.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ def get_distance_multi(self, device_addr: int, channel_num=8) -> dict:
4949
else:
5050
# use serial driver
5151
ret = self.serial.read_buffer()
52+
if ret == "":
53+
raise ValueError("read sensor fail")
5254
ret = ret.split('\r\n')
5355
ret = ret[1]
5456

dist/Productions.exe

14.7 KB
Binary file not shown.

drivers/play_sound.py

Lines changed: 54 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import os.path
2+
import time
3+
import winsound
24

35
from playsound import playsound
46
from utils import Utils
@@ -10,6 +12,8 @@
1012
Alarm_2 = os.path.join('assets', 'sounds', 'mixkit-alarm-tone-996.wav')
1113
voice = 'assets/'
1214

15+
value = 1
16+
1317

1418
def play_dog_barking():
1519
"""
@@ -19,24 +23,67 @@ def play_dog_barking():
1923
playsound(Dog_Barking)
2024

2125

22-
def play_alarm_1():
26+
def play_alarm_1(project_path=None):
2327
"""
2428
voice2
2529
:return:
2630
"""
27-
playsound(Alarm_1)
31+
if project_path is not None:
32+
voice = os.path.join(project_path, Alarm_1)
33+
else:
34+
voice = Alarm_1
35+
playsound(voice)
2836

2937

30-
def play_alarm_2(project_path):
38+
def play_alarm_2(project_path=None):
3139
"""
3240
voice2
3341
:return:
3442
"""
35-
voice = os.path.join(project_path, Alarm_2)
43+
if project_path is not None:
44+
voice = os.path.join(project_path, Alarm_2)
45+
else:
46+
voice = Alarm_2
3647
playsound(voice)
3748

3849

50+
def play_alarm_3(frequency, duration):
51+
winsound.Beep(frequency, duration)
52+
53+
3954
if __name__ == '__main__':
40-
# play_dog_barking()
41-
# play_alarm_2(
42-
pass
55+
print(root_path)
56+
# play_alarm_3(3000, 500)
57+
58+
import threading
59+
60+
61+
def play_value(f, d):
62+
play_alarm_3(f, d)
63+
64+
65+
def judge_value():
66+
while True:
67+
# if value > 0.2:
68+
# play_value(500, 1000)
69+
# elif 0.1 <value<= 0.2:
70+
# play_value(500, 1000)
71+
# elif value
72+
# elif 0.05 <= value <= 0.1:
73+
# play_value(500, 500)
74+
# elif 0.03 < value < 0.05:
75+
# play_value(1000, 500)
76+
# else:
77+
# play_value(1000, 300)
78+
_value = int(-value * 1500 + 1000)
79+
if _value < 0:
80+
_value = 1500
81+
play_alarm_3(_value, 500)
82+
83+
84+
85+
th = threading.Thread(target=judge_value)
86+
th.start()
87+
# th.join()
88+
while True:
89+
value = float(input("value:"))
Binary file not shown.

ot3_testing/hardware_control/jog.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,5 +150,5 @@ async def jog(hc: HardwareControl, mount: Mount):
150150

151151

152152
if __name__ == '__main__':
153-
hc = HardwareControl("192.168.6.44")
153+
hc = HardwareControl("192.168.6.33")
154154
asyncio.run(jog(hc, Mount.RIGHT))

ot3_testing/test_config/pipette_leveling_config.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,17 @@ class CalibrateMethod(enum.Enum):
1414
"C3-X": {"Point": Point(382, 91, 300), "compensation": {"left": 0, "right": 0}},
1515
"A2-X": {"Point": Point(213, 305, 300), "compensation": {"left": 0, "right": 0}},
1616
"D1-Z": {"Point": Point(51, 99, 318),
17-
"compensation": {"rear_left": -0.56664, "rear_right": -0.6685, "front_left": -0.43876,
17+
"compensation": {"rear_left": 0.09, "rear_right": 0.01, "front_left": 0.11,
1818
"front_right": 0}},
1919
# "B2-Z": Point(213, 324, 317),
2020
"D3-Z": {"Point": Point(377, 99, 318),
21-
"compensation": {"rear_left": -0.56664, "rear_right": -0.70712, "front_left": -0.41324,
21+
"compensation": {"rear_left": 0.09, "rear_right": 0.01, "front_left": 0.11,
2222
"front_right": 0}},
2323
"C2-Z": {"Point": Point(214, 210, 318),
24-
"compensation": {"rear_left": -0.60076, "rear_right": -0.679, "front_left": -0.32926,
24+
"compensation": {"rear_left": 0.09, "rear_right": 0.01, "front_left": 0.11,
2525
"front_right": 0}},
2626
"A2-Z": {"Point": Point(218, 424, 390.5),
27-
"compensation": {"rear_left": -0.57076, "rear_right": -0.694, "front_left": -0.40876,
27+
"compensation": {"rear_left": 0.09, "rear_right": 0.01, "front_left": 0.11,
2828
"front_right": 0}},
2929
"UninstallPos": {"Point": Point(223, 203, 500)}
3030
}
@@ -48,9 +48,9 @@ class CalibrateMethod(enum.Enum):
4848
"right_rear": {"device_addr": 1, "channel": 5, "offset": 0},
4949
}
5050

51-
SlotLocationCH8 = {"Y-C1-Left": {"Point": Point(198.42, 198.33, 299.16), "compensation": -0.015},
52-
"Y-C1-Right": {"Point": Point(172.07, 197.18, 299.16), "compensation": -0.03},
53-
"Y-C3-Right": {"Point": Point(499.83, 197.18, 299.16), "compensation": -0.03},
54-
"Y-A2-Right": {"Point": Point(335.94, 412.22, 299.16), "compensation": -0.03},
51+
SlotLocationCH8 = {"Y-C1-Left": {"Point": Point(215.42, 198.33, 299.16), "compensation": {"rear": 0, "front": 0}},
52+
"Y-C1-Right": {"Point": Point(172.07, 197.18, 299.16), "compensation": {"rear": 0, "front": 0}},
53+
"Y-C3-Right": {"Point": Point(499.83, 197.18, 299.16), "compensation": {"rear": 0, "front": 0}},
54+
"Y-A2-Right": {"Point": Point(335.94, 412.22, 299.16), "compensation": {"rear": 0, "front": 0}},
5555
"UninstallPos": {"Point": Point(223, 203, 500), "compensation": 0}
5656
}
Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,58 @@
11
from ot3_testing.ot_type import Mount, Point
2+
import enum
3+
4+
5+
class CalibrateMethod(enum.Enum):
6+
Approach = "approach"
7+
Dichotomy = "dichotomy"
28

39

410
ZStagePoint = {
511

612
Mount.LEFT: {
7-
"C2": { "point": Point(214, 210, 318), "compensation": {}}
13+
"Z-A1": {"point": Point(214, 210, 418), "compensation": {"rear": 0, "front": 0},
14+
"channel_definition": ["below_rear", "below_front"]},
15+
"Z-A2": {"point": Point(214, 210, 418), "compensation": {"rear": 0, "front": 0},
16+
"channel_definition": ["below_rear", "below_front"]},
17+
"Z-A3": {"point": Point(214, 210, 418), "compensation": {"rear": 0, "front": 0},
18+
"channel_definition": ["below_rear", "below_front"]},
19+
"Z-B1": {"point": Point(214, 210, 418), "compensation": {"rear": 0, "front": 0},
20+
"channel_definition": ["below_rear", "below_front"]},
21+
"Z-B2": {"point": Point(214, 210, 418), "compensation": {"rear": 0, "front": 0},
22+
"channel_definition": ["below_rear", "below_front"]},
23+
"Z-B3": {"point": Point(214, 210, 418), "compensation": {"rear": 0, "front": 0},
24+
"channel_definition": ["below_rear", "below_front"]},
25+
"Z-C1": {"point": Point(214, 210, 418), "compensation": {"rear": 0, "front": 0},
26+
"channel_definition": ["below_rear", "below_front"]},
27+
"Z-C2": {"point": Point(214, 210, 418), "compensation": {"rear": 0, "front": 0},
28+
"channel_definition": ["below_rear", "below_front"]},
29+
"Z-C3": {"point": Point(214, 210, 418), "compensation": {"rear": 0, "front": 0},
30+
"channel_definition": ["below_rear", "below_front"]},
31+
"Z-D1": {"point": Point(214, 210, 418), "compensation": {"rear": 0, "front": 0},
32+
"channel_definition": ["below_rear", "below_front"]},
33+
"Z-D2": {"point": Point(214, 210, 418), "compensation": {"rear": 0, "front": 0},
34+
"channel_definition": ["below_rear", "below_front"]},
35+
"Z-D3": {"point": Point(214, 210, 418), "compensation": {"rear": 0, "front": 0},
36+
"channel_definition": ["below_rear", "below_front"]},
37+
},
38+
Mount.RIGHT: {
39+
"Z-C2": {"point": Point(177, 197, 357), "compensation": {"rear": 0, "front": 0},
40+
"channel_definition": ["below_rear", "below_front"]}
41+
}
42+
}
843

44+
ZStageChannel = {
45+
Mount.LEFT: {
46+
"below_rear": {"device_addr": 1, "channel": 3},
47+
"below_front": {"device_addr": 1, "channel": 2},
48+
"left_rear": {"device_addr": 1, "channel": 1},
49+
"left_front": {"device_addr": 1, "channel": 0}
950
},
51+
1052
Mount.RIGHT: {
11-
"C2": Point(214, 210, 318)
53+
"below_rear": {"device_addr": 1, "channel": 7},
54+
"below_front": {"device_addr": 1, "channel": 6},
55+
"left_rear": {"device_addr": 1, "channel": 5},
56+
"left_front": {"device_addr": 1, "channel": 4}
1257
}
13-
}
58+
}
Binary file not shown.

ot3_testing/tests/base_init.py

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from ot3_testing.protocol.protocol_context import ProtocolContext
22
from ot3_testing.hardware_control.hardware_control import HardwareControl
3-
from typing import Union
3+
from typing import Union, List
4+
from devices.amsamotion_sensor import LaserSensor
45
import time
56

67

@@ -34,7 +35,7 @@ def delay_s(self, second):
3435
:return:
3536
"""
3637
for i in range(second):
37-
print(f"delay {(i+1)}/({second})s")
38+
print(f"delay {(i + 1)}/({second})s")
3839
time.sleep(1)
3940

4041
def get_address(self):
@@ -53,3 +54,55 @@ def print_info(self, info: str):
5354
"""
5455
input("=======Info======\n"
5556
+ info)
57+
58+
async def read_distance_mm_from_code_value(self, code_value: int, get_voltage=False, k=-2, b=35):
59+
"""
60+
read real value
61+
:param code_value:
62+
:param get_voltage: return voltage
63+
:param k:
64+
:param b:
65+
:return:
66+
"""
67+
# if self.test_name == "96ch":
68+
# voltage = round(float((code_value / 1600) / 2), 3) # /V
69+
# else:
70+
voltage = round(float(code_value), 3)
71+
if get_voltage:
72+
return voltage
73+
else:
74+
distance = k * voltage + b # /mm
75+
return round(float(distance), 3)
76+
77+
async def read_definition_distance(self, definition: List, channel_definition, laser: LaserSensor, mount,
78+
only_code=False,
79+
send=False, add_compensation=True) -> dict:
80+
"""
81+
read distance, using one device id (please use same device_id in the positions)
82+
:param definition:
83+
:param channel_definition:
84+
:param laser:
85+
:param mount:
86+
:param only_code:
87+
:param send: 是否需要发送再接收,区分两种传感器
88+
:param add_compensation: 添加补偿
89+
:return:
90+
"""
91+
print("Reading Sensor...")
92+
result = {}
93+
time.sleep(1)
94+
_channel_definition = channel_definition[mount]
95+
device_addr = _channel_definition[definition[0]]["device_addr"]
96+
code_value_list = laser.get_distance_multi(device_addr)
97+
98+
if only_code:
99+
for item in definition:
100+
result.update({item: code_value_list[_channel_definition[item]["channel"]]})
101+
102+
else:
103+
for item in definition:
104+
code_value = code_value_list[channel_definition[item]["channel"]]
105+
distance_value = await self.read_distance_mm_from_code_value(code_value)
106+
result.update({item: distance_value})
107+
108+
return result

ot3_testing/tests/pipette_leveling.py

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ async def move_to_test_slot(self, slot_name: str):
5656
"""
5757
await self.move_to_test_point(self.slot_location[slot_name]["Point"], MountDefinition)
5858

59-
async def read_definition_distance(self, position: List[str], only_code=False) -> dict:
59+
async def _read_definition_distance(self, position: List[str], only_code=False) -> dict:
6060
"""
6161
read distance, using one device id (please use same device_id in the positions)
6262
:param position:
@@ -75,12 +75,12 @@ async def read_definition_distance(self, position: List[str], only_code=False) -
7575
else:
7676
for item in position:
7777
code_value = code_value_list[self.channel_definition[item]["channel"]]
78-
distance_value = await self.read_distance_mm_from_code_value(code_value)
78+
distance_value = await self._read_distance_mm_from_code_value(code_value)
7979
result.update({item: distance_value})
8080

8181
return result
8282

83-
async def read_distance_mm_from_code_value(self, code_value: int, get_voltage=False):
83+
async def _read_distance_mm_from_code_value(self, code_value: int, get_voltage=False):
8484
"""
8585
read real value
8686
:param code_value:
@@ -165,10 +165,10 @@ async def calibrate_to_zero(self, test_name: str, spec: float, read_definition:
165165
init_step = 2
166166
while True:
167167
# read voltage
168-
ret_dict = await self.read_definition_distance(read_definition, only_code=True)
168+
ret_dict = await self._read_definition_distance(read_definition, only_code=True)
169169
# min_voltage = min(distance_list)
170170
_min = list(ret_dict.values())[0] # judge the first channel
171-
min_voltage = await self.read_distance_mm_from_code_value(_min, get_voltage=True)
171+
min_voltage = await self._read_distance_mm_from_code_value(_min, get_voltage=True)
172172
print("current min voltage is: ", min_voltage)
173173
if spec >= (min_voltage - target_voltage) >= 0:
174174
break
@@ -215,7 +215,7 @@ async def run_test_slot(self, test_slot_name: str, test_slot_value: str, read_de
215215
if with_cal:
216216
await self.calibrate_to_zero(test_slot_value, 0.1, read_definition, method=CalibrateMethod.Approach)
217217

218-
ret_dict = await self.read_definition_distance(read_definition)
218+
ret_dict = await self._read_definition_distance(read_definition)
219219
for key, value in ret_dict.items():
220220
print(f"{test_slot_value}-{key}: {value}")
221221

@@ -267,21 +267,24 @@ async def run_8ch_test(self, flex_name: str, project_path=None):
267267
csv_title.append(time_str + flex_name)
268268
print("=" * 5 + "Test Result" + "=" * 5 + "\n")
269269
for key, value in test_result.items():
270+
result = []
270271
distance_list = list(value.values())
271-
difference = distance_list[0] - distance_list[1]
272+
difference = round(abs(distance_list[0] - distance_list[1]), 3)
272273
compensation = self.slot_location[key]["compensation"]
273274
if ApplyCompensationFlag:
274-
print(f"apply offset {compensation} to {difference}, difference -> {difference - compensation}")
275-
difference = difference - compensation
276-
print(f"{key} --> {value} (mm) --> difference: {round(difference, 3)}(mm)")
275+
compensation_idx = 0
276+
for compensation_key, compensation_value in compensation.items():
277+
print(
278+
f"apply offset {compensation_key} -> {compensation_value} to {distance_list[compensation_idx]}")
279+
result.append(compensation_value + distance_list[compensation_idx])
280+
compensation_idx += 1
281+
difference = round(abs(result[0] - result[1]), 3)
282+
print(f"{key} --> {value} (mm) --> difference: {difference}(mm)")
277283
for item_key, item_value in value.items():
278284
csv_title.append(key + " " + item_key)
279-
if ApplyCompensationFlag and "front" in item_key:
280-
csv_list.append(item_value - compensation)
281-
else:
282-
csv_list.append(item_value)
285+
csv_list.append(item_value)
283286
csv_title.append(key + "-Result")
284-
csv_list.append(abs(difference))
287+
csv_list.append(difference)
285288

286289
# save csv
287290
if project_path is not None:
@@ -374,7 +377,8 @@ async def run_96ch_test(self, flex_name: str, project_path=None):
374377
if ApplyCompensationFlag:
375378
compensation_idx = 0
376379
for compensation_key, compensation_value in compensation.items():
377-
print(f"apply offset {compensation_key} -> {compensation_value} to {distance_list[compensation_idx]}")
380+
print(
381+
f"apply offset {compensation_key} -> {compensation_value} to {distance_list[compensation_idx]}")
378382
result.append(compensation_value + distance_list[compensation_idx])
379383
compensation_idx += 1
380384
difference = round((abs(max(result) - min(result))), 3)
@@ -413,5 +417,11 @@ async def run_96ch_test(self, flex_name: str, project_path=None):
413417

414418
if __name__ == '__main__':
415419
import asyncio
416-
pipette_leveling = PipetteLeveling(SlotLocationCH96, ChannelDefinitionCH96, )
417-
asyncio.run(pipette_leveling.run_96ch_test("FLXA1020240513001"))
420+
421+
# pipette_leveling = PipetteLeveling(SlotLocationCH96, ChannelDefinitionCH96, )
422+
# pipette_leveling.test_name = '96ch'
423+
# asyncio.run(pipette_leveling.run_96ch_test("0518003"))
424+
425+
pipette_leveling = PipetteLeveling(SlotLocationCH8, ChannelDefinitionCH8, )
426+
pipette_leveling.test_name = '8ch'
427+
asyncio.run(pipette_leveling.run_8ch_test("0518003"))

0 commit comments

Comments
 (0)