-
Notifications
You must be signed in to change notification settings - Fork 0
/
carmen.py
145 lines (124 loc) · 5.04 KB
/
carmen.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
import logging
from typing import List, Tuple
from carmen_communication import CommunicationCarmen
from carmen_utils import CarmenTypeplate, analyse_typeplate, convert_digout
class Carmen(object):
"""
Simple class to handle the Carmen sensor functions.
"""
def __init__(self, communication: CommunicationCarmen) -> None:
"""
Initializes a instance of Carmen.
:param communication: Communication for the Carmen sensor.
"""
self._communication = communication
self._typeplate = None
def _execute_simple_command(self, command: int, size: int) -> Tuple[bool, List[int]]:
"""
Executes a simple command.
:param command: Command to execute.
:param size: Response size for the given command.
:return: True on success, else false.
:return: The received data.
"""
response = []
success = self._communication.send(command)
if success:
success, response = self._communication.receive(size)
if success:
success = response[0] == command
if not success:
response = []
logging.error('invalid answer, wrong command')
return success, response
def stop_dsp(self) -> Tuple[bool, List[int]]:
"""
Executes the command "Stop DSP".
:return: True on success, else false.
:return: The received data.
"""
logging.info('execute command "Stop DSP"')
return self._execute_simple_command(0xA0, 4)
def continue_dsp(self) -> Tuple[bool, List[int]]:
"""
Executes the command "Continue DSP".
:return: True on success, else false.
:return: The received data.
"""
logging.info('execute command "Continue DSP"')
return self._execute_simple_command(0xA1, 4)
def soft_reset(self) -> Tuple[bool, List[int]]:
"""
Executes the command "Soft Reset".
:return: True on success, else false.
:return: The received data.
"""
logging.info('execute command "Soft Reset"')
return self._execute_simple_command(0x5A, 4)
def read_measurement_frame1(self) -> Tuple[bool, List[int]]:
"""
Executes the command "Read Measurement Frame1".
:return: True on success, else false.
:return: The received data.
"""
logging.info('execute command "Read Measurement Frame1"')
return self._execute_simple_command(0x35, 13)
def read_eeprom(self, address: int, size: int = 1) -> Tuple[bool, List[int]]:
"""
Executes the command "Read EEPROM".
:param address: Start address to read from EEPROM.
:param size: Block size to read.
:return: True on success, else false.
:return: The received data.
"""
logging.info('execute command "Read EEPROM"')
command = 0x03
response = []
success = self._communication.send(command, [address >> 8, address & 0xFF, size])
if success:
success, response = self._communication.receive(size * 4 + 5)
if success:
success = response[0] == command and response[2] == size
if not success:
response = []
logging.error('invalid answer, wrong command or invalid size')
return success, response
def read_typeplate(self) -> Tuple[bool, CarmenTypeplate]:
"""
Reads the typeplate information.
:return: True on success, else false.
:return: Typeplate information.
"""
typeplate = CarmenTypeplate()
success, _ = self.stop_dsp()
if success:
success, response = self.read_eeprom(0x0190, 12)
if success:
success, typeplate = analyse_typeplate(response[3:-2])
if success:
self._typeplate = typeplate
_, _ = self.continue_dsp()
return success, typeplate
def read_measurement(self) -> Tuple[bool, float, float, int]:
"""
Reads a measurement (pressure, temperature, status) from the Carmen sensor.
:return: True on success, else false.
:return: Pressure value.
:return: Temperature value.
:return: Actual status.
"""
pressure = 0.0
temperature = 0.0
status = 0xFFFFFF
success = True
if self._typeplate is None:
success, _ = self.read_typeplate()
if success:
success, data = self.read_measurement_frame1()
if success:
pressure_value = data[1] | (data[2] << 8) | (data[3] << 16)
pressure = convert_digout(pressure_value, 24, self._typeplate.LRV_1, self._typeplate.URV_1)
temperature_value = data[4] | (data[5] << 8)
temperature = convert_digout(temperature_value, 16, self._typeplate.LRV_2, self._typeplate.URV_2, 25)
status = data[8] | (data[9] << 8) | (data[10] << 16)
return success, pressure, temperature, status