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