編集履歴一覧に戻る
mnltのアイコン画像

mnlt が 2024年01月13日16時27分20秒 に編集

コメント無し

本文の変更

# 何を作ったのか spresenseとLoRa Add-onボード(DTH-SSLR)を使い省電力近距離GPSトラッカーを制作 # 構成 ## GPSトラッカー ・spresenseメインボード ・LoRa Add-onボード(DTH-SSLR) ## ゲートウェイ ・Xiaoesp32c3 ・Lora 評価ボード # スケッチ(GPSトラッカー) ・位置情報を4Byteで送信

+

```cpp:spresenseGPSLoraTracker.ino #include <Arduino.h> #include <GNSS.h> #include <LowPower.h> #include <RTC.h> #include <Flash.h> #include <arch/board/board.h> #include <arch/chip/pin.h> SpGnss Gnss;

+

#define SerialMon Serial #define SerialLoRa Serial2 // E220-900T22S(JP)へのピンアサイン #define LoRa_ModeSettingPin_M0 PIN_D20 #define LoRa_ModeSettingPin_M1 PIN_D21 #define LoRa_AUXPin PIN_I2S0_DATA_IN // E220-900T22S(JP)のbaud rate #define LoRa_BaudRate 9600 #define BASE_LAT 3412345 //緯度小数点以下5桁(約1m)*100000 #define BASE_LON 13612345 //経度小数点以下5桁(約1m)*100000 const int16_t sensorID = 900; int sendInterval = 60;//sec uint8_t conf[] ={0xc0, 0x00, 0x08, sensorID >> 8, //ADDH sensorID & 0xff, //ADDL 0b01110000, // baud_rate 9600 bps SF:9 BW:125 0b11100000, //subpacket_size 32, rssi_ambient_noise_flag on, transmitting_power 13 dBm 0x00, //own_channel 0b10000011, //RSSI on ,fix mode,wor_cycle 2000 ms 0x00, //CRYPT 0x00}; struct msgStruct{ uint8_t conf_0 = 0xFF; uint8_t conf_1 = 0xFF; uint8_t channel = 0x00; uint16_t myadress = sensorID; uint16_t relative_lat; uint16_t relative_lon; } msg; /** * @brief ノーマルモード(M0=0,M1=0)へ移行する */ void SwitchToNormalMode(void){ digitalWrite(LoRa_ModeSettingPin_M0, 0); digitalWrite(LoRa_ModeSettingPin_M1, 0); delay(1); while (!board_gpio_read(LoRa_AUXPin)) {} delay(2); } /** * @brief コンフィグ/sleepモード(M0=1,M1=1)へ移行する */ void SwitchToConfigurationMode(void){ digitalWrite(LoRa_ModeSettingPin_M0, 1); digitalWrite(LoRa_ModeSettingPin_M1, 1); delay(1); while (!board_gpio_read(LoRa_AUXPin)) {} delay(2); } bool state=false; static int gpio_handlerB(int irq, FAR void *context, FAR void *arg) { state = !state; digitalWrite(LED1, state); return 0; } static void SleepIn(void) { ledOff(PIN_LED0); ledOff(PIN_LED1); SwitchToConfigurationMode(); /* Save backup data to flash */ Gnss.saveEphemeris(); Gnss.stop(); Gnss.end(); Serial.printf("===Total time %"PRIu64" msec Sleep %d sec ===\n",millis(),sendInterval); Serial.println(); LowPower.deepSleep(sendInterval); } void setup() { LowPower.begin(); LowPower.clockMode(CLOCK_MODE_32MHz); bootcause_e bc = LowPower.bootCause(); SerialMon.begin(115200); delay(500); SerialMon.println("start"); pinMode( LED0 ,OUTPUT); pinMode( LED1 ,OUTPUT); pinMode(LoRa_ModeSettingPin_M0, OUTPUT); pinMode(LoRa_ModeSettingPin_M1, OUTPUT); //LoRa AUX pin 割り込み設定 board_gpio_config(LoRa_AUXPin, 0, true, false, PIN_PULLUP); board_gpio_intconfig(LoRa_AUXPin, INT_BOTH_EDGE, true, gpio_handlerB); board_gpio_int(LoRa_AUXPin, true); while (!board_gpio_read(LoRa_AUXPin)) {} //LoRa UART SerialLoRa.begin(LoRa_BaudRate); while(!SerialLoRa){}; //初回のみGNSS/LoRa初期設定 if ((bc == POR_SUPPLY) || (bc == POR_NORMAL)) { /* Remove backup file if power-on-reset */ Flash.remove("gnss_backup.bin"); SwitchToConfigurationMode(); SerialMon.printf("I send conf\r\n"); for (size_t i = 0; i < sizeof(conf); i++){ SerialMon.printf(" %02x",conf[i]); } SerialMon.println(); SerialLoRa.write((uint8_t *)conf, sizeof(conf)); delay(100); while (SerialLoRa.available()) { SerialMon.printf(" %02x",SerialLoRa.read()); } while (!board_gpio_read(LoRa_AUXPin)) {} delay(2); } SerialLoRa.flush(); // ノーマルモード(M0=0,M1=0)へ移行する SwitchToNormalMode(); /* Activate GNSS device */ int result; result = Gnss.begin(); assert(result == 0); /* Start positioning */ result = Gnss.start(); assert(result == 0); Serial.println("Gnss setup OK"); } void loop() { if (Gnss.waitUpdate(-1)) { /* Get navData. */ SpNavData navData; Gnss.getNavData(&navData); bool posFix = ((navData.posDataExist) && (navData.posFixMode != FixInvalid)); if (posFix ) { Serial.println("Position is fixed."); digitalWrite(LED0, HIGH); /*BASEからの緯度経度の差分を2Byteで送信 およそ南北72km東西60km程度の位置を1m単位で特定可能 */ msg.relative_lat = int16_t(navData.latitude * 100000 -BASE_LAT); msg.relative_lon = int16_t(navData.longitude * 100000 - BASE_LON); uint8_t payload[]={msg.conf_0, msg.conf_1, msg.channel , msg.myadress & 0xff ,msg.myadress >> 8 , msg.relative_lat & 0xff, msg.relative_lat >> 8, msg.relative_lon & 0xff, msg.relative_lon >> 8}; for (size_t i = 0; i < sizeof(payload); i++){ SerialMon.printf(" %02x",payload[i]); } SerialMon.println(); SerialLoRa.flush(); SerialLoRa.write((uint8_t *)payload, sizeof(payload)); delay(2);//これが無いとなぜか動かない while (!board_gpio_read(LoRa_AUXPin)) {} SerialMon.printf("I send %d Byte",sizeof(payload)); SleepIn(); } delay(1000); } } ```

https://github.com/mnltake/spresenseGPSLoraTracker/blob/main/spresenseGPSLoraTracker.ino # スケッチ(Lora-Wifi ゲートウェイ) SPRESENSE用 LoRa Add-onボード(DTH-SSLR)ライブラリ を使い受信します

+

受け取った構造体dataから緯度経度、信号強度等に変換しデータベースに送り利用します 詳しくはInfluxDBやGrafanaの使い方を参照(この記事では省略)

https://dragon-torch.tech/wp-content/uploads/2023/08/spresense_e220900t22s_jp_lib.zip ``` CLoRa lora; struct RecvFrameE220900T22SJP_t data;   sensorID = data.recv_data[3] | (data.recv_data[4]<<8) ;   lat = (BASE_LAT + int16_t(data.recv_data[5] | (data.recv_data[6]<<8)))*0.00001;   lon = (BASE_LON + int16_t(data.recv_data[7] | (data.recv_data[8]<<8)))*0.00001;

+

  rssi = data.rssi

```

-

・緯度経度に変換 ・RSSI

-

# クラウド(InfluxDBCloud Grafana)

-

# 省電力化

-

# 実証実験 ・乾電池 ・LiPo ・ボタン電池 ・GPS精度 ・Lora通信距離