uses BBC micro:bit to measure and display indoor air quality using Bosch BME680 and/or Sensirion SGP30

Dependencies:   microbit

uses Bosch BME680 and/or Sensirion SGP30 sensors to measure indor air quality

sensors should be connected to BBC micro:bit using i2c

commands are received and data is being sent using uBit / nordic radio protocol

display ---

last line always indicates: - first dot: bme680 detected - second dot: sgp30 detected - third dot: sgp 30 setting humidity/temperature - fourth dor: sgp30 measuring - fith dot: bme680 measuring

the detect dots should be in a stable state (not blinking) the measuring dots should be blinking (constant light means: measurement failed)

if only one bme680 is present: - first 3 lines indicate gas resistence (air quality / more dots == worse quality) - fourth line indicates humidity level

if only sgp30 is present: - first two lines indicate SGP30 VOC level - third and fourth line indicate sgp30 CO2 level

if both sensors are present: - first line indicates SGP30 VOC level - second line line indicates sgp30 CO2 level - third line indicates bme680 gas resistence (air quality) - fourth line indicates bme 680 humidity level

buttons - B display state, switches betweeen - full bright - low light - display off

AB reset sgp30 baseline in non volatile storage

data logging -- during measurements the minimum and mximum values for each measured value (temperature, air pressure, humidity,gas resistance, VOC, CO2) are being stored in non volatile storage those (and the last measurement results) are being shown when btn A has been pressed

Committer:
jsa1969
Date:
Sun Feb 17 10:54:55 2019 +0000
Revision:
47:881bfe77a00a
Parent:
46:2fed2865a0f3
Child:
48:52cad865a84f
show bme680 gas res linear, not exponential

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 46:2fed2865a0f3 30 #include "IaqNonVolatileStore.h"
jsa1969 2:544117df8c65 31
jsa1969 1:f9245fb53737 32 #include "physics.h"
jsa1969 0:cef60cc92da0 33
jsa1969 46:2fed2865a0f3 34 #include "MovingAverage.h"
jsa1969 47:881bfe77a00a 35 #include "RangeTransform.h"
jsa1969 46:2fed2865a0f3 36
jsa1969 33:af2dfab24ca9 37 #include "AppSpecificTestrunner.h"
jsa1969 33:af2dfab24ca9 38
jsa1969 0:cef60cc92da0 39 MicroBit uBit;
jsa1969 2:544117df8c65 40 Bme680* bme680 = NULL;
jsa1969 2:544117df8c65 41 struct bme680_field_data* bme680Data = NULL;
jsa1969 2:544117df8c65 42 Sgp30* sgp30 = NULL;
jsa1969 12:96eb06e837f4 43 I2cCallbacks* callbacks = NULL;
jsa1969 46:2fed2865a0f3 44 IaqNonVolatileStore* nvStore = NULL;
jsa1969 46:2fed2865a0f3 45 //MovingAverage* movingAverage = new MovingAverage(IaqNonVolatileStore::AVERAGE_BUFFER_SIZE);
jsa1969 12:96eb06e837f4 46
jsa1969 12:96eb06e837f4 47 bool cancelMeasureLoops = false;
jsa1969 12:96eb06e837f4 48 int runningLoops = 0;
jsa1969 20:2f11b93f4cbf 49 int displayState = 0;
jsa1969 0:cef60cc92da0 50
jsa1969 12:96eb06e837f4 51 void waitForLooppsToFinish() {
jsa1969 12:96eb06e837f4 52 cancelMeasureLoops=true;
jsa1969 12:96eb06e837f4 53 while (runningLoops>0) {
jsa1969 12:96eb06e837f4 54 uBit.sleep(10);
jsa1969 12:96eb06e837f4 55 }
jsa1969 12:96eb06e837f4 56 cancelMeasureLoops = false;
jsa1969 12:96eb06e837f4 57 }
jsa1969 0:cef60cc92da0 58
jsa1969 11:6844a5578b4f 59 void displayPixels(int ystart, int pixels, int maxpixels) {
jsa1969 11:6844a5578b4f 60 int y = ystart;
jsa1969 11:6844a5578b4f 61 for (int i=0; i+((y-ystart)*5)<maxpixels; ++i) {
jsa1969 11:6844a5578b4f 62 if (i==5) {
jsa1969 11:6844a5578b4f 63 ++y;
jsa1969 11:6844a5578b4f 64 i=0;
jsa1969 11:6844a5578b4f 65 }
jsa1969 11:6844a5578b4f 66 int pixelsused = i+((y-ystart)*5);
jsa1969 11:6844a5578b4f 67 uBit.display.image.setPixelValue(i, y, pixelsused<pixels? 255 : 0);
jsa1969 10:8e6b71a46871 68 }
jsa1969 10:8e6b71a46871 69 }
jsa1969 46:2fed2865a0f3 70 /*
jsa1969 46:2fed2865a0f3 71 bool strayData() {
jsa1969 46:2fed2865a0f3 72 const uint32_t* values = movingAverage->debugInfo();
jsa1969 46:2fed2865a0f3 73 uint32_t max = values[0];
jsa1969 46:2fed2865a0f3 74 for (int i=0 ; i<IaqNonVolatileStore::AVERAGE_BUFFER_SIZE; ++i) {
jsa1969 46:2fed2865a0f3 75 uint32_t val = values[i];
jsa1969 46:2fed2865a0f3 76 if (val > max) {
jsa1969 46:2fed2865a0f3 77 max = val;
jsa1969 46:2fed2865a0f3 78 }
jsa1969 46:2fed2865a0f3 79 }
jsa1969 46:2fed2865a0f3 80
jsa1969 46:2fed2865a0f3 81 bool stray = false;
jsa1969 46:2fed2865a0f3 82 for (int i=0 ; stray==false && i<IaqNonVolatileStore::AVERAGE_BUFFER_SIZE; ++i) {
jsa1969 46:2fed2865a0f3 83 stray = (max - values[i]) > 100000;
jsa1969 46:2fed2865a0f3 84 }
jsa1969 46:2fed2865a0f3 85 return stray;
jsa1969 46:2fed2865a0f3 86 }
jsa1969 46:2fed2865a0f3 87 */
jsa1969 1:f9245fb53737 88 int measureBme680(){
jsa1969 38:0f29a0ea64ca 89 int result = BME680_E_DEV_NOT_FOUND;
jsa1969 1:f9245fb53737 90 if (bme680!=NULL && bme680Data!=NULL) {
jsa1969 38:0f29a0ea64ca 91 result = bme680->measure(
jsa1969 1:f9245fb53737 92 bme680Data,
jsa1969 2:544117df8c65 93 bme680Data->temperature==0 ?
jsa1969 2:544117df8c65 94 uBit.thermometer.getTemperature()
jsa1969 45:d6a9fd9c8200 95 : bme680Data->temperature,
jsa1969 38:0f29a0ea64ca 96 2000, 350);
jsa1969 1:f9245fb53737 97 }
jsa1969 38:0f29a0ea64ca 98 return result;
jsa1969 0:cef60cc92da0 99 }
jsa1969 0:cef60cc92da0 100
jsa1969 11:6844a5578b4f 101 void measureAndDisplayBme680() {
jsa1969 11:6844a5578b4f 102 if (bme680!=NULL) {
jsa1969 46:2fed2865a0f3 103 // measuring
jsa1969 11:6844a5578b4f 104 uBit.display.image.setPixelValue(4, 4, 255);
jsa1969 11:6844a5578b4f 105 if (measureBme680()==MICROBIT_OK) {
jsa1969 27:cb75a0c5c52a 106 nvStore->updateGas(bme680Data->gas_resistance, bme680Data->humidity);
jsa1969 17:a2c4dd192146 107 nvStore->updateTemp(bme680Data->temperature);
jsa1969 17:a2c4dd192146 108 nvStore->updatePress(bme680Data->pressure);
jsa1969 17:a2c4dd192146 109 nvStore->updateHumidity(bme680Data->humidity);
jsa1969 17:a2c4dd192146 110
jsa1969 46:2fed2865a0f3 111 const uint32_t gasMax = nvStore->getGasMax(bme680Data->humidity);
jsa1969 46:2fed2865a0f3 112
jsa1969 46:2fed2865a0f3 113 // status (last line: 0 sensor found, 2, stray signals, 4, measuring)
jsa1969 14:71060505061e 114 uBit.display.image.setPixelValue(0, 4, 255);
jsa1969 46:2fed2865a0f3 115 uBit.display.image.setPixelValue(2, 4, nvStore->strayData() || gasMax < bme680Data->gas_resistance ? 255 : 0);
jsa1969 46:2fed2865a0f3 116 // will be set below uBit.display.image.setPixelValue(4, 4, 0);
jsa1969 44:67a19da5f269 117
jsa1969 46:2fed2865a0f3 118 // if sgp 30 exists, we have less room fpr bme680 resukts
jsa1969 47:881bfe77a00a 119 const int bmeY = sgp30 != NULL ? 2 : 0;
jsa1969 47:881bfe77a00a 120 const int bmeMaxPixels = sgp30 != NULL ? 5 : 15;
jsa1969 46:2fed2865a0f3 121
jsa1969 46:2fed2865a0f3 122 // bme 680 gas state
jsa1969 47:881bfe77a00a 123 const int bmeGasPixels = (gasMax - bme680Data->gas_resistance) * bmeMaxPixels / gasMax;
jsa1969 47:881bfe77a00a 124 displayPixels(bmeY, bmeGasPixels, bmeMaxPixels);
jsa1969 46:2fed2865a0f3 125
jsa1969 46:2fed2865a0f3 126 // humidity index
jsa1969 11:6844a5578b4f 127 displayPixels(3, 5*bme680Data->humidity/100000, 5);
jsa1969 14:71060505061e 128 } else {
jsa1969 46:2fed2865a0f3 129 // indicate sensor not working
jsa1969 14:71060505061e 130 uBit.display.image.setPixelValue(0, 4, 0);
jsa1969 2:544117df8c65 131 }
jsa1969 46:2fed2865a0f3 132 // not measuring
jsa1969 12:96eb06e837f4 133 uBit.display.image.setPixelValue(4, 4, 0);
jsa1969 11:6844a5578b4f 134 }
jsa1969 11:6844a5578b4f 135 }
jsa1969 11:6844a5578b4f 136
jsa1969 11:6844a5578b4f 137 void measureAndDisplaySgp30() {
jsa1969 11:6844a5578b4f 138 if (sgp30!=NULL) {
jsa1969 11:6844a5578b4f 139 int sgpMaxPixels = 10;
jsa1969 11:6844a5578b4f 140 int secondLineStart = 2;
jsa1969 11:6844a5578b4f 141 if (bme680!=NULL) {
jsa1969 11:6844a5578b4f 142 sgpMaxPixels = 5;
jsa1969 11:6844a5578b4f 143 secondLineStart = 1;
jsa1969 44:67a19da5f269 144 uBit.display.image.setPixelValue(3, 4, 255);
jsa1969 11:6844a5578b4f 145 if (sgp30->setHumidity(bme680Data->humidity, bme680Data->temperature)) {
jsa1969 44:67a19da5f269 146 uBit.display.image.setPixelValue(3, 4, 0);
jsa1969 11:6844a5578b4f 147 }
jsa1969 11:6844a5578b4f 148 uBit.sleep(10);
jsa1969 11:6844a5578b4f 149 }
jsa1969 11:6844a5578b4f 150 uBit.display.image.setPixelValue(3, 4, 255);
jsa1969 38:0f29a0ea64ca 151 bool measureOK = sgp30->IAQmeasure();
jsa1969 38:0f29a0ea64ca 152 if (measureOK) {
jsa1969 13:996026828be7 153 uBit.display.image.setPixelValue(1, 4, 255);
jsa1969 11:6844a5578b4f 154 uBit.display.image.setPixelValue(3, 4, 0);
jsa1969 18:c4ac93e01027 155
jsa1969 18:c4ac93e01027 156 nvStore->updateVoc(sgp30->TVOC);
jsa1969 18:c4ac93e01027 157 nvStore->updateCo(sgp30->eCO2);
jsa1969 18:c4ac93e01027 158
jsa1969 12:96eb06e837f4 159 int co2Dots = min (5, sgp30->eCO2 /1500);
jsa1969 47:881bfe77a00a 160 displayPixels(0, 5 - RangeTransform::exponentialTransform(sgp30->TVOC, 20000, sgpMaxPixels), sgpMaxPixels);
jsa1969 11:6844a5578b4f 161 displayPixels(secondLineStart, co2Dots, sgpMaxPixels);
jsa1969 13:996026828be7 162 } else {
jsa1969 13:996026828be7 163 uBit.display.image.setPixelValue(1, 4, 0);
jsa1969 11:6844a5578b4f 164 }
jsa1969 2:544117df8c65 165 }
jsa1969 2:544117df8c65 166 }
jsa1969 2:544117df8c65 167
jsa1969 12:96eb06e837f4 168 void bmeMeasureLoop() {
jsa1969 12:96eb06e837f4 169 if (bme680!=NULL) {
jsa1969 12:96eb06e837f4 170 ++runningLoops;
jsa1969 12:96eb06e837f4 171 while (!cancelMeasureLoops){
jsa1969 11:6844a5578b4f 172 measureAndDisplayBme680();
jsa1969 45:d6a9fd9c8200 173 uBit.sleep(500);
jsa1969 12:96eb06e837f4 174 }
jsa1969 12:96eb06e837f4 175 --runningLoops;
jsa1969 12:96eb06e837f4 176 }
jsa1969 24:07a1d2e6914e 177 release_fiber();
jsa1969 12:96eb06e837f4 178 }
jsa1969 12:96eb06e837f4 179
jsa1969 12:96eb06e837f4 180 void sgpMeasureLoop() {
jsa1969 12:96eb06e837f4 181 if (sgp30!=NULL) {
jsa1969 12:96eb06e837f4 182 ++runningLoops;
jsa1969 12:96eb06e837f4 183 while (!cancelMeasureLoops){
jsa1969 11:6844a5578b4f 184 measureAndDisplaySgp30();
jsa1969 12:96eb06e837f4 185 uBit.sleep(950);
jsa1969 2:544117df8c65 186 }
jsa1969 12:96eb06e837f4 187 --runningLoops;
jsa1969 2:544117df8c65 188 }
jsa1969 24:07a1d2e6914e 189 release_fiber();
jsa1969 12:96eb06e837f4 190 }
jsa1969 12:96eb06e837f4 191
jsa1969 34:069c4f6d5b2c 192 void startMeasureLoops() {
jsa1969 12:96eb06e837f4 193 if (runningLoops>0) {
jsa1969 12:96eb06e837f4 194 uBit.display.scroll("already running");
jsa1969 12:96eb06e837f4 195 return;
jsa1969 12:96eb06e837f4 196 }
jsa1969 14:71060505061e 197 create_fiber(sgpMeasureLoop);
jsa1969 12:96eb06e837f4 198 create_fiber(bmeMeasureLoop);
jsa1969 2:544117df8c65 199 }
jsa1969 2:544117df8c65 200
jsa1969 11:6844a5578b4f 201 void init680(){
jsa1969 9:5150afa50eb6 202 if (bme680!=NULL){
jsa1969 9:5150afa50eb6 203 delete bme680;
jsa1969 9:5150afa50eb6 204 }
jsa1969 10:8e6b71a46871 205
jsa1969 27:cb75a0c5c52a 206 uint32_t gasMax = nvStore->getGasMax(0);
jsa1969 11:6844a5578b4f 207 if (gasMax>0) {
jsa1969 11:6844a5578b4f 208 uBit.display.scroll((int)gasMax);
jsa1969 11:6844a5578b4f 209 }
jsa1969 10:8e6b71a46871 210
jsa1969 14:71060505061e 211 bme680 = new Bme680(callbacks);
jsa1969 9:5150afa50eb6 212 int code = bme680->init();
jsa1969 9:5150afa50eb6 213 if (code == MICROBIT_OK){
jsa1969 9:5150afa50eb6 214 if (bme680Data==NULL) {
jsa1969 9:5150afa50eb6 215 bme680Data = new struct bme680_field_data;
jsa1969 9:5150afa50eb6 216 }
jsa1969 9:5150afa50eb6 217 code = bme680->measure(
jsa1969 9:5150afa50eb6 218 bme680Data,
jsa1969 9:5150afa50eb6 219 uBit.thermometer.getTemperature(),
jsa1969 9:5150afa50eb6 220 100, 100);
jsa1969 9:5150afa50eb6 221 }
jsa1969 9:5150afa50eb6 222 if (code != MICROBIT_OK){
jsa1969 9:5150afa50eb6 223 delete bme680;
jsa1969 9:5150afa50eb6 224 bme680 = NULL;
jsa1969 9:5150afa50eb6 225 delete bme680Data;
jsa1969 9:5150afa50eb6 226 bme680Data = NULL;
jsa1969 9:5150afa50eb6 227 uBit.display.scroll(code);
jsa1969 9:5150afa50eb6 228 } else {
jsa1969 9:5150afa50eb6 229 uBit.display.image.setPixelValue(0, 4, 255);
jsa1969 9:5150afa50eb6 230 }
jsa1969 11:6844a5578b4f 231 }
jsa1969 9:5150afa50eb6 232
jsa1969 11:6844a5578b4f 233 void initSgp30(){
jsa1969 9:5150afa50eb6 234 if (sgp30!=NULL){
jsa1969 9:5150afa50eb6 235 delete sgp30;
jsa1969 9:5150afa50eb6 236 }
jsa1969 43:f968ca84d4ed 237 sgp30 = new Sgp30(callbacks);
jsa1969 9:5150afa50eb6 238 if (sgp30->test() && sgp30->begin()) {
jsa1969 9:5150afa50eb6 239 uBit.display.image.setPixelValue(1, 4, 255);
jsa1969 9:5150afa50eb6 240 } else {
jsa1969 9:5150afa50eb6 241 delete sgp30;
jsa1969 9:5150afa50eb6 242 sgp30 = NULL;
jsa1969 40:a67a880cb538 243 }
jsa1969 40:a67a880cb538 244 }
jsa1969 11:6844a5578b4f 245
jsa1969 11:6844a5578b4f 246 void initSensors() {
jsa1969 12:96eb06e837f4 247 waitForLooppsToFinish();
jsa1969 11:6844a5578b4f 248 init680();
jsa1969 11:6844a5578b4f 249 initSgp30();
jsa1969 9:5150afa50eb6 250 }
jsa1969 9:5150afa50eb6 251
jsa1969 12:96eb06e837f4 252 void displayValuesTxt() {
jsa1969 12:96eb06e837f4 253 waitForLooppsToFinish();
jsa1969 8:1bdb50e03d39 254 if (bme680Data!=NULL) {
jsa1969 8:1bdb50e03d39 255 uBit.display.scroll("g");
jsa1969 39:efe22f143e47 256 const int currentGas = (int)bme680Data->gas_resistance;
jsa1969 39:efe22f143e47 257 uBit.display.scroll(currentGas);
jsa1969 8:1bdb50e03d39 258 uBit.display.scroll("+");
jsa1969 38:0f29a0ea64ca 259 const int highGas = (int)nvStore->getGasMax(bme680Data->humidity);
jsa1969 38:0f29a0ea64ca 260 uBit.display.scroll(highGas);
jsa1969 44:67a19da5f269 261 if (nvStore->strayData() || highGas < currentGas) {
jsa1969 46:2fed2865a0f3 262 for (int i=0; i<IaqNonVolatileStore::AVERAGE_BUFFER_SIZE; ++i) {
jsa1969 38:0f29a0ea64ca 263 uBit.display.scroll(":");
jsa1969 38:0f29a0ea64ca 264 uBit.display.scroll((int)nvStore->debugInfo()[i]);
jsa1969 38:0f29a0ea64ca 265 }
jsa1969 38:0f29a0ea64ca 266 }
jsa1969 14:71060505061e 267 uBit.display.scroll("-");
jsa1969 14:71060505061e 268 uBit.display.scroll((int)nvStore->getGasMin());
jsa1969 17:a2c4dd192146 269 uBit.display.scroll("t");
jsa1969 17:a2c4dd192146 270 uBit.display.scroll((int)bme680Data->temperature);
jsa1969 17:a2c4dd192146 271 uBit.display.scroll("+");
jsa1969 17:a2c4dd192146 272 uBit.display.scroll((int)nvStore->getTempMax());
jsa1969 17:a2c4dd192146 273 uBit.display.scroll("-");
jsa1969 17:a2c4dd192146 274 uBit.display.scroll((int)nvStore->getTempMin());
jsa1969 17:a2c4dd192146 275 uBit.display.scroll("p");
jsa1969 17:a2c4dd192146 276 uBit.display.scroll((int)bme680Data->pressure);
jsa1969 17:a2c4dd192146 277 uBit.display.scroll("+");
jsa1969 17:a2c4dd192146 278 uBit.display.scroll((int)nvStore->getPressMax());
jsa1969 17:a2c4dd192146 279 uBit.display.scroll("-");
jsa1969 17:a2c4dd192146 280 uBit.display.scroll((int)nvStore->getPressMin());
jsa1969 17:a2c4dd192146 281 uBit.display.scroll("h");
jsa1969 17:a2c4dd192146 282 uBit.display.scroll((int)bme680Data->humidity);
jsa1969 17:a2c4dd192146 283 uBit.display.scroll("+");
jsa1969 17:a2c4dd192146 284 uBit.display.scroll((int)nvStore->getHumMax());
jsa1969 17:a2c4dd192146 285 uBit.display.scroll("-");
jsa1969 17:a2c4dd192146 286 uBit.display.scroll((int)nvStore->getHumMin());
jsa1969 8:1bdb50e03d39 287 }
jsa1969 17:a2c4dd192146 288
jsa1969 8:1bdb50e03d39 289 if (sgp30!=NULL) {
jsa1969 8:1bdb50e03d39 290 uBit.display.scroll("v");
jsa1969 8:1bdb50e03d39 291 uBit.display.scroll((int)sgp30->TVOC);
jsa1969 18:c4ac93e01027 292 uBit.display.scroll("+");
jsa1969 18:c4ac93e01027 293 uBit.display.scroll((int)nvStore->getVocMax());
jsa1969 8:1bdb50e03d39 294 uBit.display.scroll("c");
jsa1969 8:1bdb50e03d39 295 uBit.display.scroll((int)sgp30->eCO2);
jsa1969 18:c4ac93e01027 296 uBit.display.scroll("+");
jsa1969 18:c4ac93e01027 297 uBit.display.scroll((int)nvStore->getCoMax());
jsa1969 8:1bdb50e03d39 298 }
jsa1969 0:cef60cc92da0 299 }
jsa1969 0:cef60cc92da0 300
jsa1969 12:96eb06e837f4 301 void onButtonA(MicroBitEvent evt)
jsa1969 12:96eb06e837f4 302 {
jsa1969 12:96eb06e837f4 303 if (runningLoops>0) {
jsa1969 12:96eb06e837f4 304 displayValuesTxt();
jsa1969 12:96eb06e837f4 305 } else {
jsa1969 34:069c4f6d5b2c 306 startMeasureLoops();
jsa1969 12:96eb06e837f4 307 }
jsa1969 12:96eb06e837f4 308 }
jsa1969 12:96eb06e837f4 309
jsa1969 12:96eb06e837f4 310 void onButtonB(MicroBitEvent evt)
jsa1969 12:96eb06e837f4 311 {
jsa1969 20:2f11b93f4cbf 312 switch (++displayState) {
jsa1969 20:2f11b93f4cbf 313 case 1:
jsa1969 20:2f11b93f4cbf 314 uBit.display.setBrightness(5);
jsa1969 20:2f11b93f4cbf 315 break;
jsa1969 20:2f11b93f4cbf 316 case 2:
jsa1969 20:2f11b93f4cbf 317 uBit.display.disable();
jsa1969 20:2f11b93f4cbf 318 break;
jsa1969 20:2f11b93f4cbf 319 default:
jsa1969 20:2f11b93f4cbf 320 uBit.display.setBrightness(255);
jsa1969 20:2f11b93f4cbf 321 uBit.display.enable();
jsa1969 20:2f11b93f4cbf 322 displayState = 0;
jsa1969 20:2f11b93f4cbf 323 }
jsa1969 12:96eb06e837f4 324 }
jsa1969 12:96eb06e837f4 325
jsa1969 9:5150afa50eb6 326 void onButtonAB(MicroBitEvent evt)
jsa1969 9:5150afa50eb6 327 {
jsa1969 19:52e19461e867 328 waitForLooppsToFinish();
jsa1969 46:2fed2865a0f3 329 nvStore->clear();
jsa1969 19:52e19461e867 330 uBit.display.scroll("clear");
jsa1969 9:5150afa50eb6 331 }
jsa1969 9:5150afa50eb6 332
jsa1969 34:069c4f6d5b2c 333 const char* runSofwareModuleTests() {
jsa1969 34:069c4f6d5b2c 334 // heap we've got planty, stack is rare
jsa1969 33:af2dfab24ca9 335 AppSpecificTestrunner* runner = new AppSpecificTestrunner();
jsa1969 33:af2dfab24ca9 336 const char* result = runner->runAll();
jsa1969 33:af2dfab24ca9 337 delete runner;
jsa1969 33:af2dfab24ca9 338 return result;
jsa1969 33:af2dfab24ca9 339 }
jsa1969 33:af2dfab24ca9 340
jsa1969 0:cef60cc92da0 341 int main()
jsa1969 0:cef60cc92da0 342 {
jsa1969 0:cef60cc92da0 343 uBit.init();
jsa1969 0:cef60cc92da0 344
jsa1969 0:cef60cc92da0 345 uBit.messageBus.listen(MICROBIT_ID_BUTTON_A, MICROBIT_BUTTON_EVT_CLICK, onButtonA);
jsa1969 0:cef60cc92da0 346 uBit.messageBus.listen(MICROBIT_ID_BUTTON_B, MICROBIT_BUTTON_EVT_CLICK, onButtonB);
jsa1969 9:5150afa50eb6 347 uBit.messageBus.listen(MICROBIT_ID_BUTTON_AB, MICROBIT_BUTTON_EVT_CLICK, onButtonAB);
jsa1969 2:544117df8c65 348
jsa1969 46:2fed2865a0f3 349 callbacks = new I2cCallbacks(&uBit);
jsa1969 46:2fed2865a0f3 350 nvStore = new IaqNonVolatileStore(&uBit);
jsa1969 33:af2dfab24ca9 351
jsa1969 46:2fed2865a0f3 352 uBit.display.scroll("t");
jsa1969 34:069c4f6d5b2c 353 const char* testResults = runSofwareModuleTests();
jsa1969 33:af2dfab24ca9 354 if (! Testrunner::messageOK(testResults)) {
jsa1969 33:af2dfab24ca9 355 uBit.display.scroll(testResults);
jsa1969 33:af2dfab24ca9 356 return -1;
jsa1969 33:af2dfab24ca9 357 }
jsa1969 46:2fed2865a0f3 358
jsa1969 34:069c4f6d5b2c 359 // includes hardware tests
jsa1969 9:5150afa50eb6 360 initSensors();
jsa1969 9:5150afa50eb6 361
jsa1969 34:069c4f6d5b2c 362 startMeasureLoops();
jsa1969 2:544117df8c65 363
jsa1969 0:cef60cc92da0 364 release_fiber();
jsa1969 0:cef60cc92da0 365 }
jsa1969 0:cef60cc92da0 366