Ina hackathon 2nd

Dependencies:   ADXL345_I2C Chainable_RGB_LED EEAB-P1 MMA8652FC Sht31 TinyGPS mbed

Fork of ina-hack-test by dondoko don

main.cpp

Committer:
sonson
Date:
2017-08-22
Revision:
5:09935c0aa297
Parent:
3:1df2b5938eb7
Child:
6:ae7b9f0a13f7

File content as of revision 5:09935c0aa297:

#include "mbed.h"
#include "TinyGPS.h"
#include "Eeabp1.h"

//#define TEST_ANALOG
//#define TEST_TEMP_HUMID
//#define TEST_ACC


//
// 1Wire Support
//
I2C i2c(P0_30, P0_7);

// 指定アドレスにアクセスする
static void SendRegDataI2c(uint8_t address, uint8_t regdata)
{
    i2c.start();
    i2c.write((address << 1));
    i2c.write(regdata);
    i2c.stop();
    wait_us(1000);
}

// 指定アドレスに1バイトデータを送信する
static void SendRegByteDataI2c(uint8_t address, uint8_t regaddr, uint8_t data)
{
    i2c.start();
    i2c.write((address << 1));
    i2c.write(regaddr);
    i2c.write(data);
    i2c.stop();
    wait_us(1000);
}

static void RecieveDataI2c(uint8_t address, uint8_t reg1, uint8_t reg2, uint8_t* data, uint8_t datacount)
{
    i2c.start();
    i2c.write((address << 1));
    i2c.write(reg1);
    i2c.write(reg2);
    i2c.start();
    i2c.write((address << 1) + 1);

    if (datacount == 1)
    {
        *data = i2c.read(false);
    }
    else
    {
        int i = 0;
        for (i = 0; i < datacount - 1; i++)
        {
            *(data + i) = i2c.read(false);
        }
        *(data + datacount - 1) = i2c.read(true);
    }
    i2c.stop();
    wait_us(1000);

}

static void Reset1Wire()
{
    SendRegDataI2c(0x18, 0xF0); // Device Reset (After Power-Up)
}

static float GetTempFrom1Wire()
{
    SendRegDataI2c(0x18, 0xB4); // 1-Wire Reset (To Begin or End 1-Wire Communication)
    wait_us(10000);
    SendRegByteDataI2c(0x18, 0xA5, 0xCC); // CCh SKIP ROM COMMAND
    SendRegByteDataI2c(0x18, 0xA5, 0x44); // 44h CONVERT TEMPERATURE
    wait_us(10000);
    SendRegDataI2c(0x18, 0xB4); // 1-Wire Reset (To Begin or End 1-Wire Communication)
    wait_us(10000);
    SendRegByteDataI2c(0x18, 0xA5, 0xCC); // CCh SKIP ROM COMMAND
    SendRegByteDataI2c(0x18, 0xA5, 0xBE); // BEh READ SCRATCHPAD
    wait_us(10000);
    //Read from DS
    // LE 1-2バイト目が温度 0.0625℃精度
    uint8_t l = 0;
    uint8_t data[8];
    for (l = 0; l < 8; l++)
    {
        SendRegDataI2c(0x18, 0x96); // 1-Wire Read Byte Command(0x96)
        wait_us(10000);
        RecieveDataI2c(0x18, 0xE1, 0xE1, &data[l], 1); // Read from Pointer's DATA(0xE1)
        wait_us(10000);
    }
    //board.debug("TEMP:0x%02X%02X\r\n",data[1],data[0]);
    int16_t tempp = data[0] + (data[1] << 8);
    return tempp*0.0625;
}
//
// GPS Support
//
//#define GPSDEBUG
TinyGPS gps;
SPI spi(P0_25,P0_28,P0_29,P0_24);
DigitalOut gpsreset(P0_21);
DigitalOut gpspower(P0_20);
bool isGpsInitFirst = true;
bool gpsPowerOn = false;
static bool needGpsRefresh;
static uint8_t gpsTick;
static long latitude, longitude;
static int16_t altitude;
static uint8_t spiData;
#ifdef GPSDEBUG
static uint8_t buffer[1024];
#endif
static unsigned long fix_age;

static void gpsReset()
{
    gpsreset= 0;
    wait_us(10000);
    gpsreset= 1;
    wait_us(200000);
}

static void gpsTogglePower()
{
    gpspower= 1;
    wait_us(200000);
    gpspower= 0;
}
// GPS電源を有効にします
// 電源をOFFにした場合でも、GPS座標を保持する為に低電力状態で動作します。
static void GpsPower(bool state)
{
    if(state == true) {
        if(gpsPowerOn == false) {
            if(isGpsInitFirst == true) gpsReset();// GPS Reset(保持座標が全部消える)
            gpsTogglePower(); // GPS Wakeup(ToggleでON/OFFする)
            if(isGpsInitFirst == true) {
                // GPS用SPIを初期化する
                spi.format(8,1);
                spi.frequency(1000000);
                isGpsInitFirst = false;
            }
            gpsPowerOn = true;
        }
    } else {
        if(gpsPowerOn == true) {
            gpsTogglePower(); // GPS Wakeup(ToggleでON/OFFする)
            gpsPowerOn = false;
        }
    }
}

// GPS処理用のループです
// 2000ms以内のタイミングで必ず呼んで下さい
static void LoopGps()
{
    if(gpsPowerOn == true) {
      // データが無い時は、0xB4,0xA7を繰り返す
            // 有効なデータが来るまで、FIFOを最大1/4読む
            for(int j=0;j<512;j++){
                spiData = spi.write(0x00);
            if(spiData != 0xB4 && spiData != 0xA7)break;
            }
            if(spiData == 0xB4 || spiData == 0xA7) return; // 有効なデータが無かった
            // NMEAをデコードする
            // 0xB4がSPIデータ終端 各NMEAセンテンスは0x0d,0x0Aでセパレートされている為、一度だけのリードで問題無い。
#ifdef GPSDEBUG
                int i=0;
                buffer[i] = spiData;
                i++;
#endif
                while(1) {
                    spiData = spi.write(0x00);
                    if(spiData == 0xB4) { // 終端検出
#ifdef GPSDEBUG
                        buffer[i] = 0x00;
#endif
                        break;
                    }
#ifdef GPSDEBUG
                    buffer[i] = spiData;
                    i++;
#endif
                    gps.encode(spiData);
                }
                gps.get_position(&latitude, &longitude, &fix_age);
                altitude = gps.altitude(); // 高度取得は正しく動かない?
/*
#ifdef GPSDEBUG
                pc.debug("%s", buffer); // NMEAデータ表示
                pc.debug("POS:%d,%d,%d\r\n", latitude,longitude,altitude); // GPS情報表示
#endif
*/
                // GPS状態判定の為、GPS座標を定期的にリセットする
                if(needGpsRefresh == true) {
                    gps.reset_ready();
                    gps.reset_pos();
                    needGpsRefresh = false;
                }
        }
}


#if defined(TEST_DIGITAL_IN_INTTERUPT)
Eeabp1 *gp;
bool led_on = true;

void flip() {
    if (led_on)
        gp->setLedState(LED_OFF);
    else
        gp->setLedState(LED_ON);
    led_on = !led_on;
}
#endif /* defined(TEST_DIGITAL_IN_INTTERUPT) */

int main(void)
{
    Eeabp1 board;
    int ret = 0;

#if defined(TEST_DIGITAL_IN_INTTERUPT)
    gp = &board;
    led_on = true;
#endif /* defined(TEST_DIGITAL_IN_INTTERUPT) */

    board.setLedState(LED_ON);
    board.debug("Hello ina-hack!\r\n");

    board.setGrovePower(true);

    // GPSデモ
    GpsPower(true); // バッテリー駆動の場合、GPS電源をこまめに切ることを推奨します
    while(true) 
    {
        LoopGps(); // バッファが溢れる迄(目安2秒)にこのループを回して下さい。
    board.debug("POS:%d,%d,%d\r\n", latitude,longitude,altitude); // GPS情報表示
        wait(1);
        // GPSの電波状況が悪くなった場合、最終座標で固定される
        // 10秒毎にGPSが測位できているか再確認する
        if(gpsTick >= 10) {
        gpsTick =0;
        needGpsRefresh = true; //このフラグを立てることによりリフレッシュする。
    } else {
        gpsTick ++;
    }
    }

/*  
 // 1Wireデモ
    while(1){
    wait(1);
  board.debug("TEMP:%f\r\n", GetTempFrom1Wire());
    }
*/
#if defined(TEST_DIGITAL_OUT) || defined(TEST_DIGITAL_IN) || defined(TEST_DIGITAL_IN_INTTERUPT)
    board.setGrovePortType(GROVE_CH1, GROVE_DIO);
    board.setGrovePortType(GROVE_CH2, GROVE_DIO);
#endif
#if defined(TEST_DIGITAL_OUT)
    board.setGroveDioDirection(GROVE_CH1, GROVE_DIO_OUT);
    board.setGroveDioDirection(GROVE_CH2, GROVE_DIO_OUT);
#endif /* defined(TEST_DIGITAL_OUT) */
#if defined(TEST_DIGITAL_IN)
    board.setGroveDioDirection(GROVE_CH1, GROVE_DIO_IN);
    board.setGroveDioDirection(GROVE_CH2, GROVE_DIO_IN);
#endif /* defined(TEST_DIGITAL_IN) */
#if defined(TEST_DIGITAL_IN_INTTERUPT)
    board.setGroveDioDirection(GROVE_CH1, GROVE_DIO_IN, flip);
    board.setGroveDioDirection(GROVE_CH2, GROVE_DIO_IN, flip);
#endif /* defined(TEST_DIGITAL_IN_INTTERUPT) */
#if defined(TEST_ANALOG)
    board.setGrovePortType(GROVE_CH1, GROVE_ANALOG);
    board.setGrovePortType(GROVE_CH2, GROVE_ANALOG);
#endif /* defined(TEST_ANALOG) */

#if defined(TEST_LORA)
    ret = board.setLoRaPower(true);
    if (ret != 0) {
        board.debug("error %d\r\n", ret);
    }
#endif /* defined(TEST_LORA) */
#if defined(TEST_TEMP_HUMID)
    ret = board.enableTempHumidSensor();
    if (ret != 0)
        board.debug("error %d\r\n", ret);
#endif /* TEST_TEMP_HUMID */
#if defined(TEST_ACC)
    ret = board.enableAccelerometer();
    if (ret != 0)
        board.debug("error %d\r\n", ret);
#endif /* defined(TEST_ACC) */

#if defined(TEST_LORA)
    int i = 0;
#endif /* defined(TEST_LORA) */
#if defined(TEST_DIGITAL_OUT)
    bool on = true;
#endif /* defined(TEST_DIGITAL_OUT) */
    do {
        wait(0.5);
        board.loop();
#if defined(TEST_DIGITAL_OUT)
        if (on) {
            board.setGroveDio(GROVE_CH1, GROVE_DIO_HIGH);
            board.setGroveDio(GROVE_CH2, GROVE_DIO_LOW);
        }
        else {
            board.setGroveDio(GROVE_CH1, GROVE_DIO_LOW);
            board.setGroveDio(GROVE_CH2, GROVE_DIO_HIGH);
        }
        on = !on;
#endif /* defined(TEST_DIGITAL_OUT) */
#if defined(TEST_DIGITAL_IN)
        board.debug("------------\r\n");
        board.debug("P1 S1: %d\r\n", board.getGroveDio(GROVE_CH1, GROVE_SIG1));
        board.debug("P1 S2: %d\r\n", board.getGroveDio(GROVE_CH1, GROVE_SIG2));
        board.debug("P2 S1: %d\r\n", board.getGroveDio(GROVE_CH2, GROVE_SIG1));
        board.debug("P2 S2: %d\r\n", board.getGroveDio(GROVE_CH2, GROVE_SIG2));
#endif /* defined(TEST_DIGITAL_IN) */
#if defined(TEST_ANALOG)
        board.debug("------------\r\n");
        board.debug("P1 S1: %2.2f\r\n", board.getGroveAnalog(GROVE_CH1, GROVE_SIG1));
        board.debug("P1 S2: %2.2f\r\n", board.getGroveAnalog(GROVE_CH1, GROVE_SIG2));
        board.debug("P2 S1: %2.2f\r\n", board.getGroveAnalog(GROVE_CH2, GROVE_SIG1));
        board.debug("P2 S2: %2.2f\r\n", board.getGroveAnalog(GROVE_CH2, GROVE_SIG2));
#endif /* defined(TEST_ANALOG) */
#if defined(TEST_TEMP_HUMID)
        board.debug("------------\r\n");
        board.debug("Temp: %2.2f, Humid: %2.2f\r\n", board.getTemp(), board.getHumid());
#endif /* defined(TEST_ANALOG) */
#if defined(TEST_ACC)
        int x, y, z;
        board.getAcc(&x, &y, &z);
        board.debug("------------\r\n");
        board.debug("X: %d, Y: %d, Z: %d\r\n", x, y, z);
#endif /* defined(TEST_ACC) */

#if defined(TEST_LORA)
        board.sendLoRaString("hello %d", i++);
#endif /* defined(TEST_LORA) */
} while (true);
}