Code supports writing to the SD card as well as working with the Volckens group smartphone apps for the mbed HRM1017

Dependencies:   ADS1115 BLE_API BME280 Calibration CronoDot EEPROM LSM303 MCP40D17 NCP5623BMUTBG SDFileSystem SI1145 STC3100 mbed nRF51822

Fork of UPAS_BLE_and_USB by Volckens Group Sensors

Committer:
jelord
Date:
Sat Mar 05 19:11:27 2016 +0000
Revision:
123:2765e75fd0a6
Parent:
122:f26474cc223a
Child:
124:15466d0f04ab
One line removed to allow android functionality

Who changed what in which revision?

UserRevisionLine numberNew contents of line
caseyquinn 0:14d46ef4b6cb 1 #include "mbed.h"
caseyquinn 0:14d46ef4b6cb 2 #include "SDFileSystem.h"
caseyquinn 0:14d46ef4b6cb 3 #include "Adafruit_ADS1015.h"
caseyquinn 1:37babeb68ab9 4 #include "MCP40D17.h"
caseyquinn 7:a24d7156bc02 5 #include "STC3100.h"
caseyquinn 115:fb25810c1fab 6 #include "LSM303.h"
caseyquinn 12:8c00a7f5d483 7 #include "BME280.h"
caseyquinn 14:ad550174db8b 8 #include "SI1145.h"
joshuasmth04 40:ef7e1dcb3780 9 #include "NCP5623BMUTBG.h"
joshuasmth04 41:1fb3e0ac6f87 10 #include "CronoDot.h"
caseyquinn 56:c4d6bdd7c3fb 11 #include "EEPROM.h"
joshuasmth04 77:24fbeb2bfe05 12 #include "BLEDevice.h"
joshuasmth04 77:24fbeb2bfe05 13 #include "Calibration.h"
jelord 94:c57720890e76 14 #include "UPAS_Service.h"
joshuasmth04 71:78edbceff4fc 15
caseyquinn 1:37babeb68ab9 16 #define SERIAL_BAUD_RATE 9600
joshuasmth04 41:1fb3e0ac6f87 17 #define SCL 20
caseyquinn 7:a24d7156bc02 18 #define SDA 22
caseyquinn 81:480f0310ef9a 19
caseyquinn 0:14d46ef4b6cb 20
joshuasmth04 71:78edbceff4fc 21
jelord 94:c57720890e76 22
joshuasmth04 71:78edbceff4fc 23
jelord 97:c596f8ed4562 24 uint8_t startAndEndTime[12] = {0,};
jelord 97:c596f8ed4562 25 uint8_t logIntervalReadOut[1] = {0,};
jelord 94:c57720890e76 26 static const uint16_t uuid16_list[] = {UPAS_Service::UPAS_SERVICE_UUID}; //Currently a custom 16-bit representation of 128-bit UUID
joshuasmth04 71:78edbceff4fc 27 BLEDevice ble;
jelord 94:c57720890e76 28 UPAS_Service *upasServicePtr;
jelord 94:c57720890e76 29 //BLE_Menu bleMenu(ble, txPayload, rxPayload, uart_base_uuid_rev, uart_base_uuid, uartService);
joshuasmth04 71:78edbceff4fc 30
joshuasmth04 72:0b36575ab00d 31 I2C i2c(p22, p20);
joshuasmth04 72:0b36575ab00d 32 Adafruit_ADS1115 ads(&i2c);
joshuasmth04 72:0b36575ab00d 33 MCP40D17 DigPot(&i2c);
joshuasmth04 72:0b36575ab00d 34 BME280 bmesensor(p22, p20);
joshuasmth04 72:0b36575ab00d 35 STC3100 gasG(p22, p20);
joshuasmth04 72:0b36575ab00d 36 Serial pc(USBTX, USBRX);
joshuasmth04 72:0b36575ab00d 37 DigitalOut blower(p29, 0);
joshuasmth04 72:0b36575ab00d 38 DigitalOut pbKill(p18, 1);
caseyquinn 115:fb25810c1fab 39 LSM303 movementsensor(p22, p20);
joshuasmth04 72:0b36575ab00d 40 SI1145 lightsensor(p22, p20);
joshuasmth04 72:0b36575ab00d 41 NCP5623BMUTBG RGB_LED(p22, p20);
joshuasmth04 72:0b36575ab00d 42 CronoDot RTC(p22, p20);
joshuasmth04 72:0b36575ab00d 43 EEPROM E2PROM(p22, p20);
joshuasmth04 77:24fbeb2bfe05 44 DigitalOut GPS_EN(p4,0); //pin 4 is used to enable and disable the GPS, in order to recive serial communications
joshuasmth04 77:24fbeb2bfe05 45 Calibration calibrations(1); //Default serial/calibration if there are no values for the selected option
caseyquinn 57:0b554f7aa9a3 46
caseyquinn 114:84e759e07948 47 //Timeout stop; //This is the stop call back object
caseyquinn 114:84e759e07948 48 //Timeout logg; //This is the logging call back object
caseyquinn 111:5f2ba5f1a468 49
caseyquinn 110:67980ebdebf6 50
caseyquinn 67:300418575137 51
joshuasmth04 77:24fbeb2bfe05 52 uint16_t serial_num = 1; // Default serial/calibration number
joshuasmth04 77:24fbeb2bfe05 53 int RunReady =0;
caseyquinn 70:81f04e69e08a 54
caseyquinn 70:81f04e69e08a 55
caseyquinn 20:ad9883973d86 56 float press;
caseyquinn 20:ad9883973d86 57 float temp;
caseyquinn 20:ad9883973d86 58 float rh;
caseyquinn 4:69bd7e8a994c 59
caseyquinn 20:ad9883973d86 60 int uv;
caseyquinn 20:ad9883973d86 61 int vis;
caseyquinn 20:ad9883973d86 62 int ir;
caseyquinn 8:204c21adf693 63
caseyquinn 115:fb25810c1fab 64
caseyquinn 67:300418575137 65 float compass;
caseyquinn 10:f9cb61b29340 66 float accel_x;
caseyquinn 10:f9cb61b29340 67 float accel_y;
caseyquinn 10:f9cb61b29340 68 float accel_z;
lionberg 52:80480b2fafba 69 float accel_comp;
caseyquinn 105:f3be9e0314f7 70 float angle_x;
caseyquinn 105:f3be9e0314f7 71 float angle_y;
caseyquinn 105:f3be9e0314f7 72 float angle_z;
caseyquinn 10:f9cb61b29340 73 float mag_x;
caseyquinn 10:f9cb61b29340 74 float mag_y;
caseyquinn 10:f9cb61b29340 75 float mag_z;
caseyquinn 115:fb25810c1fab 76
caseyquinn 10:f9cb61b29340 77
caseyquinn 0:14d46ef4b6cb 78 int vInReading;
caseyquinn 0:14d46ef4b6cb 79 int vBlowerReading;
caseyquinn 0:14d46ef4b6cb 80 int omronDiff;
lionberg 52:80480b2fafba 81 float omronVolt; //V
caseyquinn 20:ad9883973d86 82 int omronReading;
lionberg 52:80480b2fafba 83 float atmoRho; //g/L
caseyquinn 49:19e828650618 84
caseyquinn 20:ad9883973d86 85 float massflow; //g/min
caseyquinn 20:ad9883973d86 86 float volflow; //L/min
caseyquinn 67:300418575137 87 float volflowSet = 1.0; //L/min
caseyquinn 81:480f0310ef9a 88 int logInerval = 10; //seconds
caseyquinn 57:0b554f7aa9a3 89 double secondsD = 0;
caseyquinn 105:f3be9e0314f7 90 double lastsecondD = 0;
joshuasmth04 41:1fb3e0ac6f87 91 float massflowSet;
caseyquinn 42:fc2f2b9f07ae 92 float deltaVflow = 0.0;
caseyquinn 42:fc2f2b9f07ae 93 float deltaMflow = 0.0;
caseyquinn 47:3146e8c949a9 94 float gainFlow;
lionberg 52:80480b2fafba 95 float sampledVol; //L, total sampled volume
caseyquinn 20:ad9883973d86 96
caseyquinn 55:f24d70f519cd 97 int digital_pot_setpoint; //min = 0x7F, max = 0x00
caseyquinn 55:f24d70f519cd 98 int digital_pot_set;
caseyquinn 55:f24d70f519cd 99 int digital_pot_change;
caseyquinn 55:f24d70f519cd 100 int digitalpotMax = 127;
caseyquinn 121:6631364325df 101 int digitalpotMin = 5;
caseyquinn 55:f24d70f519cd 102
joshuasmth04 59:a9b21b3d9afc 103 int dutyUp;
joshuasmth04 59:a9b21b3d9afc 104 int dutyDown;
joshuasmth04 59:a9b21b3d9afc 105
joshuasmth04 72:0b36575ab00d 106 // variables are only place holders for the US_Menu //
joshuasmth04 72:0b36575ab00d 107 int refreshtime;
joshuasmth04 72:0b36575ab00d 108 float home_lat, home_lon, work_lat, work_lon;
joshuasmth04 77:24fbeb2bfe05 109 //*************************************************//
joshuasmth04 72:0b36575ab00d 110
caseyquinn 67:300418575137 111 //int refresh_Time = 10; // refresh time in s, note calling read_GPS()(or similar) will still take how ever long it needs(hopefully < 1s)
caseyquinn 42:fc2f2b9f07ae 112
caseyquinn 81:480f0310ef9a 113 char filename[] = "/sd/XXXX0000LOG000000000000---------------.txt";
caseyquinn 7:a24d7156bc02 114 SDFileSystem sd(SPIS_PSELMOSI, SPIS_PSELMISO, SPIS_PSELSCK, SPIS_PSELSS, "sd"); // I believe this matches Todd's pinout, let me know if this doesn't work. (p12, p13, p15, p14)
caseyquinn 7:a24d7156bc02 115
caseyquinn 7:a24d7156bc02 116
joshuasmth04 71:78edbceff4fc 117 void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason)
joshuasmth04 71:78edbceff4fc 118 {
jelord 94:c57720890e76 119 ble.startAdvertising();
joshuasmth04 71:78edbceff4fc 120 }
joshuasmth04 71:78edbceff4fc 121
joshuasmth04 71:78edbceff4fc 122 void WrittenHandler(const GattCharacteristicWriteCBParams *Handler) // called any time the phone sends a message
joshuasmth04 71:78edbceff4fc 123 {
jelord 94:c57720890e76 124 uint8_t *writeData = const_cast<uint8_t*>(Handler->data);
jelord 94:c57720890e76 125 // check to see what characteristic was written, by handle
jelord 94:c57720890e76 126 if(Handler->charHandle == upasServicePtr->rtcCharacteristic.getValueAttribute().getHandle()) {
jelord 94:c57720890e76 127
jelord 94:c57720890e76 128
jelord 94:c57720890e76 129
jelord 123:2765e75fd0a6 130 //E2PROM.write(0x00015, writeData+6, 12); This line needs to be omitted for android app to function. Should not have stuck around
jelord 94:c57720890e76 131 RTC.set_time(writeData[0],writeData[1],writeData[2],writeData[3],writeData[3],writeData[4],writeData[5]);
jelord 94:c57720890e76 132
jelord 94:c57720890e76 133 }else if(Handler->charHandle == upasServicePtr->sampleTimeCharacteristic.getValueAttribute().getHandle()){
jelord 94:c57720890e76 134
jelord 94:c57720890e76 135 E2PROM.write(0x00015, writeData, 12);
jelord 94:c57720890e76 136
jelord 94:c57720890e76 137 }else if(Handler->charHandle == upasServicePtr->subjectLabelCharacteristic.getValueAttribute().getHandle()){
jelord 94:c57720890e76 138 E2PROM.write(0x00001,writeData,15);
jelord 94:c57720890e76 139
jelord 94:c57720890e76 140 }else if(Handler->charHandle == upasServicePtr->runReadyCharacteristic.getValueAttribute().getHandle()){
jelord 100:da71436aa52a 141
jelord 94:c57720890e76 142 uint8_t runData = writeData[0];
jelord 100:da71436aa52a 143 E2PROM.write(0x00033,writeData,1);
jelord 94:c57720890e76 144
jelord 100:da71436aa52a 145 if(runData == 0x0A){
jelord 100:da71436aa52a 146 RunReady = 10;
jelord 100:da71436aa52a 147 }else{
jelord 100:da71436aa52a 148 RunReady = 12;
jelord 100:da71436aa52a 149 }
jelord 94:c57720890e76 150
jelord 96:03106adb45c9 151 }else if(Handler->charHandle == upasServicePtr->logIntevalCharacteristic.getValueAttribute().getHandle()){
jelord 94:c57720890e76 152 /* Trigger demo mode*/
jelord 96:03106adb45c9 153 //RGB_LED.set_led(3,1,0);
jelord 96:03106adb45c9 154 E2PROM.write(0x00014,writeData,1);
jelord 96:03106adb45c9 155
jelord 96:03106adb45c9 156 }else if(Handler->charHandle == upasServicePtr->flowRateCharacteristic.getValueAttribute().getHandle()){
jelord 96:03106adb45c9 157 //RGB_LED.set_led(3,1,0);
jelord 98:d70ff5a0b2e6 158 E2PROM.write(0x00010,writeData,4);
jelord 98:d70ff5a0b2e6 159
jelord 98:d70ff5a0b2e6 160 //float volFlowTester = 0.0;
jelord 98:d70ff5a0b2e6 161 //uint8_t flowRateTestBytes[4] = {0,};
jelord 98:d70ff5a0b2e6 162 //E2PROM.read(0x00010,flowRateTestBytes,4);
jelord 98:d70ff5a0b2e6 163 //E2PROM.byteToFloat(flowRateTestBytes, &volFlowTester);
jelord 98:d70ff5a0b2e6 164
jelord 104:c57913399e79 165 }else if(Handler->charHandle == upasServicePtr->serialNumCharacteristic.getValueAttribute().getHandle()){
jelord 104:c57913399e79 166 E2PROM.write(0x00034,writeData,2);
jelord 94:c57720890e76 167 }
jelord 104:c57913399e79 168
joshuasmth04 71:78edbceff4fc 169 }
joshuasmth04 71:78edbceff4fc 170
caseyquinn 58:7239c2ab2b65 171
caseyquinn 113:846f67efaa80 172
jelord 96:03106adb45c9 173 /*EEPROM ADDRESSING:
jelord 96:03106adb45c9 174 0:Status bit-Unused
jelord 96:03106adb45c9 175 1-15:Device Name
jelord 96:03106adb45c9 176 16-19:Flow Rate
jelord 96:03106adb45c9 177 20: Data Log Interval
jelord 96:03106adb45c9 178 21-26: Start Time: ssmmHHddMMyy
jelord 96:03106adb45c9 179 27-32: Stop Time: ssmmHHddMMyy
jelord 96:03106adb45c9 180 33: Duty Up
jelord 96:03106adb45c9 181 34: Duty Down
jelord 96:03106adb45c9 182 35-38: Home Latitude
jelord 96:03106adb45c9 183 39-42: Home Longitude
jelord 96:03106adb45c9 184 43-46: Work Latitude
jelord 96:03106adb45c9 185 47-50: Work Longitude
jelord 96:03106adb45c9 186 51: Runready: Currently useless, should be 0
jelord 96:03106adb45c9 187 52-53: Device Calibration
jelord 96:03106adb45c9 188 54: Consider RunReady
jelord 96:03106adb45c9 189 55-56: Menu Options
jelord 96:03106adb45c9 190 57+ Nothing*/
caseyquinn 57:0b554f7aa9a3 191 int main()
caseyquinn 57:0b554f7aa9a3 192 {
joshuasmth04 91:f838d9a5b596 193 RGB_LED.set_led(1,1,1);
caseyquinn 57:0b554f7aa9a3 194 // Setup and Initialization
caseyquinn 57:0b554f7aa9a3 195 //---------------------------------------------------------------------------------------------//
joshuasmth04 71:78edbceff4fc 196 //**************//BLE initialization//**************//
jelord 94:c57720890e76 197 RTC.get_time();
jelord 94:c57720890e76 198 uint8_t rtcPassValues[6] = {RTC.seconds, RTC.minutes,RTC.hour,RTC.date,RTC.month,RTC.year};
jelord 104:c57913399e79 199
jelord 104:c57913399e79 200 uint8_t sampleTimePassValues[12] = {0x00,0x00,0x0A,0x01,0x01,0x10,0x00,0x00,0x0A,0x01,0x01,0x10}; //Start 1/1/16 12:00:00 End 1/1/16 12:00:00
jelord 104:c57913399e79 201 uint8_t subjectLabelOriginal[8] = {0x52,0x45,0x53,0x45,0x54,0x5F,0x5F,0x5f}; // RESET___
jelord 104:c57913399e79 202 uint8_t dataLogOriginal[1] = {0x0A,}; //10 seconds
jelord 104:c57913399e79 203 uint8_t flowRateOriginal[4] = {0x00,0x00,0x80,0x3F}; //1.0 LPM
jelord 104:c57913399e79 204
jelord 104:c57913399e79 205 uint8_t serialNumberAndType[6] = {0x50,0x53};
jelord 104:c57913399e79 206
jelord 104:c57913399e79 207 //Code/conditional set up to prevent bad values in the EEPROM. Does not set serial number currently
jelord 104:c57913399e79 208 uint8_t eepromFlag[1] = {0,};
jelord 104:c57913399e79 209 E2PROM.read(0x00071,eepromFlag,1);
jelord 109:33d7fc6c1b9b 210 if(eepromFlag[0]!= 0x0B){
jelord 104:c57913399e79 211 E2PROM.write(0x00015, sampleTimePassValues, 12);
jelord 104:c57913399e79 212 E2PROM.write(0x00001, subjectLabelOriginal,8);
jelord 104:c57913399e79 213 E2PROM.write(0x00014,dataLogOriginal,1);
jelord 104:c57913399e79 214 E2PROM.write(0x00010,flowRateOriginal,4);
jelord 104:c57913399e79 215
jelord 109:33d7fc6c1b9b 216 eepromFlag[0] = 0x0B;
jelord 104:c57913399e79 217 E2PROM.write(0x00071,eepromFlag,1);
jelord 104:c57913399e79 218 }
jelord 104:c57913399e79 219
jelord 104:c57913399e79 220
jelord 104:c57913399e79 221 //Retrieve current eeprom values
jelord 94:c57720890e76 222 E2PROM.read(0x00015, sampleTimePassValues, 12);
jelord 99:229435dd4cfb 223 E2PROM.read(0x00001, subjectLabelOriginal,8);
jelord 96:03106adb45c9 224 E2PROM.read(0x00014,dataLogOriginal,1);
jelord 96:03106adb45c9 225 E2PROM.read(0x00010,flowRateOriginal,4);
jelord 104:c57913399e79 226
jelord 104:c57913399e79 227
jelord 104:c57913399e79 228 //Following 12 lines of code parses the serial number from a byte id to a readable set of characters for the app user to see
jelord 104:c57913399e79 229 E2PROM.read(0x00034,serialNumberAndType+2,2);
jelord 104:c57913399e79 230 int tempSerialNum = serialNumberAndType[2]+serialNumberAndType[3];
jelord 104:c57913399e79 231 int serialNumDigits[4];
jelord 104:c57913399e79 232 serialNumDigits[0] = tempSerialNum / 1000 % 10;
jelord 104:c57913399e79 233 serialNumDigits[1] = tempSerialNum / 100 % 10;
jelord 104:c57913399e79 234 serialNumDigits[2] = tempSerialNum / 10 % 10;
jelord 104:c57913399e79 235 serialNumDigits[3] = tempSerialNum % 10;
jelord 104:c57913399e79 236
jelord 104:c57913399e79 237 serialNumberAndType[2] = serialNumDigits[0]+48;
jelord 104:c57913399e79 238 serialNumberAndType[3] = serialNumDigits[1]+48;
jelord 104:c57913399e79 239 serialNumberAndType[4] = serialNumDigits[2]+48;
jelord 104:c57913399e79 240 serialNumberAndType[5] = serialNumDigits[3]+48;
jelord 104:c57913399e79 241
jelord 118:9cf0a67fb581 242 uint8_t bleControlByte[1] = {0,};
jelord 118:9cf0a67fb581 243 E2PROM.read(0x00072,bleControlByte,1);
jelord 118:9cf0a67fb581 244 if(bleControlByte[0] == 0x01){
jelord 118:9cf0a67fb581 245 bleControlByte[0] = 0x02;
jelord 118:9cf0a67fb581 246 ble.init();
jelord 118:9cf0a67fb581 247 ble.onDisconnection(disconnectionCallback);
jelord 118:9cf0a67fb581 248 ble.onDataWritten(WrittenHandler); //add writeCharCallback (custom function) to whenever data is being written to device
jelord 118:9cf0a67fb581 249 UPAS_Service upasService(ble, false,rtcPassValues,sampleTimePassValues,subjectLabelOriginal,dataLogOriginal,flowRateOriginal); //Create a GattService that is defined in UPAS_Service.h
jelord 118:9cf0a67fb581 250 upasServicePtr = &upasService; //Create a pointer to the service (Allows advertisement without specifically adding the service
jelord 104:c57913399e79 251
jelord 118:9cf0a67fb581 252 /* setup advertising
jelord 118:9cf0a67fb581 253 Following lines do the follow:
jelord 118:9cf0a67fb581 254 1:Declare the device as Bluetooth Smart(Low-Energy)
jelord 118:9cf0a67fb581 255 2.Advertise the UPAS service that will send and receive the 113+ bits of settable values in the UPAS EEPROM
jelord 118:9cf0a67fb581 256 3.Advertise the name that will be associated with the UPAS
jelord 118:9cf0a67fb581 257 4.Allow the UPAS to advertise unrestricted (this might change) */
jelord 118:9cf0a67fb581 258
jelord 118:9cf0a67fb581 259 ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
jelord 118:9cf0a67fb581 260 ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list));
jelord 118:9cf0a67fb581 261 ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)serialNumberAndType, sizeof(serialNumberAndType));
jelord 118:9cf0a67fb581 262 ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
jelord 118:9cf0a67fb581 263 ble.setAdvertisingInterval(160); /* 160ms. */
jelord 118:9cf0a67fb581 264 ble.startAdvertising();
jelord 118:9cf0a67fb581 265
jelord 118:9cf0a67fb581 266 //**************//BLE initialization//**************//
jelord 118:9cf0a67fb581 267
jelord 118:9cf0a67fb581 268 //Logic Loop waiting for responses from the BLE iPhone App.
jelord 118:9cf0a67fb581 269 //Will not break loop without response from the app
jelord 94:c57720890e76 270
jelord 118:9cf0a67fb581 271
jelord 118:9cf0a67fb581 272 //Loop waits for response from app. When set to start, UPAS is turned off, but BLE is disabled once UPAS is turned on
jelord 100:da71436aa52a 273 while (1) {
jelord 100:da71436aa52a 274 ble.waitForEvent();
jelord 100:da71436aa52a 275
jelord 100:da71436aa52a 276 if(RunReady==10){ //Check to see if app is done with configurations
jelord 100:da71436aa52a 277 ble.stopAdvertising();
jelord 118:9cf0a67fb581 278 E2PROM.write(0x00072,bleControlByte,1);
caseyquinn 122:f26474cc223a 279 NVIC_SystemReset();
caseyquinn 122:f26474cc223a 280 //pbKill = 0;
jelord 100:da71436aa52a 281 }
jelord 98:d70ff5a0b2e6 282
jelord 100:da71436aa52a 283 }
jelord 118:9cf0a67fb581 284 }
jelord 118:9cf0a67fb581 285 bleControlByte[0] = 0x01;
jelord 118:9cf0a67fb581 286 E2PROM.write(0x00072,bleControlByte,1);
jelord 100:da71436aa52a 287
jelord 94:c57720890e76 288 E2PROM.read(0x00015, startAndEndTime, 12); //Grab start and end times from EEPROM
caseyquinn 113:846f67efaa80 289 RGB_LED.set_led(1,0,1);
jelord 94:c57720890e76 290 while(!RTC.compare(startAndEndTime[0], startAndEndTime[1], startAndEndTime[2], startAndEndTime[3], startAndEndTime[4], startAndEndTime[5])) { // this while waits for the start time by looping until the start time
jelord 94:c57720890e76 291 wait(0.5);
jelord 98:d70ff5a0b2e6 292
jelord 94:c57720890e76 293 RTC.get_time();
jelord 94:c57720890e76 294
jelord 100:da71436aa52a 295 }
caseyquinn 106:3911b3c7a24e 296
caseyquinn 106:3911b3c7a24e 297
jelord 98:d70ff5a0b2e6 298 RGB_LED.set_led(0,1,0);
jelord 102:d25eab697fe0 299
jelord 102:d25eab697fe0 300 //Get the proper serial number
jelord 102:d25eab697fe0 301 E2PROM.read(0x00034, flowRateOriginal,2);
jelord 102:d25eab697fe0 302 serial_num = ((uint16_t)flowRateOriginal[1] << 8) | flowRateOriginal[0];
caseyquinn 107:5e3364e42214 303 //----------------------------------------------
jelord 109:33d7fc6c1b9b 304 calibrations.initialize(serial_num);
jelord 109:33d7fc6c1b9b 305 pc.printf("%f\n",calibrations.MF4);
caseyquinn 107:5e3364e42214 306 //----------------------------------------------
caseyquinn 106:3911b3c7a24e 307 wait(1);
jelord 94:c57720890e76 308 blower=1;
jelord 97:c596f8ed4562 309 E2PROM.read(0x00014,logIntervalReadOut,1);
jelord 97:c596f8ed4562 310 logInerval = logIntervalReadOut[0];
jelord 100:da71436aa52a 311
joshuasmth04 89:047e8558fd09 312 pc.printf("You're done, you can now disconect the USB cable.\r\n");
caseyquinn 84:85d11d422da3 313 RunReady = 0;
joshuasmth04 85:a95dd5f03818 314
jelord 94:c57720890e76 315
caseyquinn 114:84e759e07948 316 //stop.attach(&check_stop, 30); // check if we should shut down every 30 seconds, starting 60s after the start.
joshuasmth04 85:a95dd5f03818 317
jelord 102:d25eab697fe0 318 //Use the flow rate value stored in eeprom
jelord 102:d25eab697fe0 319 E2PROM.read(0x00010,flowRateOriginal,4);
jelord 102:d25eab697fe0 320 E2PROM.byteToFloat(flowRateOriginal, &volflowSet);
jelord 98:d70ff5a0b2e6 321
caseyquinn 81:480f0310ef9a 322 if(volflowSet<=1.0) {
joshuasmth04 59:a9b21b3d9afc 323 gainFlow = 100;
caseyquinn 81:480f0310ef9a 324 } else if(volflowSet>=2.0) {
joshuasmth04 59:a9b21b3d9afc 325 gainFlow = 25;
joshuasmth04 59:a9b21b3d9afc 326 } else {
caseyquinn 88:9142f21a4715 327 gainFlow = 25;
joshuasmth04 59:a9b21b3d9afc 328 }
joshuasmth04 59:a9b21b3d9afc 329
caseyquinn 57:0b554f7aa9a3 330 RGB_LED.set_led(1,0,0);
caseyquinn 57:0b554f7aa9a3 331 press = bmesensor.getPressure();
caseyquinn 57:0b554f7aa9a3 332 temp = bmesensor.getTemperature();
caseyquinn 57:0b554f7aa9a3 333 rh = bmesensor.getHumidity();
caseyquinn 57:0b554f7aa9a3 334
caseyquinn 57:0b554f7aa9a3 335 atmoRho = ((press-((6.1078*pow((float)10,(float)((7.5*temp)/(237.3+temp))))*(rh/100)))*100)/(287.0531*(temp+273.15))+((6.1078*pow((float)10,(float)((7.5*temp)/(237.3+temp))))*(rh/100)*100)/(461.4964*(temp+273.15));
caseyquinn 57:0b554f7aa9a3 336 massflowSet = volflowSet*atmoRho;
caseyquinn 57:0b554f7aa9a3 337 //Digtal pot tf from file: UPAS v2 OSU-PrimaryFlowData FullSet 2015-05-29 CQ mods.xlsx
joshuasmth04 85:a95dd5f03818 338
joshuasmth04 85:a95dd5f03818 339
joshuasmth04 77:24fbeb2bfe05 340 digital_pot_setpoint = (int)floor(calibrations.DP4*pow(massflowSet,4)+calibrations.DP3*pow(massflowSet,3)+calibrations.DP2*pow(massflowSet,2)+calibrations.DP1*massflowSet+calibrations.DP0); //min = 0x7F, max = 0x00
joshuasmth04 85:a95dd5f03818 341
joshuasmth04 59:a9b21b3d9afc 342 if(digital_pot_setpoint>=digitalpotMax) {
caseyquinn 57:0b554f7aa9a3 343 digital_pot_setpoint = digitalpotMax;
joshuasmth04 59:a9b21b3d9afc 344 } else if(digital_pot_setpoint<=digitalpotMin) {
caseyquinn 57:0b554f7aa9a3 345 digital_pot_setpoint = digitalpotMin;
joshuasmth04 59:a9b21b3d9afc 346 }
joshuasmth04 59:a9b21b3d9afc 347
caseyquinn 57:0b554f7aa9a3 348 DigPot.writeRegister(digital_pot_setpoint);
caseyquinn 57:0b554f7aa9a3 349 wait(1);
caseyquinn 57:0b554f7aa9a3 350 blower = 1;
jelord 102:d25eab697fe0 351
jelord 97:c596f8ed4562 352
jelord 102:d25eab697fe0 353 E2PROM.read(0x00001, subjectLabelOriginal,8);
jelord 102:d25eab697fe0 354 //sprintf(filename, "/sd/%c%c%c%c%c%c%c%cLOG_%02d-%02d-%02d_%02d=%02d=%02d.txt",subjectLabelOriginal[0],subjectLabelOriginal[1],subjectLabelOriginal[2],subjectLabelOriginal[3],subjectLabelOriginal[4],subjectLabelOriginal[5],subjectLabelOriginal[6],subjectLabelOriginal[7],RTC.year,RTC.month,RTC.date,RTC.hour,RTC.minutes,RTC.seconds);
jelord 102:d25eab697fe0 355 sprintf(filename, "/sd/UPAS%04dLOG_%02d-%02d-%02d_%02d=%02d=%02d_%c%c%c%c%c%c%c%c.txt",serial_num,RTC.year,RTC.month,RTC.date,RTC.hour,RTC.minutes,RTC.seconds,subjectLabelOriginal[0],subjectLabelOriginal[1],subjectLabelOriginal[2],subjectLabelOriginal[3],subjectLabelOriginal[4],subjectLabelOriginal[5],subjectLabelOriginal[6],subjectLabelOriginal[7]);
caseyquinn 57:0b554f7aa9a3 356 FILE *fp = fopen(filename, "w");
caseyquinn 57:0b554f7aa9a3 357 fclose(fp);
joshuasmth04 59:a9b21b3d9afc 358
joshuasmth04 59:a9b21b3d9afc 359 //---------------------------------------------------------------------------------------------//
joshuasmth04 59:a9b21b3d9afc 360 //Following lines are needed to enter into the initiallization flow control loop
joshuasmth04 59:a9b21b3d9afc 361
caseyquinn 57:0b554f7aa9a3 362 wait(10);
joshuasmth04 59:a9b21b3d9afc 363
caseyquinn 57:0b554f7aa9a3 364 omronReading = ads.readADC_SingleEnded(0, 0xC583); // read channel 0 PGA = 2 : Full Scale Range = 2.048V
caseyquinn 57:0b554f7aa9a3 365 omronVolt = (omronReading*4.096)/(32768*2);
joshuasmth04 77:24fbeb2bfe05 366 if(omronVolt<=calibrations.omronVMin) {
joshuasmth04 77:24fbeb2bfe05 367 massflow = calibrations.omronMFMin;
joshuasmth04 77:24fbeb2bfe05 368 } else if(omronVolt>=calibrations.omronVMax) {
joshuasmth04 77:24fbeb2bfe05 369 massflow = calibrations.omronMFMax;
joshuasmth04 59:a9b21b3d9afc 370 } else {
joshuasmth04 77:24fbeb2bfe05 371 massflow = calibrations.MF4*pow(omronVolt,(float)4)+calibrations.MF3*pow(omronVolt,(float)3)+calibrations.MF2*pow(omronVolt,(float)2)+calibrations.MF1*omronVolt+calibrations.MF0;
joshuasmth04 59:a9b21b3d9afc 372 }
joshuasmth04 59:a9b21b3d9afc 373 deltaMflow = massflow-massflowSet;
joshuasmth04 59:a9b21b3d9afc 374 digital_pot_set = digital_pot_setpoint;
joshuasmth04 59:a9b21b3d9afc 375 wait(5);
joshuasmth04 59:a9b21b3d9afc 376
joshuasmth04 59:a9b21b3d9afc 377 //---------------------------------------------------------------------------------------------//
joshuasmth04 59:a9b21b3d9afc 378 //Sets the flow withen +-1.5% of the desired flow rate based on mass flow
joshuasmth04 59:a9b21b3d9afc 379
joshuasmth04 59:a9b21b3d9afc 380 while(abs(deltaMflow)>.015) {
joshuasmth04 77:24fbeb2bfe05 381
joshuasmth04 59:a9b21b3d9afc 382 omronReading = ads.readADC_SingleEnded(0, 0xC583); // read channel 0 PGA = 2 : Full Scale Range = 2.048V
joshuasmth04 59:a9b21b3d9afc 383 omronVolt = (omronReading*4.096)/(32768*2);
joshuasmth04 59:a9b21b3d9afc 384 //Mass Flow tf from file: UPAS v2 OSU-PrimaryFlowData FullSet 2015-05-29 CQ mods.xlsx
joshuasmth04 77:24fbeb2bfe05 385 if(omronVolt<=calibrations.omronVMin) {
joshuasmth04 77:24fbeb2bfe05 386 massflow = calibrations.omronMFMin;
joshuasmth04 77:24fbeb2bfe05 387 } else if(omronVolt>=calibrations.omronVMax) {
joshuasmth04 77:24fbeb2bfe05 388 massflow = calibrations.omronMFMax;
joshuasmth04 59:a9b21b3d9afc 389 } else {
joshuasmth04 77:24fbeb2bfe05 390 massflow = calibrations.MF4*pow(omronVolt,(float)4)+calibrations.MF3*pow(omronVolt,(float)3)+calibrations.MF2*pow(omronVolt,(float)2)+calibrations.MF1*omronVolt+calibrations.MF0;
joshuasmth04 59:a9b21b3d9afc 391 }
caseyquinn 57:0b554f7aa9a3 392
joshuasmth04 59:a9b21b3d9afc 393 atmoRho = ((press-((6.1078*pow((float)10,(float)((7.5*temp)/(237.3+temp))))*(rh/100)))*100)/(287.0531*(temp+273.15))+((6.1078*pow((float)10,(float)((7.5*temp)/(237.3+temp))))*(rh/100)*100)/(461.4964*(temp+273.15));
joshuasmth04 59:a9b21b3d9afc 394 volflow = massflow/atmoRho;
joshuasmth04 59:a9b21b3d9afc 395 massflowSet = volflowSet*atmoRho;
joshuasmth04 59:a9b21b3d9afc 396 deltaMflow = massflow-massflowSet;
jelord 94:c57720890e76 397
joshuasmth04 59:a9b21b3d9afc 398 digital_pot_set = (int)(digital_pot_set+(int)((gainFlow*deltaMflow)));
joshuasmth04 59:a9b21b3d9afc 399 if(digital_pot_set>=digitalpotMax) {
joshuasmth04 59:a9b21b3d9afc 400 digital_pot_set = digitalpotMax;
joshuasmth04 59:a9b21b3d9afc 401 } else if(digital_pot_set<=digitalpotMin) {
joshuasmth04 59:a9b21b3d9afc 402 digital_pot_set = digitalpotMin;
joshuasmth04 59:a9b21b3d9afc 403 }
joshuasmth04 59:a9b21b3d9afc 404
joshuasmth04 59:a9b21b3d9afc 405 wait(2);
joshuasmth04 59:a9b21b3d9afc 406 DigPot.writeRegister(digital_pot_set);
joshuasmth04 59:a9b21b3d9afc 407 wait(1);
joshuasmth04 59:a9b21b3d9afc 408
joshuasmth04 59:a9b21b3d9afc 409
joshuasmth04 59:a9b21b3d9afc 410 }
joshuasmth04 59:a9b21b3d9afc 411
joshuasmth04 59:a9b21b3d9afc 412 sampledVol = 0.0;
joshuasmth04 59:a9b21b3d9afc 413 RGB_LED.set_led(0,1,0);
caseyquinn 114:84e759e07948 414
caseyquinn 114:84e759e07948 415 // logg.attach(&log_data, logInerval); // uses callbacks or block Interrupts for anything that uses i2c
joshuasmth04 77:24fbeb2bfe05 416
caseyquinn 67:300418575137 417
jelord 112:fd14d51e3493 418 while(1){
jelord 112:fd14d51e3493 419 if(RTC.compare(startAndEndTime[6], startAndEndTime[7], startAndEndTime[8], startAndEndTime[9], startAndEndTime[10], startAndEndTime[11]))
jelord 112:fd14d51e3493 420 pbKill = 0; // this is were we shut everything down
jelord 112:fd14d51e3493 421
caseyquinn 120:c7818e89e3da 422 wait(logInerval);
jelord 112:fd14d51e3493 423 // if(r==0) r=1;
jelord 112:fd14d51e3493 424 // else r=0;
jelord 112:fd14d51e3493 425 // RGB_LED.set_led(r,g,b);
jelord 112:fd14d51e3493 426 // wait(0.5);
jelord 112:fd14d51e3493 427
jelord 112:fd14d51e3493 428 RTC.get_time();
jelord 112:fd14d51e3493 429
caseyquinn 117:074ebef2dc12 430 secondsD = RTC.seconds;
caseyquinn 117:074ebef2dc12 431
caseyquinn 117:074ebef2dc12 432 while(fmod(secondsD,logInerval)!=0 || floor(secondsD)==floor(lastsecondD)) {
caseyquinn 117:074ebef2dc12 433 //pc.printf("%f, %f\r\n", floor(secondsD), floor(lastsecondD));
caseyquinn 117:074ebef2dc12 434 RTC.get_time();
caseyquinn 117:074ebef2dc12 435 secondsD = RTC.seconds;
caseyquinn 117:074ebef2dc12 436 wait_ms(100);
caseyquinn 117:074ebef2dc12 437 }
caseyquinn 117:074ebef2dc12 438 lastsecondD = secondsD;
caseyquinn 117:074ebef2dc12 439
jelord 112:fd14d51e3493 440 omronReading = ads.readADC_SingleEnded(0, 0xC583); // read channel 0 PGA = 2 : Full Scale Range = 2.048V
jelord 112:fd14d51e3493 441 omronVolt = (omronReading*4.096)/(32768*2);
jelord 112:fd14d51e3493 442
jelord 112:fd14d51e3493 443 if(omronVolt<=calibrations.omronVMin) {
jelord 112:fd14d51e3493 444 massflow = calibrations.omronMFMin;
jelord 112:fd14d51e3493 445 } else if(omronVolt>=calibrations.omronVMax) {
jelord 112:fd14d51e3493 446 massflow = calibrations.omronMFMax;
jelord 112:fd14d51e3493 447 } else {
jelord 112:fd14d51e3493 448 massflow = calibrations.MF4*pow(omronVolt,(float)4)+calibrations.MF3*pow(omronVolt,(float)3)+calibrations.MF2*pow(omronVolt,(float)2)+calibrations.MF1*omronVolt+calibrations.MF0;
jelord 112:fd14d51e3493 449 }
jelord 112:fd14d51e3493 450
jelord 112:fd14d51e3493 451 atmoRho = ((press-((6.1078*pow((float)10,(float)((7.5*temp)/(237.3+temp))))*(rh/100)))*100)/(287.0531*(temp+273.15))+((6.1078*pow((float)10,(float)((7.5*temp)/(237.3+temp))))*(rh/100)*100)/(461.4964*(temp+273.15));
jelord 112:fd14d51e3493 452 volflow = massflow/atmoRho;
jelord 112:fd14d51e3493 453 sampledVol = sampledVol + ((((float)logInerval)/60.0)*volflow);
jelord 112:fd14d51e3493 454 deltaVflow = volflow-volflowSet;
jelord 112:fd14d51e3493 455 massflowSet = volflowSet*atmoRho;
jelord 112:fd14d51e3493 456 deltaMflow = massflow-massflowSet;
jelord 112:fd14d51e3493 457 if(abs(deltaMflow)>.025) {
jelord 112:fd14d51e3493 458 digital_pot_change = (int)(gainFlow*deltaMflow);
jelord 112:fd14d51e3493 459
jelord 112:fd14d51e3493 460
jelord 112:fd14d51e3493 461 if(abs(digital_pot_change)>=50) {
jelord 112:fd14d51e3493 462 digital_pot_set = (int)(digital_pot_set+(int)((10.0*deltaMflow)));
jelord 112:fd14d51e3493 463 RGB_LED.set_led(1,0,0);
jelord 112:fd14d51e3493 464 } else {
jelord 112:fd14d51e3493 465 digital_pot_set = (digital_pot_set+ digital_pot_change);
jelord 112:fd14d51e3493 466 RGB_LED.set_led(1,1,0);
jelord 112:fd14d51e3493 467 }
jelord 112:fd14d51e3493 468
jelord 112:fd14d51e3493 469 if(digital_pot_set>=digitalpotMax) {
jelord 112:fd14d51e3493 470 digital_pot_set = digitalpotMax;
jelord 112:fd14d51e3493 471 RGB_LED.set_led(1,0,0);
jelord 112:fd14d51e3493 472 } else if(digital_pot_set<=digitalpotMin) {
jelord 112:fd14d51e3493 473 digital_pot_set = digitalpotMin;
jelord 112:fd14d51e3493 474 RGB_LED.set_led(1,0,0);
jelord 112:fd14d51e3493 475 }
jelord 112:fd14d51e3493 476
jelord 112:fd14d51e3493 477
jelord 112:fd14d51e3493 478 DigPot.writeRegister(digital_pot_set);
jelord 112:fd14d51e3493 479
jelord 112:fd14d51e3493 480 } else {
jelord 112:fd14d51e3493 481 RGB_LED.set_led(0,1,0);
jelord 112:fd14d51e3493 482 }
jelord 112:fd14d51e3493 483
caseyquinn 115:fb25810c1fab 484
jelord 112:fd14d51e3493 485 movementsensor.getACCEL();
jelord 112:fd14d51e3493 486 movementsensor.getCOMPASS();
jelord 112:fd14d51e3493 487 compass = movementsensor.getCOMPASS_HEADING();
jelord 112:fd14d51e3493 488 accel_x = movementsensor.AccelData.x;
jelord 112:fd14d51e3493 489 accel_y = movementsensor.AccelData.y;
jelord 112:fd14d51e3493 490 accel_z = movementsensor.AccelData.z;
jelord 112:fd14d51e3493 491 accel_comp = pow(accel_x,(float)2)+pow(accel_y,(float)2)+pow(accel_z,(float)2)-1.0;
jelord 112:fd14d51e3493 492 mag_x = movementsensor.MagData.x;
jelord 112:fd14d51e3493 493 mag_y = movementsensor.MagData.y;
jelord 112:fd14d51e3493 494 mag_z = movementsensor.MagData.z;
caseyquinn 115:fb25810c1fab 495
jelord 112:fd14d51e3493 496 vInReading = ads.readADC_SingleEnded(1, 0xD583); // read channel 0
jelord 112:fd14d51e3493 497 vBlowerReading = ads.readADC_SingleEnded(2, 0xE783); // read channel 0
jelord 112:fd14d51e3493 498 omronDiff = ads.readADC_Differential(0x8583); // differential channel 2-3
jelord 112:fd14d51e3493 499 press = bmesensor.getPressure();
jelord 112:fd14d51e3493 500 temp = bmesensor.getTemperature()-5.0;
jelord 112:fd14d51e3493 501 rh = bmesensor.getHumidity();
jelord 112:fd14d51e3493 502 uv = lightsensor.getUV();
jelord 112:fd14d51e3493 503 vis = lightsensor.getVIS();
jelord 112:fd14d51e3493 504 ir = lightsensor.getIR();
jelord 112:fd14d51e3493 505
jelord 112:fd14d51e3493 506
jelord 112:fd14d51e3493 507 FILE *fp = fopen(filename, "a");
jelord 112:fd14d51e3493 508 fprintf(fp, "%02d,%02d,%02d,%02d,%02d,%02d,",RTC.year, RTC.month,RTC.date,RTC.hour,RTC.minutes,RTC.seconds);
jelord 112:fd14d51e3493 509 fprintf(fp, "%1.3f,%1.3f,%2.2f,%4.2f,%2.1f,%1.3f,", omronVolt,massflow,temp,press,rh,atmoRho);
caseyquinn 115:fb25810c1fab 510 fprintf(fp, "%1.3f,%5.1f,%1.1f,%1.1f,%1.1f,%1.1f,", volflow, sampledVol, accel_x, accel_y, accel_z, accel_comp);
caseyquinn 115:fb25810c1fab 511 fprintf(fp, "%.1f,%.1f,%.1f,%.3f,%.3f,%.3f,%.1f,", angle_x,angle_y,angle_z,mag_x, mag_y, mag_z,compass);
jelord 112:fd14d51e3493 512 fprintf(fp, "%d,%d,%d,%d,%d,%d," ,uv,omronReading, vInReading, vBlowerReading, omronDiff,gasG.getAmps());
jelord 112:fd14d51e3493 513 fprintf(fp, "%d,%d,%d,%1.3f,%1.3f\r\n", gasG.getVolts(), gasG.getCharge(),digital_pot_set, deltaMflow, deltaVflow);
jelord 112:fd14d51e3493 514 fclose(fp);
caseyquinn 114:84e759e07948 515 //free(fp);
jelord 112:fd14d51e3493 516
jelord 112:fd14d51e3493 517 }
caseyquinn 111:5f2ba5f1a468 518
caseyquinn 110:67980ebdebf6 519
joshuasmth04 59:a9b21b3d9afc 520
caseyquinn 0:14d46ef4b6cb 521 }
caseyquinn 0:14d46ef4b6cb 522