Jens Schmidt / MicrobitIAQ

Dependencies:   microbit

Committer:
jsa1969
Date:
Wed Dec 05 11:27:33 2018 +0000
Revision:
17:a2c4dd192146
Parent:
14:71060505061e
Child:
18:c4ac93e01027
more logging

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jsa1969 0:cef60cc92da0 1 /*
jsa1969 0:cef60cc92da0 2 The MIT License (MIT)
jsa1969 0:cef60cc92da0 3
jsa1969 0:cef60cc92da0 4 Copyright (c) 2016 British Broadcasting Corporation.
jsa1969 0:cef60cc92da0 5 This software is provided by Lancaster University by arrangement with the BBC.
jsa1969 0:cef60cc92da0 6
jsa1969 0:cef60cc92da0 7 Permission is hereby granted, free of charge, to any person obtaining a
jsa1969 0:cef60cc92da0 8 copy of this software and associated documentation files (the "Software"),
jsa1969 0:cef60cc92da0 9 to deal in the Software without restriction, including without limitation
jsa1969 0:cef60cc92da0 10 the rights to use, copy, modify, merge, publish, distribute, sublicense,
jsa1969 0:cef60cc92da0 11 and/or sell copies of the Software, and to permit persons to whom the
jsa1969 0:cef60cc92da0 12 Software is furnished to do so, subject to the following conditions:
jsa1969 0:cef60cc92da0 13
jsa1969 0:cef60cc92da0 14 The above copyright notice and this permission notice shall be included in
jsa1969 0:cef60cc92da0 15 all copies or substantial portions of the Software.
jsa1969 0:cef60cc92da0 16
jsa1969 0:cef60cc92da0 17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
jsa1969 0:cef60cc92da0 18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
jsa1969 0:cef60cc92da0 19 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
jsa1969 0:cef60cc92da0 20 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
jsa1969 0:cef60cc92da0 21 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
jsa1969 0:cef60cc92da0 22 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
jsa1969 0:cef60cc92da0 23 DEALINGS IN THE SOFTWARE.
jsa1969 0:cef60cc92da0 24 */
jsa1969 0:cef60cc92da0 25
jsa1969 0:cef60cc92da0 26 #include "MicroBit.h"
jsa1969 0:cef60cc92da0 27
jsa1969 0:cef60cc92da0 28 #include "bme680.h"
jsa1969 2:544117df8c65 29 #include "sgp30.h"
jsa1969 2:544117df8c65 30 #include "dotmath.h"
jsa1969 11:6844a5578b4f 31 #include "nvstore.h"
jsa1969 2:544117df8c65 32
jsa1969 1:f9245fb53737 33 #include "physics.h"
jsa1969 0:cef60cc92da0 34
jsa1969 0:cef60cc92da0 35 MicroBit uBit;
jsa1969 2:544117df8c65 36 Bme680* bme680 = NULL;
jsa1969 2:544117df8c65 37 struct bme680_field_data* bme680Data = NULL;
jsa1969 2:544117df8c65 38 Sgp30* sgp30 = NULL;
jsa1969 12:96eb06e837f4 39 I2cCallbacks* callbacks = NULL;
jsa1969 12:96eb06e837f4 40 NvStore* nvStore = NULL;
jsa1969 12:96eb06e837f4 41
jsa1969 12:96eb06e837f4 42 bool cancelMeasureLoops = false;
jsa1969 12:96eb06e837f4 43 int runningLoops = 0;
jsa1969 0:cef60cc92da0 44
jsa1969 12:96eb06e837f4 45 void waitForLooppsToFinish() {
jsa1969 12:96eb06e837f4 46 cancelMeasureLoops=true;
jsa1969 12:96eb06e837f4 47 while (runningLoops>0) {
jsa1969 12:96eb06e837f4 48 uBit.sleep(10);
jsa1969 12:96eb06e837f4 49 }
jsa1969 12:96eb06e837f4 50 cancelMeasureLoops = false;
jsa1969 12:96eb06e837f4 51 }
jsa1969 0:cef60cc92da0 52
jsa1969 11:6844a5578b4f 53 void displayPixels(int ystart, int pixels, int maxpixels) {
jsa1969 11:6844a5578b4f 54 int y = ystart;
jsa1969 11:6844a5578b4f 55 for (int i=0; i+((y-ystart)*5)<maxpixels; ++i) {
jsa1969 11:6844a5578b4f 56 if (i==5) {
jsa1969 11:6844a5578b4f 57 ++y;
jsa1969 11:6844a5578b4f 58 i=0;
jsa1969 11:6844a5578b4f 59 }
jsa1969 11:6844a5578b4f 60 int pixelsused = i+((y-ystart)*5);
jsa1969 11:6844a5578b4f 61 uBit.display.image.setPixelValue(i, y, pixelsused<pixels? 255 : 0);
jsa1969 10:8e6b71a46871 62 }
jsa1969 10:8e6b71a46871 63 }
jsa1969 10:8e6b71a46871 64
jsa1969 1:f9245fb53737 65 int measureBme680(){
jsa1969 1:f9245fb53737 66 if (bme680!=NULL && bme680Data!=NULL) {
jsa1969 1:f9245fb53737 67 return bme680->measure(
jsa1969 1:f9245fb53737 68 bme680Data,
jsa1969 2:544117df8c65 69 bme680Data->temperature==0 ?
jsa1969 2:544117df8c65 70 uBit.thermometer.getTemperature()
jsa1969 2:544117df8c65 71 :bme680Data->temperature,
jsa1969 12:96eb06e837f4 72 2000, 250);
jsa1969 1:f9245fb53737 73 } else {
jsa1969 1:f9245fb53737 74 return BME680_E_DEV_NOT_FOUND;
jsa1969 1:f9245fb53737 75 }
jsa1969 0:cef60cc92da0 76 }
jsa1969 0:cef60cc92da0 77
jsa1969 11:6844a5578b4f 78 void measureAndDisplayBme680() {
jsa1969 11:6844a5578b4f 79 if (bme680!=NULL) {
jsa1969 11:6844a5578b4f 80 uBit.display.image.setPixelValue(4, 4, 255);
jsa1969 11:6844a5578b4f 81 if (measureBme680()==MICROBIT_OK) {
jsa1969 14:71060505061e 82 nvStore->updateGas(bme680Data->gas_resistance);
jsa1969 17:a2c4dd192146 83 nvStore->updateTemp(bme680Data->temperature);
jsa1969 17:a2c4dd192146 84 nvStore->updatePress(bme680Data->pressure);
jsa1969 17:a2c4dd192146 85 nvStore->updateHumidity(bme680Data->humidity);
jsa1969 17:a2c4dd192146 86
jsa1969 14:71060505061e 87 uBit.display.image.setPixelValue(0, 4, 255);
jsa1969 11:6844a5578b4f 88 uBit.display.image.setPixelValue(4, 4, 0);
jsa1969 11:6844a5578b4f 89 int bmeY = sgp30!=NULL ? 2 : 0;
jsa1969 11:6844a5578b4f 90 int bmeMaxPixels = sgp30!=NULL ? 5 : 15;
jsa1969 14:71060505061e 91 displayPixels(bmeY, DotMath::pixels(bme680Data->gas_resistance, nvStore->getGasMax(), bmeMaxPixels),
jsa1969 11:6844a5578b4f 92 bmeMaxPixels);
jsa1969 11:6844a5578b4f 93 displayPixels(3, 5*bme680Data->humidity/100000, 5);
jsa1969 14:71060505061e 94 } else {
jsa1969 14:71060505061e 95 uBit.display.image.setPixelValue(0, 4, 0);
jsa1969 2:544117df8c65 96 }
jsa1969 12:96eb06e837f4 97 uBit.display.image.setPixelValue(4, 4, 0);
jsa1969 11:6844a5578b4f 98 }
jsa1969 11:6844a5578b4f 99 }
jsa1969 11:6844a5578b4f 100
jsa1969 11:6844a5578b4f 101 void measureAndDisplaySgp30() {
jsa1969 11:6844a5578b4f 102 if (sgp30!=NULL) {
jsa1969 11:6844a5578b4f 103 int sgpMaxPixels = 10;
jsa1969 11:6844a5578b4f 104 int secondLineStart = 2;
jsa1969 11:6844a5578b4f 105 if (bme680!=NULL) {
jsa1969 11:6844a5578b4f 106 sgpMaxPixels = 5;
jsa1969 11:6844a5578b4f 107 secondLineStart = 1;
jsa1969 11:6844a5578b4f 108 uBit.display.image.setPixelValue(2, 4, 255);
jsa1969 11:6844a5578b4f 109 if (sgp30->setHumidity(bme680Data->humidity, bme680Data->temperature)) {
jsa1969 11:6844a5578b4f 110 uBit.display.image.setPixelValue(2, 4, 0);
jsa1969 11:6844a5578b4f 111 }
jsa1969 11:6844a5578b4f 112 uBit.sleep(10);
jsa1969 11:6844a5578b4f 113 }
jsa1969 11:6844a5578b4f 114 uBit.display.image.setPixelValue(3, 4, 255);
jsa1969 11:6844a5578b4f 115 if (sgp30->IAQmeasure()) {
jsa1969 13:996026828be7 116 uBit.display.image.setPixelValue(1, 4, 255);
jsa1969 11:6844a5578b4f 117 uBit.display.image.setPixelValue(3, 4, 0);
jsa1969 12:96eb06e837f4 118 int co2Dots = min (5, sgp30->eCO2 /1500);
jsa1969 11:6844a5578b4f 119 displayPixels(0, 5 - DotMath::pixels(sgp30->TVOC, 20000, sgpMaxPixels), sgpMaxPixels);
jsa1969 11:6844a5578b4f 120 displayPixels(secondLineStart, co2Dots, sgpMaxPixels);
jsa1969 13:996026828be7 121 } else {
jsa1969 13:996026828be7 122 uBit.display.image.setPixelValue(1, 4, 0);
jsa1969 11:6844a5578b4f 123 }
jsa1969 2:544117df8c65 124 }
jsa1969 2:544117df8c65 125 }
jsa1969 2:544117df8c65 126
jsa1969 12:96eb06e837f4 127 void bmeMeasureLoop() {
jsa1969 12:96eb06e837f4 128 if (bme680!=NULL) {
jsa1969 12:96eb06e837f4 129 ++runningLoops;
jsa1969 12:96eb06e837f4 130 while (!cancelMeasureLoops){
jsa1969 11:6844a5578b4f 131 measureAndDisplayBme680();
jsa1969 13:996026828be7 132 uBit.sleep(500);
jsa1969 12:96eb06e837f4 133 }
jsa1969 12:96eb06e837f4 134 --runningLoops;
jsa1969 12:96eb06e837f4 135 }
jsa1969 12:96eb06e837f4 136 }
jsa1969 12:96eb06e837f4 137
jsa1969 12:96eb06e837f4 138 void sgpMeasureLoop() {
jsa1969 12:96eb06e837f4 139 if (sgp30!=NULL) {
jsa1969 12:96eb06e837f4 140 ++runningLoops;
jsa1969 12:96eb06e837f4 141 while (!cancelMeasureLoops){
jsa1969 11:6844a5578b4f 142 measureAndDisplaySgp30();
jsa1969 12:96eb06e837f4 143 uBit.sleep(950);
jsa1969 2:544117df8c65 144 }
jsa1969 12:96eb06e837f4 145 --runningLoops;
jsa1969 2:544117df8c65 146 }
jsa1969 12:96eb06e837f4 147 }
jsa1969 12:96eb06e837f4 148
jsa1969 12:96eb06e837f4 149 void startLoops() {
jsa1969 12:96eb06e837f4 150 if (runningLoops>0) {
jsa1969 12:96eb06e837f4 151 uBit.display.scroll("already running");
jsa1969 12:96eb06e837f4 152 return;
jsa1969 12:96eb06e837f4 153 }
jsa1969 14:71060505061e 154 create_fiber(sgpMeasureLoop);
jsa1969 12:96eb06e837f4 155 create_fiber(bmeMeasureLoop);
jsa1969 2:544117df8c65 156 }
jsa1969 2:544117df8c65 157
jsa1969 11:6844a5578b4f 158 void init680(){
jsa1969 9:5150afa50eb6 159 if (bme680!=NULL){
jsa1969 9:5150afa50eb6 160 delete bme680;
jsa1969 9:5150afa50eb6 161 }
jsa1969 10:8e6b71a46871 162
jsa1969 14:71060505061e 163 uint32_t gasMax = nvStore->getGasMax();
jsa1969 11:6844a5578b4f 164 if (gasMax>0) {
jsa1969 11:6844a5578b4f 165 uBit.display.scroll((int)gasMax);
jsa1969 11:6844a5578b4f 166 }
jsa1969 10:8e6b71a46871 167
jsa1969 14:71060505061e 168 bme680 = new Bme680(callbacks);
jsa1969 9:5150afa50eb6 169 int code = bme680->init();
jsa1969 9:5150afa50eb6 170 if (code == MICROBIT_OK){
jsa1969 9:5150afa50eb6 171 if (bme680Data==NULL) {
jsa1969 9:5150afa50eb6 172 bme680Data = new struct bme680_field_data;
jsa1969 9:5150afa50eb6 173 }
jsa1969 9:5150afa50eb6 174 code = bme680->measure(
jsa1969 9:5150afa50eb6 175 bme680Data,
jsa1969 9:5150afa50eb6 176 uBit.thermometer.getTemperature(),
jsa1969 9:5150afa50eb6 177 100, 100);
jsa1969 9:5150afa50eb6 178 }
jsa1969 9:5150afa50eb6 179 if (code != MICROBIT_OK){
jsa1969 9:5150afa50eb6 180 delete bme680;
jsa1969 9:5150afa50eb6 181 bme680 = NULL;
jsa1969 9:5150afa50eb6 182 delete bme680Data;
jsa1969 9:5150afa50eb6 183 bme680Data = NULL;
jsa1969 9:5150afa50eb6 184 uBit.display.scroll(code);
jsa1969 9:5150afa50eb6 185 } else {
jsa1969 9:5150afa50eb6 186 uBit.display.image.setPixelValue(0, 4, 255);
jsa1969 9:5150afa50eb6 187 }
jsa1969 11:6844a5578b4f 188 }
jsa1969 9:5150afa50eb6 189
jsa1969 11:6844a5578b4f 190 void initSgp30(){
jsa1969 9:5150afa50eb6 191 if (sgp30!=NULL){
jsa1969 9:5150afa50eb6 192 delete sgp30;
jsa1969 9:5150afa50eb6 193 }
jsa1969 9:5150afa50eb6 194 sgp30 = new Sgp30(callbacks);
jsa1969 9:5150afa50eb6 195 if (sgp30->test() && sgp30->begin()) {
jsa1969 9:5150afa50eb6 196 uBit.display.image.setPixelValue(1, 4, 255);
jsa1969 9:5150afa50eb6 197 } else {
jsa1969 9:5150afa50eb6 198 delete sgp30;
jsa1969 9:5150afa50eb6 199 sgp30 = NULL;
jsa1969 11:6844a5578b4f 200 }}
jsa1969 11:6844a5578b4f 201
jsa1969 11:6844a5578b4f 202 void initSensors() {
jsa1969 12:96eb06e837f4 203 waitForLooppsToFinish();
jsa1969 11:6844a5578b4f 204 init680();
jsa1969 11:6844a5578b4f 205 initSgp30();
jsa1969 9:5150afa50eb6 206 }
jsa1969 9:5150afa50eb6 207
jsa1969 12:96eb06e837f4 208 void displayValuesTxt() {
jsa1969 12:96eb06e837f4 209 waitForLooppsToFinish();
jsa1969 8:1bdb50e03d39 210 if (bme680Data!=NULL) {
jsa1969 8:1bdb50e03d39 211 uBit.display.scroll("g");
jsa1969 8:1bdb50e03d39 212 uBit.display.scroll((int)bme680Data->gas_resistance);
jsa1969 8:1bdb50e03d39 213 uBit.display.scroll("+");
jsa1969 14:71060505061e 214 uBit.display.scroll((int)nvStore->getGasMax());
jsa1969 14:71060505061e 215 uBit.display.scroll("-");
jsa1969 14:71060505061e 216 uBit.display.scroll((int)nvStore->getGasMin());
jsa1969 17:a2c4dd192146 217 uBit.display.scroll("t");
jsa1969 17:a2c4dd192146 218 uBit.display.scroll((int)bme680Data->temperature);
jsa1969 17:a2c4dd192146 219 uBit.display.scroll("+");
jsa1969 17:a2c4dd192146 220 uBit.display.scroll((int)nvStore->getTempMax());
jsa1969 17:a2c4dd192146 221 uBit.display.scroll("-");
jsa1969 17:a2c4dd192146 222 uBit.display.scroll((int)nvStore->getTempMin());
jsa1969 17:a2c4dd192146 223 uBit.display.scroll("p");
jsa1969 17:a2c4dd192146 224 uBit.display.scroll((int)bme680Data->pressure);
jsa1969 17:a2c4dd192146 225 uBit.display.scroll("+");
jsa1969 17:a2c4dd192146 226 uBit.display.scroll((int)nvStore->getPressMax());
jsa1969 17:a2c4dd192146 227 uBit.display.scroll("-");
jsa1969 17:a2c4dd192146 228 uBit.display.scroll((int)nvStore->getPressMin());
jsa1969 17:a2c4dd192146 229 uBit.display.scroll("h");
jsa1969 17:a2c4dd192146 230 uBit.display.scroll((int)bme680Data->humidity);
jsa1969 17:a2c4dd192146 231 uBit.display.scroll("+");
jsa1969 17:a2c4dd192146 232 uBit.display.scroll((int)nvStore->getHumMax());
jsa1969 17:a2c4dd192146 233 uBit.display.scroll("-");
jsa1969 17:a2c4dd192146 234 uBit.display.scroll((int)nvStore->getHumMin());
jsa1969 8:1bdb50e03d39 235 }
jsa1969 17:a2c4dd192146 236
jsa1969 8:1bdb50e03d39 237 if (sgp30!=NULL) {
jsa1969 8:1bdb50e03d39 238 uBit.display.scroll("v");
jsa1969 8:1bdb50e03d39 239 uBit.display.scroll((int)sgp30->TVOC);
jsa1969 8:1bdb50e03d39 240 uBit.display.scroll("c");
jsa1969 8:1bdb50e03d39 241 uBit.display.scroll((int)sgp30->eCO2);
jsa1969 8:1bdb50e03d39 242 }
jsa1969 0:cef60cc92da0 243 }
jsa1969 0:cef60cc92da0 244
jsa1969 12:96eb06e837f4 245 void onButtonA(MicroBitEvent evt)
jsa1969 12:96eb06e837f4 246 {
jsa1969 12:96eb06e837f4 247 if (runningLoops>0) {
jsa1969 12:96eb06e837f4 248 displayValuesTxt();
jsa1969 12:96eb06e837f4 249 } else {
jsa1969 12:96eb06e837f4 250 startLoops();
jsa1969 12:96eb06e837f4 251 }
jsa1969 12:96eb06e837f4 252 }
jsa1969 12:96eb06e837f4 253
jsa1969 12:96eb06e837f4 254 void onButtonB(MicroBitEvent evt)
jsa1969 12:96eb06e837f4 255 {
jsa1969 12:96eb06e837f4 256 initSensors();
jsa1969 12:96eb06e837f4 257 }
jsa1969 12:96eb06e837f4 258
jsa1969 9:5150afa50eb6 259 void onButtonAB(MicroBitEvent evt)
jsa1969 9:5150afa50eb6 260 {
jsa1969 12:96eb06e837f4 261 nvStore->resetNvStore();
jsa1969 9:5150afa50eb6 262 }
jsa1969 9:5150afa50eb6 263
jsa1969 0:cef60cc92da0 264 int main()
jsa1969 0:cef60cc92da0 265 {
jsa1969 0:cef60cc92da0 266 uBit.init();
jsa1969 0:cef60cc92da0 267
jsa1969 0:cef60cc92da0 268 uBit.messageBus.listen(MICROBIT_ID_BUTTON_A, MICROBIT_BUTTON_EVT_CLICK, onButtonA);
jsa1969 0:cef60cc92da0 269 uBit.messageBus.listen(MICROBIT_ID_BUTTON_B, MICROBIT_BUTTON_EVT_CLICK, onButtonB);
jsa1969 9:5150afa50eb6 270 uBit.messageBus.listen(MICROBIT_ID_BUTTON_AB, MICROBIT_BUTTON_EVT_CLICK, onButtonAB);
jsa1969 2:544117df8c65 271
jsa1969 9:5150afa50eb6 272 callbacks = new I2cCallbacks(&uBit);
jsa1969 12:96eb06e837f4 273 nvStore = new NvStore(&uBit);
jsa1969 9:5150afa50eb6 274
jsa1969 9:5150afa50eb6 275 initSensors();
jsa1969 9:5150afa50eb6 276
jsa1969 12:96eb06e837f4 277 startLoops();
jsa1969 2:544117df8c65 278
jsa1969 0:cef60cc92da0 279 release_fiber();
jsa1969 0:cef60cc92da0 280 }
jsa1969 0:cef60cc92da0 281