何を作ったのか
spresenseとLoRa Add-onボード(DTH-SSLR)を使い省電力近距離GPSトラッカーを制作
構成
GPSトラッカー
・spresenseメインボード
・LoRa Add-onボード(DTH-SSLR)
ゲートウェイ
・Xiaoesp32c3
・Lora 評価ボード
スケッチ(GPSトラッカー)
・位置情報を4Byteで送信
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
1
投稿者の人気記事
-
mnlt
さんが
2023/12/14
に
編集
をしました。
(メッセージ: 初版)
-
mnlt
さんが
2023/12/14
に
編集
をしました。
-
mnlt
さんが
2023/12/14
に
編集
をしました。
-
mnlt
さんが
2023/12/15
に
編集
をしました。
-
mnlt
さんが
2023/12/22
に
編集
をしました。
-
mnlt
さんが
2024/01/13
に
編集
をしました。
ログインしてコメントを投稿する