1# -*- coding: UTF-8 -*-
2
3"""
4The driver for spl06 chip, it is a temperature and humidity sensor.
5"""
6
7from driver import I2C
8from utime import sleep_ms
9import math
10
11EEPROM_CHIP_ADDRESS = 0x77;
12
13class spl06Error(Exception):
14    def __init__(self, value=0, msg="spl06 common error"):
15        self.value = value
16        self.msg = msg
17
18    def __str__(self):
19        return "Error code:%d, Error message: %s" % (self.value, str(self.msg))
20
21    __repr__ = __str__
22
23class SPL06(object):
24    """
25    This class implements spl06 chip's defs.
26    """
27    def __init__(self):
28        self.i2cDev = None
29
30    def open(self, devid):
31        self.i2cDev = I2C()
32        self.i2cDev.open(devid)
33
34    def i2c_eeprom_read_var(self, chipAddress, addr):
35        return self.devRegReadWrite1Byte(0, addr, 0);
36
37    def devRegRead1Byte(self, addr):
38        return self.devRegReadWrite1Byte(0, addr, 0);
39
40    def devRegReadWrite1Byte(self, mode, addr, value):
41        #0 read mode
42        #1 write mode
43        if (mode == 0):
44            Reg = bytearray([addr])
45            self.i2cDev.write(Reg);
46            sleep_ms(30)
47            tmp = bytearray(1)
48            self.i2cDev.read(tmp)
49            print("<-- read addr " + str(addr) + ", value = " + str(tmp[0]));
50            return tmp[0];
51        else:
52            Reg = bytearray([addr, value])
53            self.i2cDev.write(Reg);
54            print("--> write addr " + str(addr) + ", value = " + str(value));
55            return 0;
56
57    def init(self):
58        tmp = 0;
59        rRegID = bytearray([0x0D, 0x0]);
60        wRegPressure8xOversampling = bytearray([0x06, 0x03]);
61        wRegTemperature8xOversampling = bytearray([0x07, 0x83]);
62        wRegContinuousTempAndPressureMeasurement = bytearray([0x08, 0B0111]);
63        wRegFIFOPressureMeasurement = bytearray([0x09, 0x00]);
64
65        tmp = rRegID;
66        self.devRegReadWrite1Byte(0, tmp[0], tmp[1]);
67
68        tmp = wRegPressure8xOversampling;
69        self.devRegReadWrite1Byte(1, tmp[0], tmp[1]);
70        tmp = wRegTemperature8xOversampling;
71        self.devRegReadWrite1Byte(1, tmp[0], tmp[1]);
72        tmp = wRegContinuousTempAndPressureMeasurement;
73        self.devRegReadWrite1Byte(1, tmp[0], tmp[1]);
74        tmp = wRegFIFOPressureMeasurement;
75        self.devRegReadWrite1Byte(1, tmp[0], tmp[1]);
76
77    # Get the firmware version of the chip.
78    def getID(self) :
79        reg = bytearray([0x0D]);
80        version = bytearray(1);
81
82        self.i2cDev.write(reg);
83        self.i2cDev.read(version);
84        print("spl06 ID is " + str(version[0]));
85
86        return version[0];
87
88
89    def get_altitude(self, pressure, seaLevelhPa):
90        if (seaLevelhPa == 0):
91            return -1;
92
93        pressure /= 100;
94        altitude = 44330 * (1.0 - math.pow(pressure / seaLevelhPa, 0.1903));
95
96        return altitude;
97
98    def get_temperature_scale_factor(self):
99        tmp_Byte = self.i2c_eeprom_read_var(EEPROM_CHIP_ADDRESS, 0X07); # MSB
100
101        tmp_Byte = tmp_Byte & 0B00000111;
102        print("tmp_Byte: %d\n" %tmp_Byte);
103
104        if (tmp_Byte == 0B000):
105            k = 524288.0;
106
107        elif (tmp_Byte == 0B001):
108            k = 1572864.0;
109
110        elif (tmp_Byte == 0B010):
111            k = 3670016.0;
112
113        elif (tmp_Byte == 0B011):
114            k = 7864320.0;
115
116        elif (tmp_Byte == 0B100):
117            k = 253952.0;
118
119        elif (tmp_Byte == 0B101):
120            k = 516096.0;
121
122        elif (tmp_Byte == 0B110):
123            k = 1040384.0;
124
125        elif (tmp_Byte == 0B111):
126            k = 2088960.0;
127
128        print("k=%d\n" %k);
129        return k;
130
131    def get_pressure_scale_factor(self):
132        tmp_Byte = self.i2c_eeprom_read_var(EEPROM_CHIP_ADDRESS, 0X06); # MSB
133        # tmp_Byte = tmp_Byte >> 4; #Focus on bits 6-4 - measurement rate
134        tmp_Byte = tmp_Byte & 0B00000111; # Focus on 2-0 oversampling rate
135        # tmp_Byte = 0B011;
136
137        # oversampling rate
138        if (tmp_Byte == 0B000):
139            k = 524288.0;
140
141        elif (tmp_Byte == 0B001):
142            k = 1572864.0;
143
144        elif (tmp_Byte == 0B010):
145            k = 3670016.0;
146
147        elif (tmp_Byte == 0B011):
148            k = 7864320.0;
149
150        elif (tmp_Byte == 0B100):
151            k = 253952.0;
152
153        elif (tmp_Byte == 0B101):
154            k = 516096.0;
155
156        elif (tmp_Byte == 0B110):
157            k = 1040384.0;
158
159        elif (tmp_Byte == 0B111):
160            k = 2088960.0;
161
162        print("k=%d\n" %k);
163        return k;
164
165    def get_traw(self):
166        tmp_MSB  = self.i2c_eeprom_read_var(EEPROM_CHIP_ADDRESS, 0X03); # MSB
167        tmp_LSB  = self.i2c_eeprom_read_var(EEPROM_CHIP_ADDRESS, 0X04); # LSB
168        tmp_XLSB = self.i2c_eeprom_read_var(EEPROM_CHIP_ADDRESS, 0X05); # XLSB
169
170        tmp = (tmp_MSB << 8) | tmp_LSB;
171        tmp = (tmp << 8) | tmp_XLSB;
172
173        if (tmp & (1 << 23)):
174            tmp = tmp | 0XFF000000; # Set left bits to one for 2's complement
175                                    # conversion of negitive number
176        print("get_traw: tmp_MSB=%d, tmp_LSB=%d, tmp_XLSB=%d\n" %(tmp_MSB, tmp_LSB, tmp_XLSB));
177        return tmp;
178
179    def get_praw(self):
180        tmp_MSB  = self.i2c_eeprom_read_var(EEPROM_CHIP_ADDRESS, 0X00); # MSB
181        tmp_LSB  = self.i2c_eeprom_read_var(EEPROM_CHIP_ADDRESS, 0X01); # LSB
182        tmp_XLSB = self.i2c_eeprom_read_var(EEPROM_CHIP_ADDRESS, 0X02); # XLSB
183
184        tmp = (tmp_MSB << 8) | tmp_LSB;
185        tmp = (tmp << 8) | tmp_XLSB;
186
187        if (tmp & (1 << 23)):
188            tmp = -((2 << 23) - tmp)
189
190        return tmp;
191
192    def get_c0(self):
193        tmp_MSB = self.i2c_eeprom_read_var(EEPROM_CHIP_ADDRESS, 0X10);
194        tmp_LSB = self.i2c_eeprom_read_var(EEPROM_CHIP_ADDRESS, 0X11);
195
196        tmp_LSB = tmp_LSB >> 4;
197
198        tmp = (tmp_MSB << 4) | tmp_LSB;
199
200        if (tmp & (1 << 11)):
201            # Check for 2's complement negative number
202            tmp = tmp | 0XF000; # Set left bits to one for 2's complement
203                                # conversion of negitive number
204        if (tmp > (1 << 15)):
205            tmp &= 0xFFFF
206            tmp = tmp - (1<<16)
207
208        print("get_c0: tmp_MSB=%d, tmp_LSB=%d, tmp=%d\n" %(tmp_MSB, tmp_LSB, tmp));
209
210        return tmp;
211
212    def get_c1(self):
213        tmp_MSB = self.i2c_eeprom_read_var(EEPROM_CHIP_ADDRESS, 0X11);
214        tmp_LSB = self.i2c_eeprom_read_var(EEPROM_CHIP_ADDRESS, 0X12);
215
216        tmp_MSB = tmp_MSB & 0XF;
217        tmp     = (tmp_MSB << 8) | tmp_LSB;
218
219        if (tmp & (1 << 11)):
220            # Check for 2's complement negative number
221            tmp = tmp | 0XF000; # Set left bits to one for 2's complement
222                                # conversion of negitive number
223
224        if (tmp > (1 << 15)):
225            tmp = tmp - (1<<16)
226        print("get_c1: tmp_MSB=%d, tmp_LSB=%d, tmp=%d\n" %(tmp_MSB, tmp_LSB, tmp));
227        return tmp;
228
229    def get_c00(self):
230        tmp_MSB  = self.i2c_eeprom_read_var(EEPROM_CHIP_ADDRESS, 0X13);
231        tmp_LSB  = self.i2c_eeprom_read_var(EEPROM_CHIP_ADDRESS, 0X14);
232        tmp_XLSB = self.i2c_eeprom_read_var(EEPROM_CHIP_ADDRESS, 0X15);
233
234        tmp_XLSB = tmp_XLSB >> 4;
235
236        tmp = (tmp_MSB << 8) | tmp_LSB;
237        tmp = (tmp << 4) | tmp_XLSB;
238
239        tmp = tmp_MSB << 12 | tmp_LSB << 4 | tmp_XLSB >> 4;
240
241        if (tmp & (1 << 19)):
242            tmp = tmp | 0XFFF00000; # Set left bits to one for 2's complement
243                                    # conversion of negitive number
244        return tmp;
245
246    def get_c10(self):
247        tmp_MSB  = self.i2c_eeprom_read_var(EEPROM_CHIP_ADDRESS, 0X15); # 4 bits
248        tmp_LSB  = self.i2c_eeprom_read_var(EEPROM_CHIP_ADDRESS, 0X16); # 8 bits
249        tmp_XLSB = self.i2c_eeprom_read_var(EEPROM_CHIP_ADDRESS, 0X17); # 8 bits
250
251        tmp_MSB = tmp_MSB & 0b00001111;
252
253        tmp = (tmp_MSB << 4) | tmp_LSB;
254        tmp = (tmp << 8) | tmp_XLSB;
255
256        tmp = tmp_MSB << 16 | tmp_LSB << 8 | tmp_XLSB;
257
258        if (tmp & (1 << 19)):
259            tmp = tmp | 0XFFF00000; # Set left bits to one for 2's complement
260                                    # conversion of negitive number
261
262        if (tmp > (1 << 15)):
263            tmp &= 0xFFFF
264            tmp = tmp - (1<<16);
265
266        return tmp;
267
268    def get_c01(self):
269        tmp_MSB = self.i2c_eeprom_read_var(EEPROM_CHIP_ADDRESS, 0X18);
270        tmp_LSB = self.i2c_eeprom_read_var(EEPROM_CHIP_ADDRESS, 0X19);
271
272        tmp = (tmp_MSB << 8) | tmp_LSB;
273        if (tmp > (1 << 15)):
274            tmp = tmp - (1<<16);
275        return tmp;
276
277    def get_c11(self):
278        tmp_MSB = self.i2c_eeprom_read_var(EEPROM_CHIP_ADDRESS, 0X1A);
279        tmp_LSB = self.i2c_eeprom_read_var(EEPROM_CHIP_ADDRESS, 0X1B);
280
281        tmp = (tmp_MSB << 8) | tmp_LSB;
282        if (tmp > (1 << 15)):
283            tmp = tmp - (1<<16);
284        return tmp;
285
286    def get_c20(self):
287        tmp_MSB = self.i2c_eeprom_read_var(EEPROM_CHIP_ADDRESS, 0X1C);
288        tmp_LSB = self.i2c_eeprom_read_var(EEPROM_CHIP_ADDRESS, 0X1D);
289
290        tmp = (tmp_MSB << 8) | tmp_LSB;
291        if (tmp > (1 << 15)):
292            tmp = tmp - (1<<16);
293        return tmp;
294
295    def get_c21(self):
296        tmp_MSB = self.i2c_eeprom_read_var(EEPROM_CHIP_ADDRESS, 0X1E);
297        tmp_LSB = self.i2c_eeprom_read_var(EEPROM_CHIP_ADDRESS, 0X1F);
298
299        tmp = (tmp_MSB << 8) | tmp_LSB;
300        if (tmp > (1 << 15)):
301            tmp = tmp - (1<<16);
302        return tmp;
303
304    def get_c30(self):
305        tmp_MSB = self.i2c_eeprom_read_var(EEPROM_CHIP_ADDRESS, 0X20);
306        tmp_LSB = self.i2c_eeprom_read_var(EEPROM_CHIP_ADDRESS, 0X21);
307
308        tmp = (tmp_MSB << 8) | tmp_LSB;
309        if (tmp > (1 << 15)):
310            tmp = tmp - (1<<16);
311        return tmp;
312
313    def spl06_getdata(self):
314        # Serial.println("\nDevice Reset\n");
315        # i2c_eeprom_write_var(EEPROM_CHIP_ADDRESS, 0x0C, 0b1001);
316        # delay(1000);
317
318        tmp    = self.i2c_eeprom_read_var(EEPROM_CHIP_ADDRESS, 0x0D);
319        tmp    = self.i2c_eeprom_read_var(EEPROM_CHIP_ADDRESS, 0x06);
320        tmp    = self.i2c_eeprom_read_var(EEPROM_CHIP_ADDRESS, 0x07);
321        tmp    = self.i2c_eeprom_read_var(EEPROM_CHIP_ADDRESS, 0x08);
322        tmp    = self.i2c_eeprom_read_var(EEPROM_CHIP_ADDRESS, 0x09);
323        tmp    = self.i2c_eeprom_read_var(EEPROM_CHIP_ADDRESS, 0x0A);
324        tmp    = self.i2c_eeprom_read_var(EEPROM_CHIP_ADDRESS, 0x0B);
325
326        c0              = self.get_c0();
327        c1              = self.get_c1();
328        c00             = self.get_c00();
329        c10             = self.get_c10();
330        c01             = self.get_c01();
331        c11             = self.get_c11();
332        c20             = self.get_c20();
333        c21             = self.get_c21();
334        c30             = self.get_c30();
335        traw    = self.get_traw();
336        traw_sc = traw / self.get_temperature_scale_factor();
337        traw_sc = round(traw_sc,2)
338        print("traw_sc: %0.2f\n" %traw_sc);
339
340        Ctemp = c0 * 0.5 + c1 * traw_sc;
341        Ctemp = round(Ctemp,2)
342        print("Ctemp:" + str(Ctemp) + ".  " + "c0:" + str(c0) + " c1" + str(c1) + " traw_sc:" + str(traw_sc));
343
344        Ftemp = (Ctemp * 9 / 5) + 32;
345        Ftemp = round(Ftemp,2)
346        print("Ftemp: %d" %Ftemp)
347
348        praw = self.get_praw();
349
350        praw_sc = (praw) / self.get_pressure_scale_factor();
351
352        print("praw: %d" %praw)
353        print("praw_sc: %d" %praw_sc)
354
355        print("c00: %d" %c00)
356        print("c10: %d" %c10)
357        print("c20: %d" %c20)
358        print("c30: %d" %c30)
359        print("c01: %d" %c01)
360        print("c11: %d" %c11)
361        print("c21: %d" %c21)
362
363        pcomp =\
364            (c00) + \
365            praw_sc * ((c10) + \
366                    praw_sc * ((c20) + praw_sc * (c30))) + \
367            traw_sc * (c01) + \
368            traw_sc * praw_sc * ((c11) + praw_sc * (c21));
369
370        pressure = pcomp / 100; # convert to mb
371        print("pressure: %d" %pressure)
372
373        # local_pressure = 1010.5; # Look up local sea level pressure on
374        # google
375        local_pressure =  \
376            1011.1; # Look up local sea level pressure on google # Local pressure
377                    # from airport website 8/22
378        print("Local Airport Sea Level Pressure: %0.2f mb\n" %local_pressure);
379        altitude = self.get_altitude(pcomp, local_pressure);
380        print("altitude: %d" %altitude)
381
382    def close(self):
383        self.i2cDev.close()
384