send GPS data via LoRaWAN
Dependencies: TinyGPS mbed ADXL345_I2C Sht31
EEAB-P1/Eeabp1.cpp
- Committer:
- koyo_take
- Date:
- 2017-06-24
- Revision:
- 1:195da8230785
- Parent:
- 0:97a57be77fbb
File content as of revision 1:195da8230785:
#include "Eeabp1.h" //#include "rtos.h" //Thread thread; static const int lora_msg_max_len = 11; Eeabp1::Eeabp1() : pwr_en(P0_0), led(P0_23), lora_power(P0_5), lora_reset(P0_22), grove_power(P0_6), grv_sel2a(P0_19), grv_sel2g(P0_18), grv_sel1a(P0_17), grv_sel1g(P0_16), grv_p1s1a(P0_2), grv_p1s2a(P0_1), grv_p2s1a(P0_4), grv_p2s2a(P0_3) { this->led_state = LED_OFF; this->led = 0; this->serial = new RawSerial(P0_9, P0_11); this->serial->baud(9600); /* use for LoRa */ this->pwr_en = 1; // メイン電源投入 this->lora_power = 0; this->lora_reset = 0; this->grove_power = 0; this->lora_enabled = false; this->grove_enabled = false; // Grove端子をHiZに this->grv_sel1g = 1; this->grv_sel1a = 1; this->grv_sel2g = 1; this->grv_sel2a = 1; grv_p1s1do = NULL, grv_p1s2do = NULL, grv_p1s1di = NULL, grv_p1s2di = NULL; grv_p2s1do = NULL, grv_p2s2do = NULL, grv_p2s1di = NULL, grv_p2s2di = NULL; temp_humid_sensor = NULL; } int Eeabp1::setLedState(EeabLedState state) { this->led_state = state; if (this->led_state == LED_OFF) { this->led = 0; } else { this->led = 1; } return 0; } void Eeabp1::loop(void) { switch (this->led_state) { case LED_OFF: /* fall through */ case LED_ON: break; case LED_BLINK_FAST: case LED_BLINK_MID: case LED_BLINK_SLOW: this->led = !this->led; break; } } int Eeabp1::debug(const char * format, ...) { char tmp[80]; int ret; std::va_list arg; va_start(arg, format); vsnprintf(tmp, sizeof(tmp), format, arg); va_end(arg); delete this->serial; this->serial = new RawSerial(P0_8, P0_10); ret = this->serial->puts(tmp); delete this->serial; this->serial = new RawSerial(P0_9, P0_11); return ret; } int Eeabp1::setLoRaPower(bool on) { int ret; if (on) { if (lora_enabled) return 0; /* power is already on, do nothing */ this->lora_power= 1; this->lora_reset = 1; wait_us(500000); serial->printf("mod set_echo off\r\n"); // ローカルエコー:無効 wait(1); flushSerial(); serial->printf("mod factory_reset\r\n"); // ファクトリーリセットを行い鍵をリフレッシュ ret = chkSerialCharOk(); if (ret != 0) return ret; serial->printf("mod set_echo off\r\n"); // ローカルエコー:無効 wait(1); serial->printf("lorawan join otaa\r\n"); // Gatewayに接続(OTAA) ret = chkSerialCharRes('a'); // 成功 ">> accepted" 失敗 ">> unsuccess" if (ret != 0) return ret; serial->printf("lorawan set_dr 2\r\n"); // データレートの設定(11byte) ret = chkSerialCharOk(); if (ret != 0) return ret; this->lora_enabled = true; } else { /* off */ if (!lora_enabled) return 0; /* power is already off, do nothing */ lora_power= 0; lora_enabled = false; } return 0; } int Eeabp1::sendLoRaString(const char * format, ...) { char str[lora_msg_max_len+1] = {0x00, }; char msg[64]; char *p = msg; std::va_list arg; va_start(arg, format); vsnprintf(str, sizeof(str), format, arg); va_end(arg); p += sprintf(msg, "lorawan tx ucnf 16 "); for (unsigned int i = 0; i < strlen(str); i++) { p += sprintf(p, "%02x", str[i]); } sprintf(p, "\r\n"); flushSerial(); serial->puts(msg); return 0; } void Eeabp1::setGrovePower(bool on) { if (on) { if (grove_enabled) return; /* power is already on, do nothing */ grove_power = 1; } else { if (!grove_enabled) return; /* power is already off, do nothing */ // Grove端子をHiZに grv_sel1g = 1; grv_sel1a = 1; grv_sel2g = 1; grv_sel2a = 1; grove_power = 0; } } int Eeabp1::setGrovePortType(EeabGrovePort port, EeabGrovePortType type) { switch (port) { case GROVE_CH1: if (type == GROVE_ANALOG) { grv_sel1g = 1; grv_sel1a = 0; } else { grv_sel1g = 0; grv_sel1a = 1; } break; case GROVE_CH2: if (type == GROVE_ANALOG) { grv_sel2g = 1; grv_sel2a = 0; } else { grv_sel2g = 0; grv_sel2a = 1; } break; default: /* do nothing */ break; } return 0; } int Eeabp1::setGroveDioDirection(EeabGrovePort port, EeabGroveDioDirection dir, Callback<void()> f) { switch (port) { case GROVE_CH1: if(dir == GROVE_DIO_OUT) { if (grv_p1s1di) { delete grv_p1s1di; grv_p1s1di = NULL; } grv_p1s1do = new DigitalOut(P0_13); if (grv_p1s2di) { delete grv_p1s2di; grv_p1s2di = NULL; } grv_p1s2do = new DigitalOut(P0_12); } else { /* GROVE_DIO_IN */ if (grv_p1s1do) { delete grv_p1s1do; grv_p1s1do = NULL; } grv_p1s1di = new InterruptIn(P0_13); if (f) grv_p1s1di->rise(f); if (grv_p1s2do) { delete grv_p1s2do; grv_p1s2do = NULL; } grv_p1s2di = new InterruptIn(P0_12); grv_p1s2di->rise(f); } break; case GROVE_CH2: if(dir == GROVE_DIO_OUT) { if (grv_p2s1di) { delete grv_p2s1di; grv_p2s1di = NULL; } grv_p2s1do = new DigitalOut(P0_15); if (grv_p2s2di) { delete grv_p2s2di; grv_p2s2di = NULL; } grv_p2s2do = new DigitalOut(P0_14); } else { /* GROVE_DIO_IN */ if (grv_p2s1do) { delete grv_p2s1do; grv_p2s1do = NULL; } grv_p2s1di = new InterruptIn(P0_15); if (f) grv_p2s1di->rise(f); if (grv_p2s2do) { delete grv_p2s2do; grv_p2s2do = NULL; } grv_p2s2di = new InterruptIn(P0_14); grv_p2s2di->rise(f); } break; default: /* do nothing */ break; } return 0; } int Eeabp1::setGroveDio(EeabGrovePort port, EeabGroveDio val) { switch (port) { case GROVE_CH1: *grv_p1s1do = val; *grv_p1s2do = val; break; case GROVE_CH2: *grv_p2s1do = val; *grv_p2s2do = val; break; default: break; } return 0; } int Eeabp1::getGroveDio(EeabGrovePort port, EeabGroveSig sig) { switch (port) { case GROVE_CH1: if (grv_p1s1di == NULL) return -1; return (sig == GROVE_SIG1) ? grv_p1s1di->read() : grv_p1s2di->read(); case GROVE_CH2: if (grv_p2s1di == NULL) return -1; return (sig == GROVE_SIG1) ? grv_p2s1di->read() : grv_p2s2di->read(); default: break; } return -1; } float Eeabp1::getGroveAnalog(EeabGrovePort port, EeabGroveSig sig) { switch (port) { case GROVE_CH1: return (sig == GROVE_SIG1) ? grv_p1s1a.read() : grv_p1s2a.read(); case GROVE_CH2: return (sig == GROVE_SIG1) ? grv_p2s1a.read() : grv_p2s2a.read(); default: break; } return -1; } int Eeabp1::enableTempHumidSensor(void) { temp_humid_sensor = new Sht31(P0_30, P0_7); return 0; } float Eeabp1::getTemp(void) { if (!temp_humid_sensor) return -1; return temp_humid_sensor->readTemperature(); } float Eeabp1::getHumid(void) { if (!temp_humid_sensor) return -1; return temp_humid_sensor->readHumidity(); } int Eeabp1::enableAccelerometer(void) { accelerometer = new ADXL345_I2C(P0_30, P0_7); this->debug("Device ID is: 0x%02x\n", accelerometer->getDeviceID()); wait(.001); // These are here to test whether any of the initialization fails. It will print the failure if (accelerometer->setPowerControl(0x00)) { this->debug("didn't intitialize power control\n"); return -1; } wait(.001); //Full resolution, +/-16g, 4mg/LSB. if(accelerometer->setDataFormatControl(0x0B)) { this->debug("didn't set data format\n"); return -1; } wait(.001); //3.2kHz data rate. if(accelerometer->setDataRate(ADXL345_3200HZ)) { this->debug("didn't set data rate\n"); return -1; } wait(.001); //Measurement mode. if(accelerometer->setPowerControl(MeasurementMode)) { this->debug("didn't set the power control to measurement\n"); return -1; } return 0; } int Eeabp1::getAcc(int *x, int *y, int *z) { int readings[3] = {0, 0, 0}; accelerometer->getOutput(readings); *x = readings[0]; *y = readings[1]; *z = readings[2]; return 0; } /* private functions */ void Eeabp1::flushSerial() { while(serial->readable() == true) { serial->getc(); wait_us(1000); } } int Eeabp1::chkSerialChar(const char ch,uint16_t timeout_ms) { uint32_t timeoutCount = 0; while(serial->readable() == false) { wait_us(50); timeoutCount++; if((timeoutCount / 20) >= timeout_ms) return -2; } return (serial->getc() == ch) ? 0 : -1; } int Eeabp1::waitSerialChar(const char ch,uint16_t timeout_ms) { uint32_t timeoutCount = 0; do { while(serial->readable() == false) { wait_us(50); timeoutCount++; if((timeoutCount / 20) >= timeout_ms) return -2; } } while(serial->getc() != ch); return 0; } int Eeabp1::chkSerialCharOk() { int ret; ret = waitSerialChar('>',4000); if (ret != 0) return __LINE__; ret = chkSerialChar('>',2000); if (ret != 0) return __LINE__; ret = chkSerialChar(' ',2000); if (ret != 0) return __LINE__; ret = chkSerialChar('O',2000); if (ret != 0) return __LINE__; ret = chkSerialChar('k',2000); if (ret != 0) return __LINE__; ret = waitSerialChar('>',4000); if (ret != 0) return __LINE__; wait_us(1000); return 0; } int Eeabp1::chkSerialCharRes(char chkchr) { int ret; ret = waitSerialChar('>', 10000); if (ret != 0) return __LINE__; ret = chkSerialChar('>',2000); if (ret != 0) return __LINE__; ret = chkSerialChar(' ',2000); if (ret != 0) return __LINE__; ret = chkSerialChar('O',2000); if (ret != 0) return __LINE__; ret = chkSerialChar('k',2000); if (ret != 0) return __LINE__; ret = waitSerialChar('>',16000); if (ret != 0) return __LINE__; ret = chkSerialChar('>',2000); if (ret != 0) return __LINE__; ret = chkSerialChar(' ',2000); if (ret != 0) return __LINE__; ret = waitSerialChar(chkchr,4000); if (ret != 0) return __LINE__; ret = waitSerialChar('>',4000); if (ret != 0) return __LINE__; wait_us(1000); return 0; }