-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathms5637.py
159 lines (126 loc) · 6.38 KB
/
ms5637.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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# coding=utf-8
"""The MS5637 has only five basic commands:
1. Reset
2. Read PROM (112 bit of calibration words)
3. D1 conversion (pressure)
4. D2 conversion (temperature)
5. Read ADC result (24 bit pressure / temperature
They are executed in order. A loop can then be shortened to steps 3-5
Code initiated by Yadwinder Singh
"""
from __future__ import division
from time import sleep
import smbus
__author__ = 'Moe'
__copyright__ = 'Copyright 2016 Moe'
__license__ = 'MIT'
__version__ = '0.0.2'
# MS5637 default address.
CHIP = 0x76
# Registers PROM Read 0XA0 to 0XAC
REGISTER_C0 = 0XA0 # CRC, and 'Factory defined'. e.g., [189, 225].
REGISTER_C1 = 0XA2 # Sensitivity
REGISTER_C2 = 0XA4 # Pressure Offset
REGISTER_C3 = 0XA6 # Temp Coefficient of Pressure Sensitivity
REGISTER_C4 = 0XA8 # Temp Coefficient of Pressure Offset
REGISTER_C5 = 0XAA # Reference Temperature
REGISTER_C6 = 0XAC # Temp Coefficient of Temperature
# Operating Modes OSR256 OSR512 0SR1024 OSR2048 OSR4096 OSR8192
# Resolution : 11 | 6.2 | 3.9 | 2.8 | 2.1 | 1.6 # Pascals
# : 0.012 | 0.009| 0.006 | 0.004 | 0.003 | 0.002 # Celsius
# Oversampling Ratio: 256 | 512 | 1024 | 2048 | 4096 | 8192
# Sampling rate ms : 0.54 | 1.06 | 2.08 | 4.13 | 8.22 | 16.44 # Manufacturer data sheet
# delay sampling ms : 2 | 4 | 6 | 10 | 18 | 34 # Recommended from Arduino driver. I've no idea.
# Pressure Convert=Address, delay sec # Temperature Convert Address incremented at function.
OSR256 = (0x40, 0.002) # OSR-256 D1 # OSR256 = 0x50 # OSR-256 D2
OSR512 = (0x42, 0.004) # OSR-512 D1 # OSR512 = 0x52 # OSR-512 D2
OSR1024 = (0x44, 0.006) # OSR-1024 D1 # OSR1024 = 0x54 # OSR-1024 D2
OSR2048 = (0x46, 0.010) # OSR-2048 D1 # OSR2048 = 0x56 # OSR-2048 D2
OSR4096 = (0x48, 0.018) # OSR-4096 D1 # OSR4096 = 0x58 # OSR-4096 D2
OSR8192 = (0x4A, 0.034) # OSR-8192 D1 # OSR8192 = 0x5A # OSR-8192 D2
# Command keys
ADC_READ = 0x00
RESET = 0x1E
class Chip(object):
""". . ."""
def __init__(self, i2c_bus=1):
self._device = smbus.SMBus(i2c_bus)
self.reset()
def reset(self):
"""
The Reset sequence shall be sent once after power-on to make sure that the calibration PROM gets loaded
into the internal register. It can be also used to reset the device PROM from an unknown condition.
The read command for PROM shall be executed once after reset by the user to read the content of the calibration
PROM and to calculate the calibration coefficients. There are in total 7 addresses resulting in a total memory
of 112 bit.
"""
self._device.write_byte(CHIP, RESET)
self._read_calibration_data()
def _read_calibration_data(self):
# self.CRC, self.FACTORY = self._device.read_byte_data(CHIP, REGISTER_C0, 2) # CRC and Factory settings
data = self._device.read_i2c_block_data(CHIP, REGISTER_C1, 2) # Sensitivity self.SENS
self.SENS = data[0] * 256 + data[1]
data = self._device.read_i2c_block_data(CHIP, REGISTER_C2, 2) # Pressure Offset self.OFF
self.OFF = data[0] * 256 + data[1]
data = self._device.read_i2c_block_data(CHIP, REGISTER_C3, 2) # Temp Coefficient of Pressure Sens. self.TCF
self.TCF = data[0] * 256 + data[1]
data = self._device.read_i2c_block_data(CHIP, REGISTER_C4, 2) # Temp Coefficient of Pressure Offset self.TCO
self.TCO = data[0] * 256 + data[1]
data = self._device.read_i2c_block_data(CHIP, REGISTER_C5, 2) # Reference Temperatureself.TREF
self.TREF = data[0] * 256 + data[1]
data = self._device.read_i2c_block_data(CHIP, REGISTER_C6, 2) # Temp Coefficient of Temperature self.TEMPSENS
self.TEMPSENS = data[0] * 256 + data[1]
def _read_raw_pressure(self, osr=OSR256):
"""Request converted data. Waits times used im an Arduino driver before reading that request."""
self._device.write_byte(CHIP, osr[0])
sleep(osr[1])
raw_value = self._device.read_i2c_block_data(CHIP, ADC_READ, 3) # raw_value = MSB2, MSB1, LSB
raw_pressure = raw_value[0] * 65536 + raw_value[1] * 256 + raw_value[2] # should 256 become OSR value?
return raw_pressure # D1
def _read_raw_temperature(self, osr=OSR256):
"""Request converted data. Waits times used im an Arduino driver before blah, blah, blah."""
tempsample = 16 + osr[0] # Increment Temperature convert command address from Pressure address
self._device.write_byte(CHIP, tempsample) # sh/could stay with OSR256.
sleep(osr[1]) # Only assuming the delay requirement for Temperature is the same as Pressure.
raw_value = self._device.read_i2c_block_data(CHIP, ADC_READ, 3) # raw_value = MSB2, MSB1, LSB
raw_temperature = raw_value[0] * 65536 + raw_value[1] * 256 + raw_value[2]
return raw_temperature # D2
def get_data(self):
"""Convert raw date into calibrated pressure (pascals) and temperature (degrees)
"""
raw_pressure = self._read_raw_pressure() # TODO: OSR settings
raw_temperature = self._read_raw_temperature()
delta_temp = raw_temperature - self.TREF * 256
offset = self.OFF * 131072 + (self.TCO * delta_temp) / 64
sens = self.SENS * 65536 + (self.TCF * delta_temp) / 128
offset2 = 0
sens2 = 0
t2 = 0 # Temp scaling
temp = 2000 + delta_temp * self.TEMPSENS / 8388608
if temp > 2000:
t2 = 5 * delta_temp * delta_temp / 274877906944
offset2 = 0
sens2 = 0
elif temp < 2000:
t2 = 3 * (delta_temp * delta_temp) / 8589934592
offset2 = 61 * ((temp - 2000) * (temp - 2000)) / 16
sens2 = 29 * ((temp - 2000) * (temp - 2000)) / 16
if temp < -1500:
offset2 += 17 * ((temp + 1500) * (temp + 1500))
sens2 += 9 * ((temp + 1500) * (temp + 1500))
offset -= offset2
sens -= sens2
temp -= t2
pressure = ((((raw_pressure * sens) / 2097152) - offset) / 32768.0)
temperature = temp / 100.0
return pressure, temperature
if __name__ == '__main__':
chip = Chip()
while True:
pressure, temperature = chip.get_data()
print('Pascals: {} TempC: {}'.format(pressure, temperature))
sleep(1)
#
# Someday a cleaner Python interface will live here
#
# End