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:
koyo_take
Date:
2017-08-26
Revision:
8:06b52bde3c82
Parent:
7:6a352003742d
Child:
9:aec372b347f1

File content as of revision 8:06b52bde3c82:

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

#define TEST_LORA
//#define TEST_ANALOG // WaterSensor(ハイインピ過ぎる),SoundSensor(動くが設計に問題有),MoistureSensor,LightSensor,MotionSensor
//#define TEST_TEMP_HUMID //SHT31
//#define TEST_ACC // ADXL345
//#define TEST_DIGITAL_IN // Button,Switch
//#define TEST_DIGITAL_OUT // Buzzer,LED
//#define TEST_DIGITAL_IN_INTTERUPT

//
// RGBLED Support
//
ChainableLED color_led(P0_13, P0_12, 1); // ChainableLED(clk, data, number_of_leds)

//
// 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);


    // RGBLEDデモ
    // 本来はデータシート通り5Vで操作させないと色がおかしいが、
    // 3.3Vでも動作自体は問題無い
    uint8_t R = 50;
    uint8_t G = 100;
    uint8_t B = 200;
    board.setGrovePortType(GROVE_CH1, GROVE_DIO);
    board.setGroveDioDirection(GROVE_CH1, GROVE_DIO_OUT);
    wait(0.1);
    // ChainableLED.setColorRGB(index_of_led, red, green, blue)
    color_led.setColorRGB(0, R, G, B);    // increase brightness cascade down chain of LED's

    /*
    // 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); // SIG1&2両方変更したい場合
            board.setGroveDio(GROVE_CH1, GROVE_SIG1 , GROVE_DIO_HIGH);
            board.setGroveDio(GROVE_CH1, GROVE_SIG2 , GROVE_DIO_LOW);
            board.setGroveDio(GROVE_CH2, GROVE_SIG1 , GROVE_DIO_HIGH);
            board.setGroveDio(GROVE_CH2, GROVE_SIG2 , GROVE_DIO_LOW);
        } else {
            board.setGroveDio(GROVE_CH1, GROVE_SIG1 , GROVE_DIO_LOW);
            board.setGroveDio(GROVE_CH1, GROVE_SIG2 , GROVE_DIO_HIGH);
            board.setGroveDio(GROVE_CH2, GROVE_SIG1 , GROVE_DIO_LOW);
            board.setGroveDio(GROVE_CH2, GROVE_SIG2 , 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);
}