|
| 1 | +rem |
| 2 | +rem https://piico.dev/p2 |
| 3 | +rem https://www.mouser.com/datasheet/2/783/BST-BME280-DS002-1509607.pdf |
| 4 | +rem |
| 5 | +rem based on:https://raw.githubusercontent.com/CoreElectronics/CE-PiicoDev-BME280-MicroPython-Module/main/PiicoDev_BME280.py |
| 6 | +rem Original header: |
| 7 | +rem A MicroPython class for the Core Electronics PiicoDev Atmospheric Sensor BME280 |
| 8 | +rem Ported by Michael Ruppe at Core Electronics |
| 9 | +rem MAR 2021 |
| 10 | +rem Original repo https://bit.ly/2yJwysL |
| 11 | +rem |
| 12 | +rem wiring: |
| 13 | +rem SDA1 -> pin 17 |
| 14 | +rem CLK1 -> pin 16 |
| 15 | +rem |
| 16 | + |
| 17 | +import teensy |
| 18 | +import ssd1306 as display |
| 19 | + |
| 20 | +const screenWidth = 128 |
| 21 | +const screenHeight = 64 |
| 22 | +const address = 0x77 |
| 23 | +const t_mode = 2 |
| 24 | +const p_mode = 5 |
| 25 | +const h_mode = 1 |
| 26 | +const iir = 1 |
| 27 | + |
| 28 | +I2C = teensy.OpenI2C(1, 17, 16) |
| 29 | +sdata = bme280_init(t_mode, p_mode, h_mode, iir) |
| 30 | + |
| 31 | +display.init() |
| 32 | +display.clear() |
| 33 | +display.setCursor(0, 0) |
| 34 | +display.setTextSize(1) |
| 35 | + |
| 36 | +while 1 |
| 37 | + [temp, pres, humi] = values(sdata) |
| 38 | + display.clear() |
| 39 | + display.setCursor(0, 0): display.print("Temp: " + temp) |
| 40 | + display.setCursor(0, 10): display.print("Pres: " + pres) |
| 41 | + display.setCursor(0, 20): display.print("Humi: " + humi) |
| 42 | + display.setCursor(0, 30): display.print("Cntr: " + j) |
| 43 | + display.setCursor(0, 40): display.print("Free: " + str(teensy.free())) |
| 44 | + display.flush() |
| 45 | + delay 1 |
| 46 | + j++ |
| 47 | +wend |
| 48 | + |
| 49 | +rem the code below could be moved to a unit |
| 50 | +func short(dat) |
| 51 | + if dat > 32767 then |
| 52 | + return dat - 65536 |
| 53 | + else |
| 54 | + return dat |
| 55 | + endif |
| 56 | +end |
| 57 | + |
| 58 | +func read8(register) |
| 59 | + I2C.write(ADDRESS, register) |
| 60 | + return I2C.read(ADDRESS, 1) |
| 61 | +end |
| 62 | + |
| 63 | +func read16(register) |
| 64 | + I2C.write(ADDRESS, register) |
| 65 | + ' local b1 = I2C.read(ADDRESS, 1) |
| 66 | + ' local b2 = I2C.read(ADDRESS, 1) |
| 67 | + ' return (b2 lshift 8) BOR b1 |
| 68 | + local buffer = I2C.read(ADDRESS, 2) |
| 69 | + return (buffer[1] lshift 8) BOR buffer[0] |
| 70 | +end |
| 71 | + |
| 72 | +sub write8(register, dat) |
| 73 | + I2C.write(ADDRESS, register) |
| 74 | + I2C.write(ADDRESS, dat) |
| 75 | +end |
| 76 | + |
| 77 | +func bme280_init(t_mode, p_mode, h_mode, iir) |
| 78 | + local result = {} |
| 79 | + result.t_mode = t_mode |
| 80 | + result.p_mode = p_mode |
| 81 | + result.h_mode = h_mode |
| 82 | + result.iir = iir |
| 83 | + result.t_fine = 0 |
| 84 | + result.T1 = read16(0x88) |
| 85 | + result.T2 = short(read16(0x8A)) |
| 86 | + result.T3 = short(read16(0x8C)) |
| 87 | + result.P1 = read16(0x8E) |
| 88 | + result.P2 = short(read16(0x90)) |
| 89 | + result.P3 = short(read16(0x92)) |
| 90 | + result.P4 = short(read16(0x94)) |
| 91 | + result.P5 = short(read16(0x96)) |
| 92 | + result.P6 = short(read16(0x98)) |
| 93 | + result.P7 = short(read16(0x9A)) |
| 94 | + result.P8 = short(read16(0x9C)) |
| 95 | + result.P9 = short(read16(0x9E)) |
| 96 | + result.H1 = read8(0xA1) |
| 97 | + result.H2 = short(read16(0xE1)) |
| 98 | + result.H3 = read8(0xE3) |
| 99 | + |
| 100 | + local a = read8(0xE5) |
| 101 | + result.H4 = (read8(0xE4) lshift 4) + (a mod 16) |
| 102 | + result.H5 = (read8(0xE6) lshift 4) + (a rshift 4) |
| 103 | + result.H6 = read8(0xE7) |
| 104 | + if result.H6 > 127 then result.H6 -= 256 |
| 105 | + |
| 106 | + write8(0xF2, h_mode) |
| 107 | + sleep_ms(10) |
| 108 | + write8(0xF4, 0x24) |
| 109 | + sleep_ms(10) |
| 110 | + write8(0xF5, iir lshift 2) |
| 111 | + return result |
| 112 | +end |
| 113 | + |
| 114 | +func read_raw_data(sdata) |
| 115 | + write8(0xF4, (sdata.p_mode lshift 5 | sdata.t_mode lshift 2 | 1)) |
| 116 | + sleep_time = 1250 |
| 117 | + |
| 118 | + if sdata.t_mode in [1, 2, 3, 4, 5] then |
| 119 | + sleep_time += 2300*(1 lshift sdata.t_mode) |
| 120 | + endif |
| 121 | + if sdata.p_mode in [1, 2, 3, 4, 5] then |
| 122 | + sleep_time += 575+(2300*(1 lshift sdata.p_mode)) |
| 123 | + endif |
| 124 | + if sdata.h_mode in [1, 2, 3, 4, 5] then |
| 125 | + sleep_time += 575+(2300*(1 lshift sdata.h_mode)) |
| 126 | + endif |
| 127 | + |
| 128 | + sleep_ms(1 + sleep_time / 1000) |
| 129 | + |
| 130 | + while (read16(0xF3) & 0x08) |
| 131 | + sleep_ms(1) |
| 132 | + wend |
| 133 | + |
| 134 | + local raw_p = ((read8(0xF7) lshift 16) | (read8(0xF8) lshift 8) | read8(0xF9)) rshift 4 |
| 135 | + local raw_t = ((read8(0xFA) lshift 16) | (read8(0xFB) lshift 8) | read8(0xFC)) rshift 4 |
| 136 | + local raw_h = (read8(0xFD) lshift 8)| read8(0xFE) |
| 137 | + return [raw_t, raw_p, raw_h] |
| 138 | +end |
| 139 | + |
| 140 | +rem yikes !!!! |
| 141 | +func read_compensated_data(sdata) |
| 142 | + local raw_t, raw_p, raw_h, var1, var2, var3, h |
| 143 | + |
| 144 | + [raw_t, raw_p, raw_h] = read_raw_data(sdata) |
| 145 | + |
| 146 | + var1 = ((raw_t rshift 3) - (sdata.T1 lshift 1)) * (sdata.T2 rshift 11) |
| 147 | + var2 = (raw_t rshift 4) - sdata.T1 |
| 148 | + var2 = var2*((raw_t rshift 4) - sdata.T1) |
| 149 | + var2 = ((var2 rshift 12) * sdata.T3) rshift 14 |
| 150 | + sdata.t_fine = var1+var2 |
| 151 | + |
| 152 | + local temp = (sdata.t_fine * 5 + 128) rshift 8 |
| 153 | + var1 = sdata.t_fine - 128000 |
| 154 | + var2 = var1 * var1 * sdata.P6 |
| 155 | + var2 = var2 + ((var1*sdata.P5) lshift 17) |
| 156 | + var2 = var2 + (sdata.P4 lshift 35) |
| 157 | + var1 = (((var1 * var1 * sdata.P3) rshift 8) + ((var1 * sdata.P2) lshift 12)) |
| 158 | + var1 = (((1 lshift 47)+var1)*sdata.P1) rshift 33 |
| 159 | + if var1 == 0 then |
| 160 | + pres = 0 |
| 161 | + else |
| 162 | + p = ((((1048576-raw_p) lshift 31)-var2) * 3125) / var1 |
| 163 | + var1 = (sdata.P9 * (p rshift 13) * (p rshift 13)) rshift 25 |
| 164 | + var2 = (sdata.P8 * p) rshift 19 |
| 165 | + pres = ((p + var1 + var2) rshift 8) + (sdata.P7 lshift 4) |
| 166 | + endif |
| 167 | + |
| 168 | + h = sdata.t_fine - 76800 |
| 169 | + h = (((((raw_h lshift 14) - (sdata.H4 lshift 20) - (sdata.H5 * h)) + 16384) rshift 15) * & |
| 170 | + (((((((h * sdata.H6) rshift 10) * (((h * sdata.H3) rshift 11) + 32768)) rshift 10) + 2097152) * sdata.H2 + 8192) rshift 14)) |
| 171 | + h = h - (((((h rshift 15) * (h rshift 15)) rshift 7) * sdata.H1) rshift 4) |
| 172 | + h = iff(h < 0, 0, h) |
| 173 | + h = iff(h > 419430400, 419430400, h) |
| 174 | + humi = h rshift 12 |
| 175 | + return [temp, pres, humi] |
| 176 | +end |
| 177 | + |
| 178 | +func values(sdata) |
| 179 | + local temp, pres, humi |
| 180 | + [temp, pres, humi] = read_compensated_data(sdata) |
| 181 | + return [temp / 100, pres / 256, humi / 1024] |
| 182 | +end |
| 183 | + |
| 184 | +func pressure_precision(sdata) |
| 185 | + local p = read_compensated_data(sdata)[1] |
| 186 | + local pi = p / 256 |
| 187 | + local pd = (p % 256) / 256 |
| 188 | + return [pi, pd] |
| 189 | +end |
| 190 | + |
| 191 | +func altitude(sdata) |
| 192 | + local pi, pd |
| 193 | + local pressure_sea_level=1013.25 |
| 194 | + [pi, pd] = pressure_precision(sdata) |
| 195 | + return 44330 * (1 - (((pi + pd) / 100) / pressure_sea_level) * (1 / 5.255)) |
| 196 | +end |
| 197 | + |
| 198 | +sub sleep_ms(ms) |
| 199 | + delay ms |
| 200 | +end |
0 commit comments