melodieのアイコン画像
melodie 2022年09月25日作成 (2022年09月25日更新)
製作品 製作品 閲覧数 415
melodie 2022年09月25日作成 (2022年09月25日更新) 製作品 製作品 閲覧数 415

Spresenseによる歩数計付きGPSトラッカ

SpresenseでELTRESアドオンボードを利用して、
歩数とGPS座標をサーバへ送信します。
歩数は、加速度センサを利用して計測します。
計測方法は、Arduino Spresenseのサンプルコードである
「Step Counterサンプルスケッチ」を参考にしています。

部品

  • SPRESENSEメインボード
  • SPRESENSE用Qwiic接続基板
  • Qwiicケーブル(Qwiic -Qwiic)50 mm
  • Qwiic - LSM6DSO搭載 6DoFモジュール
  • ELTRESアドオンボード
  • SPRESENSE用ELTRESアドオンボード対応 LPWAアンテナ
  • uFL接続 15mm GPS用アンテナ

設計図

接続箇所はそれぞれ一通りなので、つなげていきます。
キャプションを入力できます

ソースコード

歩数計付きGPSトラッカ

#include <EltresAddonBoard.h> #include <SparkFunLSM6DSO.h> #include <MemoryUtil.h> #include <SensorManager.h> #include <AccelSensor.h> #include <Aesm.h> #include <ApplicationSensor.h> const int walking_stride = 60; /* 60cm */ const int running_stride = 80; /* 80cm */ const int accel_range = 2; /* 2G */ const int accel_rate = 52; /* 52 Hz */ // const int accel_rate = 50; /* 50 Hz */ const int accel_sample_num = 50; /* 50 sample */ const int accel_sample_size = sizeof(float) * 3; /* 最新)GGS情報 */ static eltres_board_gga_info last_gga_info; /* (最新)緯度:dmm形式の度 */ static uint8_t last_lat_deg; /* (最新)緯度:dmm形式の分 */ static double last_lat_min; /* (最新)経度:dmm形式の度 */ static uint8_t last_lon_deg; /* (最新)経度:dmm形式の分 */ static double last_lon_min; /* GNSS情報更新時間 */ static uint32_t last_gnss_update_time; /* ペイロード格納領域 */ static uint8_t payload_data[16]; /* 歩数の最新値 */ uint32_t latest_step = 0; /* 加速度センサ */ static LSM6DSO myIMU; /** * ペイロードの作成と設定 */ void set_eltres_payload(void) { String temp; const uint8_t lat_deg = last_lat_deg; const uint8_t lon_deg = last_lon_deg; const double lat_min = last_lat_min; const double lon_min = last_lon_min; memset(payload_data, 0, sizeof(payload_data)); payload_data[0] = 0x81; // 緯度 temp = String(lat_deg); payload_data[1] = ((temp.charAt(0) - '0') << 4) + (temp.charAt(1) - '0'); temp = String(lat_min / 100, 6).substring(2); payload_data[2] = ((temp.charAt(0) - '0') << 4) + (temp.charAt(1) - '0'); payload_data[3] = ((temp.charAt(2) - '0') << 4) + (temp.charAt(3) - '0'); payload_data[4] = ((temp.charAt(4) - '0') << 4) + (temp.charAt(5) - '0'); // 経度 temp = String(lon_deg); payload_data[5] = (temp.charAt(0) - '0'); payload_data[6] = ((temp.charAt(1) - '0') << 4) + (temp.charAt(2) - '0'); temp = String(lon_min / 100, 6).substring(2); payload_data[7] = ((temp.charAt(0) - '0') << 4) + (temp.charAt(1) - '0'); payload_data[8] = ((temp.charAt(2) - '0') << 4) + (temp.charAt(3) - '0'); payload_data[9] = ((temp.charAt(4) - '0') << 4) + (temp.charAt(5) - '0'); // epoch秒のところに歩数を入れる payload_data[10] = (uint8_t)((latest_step >> 24) & 0xff); payload_data[11] = (uint8_t)((latest_step >> 16) & 0xff); payload_data[12] = (uint8_t)((latest_step >> 8) & 0xff); payload_data[13] = (uint8_t)((latest_step >> 0) & 0xff); EltresAddonBoard.set_payload(payload_data); } void eltres_event_cb(eltres_board_event event) { switch (event) { case ELTRES_BOARD_EVT_SEND_READY: // 送信前通知時 set_eltres_payload(); break; } } void gga_event_cb(const eltres_board_gga_info *gga_info) { last_gga_info = *gga_info; if (last_gga_info.m_pos_status) { last_gnss_update_time = (uint32_t) (millis() / 1000); int dot_index; String lat_str = String((char*)gga_info->m_lat); double lat = lat_str.toDouble(); // ddmm.mmmm last_lat_deg = (uint8_t) (floor(lat / 100.0)); last_lat_min = lat - ((double)last_lat_deg) * 100.0; String lon_str = String((char*)gga_info->m_lon); double lon = lon_str.toDouble(); // ddmm.mmmm last_lon_deg = (uint8_t) (floor(lon / 100.0)); last_lon_min = lon - ((double)last_lon_deg) * 100.0; } } bool step_counter_result(sensor_command_data_mh_t &data) { StepCounterStepInfo* steps = reinterpret_cast<StepCounterStepInfo*> (StepCountReader.subscribe(data)); if (steps == NULL) { return 0; } latest_step = steps->step; return 0; } void setup() { Serial.begin(115200); eltres_board_result e_ret; e_ret = EltresAddonBoard.begin(ELTRES_BOARD_SEND_MODE_1MIN, eltres_event_cb, gga_event_cb); if (e_ret != ELTRES_BOARD_RESULT_OK) { exit(1); } delay(500); Wire.begin(); delay(10); myIMU.begin(); // myIMU.initialize(BASIC_SETTINGS); myIMU.setIncrement(); myIMU.setAccelRange(accel_range); myIMU.setAccelDataRate(accel_rate); myIMU.setBlockDataUpdate(true); /* Initialize sensor class */ SensorManager.begin(); AccelSensor.begin(SEN_accelID, accel_rate, accel_sample_num, accel_sample_size); Aesm.begin(SEN_stepcounterID, SUBSCRIPTION(SEN_accelID), accel_rate, accel_sample_num, accel_sample_size); StepCountReader.begin(SEN_app0ID, SUBSCRIPTION(SEN_stepcounterID), step_counter_result); Aesm.set(walking_stride, running_stride); } void loop() { float x; float y; float z; x = myIMU.readFloatAccelX(); y = myIMU.readFloatAccelY(); z = myIMU.readFloatAccelZ(); AccelSensor.write_data(x, y, z); }

今後の課題

実際にデータを送信してみて、歩数が多いところがありました。
Spresenseのサンプルソースコードの処理に従っているため、
一部補正値などの指定が間違っている可能性がありますが、
加速度センサに合わせた調整も必要かもしれません。

ログインしてコメントを投稿する