山行記録のための行動ログを取りたい⑥ ブザー・OLED

正常動作してるかの確認機能

こちらの山行時

https://dalomo.net/blog/2023/02/23/1991/

ロガーを持っていったものの、正常にログが取れていなかった。13時間半も歩いたのにすごく悲しかった(実際後で調査したら気づいてもその場で修復できるようなものではなかったが)ので、ログの記録に異常が出た場合には気づけるようにしたい。XIAOの拡張ボードにはブザー、OLED、ボタンがついているので、これでどうにかならんだろか。

ブザー

Seeeduino XIAO Expansion Boardにはもとからブザーがついている。3ピンめがけてコード書けば良い。

勢い余ってサンプル使ってこんなん作った。

https://www.print-gakufu.com/scene/detail/2117/

が、実際のところブザーでのお知らせってどうなんだろう。ダメだった時にブザー鳴らすにしても、それがすぐ直せないようなものだったらずっと鳴ってる。それを避けるために何分かに一回とかにしても気づかなかったらその間のログはない。逆にログが取れてるときに間欠的に鳴らすとしてもずーっと聞いてたら気が狂ってきそう。クマ避けになる?wまぁこの方法はやめとこう。

OLED

じゃあOLEDだったら気づくの?と言われるとそういうわけではない。だから音が嫌なんだな俺は。とりあえず公式で提示されているサンプルを

https://wiki.seeedstudio.com/Seeeduino-XIAO-Expansion-Board/#oled-display

https://github.com/olikraus/U8g2_Arduino

U8g2というライブラリ中のU8x8というライブラリを使用している。

U8x8

U8g2 also includes U8x8 library. Features for U8g2 and U8x8 are:

  • U8g2
    • Includes all graphics procedures (line/box/circle draw).
    • Supports many fonts. (Almost) no restriction on the font height.
    • Requires some memory in the microcontroller to render the display.
  • U8x8
    • Text output only (character) device.
    • Only fonts allowed with fixed size per character (8×8 pixel).
    • Writes directly to the display. No buffer in the microcontroller required.

https://github.com/olikraus/u8g2/wiki

8×8ピクセルのフォント(またはその倍数?)しか使えないらしい。ディスプレイの解像度は128×64なので、横は16文字まで入る。そうなると「2023/03/18 23:59:59」が

こうなる。入らない。あと日本語を使おうとしても、フォントが無い(多分)ため表示ができない。ちゅーことでU8g2の方でやってみよう。

U8g2

リファレンスがかなり詳細なので、読み込めば大抵の疑問は解決するのではなかろうか。

https://github.com/olikraus/u8g2/wiki/u8g2setupcpp

https://github.com/olikraus/u8g2/wiki/u8g2reference

#include <Arduino.h>
#include <SPI.h>
#include <U8g2lib.h>

U8G2_SSD1306_128X64_NONAME_1_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE, PIN_WIRE_SCL, PIN_WIRE_SDA);

void setup(void) {
  u8g2.begin();
}

void loop(void) {
  u8g2.firstPage();
  do {
    u8g2.setFont(u8g2_font_b10_t_japanese2);
    u8g2.drawUTF8(0, 10, "こんにちは, 世界!");
    u8g2.drawUTF8(0, 20, "2023/03/19 23:59:59");
  } while (u8g2.nextPage());
  
}

とりあえず動いたコード。コンストラクタI2Cでなんで動くのと言うのは置いといて、u8g2_font_b10_t_japanese2は日本語が含まれているフォント。英数の場合はdrawStrで文字を表示したがASCII外の文字(でいいのかな?)を表示する場合は、drawUTF8を使う。結果

正直に言うと、日本語の字形はおかしく感じる。「んち」は途中で切れているし、全体的にバランスが悪い。また句読点「、。」などは収録されていないようだ。また、英数と記号だけでも文字幅のピクセルが違うようで全体的な統一感に欠けるかなという印象だった。ただ他にフォントがなさそう。既存フォントを利用できないかなー?

U8g2で外部フォントを使う

で、以前使ったことがある美咲フォントが使えないかなと思った。

https://littlelimit.net/misaki.htm

U8g2で外部フォントを使う方法を調べたところFAQに記述があった。

https://github.com/olikraus/u8g2/blob/master/doc/faq.txt#L245

こちらを見ながらやっていく。簡単にいうとbdf形式のフォントデータから変換するらしい。ということでまず美咲フォントのX11 BDF 形式を入手してきておく。そんで

https://github.com/olikraus/u8g2/tree/master/tools/font/bdfconv

からbdfconv.exeを入手(Windowsの場合)。適当な同じフォルダに入れておく。今回はC:\tmp\font内にmisaki_gothic.bdfとbdfconv.exeを配置した。そしたら変換用のコマンドを作る。

https://github.com/olikraus/u8g2/blob/master/doc/faq.txt#L261

ここの説明から、ユニコードのどの部分を変換するかの指定をしなければいけない。その助けとなるのが

https://stncrn.github.io/u8g2-unifont-helper/

こちらに必要事項を入力していくとコマンドを発行してくれる。Character rangesの部分は適当にBasic LatinとCJK Symbols and Punctuation、Hiragana、Katakana、CJK Unified Ideographs、Halfwidth and Fullwidth Formsにした。こうしてできたコマンドがこれ。

bdfconv -v -f 1 -m "0-127,12288-12351,12352-12447,12448-12543,19968-40959,65280-65519" misaki_gothic.bdf -o misaki_gothic.c -n misaki_gothic -d misaki_gothic.bdf

これをコマンドプロンプトで実行してみると

同フォルダ内にbdf.tgaとmisaki_gothic.cが作成された!

bdf.tgaはフォントの一覧みたい(画像は一部をpngに変換)。できたcファイルをArduinoで読み込む。Sketch→Add file…でmisaki_gothic.cを指定すればよい。そしたらコード内で使うように変更してく。

#include <Arduino.h>
#include <SPI.h>
#include <U8g2lib.h>
#include "misaki_gothic.c"

U8G2_SSD1306_128X64_NONAME_1_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE, PIN_WIRE_SCL, PIN_WIRE_SDA);

void setup(void) {
  u8g2.begin();
}

void loop(void) {
  u8g2.firstPage();
  do {
    u8g2.setFont(misaki_gothic);
    u8g2.drawUTF8(0, 8, "Hello, World!");
    u8g2.drawUTF8(0, 16, "こんにちは、世界!");
    u8g2.drawUTF8(0, 24, "2023/03/19 23:59:59");
  } while (u8g2.nextPage());
  
}

includeで追加したファイル名を指定し、setFontでフォント名を指定する。実行してみると

たんと表示されました~。

寿限無とかも表示できるよ。

U8g2で2値画像を表示する

リファレンス読んでたら図形等も表示できることを知った。他にもXBMという形式の2値画像が表示できるようで、このサイトのfaviconを表示してみたくなった。

画像の準備

もともとの画像がこちらで、これを2値化する。これは適当に手作業で

こんな感じ。ディスプレイが黒背景なため四隅を丸くし浮かないようにした。また背景は透過にするのでなく色を置いた。画像で黒が置かれたところが点灯し白色として表示されるため、ネガポジは反転しないと上手く表示されない。そしたらこの画像をXBMに変換する。変換ツールはいろんなのがあるが、

https://convertio.co/ja/xbm-converter/

とか。今回は検索して最初に出てきたやつにした。変換されたファイルをダウンロードする。XBMの実態はテキストファイルなので、VSCとかで開くと

#define dalomo_width 16
#define dalomo_height 16
static char dalomo_bits[] = {
  0xF8, 0x1D, 0x4C, 0x35, 0x18, 0x34, 0x03, 0xD0, 0x06, 0xE0, 0x06, 0x00, 
  0xC1, 0x43, 0xE3, 0xC7, 0x63, 0xC6, 0x43, 0xC2, 0x00, 0x80, 0x85, 0xA1, 
  0x0F, 0xE0, 0x26, 0x6C, 0xB0, 0x0D, 0xF8, 0x1C, };

みたいな表示になっているはず。変数名が長いので適当に直した。これで画像を変換することができた。

スケッチ

これをそのままスケッチに追加してコピーすると

#include <Arduino.h> 
#include <SPI.h> 
#include <U8g2lib.h>
#include "misaki_gothic.c"

#define dalomo_width 16
#define dalomo_height 16
static unsigned char dalomo_bits[] = {
  0xF8,  0x1D,  0x4C,  0x35,  0x18,  0x34,
  0x03,  0xD0,  0x06,  0xE0,  0x06,  0x00,
  0xC1,  0x43,  0xE3,  0xC7,  0x63,  0xC6,
  0x43,  0xC2,  0x00,  0x80,  0x85,  0xA1,
  0x0F,  0xE0,  0x26,  0x6C,  0xB0,  0x0D,
  0xF8,  0x1C,
};

U8G2_SSD1306_128X64_NONAME_1_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE, PIN_WIRE_SCL, PIN_WIRE_SDA);

void setup(void) {
  u8g2.begin();
}

void loop(void) {
  u8g2.firstPage();
  do {
    u8g2.setFont(misaki_gothic);
    u8g2.drawUTF8(0, 8, "2023/03/19 23:59:59");
    u8g2.drawUTF8(0, 16, "緯度:35.6825");
    u8g2.drawUTF8(0, 24, "経度:139.752778");
    u8g2.drawUTF8(0, 32, "高度:10 m");
    u8g2.drawUTF8(0, 40, "温度:17 度");
    u8g2.drawUTF8(0, 48, "気圧:1013 hPa");

    u8g2.drawXBM(112, 48, dalomo_width, dalomo_height, dalomo_bits);
  } while (u8g2.nextPage());
}

気をつける点としてdalomo_bitsの型をunsigned charに変更しておく。実行すると

表示された!ちょっとガタついてんな。まぁいっか!そしたら行動ロガーに組み込んでいこう。

行動ロガーのスケッチを更新する

#include <SoftwareSerial.h>
#include "TinyGPS++.h"
#include <Dps310.h>
#include <SPI.h>
#include <SD.h>
#include <U8g2lib.h>
#include "misaki_gothic.c"

#define dalomo_width 16
#define dalomo_height 16
static unsigned char dalomo_bits[] = {
  0xF0, 0x0D, 0x4C, 0x35, 0x18, 0x34, 0x02, 0x50, 0x07, 0xE0, 0x06, 0x00, 
  0xC1, 0x43, 0xE3, 0xC7, 0x63, 0xC6, 0x43, 0xC2, 0x00, 0x80, 0x85, 0xA1, 
  0x0F, 0x60, 0x26, 0x6C, 0xB0, 0x0D, 0xF0, 0x1C, };


TinyGPSPlus gps;
SoftwareSerial mySerial(7, 6);

Dps310 Dps310PressureSensor = Dps310();

U8G2_SSD1306_128X64_NONAME_1_HW_I2C u8g2(U8G2_R0);

const int chipSelect = 2;
String fileName;
File root;

String dataString;

void setup() {
  Serial.begin(57600);
  mySerial.begin(9600);

  u8g2.begin();
  u8g2.setFont(misaki_gothic);

  Dps310PressureSensor.begin(Wire);

  if (!SD.begin(chipSelect)) {
    while (1)
      ;
  }
  root = SD.open("/");
  checkDupFile(root, 0);
}

void loop() {
  float temperature;
  float pressure;
  uint8_t oversampling = 7;
  int16_t ret;
  String ymd;
  String hms;

  u8g2.firstPage();

  while (mySerial.available() > 0) {
    char c = mySerial.read();
    gps.encode(c);
    if (gps.time.isUpdated() || gps.date.isUpdated() || gps.location.isUpdated()) {  //if (gps.location.isUpdated() && gps.time.isValid()) {//

      ymd += gps.date.year();
      ymd += "/";
      if (gps.date.month() < 10) ymd += "0";
      ymd += gps.date.month();
      ymd += "/";
      if (gps.date.day() < 10) ymd += "0";
      ymd += gps.date.day();
      dataString += ymd + ",";

      if (gps.time.hour() < 10) hms += "0";
      hms += gps.time.hour();
      hms += ":";
      if (gps.time.minute() < 10) hms += "0";
      hms += gps.time.minute();
      hms += ":";
      if (gps.time.second() < 10) hms += "0";
      hms += gps.time.second();
      dataString += hms + ",";

      dataString += String(gps.location.lat(), 7);
      dataString += ",";
      dataString += String(gps.location.lng(), 7);
      dataString += ",";
      dataString += String(gps.altitude.meters());
      dataString += ",";

      ret = Dps310PressureSensor.measureTempOnce(temperature, oversampling);

      if (ret != 0) {
        Serial.print("FAIL! ret = ");
        Serial.println(ret);
      } else {
        dataString += String(temperature);
      }

      dataString += ",";

      ret = Dps310PressureSensor.measurePressureOnce(pressure, oversampling);
      if (ret != 0) {
        Serial.print("FAIL! ret = ");
        Serial.println(ret);
      } else {
        dataString += String(pressure);
      }

      File dataFile = SD.open(fileName, FILE_WRITE);
      if (dataFile) {
        dataFile.println(dataString.c_str());
        dataFile.close();
      }

      do {
        u8g2.drawStr(0, 9, (ymd + " " + hms).c_str());
        u8g2.drawUTF8(0, 18, ("緯度 : " + String(gps.location.lat(), 7)).c_str());
        u8g2.drawUTF8(0, 27, ("経度 : " + String(gps.location.lng(), 7)).c_str());
        u8g2.drawUTF8(0, 36, ("高度 : " + String(gps.altitude.meters()) + " m").c_str());
        u8g2.drawUTF8(0, 45, ("温度 : " + String(temperature)).c_str());
        u8g2.drawUTF8(0, 54, ("気圧 : " + String(pressure) + " Pa").c_str());
        u8g2.drawXBM(112, 48, dalomo_width, dalomo_height, dalomo_bits);
      } while (u8g2.nextPage());

      ymd = "";
      hms = "";
      dataString = "";
    }
  }
}

void checkDupFile(File dir, int num) {
  bool existFile = false;
  while (true) {
    File entry = dir.openNextFile();
    if (!entry) {
      if (num == 0) {
        fileName = "LOG0.CSV";
      }
      break;
    }

    num++;
    fileName = "LOG" + String(num) + ".CSV";
  }
}

ほんとにただ追加しただけ。行間はちょっと開けた。

とりまおっけーい!

カテゴリー: したい | タグ: , , | コメントする

『ルーヴル美術館展 愛を描く』に行ってきた

ルーヴル美術館展 愛を描く

国立新美術館で開催中のルーヴル美術館展に行ってきた。

最近の展示って作品の写真撮影がオッケーな場所あったりするからいいよね。顔がえっちだなーと思って顔アップの写真撮ったら全体の写真撮るの忘れてた。あとスマホカメラが勝手に補正かけてしまった。見どころはいろいろあったものの、一番好きかなーと思った作品はリオネッロ・スパーダ《放蕩息子の帰宅》だった。なんか知らんがグッときたなぁ。お父さんの顔とか、二人に焦点を当てた構図とか。あとはジャン=バスティト・グルーズ《アモルに導かれる「無垢」》、または《ヒュメナイオスの勝利》が好き。特に無垢のラリラリな表情が。愛は人を狂わせるね。

お土産買ったけど写真撮るのめんどい。

途中あれ?ここはサイゼ?となったものの全体的に満足^^

カテゴリー: のーと | タグ: , | コメントする

朝日峠・小町山・宝篋山

朝日峠・小町山・宝篋山

お久しぶりで8時ぐらいから登り始め。行ったことなかった朝日峠方面へ。けっこー広いところかつ眺望もよくて気持ちよかった。そこから小町山へ。こっちからの登りは意外ときつかった。前回からちょっと日があいたのも関係してるのかな。漢方とかは飲まず、行動食ぐらいであとは水分補給って感じでケアが少なかったかなぁ。小町山に登ったらそのまま宝篋山へ。国有林である旨の注意書きをよく見た。これはもしかして整備されてる方たちが怒られちゃったのかな?ていうかあれ無許可だったの…?この前通らせてもらった道の所にも看板があって、なんだか不穏な感じだった。宝篋山からはまた東城寺方面へ周回だけど、今回は(も?)弁慶平経由で登り返しーの、沢伝いに降りてきた。この沢伝いの道が好きです。前も言ったっけ。全体で5時間ぐらい。トレランの人超いっぱいいた。あったかくなってきたからみんな出てきたんかな。蛭ヶ岳で結構ダメージ食らった感があったのでちょっと間隔をあけたけど、これはこれで体鈍っちゃったのか、足痛いし疲れた。次どうすっかなー。

https://drive.google.com/file/d/1ozPgHgpGUmGEV_zvNSoMS8ON2KcDmNWL/view?usp=sharing

カテゴリー: やま | タグ: , | コメントする

山行記録のための行動ログを取りたい⑤ GPS・GNSSの精度を上げたい

GPS・GNSSの精度

前回山行で位置情報のズレがかなり出た。この精度を向上させたい。

原因

位置情報の精度に影響する要因として、こちらのページでは9つの原因をあげている。

https://www.ne.jp/asahi/nature/kuro/HGPS/principle_gps.htm#:~:text=%E3%81%BE%E3%81%99%E3%80%82%EF%BC%88%E8%B3%87%E6%96%99%EF%BC%89-,GPS%E8%AA%A4%E5%B7%AE%E3%81%AE%E5%8E%9F%E5%9B%A0,-GPS%E3%81%AE%E4%BD%8D%E7%BD%AE

これをもとに対策を取った。

アンテナの変更

一番影響が大きいのが9のやつということで、受信感度が不足してるのかな?という予測のもと秋月電子で

https://akizukidenshi.com/catalog/g/gM-12223/

https://akizukidenshi.com/catalog/g/gC-12225/

を購入して、もとからついているアンテナから変更した。

また、前回はアンテナ部分をウエストポーチの中にしまってしまったが、アンテナ部分だけ出すことが可能になったので、出しておくことにした。この他に、アンテナの裏に金属板を装着し電波の掴みを良くするというのも考えたが実行はしなかった。ということで、山に行きました。

動作確認

この山行のときに持っていった。

https://dalomo.net/blog/2023/02/11/1958/

岩瀬駅から出発時に電源オン。時たまLEDが付いてるかどうかだけ確認した。途中ギブアップしたが、帰りのバス乗車中も電源はつけたままにしておいた。

生データ

https://drive.google.com/file/d/1P9m5152oQiIB6xBVKPffzSvxC6cmuUUN/view?usp=sharing

時間が長いだけあって、データ量も多くなった。

GPS Visualizer

google earthだと重くなっちゃったのでこちらだけ。

見た感じかなりキレイに取れている。実質尾根歩きだったのも関係しているんだろうか。帰りのバスが雨引神社の方へ行くバスだったためそちらにも立ち寄っているが、そこがビミョーなズレが見受けられる。ただまぁほぼほぼ正確と言っていいかも。アンテナ変えるだけでこんな効果あるのすごくね。

標高

標高も期待できるかも!と思って作成してみたグラフが

GPS

すごい!とってもキレイに取れてると思う。最大値が714.7なので、公称の加波山標高709mよりはズレがある。でもまぁとってもキレイよね。

気圧

この日海面気圧のブレが大きく、一時間毎に使用校正値を変化させてグラフを作った。最大値が695.7なので、やはり下にブレるらしい。でもGPSともに良い結果が出てると思う。良き良き。

カテゴリー: したい | タグ: , | コメントする

山行記録のための行動ログを取りたい④ 動作確認+ログの加工

山に行ってきた

この

https://dalomo.net/blog/2023/01/28/1932/

山行の時に持っていった。

バッテリー

自分が普段から使っているモバイルバッテリーだとこういった電子工作に使うと安全機能が働いて電源が切れてしまう。そのためそれ用のバッテリーを買うことにした。

これ。ちょっとでかい。一日使っても全然減ってなかったのでもっと小さくても良かったかもしれない。

携行

どう持ってこーか悩んだ結果ジップロックに入れて、ウエストバックの中に全部入れてリュックの上の取っ手のところにつけることにした。ジップロックから気圧モジュールだけは出してるけどエストバックには全部入れた。

生データ

富山

https://drive.google.com/file/d/1_5coJZ_yN28gUfzwVwSi3Il-V-spck4q/view?usp=share_link

伊予ヶ岳

https://drive.google.com/file/d/12JCHOZ5DE-A4kRONfGOQUzmDSNq5f1ZA/view?usp=share_link

データ形式

コンマ区切りのCSV、並びは

時刻,緯度,経度,標高,気温,気圧

だった。日付ないや。

Google Earth Proで表示

おおー。すごいちゃんとデータ取れてる。表示されてるーすごいー。使い方がよく分からずポイント表示、データがそうだから当たり前なんだけど、なのでライン表示できるやつも探す。

GPS Visualizer

https://www.gpsvisualizer.com/

seeedのwikiで紹介されていたサービス。だけど外部公開はできないみたい。ただ画像をダウンロードできるのでそれを。

う~~~ん、こうしてみるとかなりズレてるな。往復だったので行きと帰りのログは軌跡が一致してないと正しくないはず。地点がジャンプしてしまっている部分もあるしこれはちょっとうまく行ってない感じがする。ここから滑らかにとかそういう処理をかけるレベルのデータではなさそう…。これは次の課題かなぁ。例えば車で移動中

ダッシュボードにロガーを置いておいたが、これだとかなりキレイに取れていた。むむむー。

標高

標高データとしては2種類ある。GPSからの標高データと気圧のデータだ。まずはGPSのデータをGSSでグラフにする。

GPS

富山

伊予ヶ岳

どちらもかなりブレブレの上、素っ頓狂な飛び方をしているデータもある。標高以上のデータが取れてたりもする。むむむー。

気圧

富山

伊予ヶ岳

こちらはかなりキレイ。ただ正確な標高というわけではない。試しに気圧から標高を求めてみる。

気圧から標高を求める

めんどそうなので伊予ヶ岳のみ。気圧から標高を求める式として

https://keisan.casio.jp/exec/system/1257609530

こちらがある。もっと詳しく知りたい時には、国際標準大気とかしらべるよろし。ただ海面気圧も温度も逐一変わる数値なので、それなりの正確性にはなると思われる。海面気圧については気象庁のページに気象台地点での観測記録が残っている。

https://www.jma.go.jp/jma/menu/menureport.html

なので、それの一番近い場所の日別平均値を利用してみる。

意外と近似した。ただまあやっぱり最大値が公表されている標高より10mぐらい低く出た。ふむふむー。

カテゴリー: したい | タグ: , | コメントする

嶺岡愛宕山 in 峯岡山分屯基地開放日

嶺岡愛宕山&峯岡山分屯基地

神奈川県の最高峰に登ったので、こりゃ関東の各県最高峰ぐらいなら行けるかなーと調べてたら、千葉県の最高峰は自衛隊基地の中にあり、しかも今日がちょうど年に一回の開放日ということを知った。本来であれば登頂に手続きが必要だがこの日は予約不要・コロナ検査不要とのこと。こりゃ行くしかないわ!ということで行ってきた。

展示

ヘリもあったけど撮るの忘れたわ。

嶺岡愛宕山

案内図~

本来であれば愛宕神社内を通って山頂に向かうそうだが、倒木により通行止めになったらしい。それによって源頼朝が建てたらしい塔?も見ることは叶わなかった。

体育館脇の道路を登って階段上ると

神社に出る。本来だとこの中を通ってったそう。行きたかったな。

 

神社前の道を左に登ってくと

 

階段を上る。そんでちょっと行くと

山頂!

696番!惜しい!

山頂からちょっと行った広場にあったでかいやつ。

山バッジも売ってたので買っちゃった。

あとなんかスタンプラリーやってたので参加した。クリアファイルもろた。たのしゅうございました。

カテゴリー: やま | タグ: , | コメントする

塔ノ岳・丹沢山・蛭ヶ岳

塔ノ岳・丹沢山・蛭ヶ岳

大倉バス停からいってこいしてきたが、死ぬかと思った。ナイトハイクで2:15ぐらいに出発、5:30塔ノ岳、7:00丹沢山、9:00蛭ヶ岳という感じだったらしい。風びゅんびゅんでクソ寒く、蛭ヶ岳まで行くか迷ったが無事帰ってこれてよかった、マジで。下りは、というか上りの途中からもう足はがくがくでフラフラになりながら下りてきた。大倉バス停に着いたのが15:40、13時間半も動いていたのか、筑波連山リタイアしてもこれだけ時間かければこっちは行けるみたいですよ。ついでに鍋割山も行こうかと思ったが、さすがに帰れなくなるか、動けなくなってレスキューかというところだったのでまた今度の機会に。山バッジ増えた!塔ノ岳は品切れだった、残念。丹沢山塊はまだ色々あるみたいなので機会があったら行ってみたい。足がつるか心配だったのでネットで見つけた芍薬甘草湯という漢方を予防的に飲んでみた。これがよかったのかつりはしなかった、ガクガクにはなったけど。行きは道が凍っていて歩きやすかったが、陽が出てきた帰りはぬかるみがひどかった。行動ロガー持って行ったんだけど何も記録されていなかった。超ショック。なんか対策しないとね。

カテゴリー: やま | タグ: , | コメントする

山行記録のための行動ログを取りたい③ 取得した数値をSDカードに保存

ログを保存

MicroSDにログを保存する。保存したログを後でPCで加工していきたいのである程度形になってるといいなーと思ったが、あまり欲張らずできることをやろう。SDカードは

こちらを購入した。ドンキで。これを

拡張ボードには裏にスロットがあるのでぶっ刺す。

コード

ArduinoにはSDカード用のライブラリがもとからある。

https://www.arduino.cc/reference/en/libraries/sd/

これを使ってまず動作確認。

#include <SPI.h>
#include <SD.h>

const int chipSelect = 2;
File myFile;

void setup() {
  if (!SD.begin(chipSelect)) {
    while (1)
      ;
  }

  myFile = SD.open("test.txt", FILE_WRITE);

  if (myFile) {
    myFile.println("testing 1, 2, 3.");
    myFile.close();
  }
}

void loop() {
}

サンプルを簡略化して流用。

できておりますね。そしたら全部合体させてしまおう。紆余曲折あったが最終的に動いたのが

#include <SoftwareSerial.h>
#include "TinyGPS++.h"
#include <Dps310.h>
#include <SPI.h>
#include <SD.h>

TinyGPSPlus gps;
SoftwareSerial mySerial(7, 6);

Dps310 Dps310PressureSensor = Dps310();

const int chipSelect = 2;
String fileName;
File root;

String dataString;

void setup() {
  Serial.begin(57600);
  while (!Serial) {
    ;
  }

  mySerial.begin(9600);

  Dps310PressureSensor.begin(Wire);

  if (!SD.begin(chipSelect)) {
    while (1)
      ;
  }
  root = SD.open("/");
  checkDupFile(root, 0);

  Serial.println("init finish");
}

void loop() {
  float temperature;
  float pressure;
  uint8_t oversampling = 7;
  int16_t ret;

  while (mySerial.available() > 0) {
    char c = mySerial.read();
    gps.encode(c);
    if (gps.time.isUpdated() || gps.date.isUpdated() || gps.location.isUpdated()) { //if (gps.location.isUpdated() && gps.time.isValid()) {// 
      dataString += gps.date.year();
      dataString += "/";
      dataString += gps.date.month();
      dataString += "/";
      dataString += gps.date.day();
      dataString += ",";

      if (gps.time.hour() < 10) dataString += "0";
      dataString += gps.time.hour();
      dataString += ":";
      if (gps.time.minute() < 10) dataString += "0";
      dataString += gps.time.minute();
      dataString += ":";
      if (gps.time.second() < 10) dataString += "0";
      dataString += gps.time.second();
      dataString += ",";

      dataString += String(gps.location.lat(), 7);
      dataString += ",";
      dataString += String(gps.location.lng(), 7);
      dataString += ",";
      dataString += String(gps.altitude.meters());
      dataString += ",";

      ret = Dps310PressureSensor.measureTempOnce(temperature, oversampling);

      if (ret != 0) {
        Serial.print("FAIL! ret = ");
        Serial.println(ret);
      } else {
        dataString += String(temperature);
      }

      dataString += ",";

      ret = Dps310PressureSensor.measurePressureOnce(pressure, oversampling);
      if (ret != 0) {
        Serial.print("FAIL! ret = ");
        Serial.println(ret);
      } else {
        dataString += String(pressure);
      }

      File dataFile = SD.open(fileName, FILE_WRITE);
      if (dataFile) {
        dataFile.println(dataString.c_str());
        dataFile.close();
      }

      dataString = "";
    }
  }
}

void checkDupFile(File dir, int num) {
  bool existFile = false;
  while (true) {
    File entry = dir.openNextFile();
    if (!entry) {
      if (num == 0) {
        fileName = "LOG0.CSV";
      }
      break;
    }

    num++;
    fileName = "LOG" + String(num) + ".CSV";
  }
}

こう。何故か日付が取れたり取れなかったりする。ということで基本はできた。これを山に持っていって動作確認してみよう!

このコードはPC接続だとログが保存されるが、バッテリー接続だとログが保存されない

なんでか考えてみてくれ。自分のアホさ加減よ。やっぱコピペに頼るとだめだな。

カテゴリー: したい | タグ: , | コメントする

山行記録のための行動ログを取りたい② DPS310で高度計

高度計

GPS部分はできたっぽいので、あとなにが欲しいかなーと思ったら高度計があった。気圧を計ることによって高さが分かるはず。

DPS310

https://www.seeedstudio.com/Grove-High-Precision-Barometer-Sensor-DPS310-p-4397.html

https://wiki.seeedstudio.com/Grove-High-Precision-Barometric-Pressure-Sensor-DPS310/

ということでGroveのDPS310を買ってみた。かなりの高精度らしい。公式にあったGIFを見ると

わずか数cmの変化でも分かるようだ。すごー。これを持っていけば山行時の標高の変化がとれたりするはず。てことで使ってみる。

コード書く

チップメーカーからライブラリが出ているのでそれを使う。詳しくはそっちとか見るといい思う。

https://github.com/Infineon/DPS310-Pressure-Sensor

サンプルをちょこっと変えてコードを書いてみた。

#include <Dps310.h>
Dps310 Dps310PressureSensor = Dps310();

void setup() {
  Serial.begin(9600);
  Dps310PressureSensor.begin(Wire);
}

void loop() {
  float pressure;
  uint8_t oversampling = 7;
  int16_t ret;

  ret = Dps310PressureSensor.measurePressureOnce(pressure, oversampling);
  if (ret != 0) {
    Serial.print("FAIL! ret = ");
    Serial.println(ret);
  } else {
    Serial.println(pressure);
  }

}

すっと

簡単、らくちん。温度込みのも書いた気がするけどどっかいった。ここから気圧⇔標高の変換が必要だがそれは後回しにすることにした。

カテゴリー: したい | タグ: , , , | コメントする

御嶽山・雨引山・燕山・加波山・足尾山・きのこ山

筑波連山縦走

今度こそリベンジと思って向かったが結論から言うとまた失敗した。燕山の地獄の登りでおそらくやってしまったのかと思うが、燕山の下りから加波山にかけての道で足がつってしまった。加波山神社でしばらく休んで様子を見つつ山行を続けたがキャンプ場への登りは足が持たないと判断し、きのこ山でエスケープ。息は切れていなかったため、大変悔しいがしょうがない。途中で会った他の登山者の方に筑波山まで行くとか言ってたが嘘ついてしまった。きのこ山からの下り、関東ふれあいの道だそうだが結構整ってた、こんなとこあったんですね。ハイキング客へアピールすればいいのにね。まぁ筑波山が有名すぎるからなぁ。帰りのバス停で待ってたら通りすがりのおばちゃんに連山のパンフレットもらった。こんなのあったのか!ありがとうございます、市役所とかにあるらしいよ。しかしまぁ週末の山登りぐらいじゃ運動不足は解消されてなかったってことよな。うーむ、これじゃ一日中行動するなんて夢のまた夢だなぁ。

カテゴリー: やま | タグ: , | コメントする