ScienceSensorHub using the MAX32630FTHR
Dependencies: Adafruit_FeatherOLED BMI160_Fork OneWire SDFileSystem TSL2561 USBDevice VEML6070 max32630fthr
main.cpp@0:15959decb4ea, 2017-06-21 (annotated)
- Committer:
- smatthew
- Date:
- Wed Jun 21 01:06:37 2017 +0000
- Revision:
- 0:15959decb4ea
initial commit
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
smatthew | 0:15959decb4ea | 1 | #include "mbed.h" |
smatthew | 0:15959decb4ea | 2 | #include "max32630fthr.h" |
smatthew | 0:15959decb4ea | 3 | #include "OneWire.h" |
smatthew | 0:15959decb4ea | 4 | #include "USBSerial.h" |
smatthew | 0:15959decb4ea | 5 | #include "bmi160.h" |
smatthew | 0:15959decb4ea | 6 | #include "TSL2561.h" |
smatthew | 0:15959decb4ea | 7 | #include "Adafruit_SSD1306.h" |
smatthew | 0:15959decb4ea | 8 | #include "VEML6070.h" |
smatthew | 0:15959decb4ea | 9 | #include "SDFileSystem.h" |
smatthew | 0:15959decb4ea | 10 | |
smatthew | 0:15959decb4ea | 11 | #define BUFF_LENGTH 9 |
smatthew | 0:15959decb4ea | 12 | |
smatthew | 0:15959decb4ea | 13 | |
smatthew | 0:15959decb4ea | 14 | MAX32630FTHR pegasus(MAX32630FTHR::VIO_3V3); |
smatthew | 0:15959decb4ea | 15 | |
smatthew | 0:15959decb4ea | 16 | AnalogIn batMonitor(AIN_0); |
smatthew | 0:15959decb4ea | 17 | |
smatthew | 0:15959decb4ea | 18 | // Hardware serial port over DAPLink |
smatthew | 0:15959decb4ea | 19 | Serial daplink(P2_1, P2_0); |
smatthew | 0:15959decb4ea | 20 | |
smatthew | 0:15959decb4ea | 21 | // UART 2. Connected to ScienceSensorBus0 |
smatthew | 0:15959decb4ea | 22 | RawSerial uart2(P3_1, P3_0); |
smatthew | 0:15959decb4ea | 23 | |
smatthew | 0:15959decb4ea | 24 | // UART 3. Connected to ScienceSensorBus1 |
smatthew | 0:15959decb4ea | 25 | //Serial uart3(P5_4, P5_3); |
smatthew | 0:15959decb4ea | 26 | |
smatthew | 0:15959decb4ea | 27 | // Virtual serial port over USB |
smatthew | 0:15959decb4ea | 28 | USBSerial microUSB; |
smatthew | 0:15959decb4ea | 29 | |
smatthew | 0:15959decb4ea | 30 | |
smatthew | 0:15959decb4ea | 31 | using namespace OneWire; |
smatthew | 0:15959decb4ea | 32 | using namespace RomCommands; |
smatthew | 0:15959decb4ea | 33 | |
smatthew | 0:15959decb4ea | 34 | DigitalOut rLED(LED1, LED_ON); |
smatthew | 0:15959decb4ea | 35 | DigitalOut gLED(LED2, LED_OFF); |
smatthew | 0:15959decb4ea | 36 | DigitalOut bLED(LED3, LED_OFF); |
smatthew | 0:15959decb4ea | 37 | |
smatthew | 0:15959decb4ea | 38 | //Buttons A,B,C on FeatherWingOLED |
smatthew | 0:15959decb4ea | 39 | DigitalIn aButton(P5_3, PullUp); |
smatthew | 0:15959decb4ea | 40 | DigitalIn bButton(P3_3, PullUp); |
smatthew | 0:15959decb4ea | 41 | DigitalIn cButton(P3_2, PullUp); |
smatthew | 0:15959decb4ea | 42 | |
smatthew | 0:15959decb4ea | 43 | InterruptIn imuInt(P3_6); |
smatthew | 0:15959decb4ea | 44 | |
smatthew | 0:15959decb4ea | 45 | //Get 1-Wire Master (owm) instance |
smatthew | 0:15959decb4ea | 46 | // (extWeakPup, extStrongPup) |
smatthew | 0:15959decb4ea | 47 | MCU_OWM owm(false, true); |
smatthew | 0:15959decb4ea | 48 | |
smatthew | 0:15959decb4ea | 49 | //Make sure owm is initialized |
smatthew | 0:15959decb4ea | 50 | OneWireMaster::CmdResult result = owm.OWInitMaster(); |
smatthew | 0:15959decb4ea | 51 | |
smatthew | 0:15959decb4ea | 52 | // |
smatthew | 0:15959decb4ea | 53 | SDFileSystem sd(P0_5, P0_6, P0_4, P0_7, "sd"); // mosi, miso, sclk, cs |
smatthew | 0:15959decb4ea | 54 | |
smatthew | 0:15959decb4ea | 55 | //Setup I2C busses |
smatthew | 0:15959decb4ea | 56 | I2C i2cBus(P5_7, P6_0); //Actually i2c2 |
smatthew | 0:15959decb4ea | 57 | I2C i2cBus1(P3_4, P3_5); |
smatthew | 0:15959decb4ea | 58 | |
smatthew | 0:15959decb4ea | 59 | //Setup FeatherOLED |
smatthew | 0:15959decb4ea | 60 | Adafruit_SSD1306_I2c featherOLED(i2cBus1); |
smatthew | 0:15959decb4ea | 61 | |
smatthew | 0:15959decb4ea | 62 | //Setup PMIC |
smatthew | 0:15959decb4ea | 63 | MAX14690 pmic(i2cBus); |
smatthew | 0:15959decb4ea | 64 | |
smatthew | 0:15959decb4ea | 65 | // Variable Definitions |
smatthew | 0:15959decb4ea | 66 | uint8_t screenMode = 0; |
smatthew | 0:15959decb4ea | 67 | uint8_t screenMax = 4; |
smatthew | 0:15959decb4ea | 68 | event_callback_t serialRXCb; |
smatthew | 0:15959decb4ea | 69 | uint16_t co2Level = 420; |
smatthew | 0:15959decb4ea | 70 | char rx_buf[BUFF_LENGTH + 1]; |
smatthew | 0:15959decb4ea | 71 | volatile int rx_in=0; |
smatthew | 0:15959decb4ea | 72 | volatile int rx_out=0; |
smatthew | 0:15959decb4ea | 73 | |
smatthew | 0:15959decb4ea | 74 | // Circular buffers for serial TX and RX data - used by interrupt routines |
smatthew | 0:15959decb4ea | 75 | const int buffer_size = 255; |
smatthew | 0:15959decb4ea | 76 | // might need to increase buffer size for high baud rates |
smatthew | 0:15959decb4ea | 77 | char tx_buffer[buffer_size+1]; |
smatthew | 0:15959decb4ea | 78 | char rx_buffer[buffer_size+1]; |
smatthew | 0:15959decb4ea | 79 | |
smatthew | 0:15959decb4ea | 80 | void doubleTapDetected(void) |
smatthew | 0:15959decb4ea | 81 | { |
smatthew | 0:15959decb4ea | 82 | rLED = !rLED; |
smatthew | 0:15959decb4ea | 83 | screenMode = (screenMode + 1) % screenMax; |
smatthew | 0:15959decb4ea | 84 | } |
smatthew | 0:15959decb4ea | 85 | |
smatthew | 0:15959decb4ea | 86 | // Interupt Routine to read in data from serial port |
smatthew | 0:15959decb4ea | 87 | void serialRX(void) |
smatthew | 0:15959decb4ea | 88 | { |
smatthew | 0:15959decb4ea | 89 | bLED = LED_ON; |
smatthew | 0:15959decb4ea | 90 | // Loop just in case more than one character is in UART's receive FIFO buffer |
smatthew | 0:15959decb4ea | 91 | // Stop if buffer full |
smatthew | 0:15959decb4ea | 92 | while ((uart2.readable()) && (((rx_in + 1) % buffer_size) != rx_out)) { |
smatthew | 0:15959decb4ea | 93 | rx_buffer[rx_in] = uart2.getc(); |
smatthew | 0:15959decb4ea | 94 | // Uncomment to Echo to USB serial to watch data flow |
smatthew | 0:15959decb4ea | 95 | // monitor_device.putc(rx_buffer[rx_in]); |
smatthew | 0:15959decb4ea | 96 | rx_in = (rx_in + 1) % buffer_size; |
smatthew | 0:15959decb4ea | 97 | } |
smatthew | 0:15959decb4ea | 98 | bLED = LED_OFF; |
smatthew | 0:15959decb4ea | 99 | return; |
smatthew | 0:15959decb4ea | 100 | } |
smatthew | 0:15959decb4ea | 101 | |
smatthew | 0:15959decb4ea | 102 | |
smatthew | 0:15959decb4ea | 103 | |
smatthew | 0:15959decb4ea | 104 | // main() runs in its own thread in the OS |
smatthew | 0:15959decb4ea | 105 | // (note the calls to Thread::wait below for delays) |
smatthew | 0:15959decb4ea | 106 | int main() |
smatthew | 0:15959decb4ea | 107 | { |
smatthew | 0:15959decb4ea | 108 | |
smatthew | 0:15959decb4ea | 109 | uart2.attach(&serialRX, Serial::RxIrq); |
smatthew | 0:15959decb4ea | 110 | imuInt.mode(PullDown); |
smatthew | 0:15959decb4ea | 111 | |
smatthew | 0:15959decb4ea | 112 | pmic.monCfg = MAX14690::MON_BAT; |
smatthew | 0:15959decb4ea | 113 | char tVar, pmicStatusA, pmicStatusB; |
smatthew | 0:15959decb4ea | 114 | pmic.readReg(MAX14690::REG_BOOT_CFG, &tVar); |
smatthew | 0:15959decb4ea | 115 | pmic.readReg(MAX14690::REG_STATUS_A, &pmicStatusA); |
smatthew | 0:15959decb4ea | 116 | pmic.readReg(MAX14690::REG_STATUS_B, &pmicStatusB); |
smatthew | 0:15959decb4ea | 117 | gLED = LED_ON; |
smatthew | 0:15959decb4ea | 118 | rLED = LED_ON; |
smatthew | 0:15959decb4ea | 119 | char co2cmd[9]= {0xff,0x01,0x86,0x00,0x00,0x00,0x00,0x00,0x79}; |
smatthew | 0:15959decb4ea | 120 | char co2rtrn[9]; |
smatthew | 0:15959decb4ea | 121 | |
smatthew | 0:15959decb4ea | 122 | |
smatthew | 0:15959decb4ea | 123 | i2cBus.frequency(100000); |
smatthew | 0:15959decb4ea | 124 | i2cBus1.frequency(400000); |
smatthew | 0:15959decb4ea | 125 | |
smatthew | 0:15959decb4ea | 126 | uint32_t failures = 0; |
smatthew | 0:15959decb4ea | 127 | |
smatthew | 0:15959decb4ea | 128 | DigitalIn uSDdetect(P2_2, PullUp); |
smatthew | 0:15959decb4ea | 129 | static const uint32_t N = 14400; |
smatthew | 0:15959decb4ea | 130 | uint32_t samples = 0; |
smatthew | 0:15959decb4ea | 131 | float accYaxisBuff[N]; |
smatthew | 0:15959decb4ea | 132 | float accZaxisBuff[N]; |
smatthew | 0:15959decb4ea | 133 | float gyroXaxisBuff[N]; |
smatthew | 0:15959decb4ea | 134 | int32_t pulseWidthBuff[N]; |
smatthew | 0:15959decb4ea | 135 | |
smatthew | 0:15959decb4ea | 136 | //Sensor data vars |
smatthew | 0:15959decb4ea | 137 | BMI160::SensorData accData; |
smatthew | 0:15959decb4ea | 138 | BMI160::SensorData gyroData; |
smatthew | 0:15959decb4ea | 139 | BMI160::SensorTime sensorTime; |
smatthew | 0:15959decb4ea | 140 | |
smatthew | 0:15959decb4ea | 141 | //Configure Color Sensor Instance. (Attached to I2C2) |
smatthew | 0:15959decb4ea | 142 | // TCS3472_I2C rgbSensor(i2cBus); |
smatthew | 0:15959decb4ea | 143 | |
smatthew | 0:15959decb4ea | 144 | //get Lux Sensor instance and configure it. |
smatthew | 0:15959decb4ea | 145 | TSL2561 luxSensor(i2cBus, TSL2561_ADDRESS_GND); |
smatthew | 0:15959decb4ea | 146 | |
smatthew | 0:15959decb4ea | 147 | //Get UV Sensor Instance & Configure It. |
smatthew | 0:15959decb4ea | 148 | VEML6070 uvSensor(i2cBus); |
smatthew | 0:15959decb4ea | 149 | uvSensor.begin(VEML6070_4_T); |
smatthew | 0:15959decb4ea | 150 | |
smatthew | 0:15959decb4ea | 151 | //Get IMU instance and configure it |
smatthew | 0:15959decb4ea | 152 | BMI160_I2C imu(i2cBus, BMI160_I2C::I2C_ADRS_SDO_LO); |
smatthew | 0:15959decb4ea | 153 | |
smatthew | 0:15959decb4ea | 154 | //Power up sensors in normal mode |
smatthew | 0:15959decb4ea | 155 | if(imu.setSensorPowerMode(BMI160::GYRO, BMI160::NORMAL) != BMI160::RTN_NO_ERROR) { |
smatthew | 0:15959decb4ea | 156 | printf("Failed to set gyroscope power mode\n"); |
smatthew | 0:15959decb4ea | 157 | failures++; |
smatthew | 0:15959decb4ea | 158 | } |
smatthew | 0:15959decb4ea | 159 | |
smatthew | 0:15959decb4ea | 160 | wait(0.1); |
smatthew | 0:15959decb4ea | 161 | |
smatthew | 0:15959decb4ea | 162 | if(imu.setSensorPowerMode(BMI160::ACC, BMI160::NORMAL) != BMI160::RTN_NO_ERROR) { |
smatthew | 0:15959decb4ea | 163 | printf("Failed to set accelerometer power mode\n"); |
smatthew | 0:15959decb4ea | 164 | failures++; |
smatthew | 0:15959decb4ea | 165 | } |
smatthew | 0:15959decb4ea | 166 | wait(0.1); |
smatthew | 0:15959decb4ea | 167 | |
smatthew | 0:15959decb4ea | 168 | BMI160::AccConfig accConfig; |
smatthew | 0:15959decb4ea | 169 | BMI160::AccConfig accConfigRead; |
smatthew | 0:15959decb4ea | 170 | accConfig.range = BMI160::SENS_4G; |
smatthew | 0:15959decb4ea | 171 | accConfig.us = BMI160::ACC_US_OFF; |
smatthew | 0:15959decb4ea | 172 | accConfig.bwp = BMI160::ACC_BWP_2; |
smatthew | 0:15959decb4ea | 173 | accConfig.odr = BMI160::ACC_ODR_11; |
smatthew | 0:15959decb4ea | 174 | |
smatthew | 0:15959decb4ea | 175 | imu.writeRegister(BMI160::CMD, 0xB1); //Reset the interrupt engine |
smatthew | 0:15959decb4ea | 176 | imu.writeRegister(BMI160::INT_EN_0, 0x30); // Set DoubleTap Detection Interrupt |
smatthew | 0:15959decb4ea | 177 | imu.writeRegister(BMI160::INT_OUT_CTRL, 0b00001010); // Interrupt Output Control |
smatthew | 0:15959decb4ea | 178 | imu.writeRegister(BMI160::INT_LATCH, 0b00000100); // Interrupt Latch. |
smatthew | 0:15959decb4ea | 179 | imu.writeRegister(BMI160::INT_MAP_0, 0b00110000); // Map DoubleTap to Interrupt 1 |
smatthew | 0:15959decb4ea | 180 | imu.writeRegister(BMI160::INT_TAP_0, 0b00000111); |
smatthew | 0:15959decb4ea | 181 | imu.writeRegister(BMI160::INT_TAP_1, 0b00001010); |
smatthew | 0:15959decb4ea | 182 | imuInt.fall(&doubleTapDetected); |
smatthew | 0:15959decb4ea | 183 | |
smatthew | 0:15959decb4ea | 184 | Thread::wait(50); |
smatthew | 0:15959decb4ea | 185 | |
smatthew | 0:15959decb4ea | 186 | featherOLED.clearDisplay(); |
smatthew | 0:15959decb4ea | 187 | featherOLED.setTextCursor(0,0); |
smatthew | 0:15959decb4ea | 188 | featherOLED.printf("%ux%u OLED Display\r\n", featherOLED.width(), featherOLED.height()); |
smatthew | 0:15959decb4ea | 189 | featherOLED.printf("HelloWorld \r"); |
smatthew | 0:15959decb4ea | 190 | featherOLED.display(); |
smatthew | 0:15959decb4ea | 191 | |
smatthew | 0:15959decb4ea | 192 | FILE *fp = fopen("/sd/myfile.txt", "w"); |
smatthew | 0:15959decb4ea | 193 | fprintf(fp, "Begin Logging!\n"); |
smatthew | 0:15959decb4ea | 194 | // fclose(fp); |
smatthew | 0:15959decb4ea | 195 | rLED = LED_OFF; |
smatthew | 0:15959decb4ea | 196 | |
smatthew | 0:15959decb4ea | 197 | while (true) { |
smatthew | 0:15959decb4ea | 198 | gLED = !gLED; |
smatthew | 0:15959decb4ea | 199 | pmic.readReg(MAX14690::REG_STATUS_A, &pmicStatusA); |
smatthew | 0:15959decb4ea | 200 | pmic.readReg(MAX14690::REG_STATUS_B, &pmicStatusB); |
smatthew | 0:15959decb4ea | 201 | featherOLED.clearDisplay(); |
smatthew | 0:15959decb4ea | 202 | featherOLED.setTextCursor(0,0); |
smatthew | 0:15959decb4ea | 203 | switch (screenMode) { |
smatthew | 0:15959decb4ea | 204 | case 0x00 : //Main Screen |
smatthew | 0:15959decb4ea | 205 | featherOLED.printf("MAX32630FTHR OLED\n"); |
smatthew | 0:15959decb4ea | 206 | featherOLED.printf("ScienceSensorHub\r\n"); |
smatthew | 0:15959decb4ea | 207 | featherOLED.printf("by Scott Roberts\r\n"); |
smatthew | 0:15959decb4ea | 208 | break; |
smatthew | 0:15959decb4ea | 209 | case 0x01 : //Light Values |
smatthew | 0:15959decb4ea | 210 | featherOLED.printf("Plant Sensors\r\n"); |
smatthew | 0:15959decb4ea | 211 | featherOLED.printf("Lux: %+5.2f \r\n", luxSensor.lux()); |
smatthew | 0:15959decb4ea | 212 | featherOLED.printf("UV: %+3u\r\n", uvSensor.readUV()); |
smatthew | 0:15959decb4ea | 213 | featherOLED.printf("CO2: %3u ",co2Level); |
smatthew | 0:15959decb4ea | 214 | |
smatthew | 0:15959decb4ea | 215 | break; |
smatthew | 0:15959decb4ea | 216 | case 0x02 : //IMU Values |
smatthew | 0:15959decb4ea | 217 | featherOLED.printf("IMU Values\r\n"); |
smatthew | 0:15959decb4ea | 218 | imu.getSensorXYZ(accData, accConfig.range); |
smatthew | 0:15959decb4ea | 219 | featherOLED.printf("X: %f\r\n",accData.xAxis.scaled); |
smatthew | 0:15959decb4ea | 220 | featherOLED.printf("Y: %f\r\n",accData.yAxis.scaled); |
smatthew | 0:15959decb4ea | 221 | featherOLED.printf("Z: %f\r\n",accData.zAxis.scaled); |
smatthew | 0:15959decb4ea | 222 | break; |
smatthew | 0:15959decb4ea | 223 | case 0x03 : //Diagnostics |
smatthew | 0:15959decb4ea | 224 | featherOLED.printf("Diagnostics\r\n"); |
smatthew | 0:15959decb4ea | 225 | featherOLED.printf("B: %5.3f \r\n",batMonitor.read()*5.0f); |
smatthew | 0:15959decb4ea | 226 | if((pmicStatusB & 0x08) != 0) featherOLED.printf("USBok/"); |
smatthew | 0:15959decb4ea | 227 | if((pmicStatusB & 0x01) ==1) featherOLED.printf("ChgTmo/"); |
smatthew | 0:15959decb4ea | 228 | switch(pmicStatusA & 0x07) { |
smatthew | 0:15959decb4ea | 229 | case 0x00 : |
smatthew | 0:15959decb4ea | 230 | featherOLED.printf("Coff/"); |
smatthew | 0:15959decb4ea | 231 | break; |
smatthew | 0:15959decb4ea | 232 | case 0x01 : |
smatthew | 0:15959decb4ea | 233 | featherOLED.printf("LTemp/"); |
smatthew | 0:15959decb4ea | 234 | break; |
smatthew | 0:15959decb4ea | 235 | case 0x02 : |
smatthew | 0:15959decb4ea | 236 | featherOLED.printf("PreC/"); |
smatthew | 0:15959decb4ea | 237 | break; |
smatthew | 0:15959decb4ea | 238 | case 0x03 : |
smatthew | 0:15959decb4ea | 239 | featherOLED.printf("FCCC/"); |
smatthew | 0:15959decb4ea | 240 | break; |
smatthew | 0:15959decb4ea | 241 | case 0x04 : |
smatthew | 0:15959decb4ea | 242 | featherOLED.printf("FCCV/"); |
smatthew | 0:15959decb4ea | 243 | break; |
smatthew | 0:15959decb4ea | 244 | case 0x05 : |
smatthew | 0:15959decb4ea | 245 | featherOLED.printf("MCinPr/"); |
smatthew | 0:15959decb4ea | 246 | break; |
smatthew | 0:15959decb4ea | 247 | case 0x06 : |
smatthew | 0:15959decb4ea | 248 | featherOLED.printf("MTdone/"); |
smatthew | 0:15959decb4ea | 249 | break; |
smatthew | 0:15959decb4ea | 250 | case 0x07 : |
smatthew | 0:15959decb4ea | 251 | featherOLED.printf("Cfault/"); |
smatthew | 0:15959decb4ea | 252 | break; |
smatthew | 0:15959decb4ea | 253 | } |
smatthew | 0:15959decb4ea | 254 | break; |
smatthew | 0:15959decb4ea | 255 | case 0x04 : //Oops |
smatthew | 0:15959decb4ea | 256 | featherOLED.printf("Misc\r\n"); |
smatthew | 0:15959decb4ea | 257 | break; |
smatthew | 0:15959decb4ea | 258 | |
smatthew | 0:15959decb4ea | 259 | } |
smatthew | 0:15959decb4ea | 260 | |
smatthew | 0:15959decb4ea | 261 | |
smatthew | 0:15959decb4ea | 262 | featherOLED.display(); |
smatthew | 0:15959decb4ea | 263 | |
smatthew | 0:15959decb4ea | 264 | Thread::wait(750); |
smatthew | 0:15959decb4ea | 265 | } |
smatthew | 0:15959decb4ea | 266 | } |
smatthew | 0:15959decb4ea | 267 |