ScienceSensorHub using the MAX32630FTHR

Dependencies:   Adafruit_FeatherOLED BMI160_Fork OneWire SDFileSystem TSL2561 USBDevice VEML6070 max32630fthr

main.cpp

Committer:
smatthew
Date:
2017-06-21
Revision:
0:15959decb4ea

File content as of revision 0:15959decb4ea:

#include "mbed.h"
#include "max32630fthr.h"
#include "OneWire.h"
#include "USBSerial.h"
#include "bmi160.h"
#include "TSL2561.h"
#include "Adafruit_SSD1306.h"
#include "VEML6070.h"
#include "SDFileSystem.h"

#define BUFF_LENGTH     9


MAX32630FTHR pegasus(MAX32630FTHR::VIO_3V3);

AnalogIn batMonitor(AIN_0);

// Hardware serial port over DAPLink
Serial daplink(P2_1, P2_0);

// UART 2. Connected to ScienceSensorBus0
RawSerial uart2(P3_1, P3_0);

// UART 3. Connected to ScienceSensorBus1
//Serial uart3(P5_4, P5_3);

// Virtual serial port over USB
USBSerial microUSB;


using namespace OneWire;
using namespace RomCommands;

DigitalOut rLED(LED1, LED_ON);
DigitalOut gLED(LED2, LED_OFF);
DigitalOut bLED(LED3, LED_OFF);

//Buttons A,B,C on FeatherWingOLED
DigitalIn aButton(P5_3, PullUp);
DigitalIn bButton(P3_3, PullUp);
DigitalIn cButton(P3_2, PullUp);

InterruptIn imuInt(P3_6);

//Get 1-Wire Master (owm) instance
//         (extWeakPup, extStrongPup)
MCU_OWM owm(false, true);

//Make sure owm is initialized
OneWireMaster::CmdResult result = owm.OWInitMaster();

//
SDFileSystem sd(P0_5, P0_6, P0_4, P0_7, "sd");  // mosi, miso, sclk, cs

//Setup I2C busses
I2C i2cBus(P5_7, P6_0);     //Actually i2c2
I2C i2cBus1(P3_4, P3_5);

//Setup FeatherOLED
Adafruit_SSD1306_I2c featherOLED(i2cBus1);

//Setup PMIC
MAX14690 pmic(i2cBus);

// Variable Definitions
uint8_t             screenMode = 0;
uint8_t             screenMax = 4;
event_callback_t    serialRXCb;
uint16_t            co2Level = 420;
char             rx_buf[BUFF_LENGTH + 1];
volatile int rx_in=0;
volatile int rx_out=0;

// Circular buffers for serial TX and RX data - used by interrupt routines
const int buffer_size = 255;
// might need to increase buffer size for high baud rates
char tx_buffer[buffer_size+1];
char rx_buffer[buffer_size+1];

void doubleTapDetected(void)
{
    rLED = !rLED;
    screenMode = (screenMode + 1) % screenMax;
}

// Interupt Routine to read in data from serial port
void serialRX(void)
{
    bLED = LED_ON;
// Loop just in case more than one character is in UART's receive FIFO buffer
// Stop if buffer full
    while ((uart2.readable()) && (((rx_in + 1) % buffer_size) != rx_out)) {
        rx_buffer[rx_in] = uart2.getc();
// Uncomment to Echo to USB serial to watch data flow
//        monitor_device.putc(rx_buffer[rx_in]);
        rx_in = (rx_in + 1) % buffer_size;
    }
    bLED = LED_OFF;
    return;
}



// main() runs in its own thread in the OS
// (note the calls to Thread::wait below for delays)
int main()
{

    uart2.attach(&serialRX, Serial::RxIrq);
    imuInt.mode(PullDown);

    pmic.monCfg = MAX14690::MON_BAT;
    char tVar, pmicStatusA, pmicStatusB;
    pmic.readReg(MAX14690::REG_BOOT_CFG, &tVar);
    pmic.readReg(MAX14690::REG_STATUS_A, &pmicStatusA);
    pmic.readReg(MAX14690::REG_STATUS_B, &pmicStatusB);
    gLED = LED_ON;
    rLED = LED_ON;
    char co2cmd[9]= {0xff,0x01,0x86,0x00,0x00,0x00,0x00,0x00,0x79};
    char co2rtrn[9];


    i2cBus.frequency(100000);
    i2cBus1.frequency(400000);

    uint32_t failures = 0;

    DigitalIn uSDdetect(P2_2, PullUp);
    static const uint32_t N = 14400;
    uint32_t samples = 0;
    float accYaxisBuff[N];
    float accZaxisBuff[N];
    float gyroXaxisBuff[N];
    int32_t pulseWidthBuff[N];

    //Sensor data vars
    BMI160::SensorData accData;
    BMI160::SensorData gyroData;
    BMI160::SensorTime sensorTime;

    //Configure Color Sensor Instance. (Attached to I2C2)
//    TCS3472_I2C rgbSensor(i2cBus);

    //get Lux Sensor instance and configure it.
    TSL2561 luxSensor(i2cBus, TSL2561_ADDRESS_GND);

    //Get UV Sensor Instance & Configure It.
    VEML6070 uvSensor(i2cBus);
    uvSensor.begin(VEML6070_4_T);

    //Get IMU instance and configure it
    BMI160_I2C imu(i2cBus, BMI160_I2C::I2C_ADRS_SDO_LO);

    //Power up sensors in normal mode
    if(imu.setSensorPowerMode(BMI160::GYRO, BMI160::NORMAL) != BMI160::RTN_NO_ERROR) {
        printf("Failed to set gyroscope power mode\n");
        failures++;
    }

    wait(0.1);

    if(imu.setSensorPowerMode(BMI160::ACC, BMI160::NORMAL) != BMI160::RTN_NO_ERROR) {
        printf("Failed to set accelerometer power mode\n");
        failures++;
    }
    wait(0.1);

    BMI160::AccConfig accConfig;
    BMI160::AccConfig accConfigRead;
    accConfig.range = BMI160::SENS_4G;
    accConfig.us = BMI160::ACC_US_OFF;
    accConfig.bwp = BMI160::ACC_BWP_2;
    accConfig.odr = BMI160::ACC_ODR_11;

    imu.writeRegister(BMI160::CMD, 0xB1); //Reset the interrupt engine
    imu.writeRegister(BMI160::INT_EN_0, 0x30);  // Set DoubleTap Detection Interrupt
    imu.writeRegister(BMI160::INT_OUT_CTRL, 0b00001010);  // Interrupt Output Control
    imu.writeRegister(BMI160::INT_LATCH, 0b00000100);  // Interrupt Latch.
    imu.writeRegister(BMI160::INT_MAP_0, 0b00110000);   // Map DoubleTap to Interrupt 1
    imu.writeRegister(BMI160::INT_TAP_0, 0b00000111);
    imu.writeRegister(BMI160::INT_TAP_1, 0b00001010);
    imuInt.fall(&doubleTapDetected);

    Thread::wait(50);

    featherOLED.clearDisplay();
    featherOLED.setTextCursor(0,0);
    featherOLED.printf("%ux%u OLED Display\r\n", featherOLED.width(), featherOLED.height());
    featherOLED.printf("HelloWorld \r");
    featherOLED.display();

    FILE *fp = fopen("/sd/myfile.txt", "w");
    fprintf(fp, "Begin Logging!\n");
//    fclose(fp);
    rLED = LED_OFF;

    while (true) {
        gLED = !gLED;
        pmic.readReg(MAX14690::REG_STATUS_A, &pmicStatusA);
        pmic.readReg(MAX14690::REG_STATUS_B, &pmicStatusB);
        featherOLED.clearDisplay();
        featherOLED.setTextCursor(0,0);
        switch (screenMode) {
            case 0x00 :  //Main Screen
                featherOLED.printf("MAX32630FTHR OLED\n");
                featherOLED.printf("ScienceSensorHub\r\n");
                featherOLED.printf("by Scott Roberts\r\n");
                break;
            case 0x01 :  //Light Values
                featherOLED.printf("Plant Sensors\r\n");
                featherOLED.printf("Lux: %+5.2f \r\n", luxSensor.lux());
                featherOLED.printf("UV: %+3u\r\n", uvSensor.readUV());
                featherOLED.printf("CO2: %3u ",co2Level);

                break;
            case 0x02 :  //IMU Values
                featherOLED.printf("IMU Values\r\n");
                imu.getSensorXYZ(accData, accConfig.range);
                featherOLED.printf("X: %f\r\n",accData.xAxis.scaled);
                featherOLED.printf("Y: %f\r\n",accData.yAxis.scaled);
                featherOLED.printf("Z: %f\r\n",accData.zAxis.scaled);
                    break;
                case 0x03 :  //Diagnostics
                        featherOLED.printf("Diagnostics\r\n");
                        featherOLED.printf("B: %5.3f \r\n",batMonitor.read()*5.0f);
                        if((pmicStatusB & 0x08) != 0) featherOLED.printf("USBok/");
                        if((pmicStatusB & 0x01) ==1) featherOLED.printf("ChgTmo/");
                        switch(pmicStatusA & 0x07) {
                            case 0x00 :
                                featherOLED.printf("Coff/");
                                    break;
                                case 0x01 :
                                    featherOLED.printf("LTemp/");
                                    break;
                                case 0x02 :
                                    featherOLED.printf("PreC/");
                                    break;
                                case 0x03 :
                                    featherOLED.printf("FCCC/");
                                    break;
                                case 0x04 :
                                    featherOLED.printf("FCCV/");
                                    break;
                                case 0x05 :
                                    featherOLED.printf("MCinPr/");
                                    break;
                                case 0x06 :
                                    featherOLED.printf("MTdone/");
                                    break;
                                case 0x07 :
                                    featherOLED.printf("Cfault/");
                                    break;
                            }
                break;
            case 0x04 : //Oops
                    featherOLED.printf("Misc\r\n");
                    break;

                }


        featherOLED.display();

        Thread::wait(750);
    }
}