mplfinanceの凡例の表示が狂う件

私はpythonで株価チャートの移動平均線を表示する際にmplfinanceを使っているのですが、凡例を意図した通りに表示できずにハマったので記録を残しておこうと思います。
mplfinanceで凡例を表示する方法を解説している記事が既にありますが、移動平均"線"ではなく、ロウソク足の太い線を表示してしまうケースを紹介している記事が多いかと思います。

1は無駄話のため、結論だけ知りたい方は2に飛んでください。
4でもう一つの案を紹介しています。

環境

MacOS 12.3.1
python 3.11.4
matplotlib 3.7.2
mplfinance 0.12.10b0

1. 昔の方式の実装例

記事執筆時点で2023年ですが、数年前の記事や書籍を参照した場合、凡例の表示方法は次のようなやり方で紹介されていることがあると思います。

import datetime as dt
import pandas_datareader.data as pdr
import matplotlib.pyplot as plt
import mplfinance as mpf

df = pdr.DataReader('7203.JP', 'stooq').sort_index()	#トヨタ

# 移動平均
df['ma5'] = df['Close'].rolling(window=5).mean()
df['ma25'] = df['Close'].rolling(window=25).mean()
df['ma75'] = df['Close'].rolling(window=75).mean()

cdf = df[dt.datetime(2023, 1, 1):]
apd = [mpf.make_addplot(cdf['ma5'], color='blue'),
	mpf.make_addplot(cdf['ma25'], color='green'),
	mpf.make_addplot(cdf['ma75'], color='red')]

# 描画情報を取得
fig, axes = mpf.plot(cdf, type='candle', addplot=apd, returnfig=True)

# ラベルを追加
legend_list = ['MA5', 'MA25', 'MA75']
axes[0].legend(legend_list)
plt.show()

現在の環境で実行すると凡例は全然合っていません。線の太さもおかしいです。
しかし、試しにラベルの追加の部分を次のようにして0~6の連番になるように変更してみると、、、

axes[0].legend(range(7))

2,3,4 が移動平均線に対応、5以降は無視されることがわかりました。すると、0はロウソク足のヒゲ、1はロウソク本体のようです。
そこで、0,1を無視して2,3,4を残すような方法がわかると嬉しいですね。。。


2. 1の改善案

こちらを参考にして解決しました。
how to add legend to the plot? · Issue #181 · matplotlib/mplfinance · GitHub

import datetime as dt
import pandas_datareader.data as pdr
import matplotlib.pyplot as plt
import mplfinance as mpf

df = pdr.DataReader('7203.JP', 'stooq').sort_index()	#トヨタ

# 移動平均
df['ma5'] = df['Close'].rolling(window=5).mean()
df['ma25'] = df['Close'].rolling(window=25).mean()
df['ma75'] = df['Close'].rolling(window=75).mean()

cdf = df[dt.datetime(2023, 1, 1):]
apd = [mpf.make_addplot(cdf['ma5'], color='blue'),
		mpf.make_addplot(cdf['ma25'], color='green'),
		mpf.make_addplot(cdf['ma75'], color='red')]

# 描画情報を取得
fig, axes = mpf.plot(cdf, type='candle', addplot=apd, returnfig=True)

# ラベルを追加
legend_list = ['MA5', 'MA25', 'MA75']
######## ここから変更 #################################################
axes[0].legend([None]*2 + legend_list)
handles = axes[0].get_legend().legend_handles
axes[0].legend(handles=handles[2:], labels=legend_list)
######## ここまで    #################################################
plt.show()

無事、細い線3本の凡例を表示できるようになりました。
凡例のハンドルを取得してから、最初の2つを除いて表示するようにしています。


3. ググるとよく出てくる方法

2の方法に行き着く前に軽くググっていたらPatchを使う方法がいくつか出てきました。

import datetime as dt
import pandas_datareader.data as pdr
import matplotlib.pyplot as plt
import mplfinance as mpf
import matplotlib.patches as mpatches    #追加

df = pdr.DataReader('7203.JP', 'stooq').sort_index()	#トヨタ

# 移動平均
df['ma5'] = df['Close'].rolling(window=5).mean()
df['ma25'] = df['Close'].rolling(window=25).mean()
df['ma75'] = df['Close'].rolling(window=75).mean()

cdf = df[dt.datetime(2023, 1, 1):]
apd = [mpf.make_addplot(cdf['ma5'], color='blue'),
	mpf.make_addplot(cdf['ma25'], color='green'),
	mpf.make_addplot(cdf['ma75'], color='red')]

# 描画情報を取得
fig, axes = mpf.plot(cdf, type='candle', addplot=apd, returnfig=True)

######## ここから変更 #################################################
patches = [
	mpatches.Patch(color='blue', label='MA5'),
	mpatches.Patch(color='green', label='MA25'),
	mpatches.Patch(color='red', label='MA75')]
axes[0].legend(handles=patches)
######## ここまで    #################################################
plt.show()

ロウソク本体の太い線に色がついたような凡例になっています。細線ではないので惜しいです。


4. 3の改善案

こちらの記事を参考にして改善しました。
python - How to manually create a legend - Stack Overflow

import datetime as dt
import pandas_datareader.data as pdr
import matplotlib.pyplot as plt
import mplfinance as mpf
import matplotlib.patches as mpatches	#追加
from matplotlib.lines import Line2D	#追加

df = pdr.DataReader('7203.JP', 'stooq').sort_index()	#トヨタ

# 移動平均
df['ma5'] = df['Close'].rolling(window=5).mean()
df['ma25'] = df['Close'].rolling(window=25).mean()
df['ma75'] = df['Close'].rolling(window=75).mean()

cdf = df[dt.datetime(2023, 1, 1):]
apd = [mpf.make_addplot(cdf['ma5'], color='blue'),
		mpf.make_addplot(cdf['ma25'], color='green'),
		mpf.make_addplot(cdf['ma75'], color='red')]

# 描画情報を取得
fig, axes = mpf.plot(cdf, type='candle', addplot=apd, returnfig=True)

######## ここから変更 #################################################
patches = [
	Line2D([], [], color='blue', label='<1>MA5'),
	Line2D([], [], color='green', label='<1>MA25'),
	Line2D([], [], color='red', label='<1>MA75'),
	mpatches.Patch(color='blue', label='<2>MA5'),
	mpatches.Patch(color='green', label='<2>MA25'),
	mpatches.Patch(color='red', label='<2>MA75'),
	mpatches.Rectangle((0,0), 0, 0, color='blue', label='<3>MA5'),
	mpatches.Rectangle((0,0), 0, 0, color='green', label='<3>MA25'),
	mpatches.Rectangle((0,0), 0, 0, color='red', label='<3>MA75'),
]
axes[0].legend(handles=patches)
######## ここまで    #################################################
plt.show()

<1>:Line2Dを使用した細線の表示例
<2>:上述の大項目3と同じ。mpatches.Patchを使用した場合
<3>:mpatches.Rectangleを使用して<2>と同じ表示をしてみた例

<1>が表示したかった細線で、<2><3>はおまけです。
matplotlib.lines.Line2Dオブジェクトを使用すれば細線の凡例を自作できることがわかりました。
リンク先を見るとわかりますが、Line2Dを使用してポイントの凡例を作ることもできるようです。

.

成人向け水泳教室に通って泳げるようになった話

私は現在、成人向けの水泳教室に通っています。
クロールを全く泳げない状態から1年と少し経って、四泳法がある程度泳げるようになったので振り返ろうと思います。
成人済みの方で水泳教室に通うか迷っている方の参考になればと思います。

背景

年齢・性別

20代後半、男

体型

痩せ型、BMI 19〜20くらいです。
通学で自転車に乗ったり趣味でボウリングをしたりしていたので、太ももと腕には筋肉がついている方かも。
ジムには通ったりはしておらず、腹筋や胸筋は全くないです。

水泳歴

小学生:授業ではほとんど泳げるようにならず。ゴーグルの着用が許可されていなかったため、目が痛くなるし初夏の空気は冷たいしで水泳は嫌なイメージ。小5の夏休みに10日間の短期教室に通った時のクロール13mが今回の成人向け教室に通う前の最高記録。
中高生:学校にプールがないため水泳授業なし。

運動歴

小学生:ミニバスケットボール部。週3,4回くらいバスケ。
中高生:帰宅部。駅まで全力で自転車漕いだり電車間に合わなくて走ったりするくらいの運動をほぼ毎日。
大学以降:ボウリングが趣味になったので時々ボウリング。移動に時々自転車を使うくらい。

運動は好きな方で鬼ごっこや球技で遊ぶのは好きだけれど運動音痴であまり上手にはならないタイプでした。
水泳や鉄棒、跳び箱、筋トレ、ダンスは苦手でした。また、体力がないので持久走も苦手でした。

教室に通おうと思った理由

泳げることで役立つことがあるかはわからないけれど、一生泳げないよりは泳げるようになっておきたい気持ちがあり、また、年を取ってからできる運動でもあるので水泳を今後できる運動の選択肢に入れておきたかったので。

水泳教室の特徴

成人向けコースは初級、中級、上級に分かれています。
料金は月4回で月額7150円(2023年夏に値上がりして7700円)です。

1回につき60分で、通年で前半30分はクロールを習い、後半は下記のように2ヶ月おきに習う泳法が変わるシステムです。
1,2月と7,8月:背泳ぎ
3,4月と9,10月:平泳ぎ
5,6月と11,12月:バタフライ

準備

水着やゴーグルについて。
水着、ゴーグル、キャップ、それに教習後に身体を拭くタオルは必須です。

実は大学時代に一度だけ大学で募集していた水泳教室に通ったことがあり、その際にこちらのセットを購入していました。
Amazon.co.jp: [アスレエックス] メンズ 水着 フィットネス 競泳水着 男性 スイミング ゴーグル 水中眼鏡 スイムキャップ セイムタオル セーム 大きいサイズ プール備品 5点セット : スポーツ&アウトドア

既に泳げる人が多い中で私一人だけが全く泳げなかったのが気まずくて、この大学でやっていた教室は1度だけ通ってやめてしまいました。
この時のセットの水着は、パッツリしすぎていて股間もっこり感が気になったので、今通っている水泳教室では別の水着を用意しました。5点セットのうち、現在も使用しているものはゴーグルとキャップのみです。

水着はミズノの股間キャップを挿入できるタイプのものを購入しました。
楽天で4100円で購入しましたが、現在は品切れのようです。Amazonで色違いを見つけましたが値上がりしていますね。
Amazon | MIZUNO(ミズノ) フィットネス 水着 ジム用 メンズ ハーフスパッツ Lサイズ 96:ブラック×レッド N2JB8606 | MIZUNO(ミズノ) | メンズ

股間キャップはAmazonで購入しました。
Amazon.co.jp: MIZUNO(ミズノ) スイムカップ 水着インナー メンズ セットポジションカップ 85ZF35009 ブラック 09:ブラック : ファッション

最初はもっこり感を気にしていましたが、今振り返るとプールで水面から出るのは上半身だけなので気にする必要はなかったと思います。
スパッツタイプではないレジャー用の水着も迷いましたが、水泳教室には緩いタイプの水着を着用している人はいなかったので、スパッツタイプで正解だったと思います。

教室参加者の様子

私は土曜日の回に毎週参加していますが、初級コースには10人前後の参加者がいます。隣の2レーン分を中級コースが使っていますが、中級コースは15人ほどでしょうか。
年齢層は(見た目でしかわかりませんが)20代は私くらいでほとんどいません。30代が2,3人で40-60代の方が多い印象です。
性別は初心者コースは男女半々くらい、中級コースは女性が8割9割くらいです。コースによって男女構成が変わるのは興味深いです。

私の成長の記録

クロール

小さいビート板を持って腕をかく練習から始まりました。
最初は全く息継ぎができない状態だったので、ビート板を持っている状態で息継ぎをするのが精一杯です。
2週目でビート板なしでもやってみようと先生に促されてやってみましたが、鼻に水が入って咽せたりして苦しい状態でした。
3週目あたりで咽せる回数がかなり減りました。数回息継ぎしては足をつけて休憩するくらいの進み具合です。終盤は20mくらい進めていたと思います。

4週目になり、先生から「鼻から息をずっと出し続けるのではなく、息継ぎをする直前に一気に吐いてみてはどうか」とアドバイスをもらい、その通りにしたらかなり楽になりました。一度だけ足を着けずに25m泳ぎ切ることが出来ました。
25m泳ぐには数ヶ月かかると思っていただけに驚きました。小学生の頃と比べると身体も筋力も大きくなっているので進みやすくなっていたのだと思います。


毎回クロールの練習はビート板なしで6往復するのですが、8週目で初めて6回連続で25m足を着かずに泳ぐことが出来ました。往路で体力が尽きてしまうので、復路の25mは休憩しながら戻ってくる状況です。

5ヶ月で往路の25mの後、一息休憩を入れて復路の25mを足を着かずに毎回泳ぎ切ることができるようになりました。泳ぐのに必要な筋力がついてきたのだと思います。この頃から胸筋がついてきたように感じました。

8ヶ月目に入って、ターンを教わりました。往路の25m終わった後に一息つけなくので連続50m泳ぐことになり苦しくなります。

10ヶ月目。これまでは右手でかく時に毎回息継ぎをしていましたが、一度飛ばして4回かくタイミングで息継ぎできるようになりました。

1年2ヶ月目(現在)、息継ぎを減らすことができるようになり、息継ぎ1-3回で25m泳げるようになりました。帰りは苦しいので何回も息継ぎしますが、行きは半分を超えてから初回の息継ぎをするくらいです。

先生からは9ヶ月頃から中級コースに移ることを勧められていたので、クロールだけ見れば中級に移ってもいいくらいには泳げているのだと思います。実際、クロールなら初級コースの中で一番速く泳げるようになりました。
しかし、他の泳法が上達していないので私はもうしばらく初級に残って練習したいと考えています。

平泳ぎ

4月と9,10月の3ヶ月間やって、最終週に初めて25m泳げるようになりました。まだ足の向きがおかしいだとかの変な癖は残っています。

背泳ぎ

最初はひっくり返って泳ぐなんて考えられませんでした。なかなか身体を浮かせることができず、鼻に水が入ってくることも多かったので苦しかったですが、慣れてくると息継ぎには困らないので2ヶ月ほどで25m泳げるようになりました。
ただ、足を攣ることが多いです。

バタフライ

ものすごく苦戦しました。
平泳ぎも背泳ぎも2,3ヶ月で25m泳げるようになりましたが、バタフライには6ヶ月かかりました。
足を打つタイミングと腕を回すタイミングの取り方が難しかったり、息継ぎできるほど頭を水面に出せない難しさもありました。
5,6ヶ月目になんとなくコツを掴んで息継ぎができるようになったのですが、言語化が難しいです。
日々の練習で筋力がついてきた影響も大きいかもしれません。


以上、私の水泳教室の記録でした。
また進展があれば更新したいと思います。

Windowsでスクリーンショットのショートカットキーと保存先を変更する【AutoHotkey】

Windowsスクリーンショットを撮る際のショートカットキーの変更方法、スクリーンショットの保存先・保存ファイル名の変更方法を解説します。

ここでは全画面スクリーンショットとアクティブウィンドウのスクリーンショットの設定変更方法を紹介します。
ショートカットの変更にはAutoHotkeyというソフトを使用します。

全画面スクショは他にソフトを使用せずに設定できますが、アクティブウィンドウのスクショにはOne DriveかXbox Game Barがインストールされている必要があります。両方ともデフォルトでWindowsにインストールされていることが多いと思いますが、持っていない場合はインストールする必要があります。

(他のソフトをインストールせずにAutoHotkeyのみでアクティブウィンドウスクショを行う方法は分かりませんでした。ご存知の方がいらっしゃればコメントで教えていただきたいです。範囲選択スクショの方法もわからずです。)

以下、私の使用環境とソフトウェアバージョンです。私はショートカットキーにCapsLockを使用しているのですが、その場合はChange Keyというソフトもインストールする必要があります(別記事参照)。

  • Windows10
  • AutoHotkey v2.0.2
  • OneDrive v19.23.19.0
  • Xbox Game Bar v5.823.3261.0



1. 必要なソフトのインストール

CapsLockキーをショートカットキーに使用する場合

別記事を参照して Lhaplus, Change Key をインストール、「2. Change Key でのキー割り当て変更」を済ませておいてください。

AutoHotkey

AutoHotkey
「Download」をクリック→「Download v2.0」をクリック
でダウンロードできます。

OneDrive もしくは Xbox Game Bar

アクティブウィンドウのスクショ保存を設定する場合はどちらかをインストールしておいてください。

2. AutoHotkey でのショートカットキー割り当て

AutoHotkeyの使用手順です。

 2回目以降は警告のポップアップが出ますが、「はい」をクリックすれば実行できます。

3. OneDriveを使用する場合の準備

OneDriveをインストールしてある場合、
[PrintScreen] で全画面スクショを
[Alt] + [PrintScreen] でアクティブウィンドウスクショを
OneDriveのScreenShotフォルダに自動で保存することができるので、この設定をしておきます。

ちなみに、OneDriveの設定をしない場合、上記のショートカットキーはクリップボードにスクショ画像をコピーする操作になります。

設定手順


4-1. 全画面スクリーンショットスクリプト

OneDriveを使用する場合

私の場合、CapsLock + 3 で全画面スクショを保存するように設定しています。
CapsLock をF13キーに置き換えているため、「F13 & 3」となっています。
キーを変更したい場合はクイックリファレンスを参照してください。
キー(キーボード、マウス、ジョイスティック)一覧|AutoHotkey v2


スクショは一旦、ScreenShotフォルダに「yyyy-MM-dd.png」形式で保存されます。それを保存したいフォルダに移動しています。

簡単な流れは次の通りです。(2023/6/1 12:34:56 に実行した想定)
CapsLock + 3 キーが押される
→実行日と同じ日に手動で既に保存済みのスクショ画像 yyyy-MM-dd.png (例えば、2023-06-01.png) があれば "ScreenShot/_"フォルダに退避
→ "yyMM" (例えば 2306) フォルダを作成
→ [PrintScreen]キーが押される
→ yyyy-MM-dd.png が保存される (2秒待機)
→ 保存された画像を "yyMM / ScreenShot_yyMMdd_HHmmss.png" (2306 / ScreenShot_230601_123456.png) に保存

以下、スクリプトになりますが「;」以降はコメントのため消して構いません。
[user_name] はユーザ名を入力して、その他、保存ファイル名や保存先フォルダも適宜変更して使用してください。

ちなみに、特に保存先のフォルダ名やファイル名を変更しないのであれば、
F13 & 3:: Send "{PrintScreen}"
のように、1行で構いません。

;------------------------------------
; スクショ保存(全画面)
;------------------------------------
F13 & 3::
{
	user_dir := "C:\Users\[user_name]\"
	screenshot_dir := user_dir "OneDrive\Picture\ScreenShot\"
	yymm := FormatTime(,"yyMM")    ;2306
	file_name := "ScreenShot_" FormatTime(,"yyMMdd_HHmmss") ".png"   ;保存ファイル名
	yymm_dir := screenshot_dir yymm
	png_path := yymm_dir "\" file_name    ;保存先フォルダ
	
	if not DirExist(yymm_dir)
	{
		;MsgBox "not exist"
		DirCreate yymm_dir
	}

	;src_file := screenshot_dir "スクリーンショット *.png"    ;<OneDrive不使用>
	src_file := screenshot_dir FormatTime(,"yyyy-MM-dd") "*.png"
	drop_dir := screenshot_dir "_\"
	FileMove src_file, drop_dir
	;Send "#{PrintScreen}"    ;<OneDrive不使用>
	Send "{PrintScreen}"
	Sleep 2000
	FileMove src_file, png_path
	Return
}
OneDriveを使用しない場合

[Win] + [PrintScreen] で全画面スクショを保存する方法を使っています。
上記のOneDriveを使用する場合のスクリプト
2ヶ所あるのコメントのある行の先頭の「;」を消して、
直後の1行を削除してください。


4-2. アクティブウィンドウのスクリーンショットスクリプト

OneDriveを使用する場合

CapsLock + 4 でスクショを撮るように設定しています。

全画面の場合と同様ですが、[Alt] + [PrintScreen] でScreenShotフォルダに保存された画像を指定したフォルダ・ファイル名で移動しています。

;------------------------------------
; スクショ保存(アクティブウィンドウ)
;------------------------------------
F13 & 4::
{
	user_dir := "C:\Users\[user_name]\"
	screenshot_dir := user_dir "OneDrive\Picture\ScreenShot\"
	yymm := FormatTime(,"yyMM") ;2306
	file_name := "ScreenShot_" FormatTime(,"yyMMdd_HHmmss") ".png"
	yymm_dir := screenshot_dir yymm
	dst_file := yymm_dir "\" file_name
	
	if not DirExist(yymm_dir)
	{
		;MsgBox "not exist"
		DirCreate yymm_dir
	}

	src_file := screenshot_dir FormatTime(,"yyyy-MM-dd") "*.png"
	drop_dir := screenshot_dir "_\"
	FileMove src_file, drop_dir
	Send "!{PrintScreen}"
	Sleep 2000
	FileMove src_file, dst_file
	Return
}
Xbox Game Bar を使用する場合

[Win] + [Alt] + [PrintScreen] を押すと
"C:\Users\[user_name]\Videos\Captures\"
にアクティブウィンドウのスクショが保存されます。

上記スクリプトを2点、修正してください。
①一時保存先ファイル名

	src_file := screenshot_dir FormatTime(,"yyyy-MM-dd") "*.png"

	capture_dir := user_dir "Videos\Captures\"
	src_file := capture_dir "*.png"

②送信コマンド

	Send "!{PrintScreen}"

	Send "#!{PrintScreen}"

4. 設定を維持する

そのままではPCを起動する度に.ahkファイルを実行する必要があるため、起動時に自動実行するように設定します。

  • エクスプローラで.ahkファイルを右クリック → ショートカットの作成
  • Windowsキー + R で「ファイルを指定して実行」を開く
  • shell:startup → OK でスタートアップフォルダを開く
  • .ahkのショートカットファイルをスタートアップフォルダに移動する
  • 再起動



Windowsで(Macのような)Emacs風キー操作を使用する【AutoHotkey】

この記事ではWindowsMacと同様のEmacsキーバインドを使用する方法を説明します。

すなわち、Macで標準的に行える、Ctrl+DでDeleteしたりCtrl+Eで行末に飛ぶような操作をWindowsでもControlキーの代わりに CapsLockキーを使ってできるようにしてしまおうというお話です。

AutoHotkeyという各種操作にショートカットキーを割り当てることができるソフトを使用します。
残念ながらCapsLockキーを直接ショートカットキーに登録することはできないので、Change Keyというキー割り当てを変更するソフトを使用して、一旦CapsLockキーをF13キー(標準的なキーボードには存在しないキー)に割り当ててからAutoHotkeyにショートカット登録をしていきます。

私の使用環境、ソフトウェアバージョンは以下に記載の通りになります。AutoHotkeyは2022年にv2へバージョンアップしており、文法に変更がありました。

  • Windows10
  • Lhaplus v1.74
  • Change Key v1.50
  • AutoHotkey v2.0.2


1. 必要なソフトのインストール

Lhaplus

圧縮・解凍ソフトです。
Change Keyは圧縮ファイルでダウンロードされますがWindowsの初期状態では解凍できない形式のため、こちらのソフトを使用して解凍します。

「Lhaplus」定番の圧縮・解凍ソフト - 窓の杜
窓の杜からダウンロード」をクリック。
インストール後に初期設定のウィンドウが開きますが、初期状態のままで問題ありません。
「解凍」にある「lzh」のチェックは外さないでおいてください。

Change Key

「Change Key」非常駐型でフリーのキー配置変更ソフト - 窓の杜
窓の杜からダウンロード」をクリック。
ダウンロードできたらダウンロードフォルダの「ChgKey15.LZH」ファイルを解凍してください。(上記のLhaplusインストール後ならエクスプローラからダブルクリックで解凍できると思います。)

AutoHotkey

AutoHotkey
「Download」をクリック→「Download v2.0」をクリック
でダウンロードできます。

2. Change Key でのキー割り当て変更

以下の順でCapsLockキーをF13キーに割り当てます。
CapsLockキーを直接F13キーに割り当てようとするとうまくいかないことがあるようなので、Endキーへの割り当てを経由します。

  • ChgKey15フォルダ内に展開された ChgKey.exe を管理者実行
  • CapsLock をクリック
  • End をクリック
  • 「登録」タブの「現在の設定内容で登録します」をクリック
  • 再起動
  • 再び ChgKey.exe を管理者実行
  • CapsLock の位置にある End をクリック
  • 右上「Scan code」をクリック
  • 0x「0064」を入力
  • 「登録」タブの「現在の設定内容で登録します」をクリック
  • 再起動


3. AutoHotkey でのショートカットキー割り当て

 2回目以降は警告のポップアップが出ますが、「はい」をクリックすれば実行できます。

#Requires AutoHotkey v2.0

;------------------------------------
; Emacs キーバインド
;------------------------------------
F13 & b::Send "{Left}"			; ←移動
F13 & f::Send "{Right}"			; →移動
F13 & n::Send "{Down}"			; ↓移動
F13 & p::Send "{Up}"			; ↑移動
F13 & e::Send "{End}"			; 行末へ移動
F13 & a::Send "{Home}"			; 行頭へ移動
F13 & h::Send "{Backspace}"		; 左の1文字を削除
F13 & d::Send "{Delete}"		; 右の1文字を削除
F13 & k::Send "{Shift down}+{End}+{Shift up}+{Backspace}"	; 行末まで削除



4. 設定を維持する

そのままではPCを起動する度に.ahkファイルを実行する必要があるため、起動時に自動実行するように設定します。

  • エクスプローラで.ahkファイルを右クリック → ショートカットの作成
  • Windowsキー + R で「ファイルを指定して実行」を開く
  • shell:startup → OK でスタートアップフォルダを開く
  • .ahkのショートカットファイルをスタートアップフォルダに移動する
  • 再起動


ufwコマンドを使用できなくなった

UbuntuOpenVPNサーバを構築するためにufw設定ファイルを更新したところ、ufwコマンドが使用できなくなりました。
結論を先に述べると、設定ファイルに誤字がありました。
以下、やったことと解決法です。


ufwの設定ファイル /etc/default/ufw
フォワーディング設定を次のように変更しました。

DEFAULT_FORWARD_POLICY=“ACCEPT"

正しくは、
DEFAULT_FORWARD_POLICY="ACCEPT"
です。
”と"の違いですね。
MacでもWindowsでも日本語入力の状態でShift+2を叩くと前者が出ます。


誤った方でファイルを保存してufwコマンドを使用すると以下のようなエラーが出ます。

$ sudo ufw status
ERROR: Missing policy for 'forward'


こういうくだらないミスで時間を溶かすと徒労感がすごいですね。。。

12ステップで作る組込みOS自作入門の環境構築(VirtualBox使用)

はじめに

12ステップで作る組込みOS自作入門の環境構築に苦戦したので、やったことをまとめておきます。

 

いくつか環境を変えて挑戦してみました。

この記事では、成功したVirtualBoxUbuntu環境を構築した際の方法をまとめます。

失敗した方法もいつか記事にしておきたいと思います。成功された方はコメントで教えていただけるとありがたいです。

 

主に参考にしたサイト

  1. [機材, ビルド方法] 12ステップで作る組み込みOS自作入門 - marlesanのブログ

  2. [ビルド前環境構築] 組込みOS自作 H8マイコンの開発環境構築|コアダンプの数だけ強くなれるよ

  3. [共有ファイル設定] VirtualBoxでWindows10とUbuntu間のファイル共有

 

PCスペック

DELL Inspiron16

Windows10

 

購入した機材

まず、購入したものはこちらです。通販で買うなら注文してから届くまでの間に環境構築を進めてしまうと効率的ですね!

 

  1. マイコン(必須)[H8/3069Fネット対応マイコンLANボード(完成品)]
  2. USB-シリアルケーブル(必須)[ELECOM USBtoシリアルケーブル USBオス-RS-232C用 UC-SGT1]
  3. ACアダプター(必須)[超小型スイッチングACアダプター5V1A AD-D50P100]
  4. シリアル延長ケーブル(4 or 5)[StarTech.com RS-232C ストレートケーブル 0.5m ブラック D-Sub 9ピン(オス) - D-Sub 9ピン(メス) MXT10050CMBK]
  5. ペンチ(4 or 5)ダイソーで200円のペンチを購入しました。)
  6. スペーサー[3mmプラネジ(7mm)+六角スペーサー(14mm)セット]

1, 2, 3 は必須ですね。

色々記事を見ていて2のシリアルケーブルを使っていた方は見なかった気がしますが、問題なく使用できました。スケルトンなところが気に入って購入しました。

 

4 or 5 についてですが、2のシリアルケーブルだけではマイコンに接続できません。端子はオスとメスなので問題ないですが、留め具が両方メスなので噛み合わないのです......

端子メス,オス、留め具は両方オスになっているシリアル延長ケーブルを購入するか、ペンチでマイコン側の留め具と取ってしまいましょう。

私は初め延長ケーブルを使用していたのですが、どうにも嵩張るのでペンチを買ってマイコン側の留め具を取ってしまいました。留め具を取ってしまうと接地ができずないため不具合が起こる可能性があると書いている記事をどこかで見ましたが、私は(まだ数回しか使っていませんが)今のところ問題なく使用できています。

不具合を確認できたら追記します。

 

6はマイコンを机から浮かせるためのものです。なくてもOS作成は可能です。

 

VirtualBox / Ubuntuのインストール

VirtualBoxUbuntu環境を構築します。

VirtualBoxのインストール方法は検索かけると色々と出てくると思います。

Ubuntuのインストールについても参照サイト2で詳しく書かれているのでご参照ください。

 

私がインストールしたバージョンは次の通りです。

 

USBシリアルの接続確認

書籍とは順序が異なりますが、環境構築の最後の最後にシリアルの接続ができないとなるとショックなので早いところ確認してしまいましょう。

 

Ubuntuが起動したままだと失敗してしまうので、起動している場合は電源を切ってください。

USBの設定画面を開くと最初はUSBデバイスフィルターに何も表示されてないと思います。

画面右の+マークから追加しましょう。

 

+マークを押すと候補が表示されます。

USBシリアルを選択します。どれかよくわからなければ、USBシリアルをPCから抜き挿ししてみて、挿した時のみ表示されているものを選択しましょう。

f:id:hayariapp:20211228193227p:plain

 

Ubuntuを起動して端末で次のコマンドを打つとUSB接続が認識されているかわかります。

ls -l /dev/serial/by-id

 

USB接続が認識されていればこのように ../../tty*** と表示されると思います。

f:id:hayariapp:20220123164836p:plain

 

SSH接続

こちらも参照サイト2で書かれている通りです。

これと次項の共有ファイル設定を行うことで、Windows環境でコーディングを進めることができます。

 

Ubuntuの端末で実行したコマンドはこちら。

sudo apt update
sudo apt install openssh-server sudo systemctl enable ssh sudo systemctl start ssh

2行目の

sudo apt install openssh-server

の前に

sudo dpkg --configure -a

をする必要がある方もいらっしゃるかもしれません。(私がそうでした。)

 

その後は参考サイト2の通りにポートフォワーディングを進めましょう。

一応リンク切れになった時のために文字に起こしておきます。

 

VirtualBoxの設定 > ネットワーク > アダプター1

  > 割り当て:NAT

 

・同画面下部「ポートフォワーディング」をクリック。

 ポートフォワーディングルールの画面が表示されるので、+マークをクリックして、

  ホストポート:10022

  ゲストポート:22

 を設定。

 

WindowsTeratermを起動して、

 ホスト:127.0.0.1

 TCPポート:10022

 サービス:SSH

 を設定してOK。

 

これでWindowsTeratermからVirtualBoxUbuntuを操作できるようになりました。

 

ホームディレクトリのフォルダ名を日本語から英語に変更

以下を実行して、出てきた画面でUpdateNowをクリックします。

LANG=C xdg-user-dirs-gtk-update

 

共有フォルダ設定

共有フォルダーを設定すると、Windowsで共有設定したフォルダの中身とUbuntuで共有設定フォルダを同期させることができます。

つまり、

Windowsの共有フォルダ:C¥DirWin

Ubuntuの共有フォルダ:/DirUbuntu

の時、Window側から見た時のDirWinの中身とUbuntu側から見たDirUbuntuの中身が同じものになります。

 

設定する際に参考サイト3を主に参考にしました。

 

Windows側、Ubuntu側で共有フォルダを作成しておく。(上記の例と同じフォルダで設定することにします)

 

VirtualBoxの設定 > 共有フォルダー の +マークをクリック

 フォルダーのパス:C:¥DirWin

 フォルダー名:(自動で入力されます)  −−− (1)

  読み取り専用:OFF

  自動マウント:ON

 マウントポイント:/DirUbuntu    −−− (2)

  永続化する:ON

 

Ubuntuを再起動する

 

Ubuntuで以下のコマンドを実行します。

sudo apt install virtualbox-guest-utils
sudo mount.vboxsf [上記(1)] [上記(2)]
sudo gpasswd --add [Ubuntuのユーザ名] vboxsf

 

設定がうまく行っているか、共有設定したフォルダに新規ファイルを作成して確認してみてください。

 

binutils / gcc / kz_h8write のビルド

主に参考サイト1を参考にしました。

私が使用したバージョンは次の通りです。

binutils:2.19.1

gcc:3.4.6

 

binutils

Ubuntuで作業ディレクトリまで移動して、下記のコマンドを実行します。

wget https://ftp.gnu.org/gnu/binutils/binutils-2.19.1.tar.bz2
tar -jxvf binutils-2.19.1.tar.bz2
cd binutils-2.19.1/
mkdir build
cd build
../configure --target=h8300-elf --disable-nls --disable-werror
make
sudo make install

 

gcc

再び作業ディレクトリに戻り、下記のコマンドを実行します。

wget http://core.ring.gr.jp/pub/GNU/gcc/gcc-3.4.6/gcc-3.4.6.tar.gz
tar zxvf gcc-3.4.6.tar.gz
cd gcc-3.4.6/
vi gcc/collect2.c
(書籍にある通りにcollect2.cを修正)

cd ..
wget http://kozos.jp/books/makeos/patch-gcc-3.4.6-x64-h8300.txt
patch -p0 < patch-gcc-3.4.6-x64-h8300.txt
mkdir build
cd build/
../configure --target=h8300-elf --disable-nls --disable-threads --disable-shared --enable-languages=c --disable-werror
make
sudo make install

 

kz_h8write

次の配布サイトから kz_h8write-v0.2.1.zip をダウンロードして作業フォルダに移動しておきます。

H8/3069F writer for KOZOS (kz_h8write) プロジェクト日本語トップページ - OSDN

 

zipを解凍してmakeします。make install はしなくて良いです。

unzip kz_h8write-v0.2.1.zip
cd PackageFiles/src
make

makeすると kz_h8write というファイルができると思います。

 

書籍の通り、src/tools/h8write フォルダを作成して、

kz_h8write

kz_h8write.c

を移動しましょう。

この時、ファイル名の先頭のkz_を消して h8write, h8write.c に変更してください。

 

ソースファイルの作成

書籍を見ながら src/01/bootload にソースファイルを作成していきましょう。

 

サポートページからダウンロードすることもできます。

(OS自作本編第3回)Ubuntu,Fedora,Cygwinで動作確認した

サイト内の「こちらは上のソースコードをアーカイブしたもの」をクリックするとzipファイルがダウンロードされます。

 

プログラムをビルドする

Makefileの修正

Makefile内のシリアル接続先を変更します。

 

PCとマイコンを接続してから、次のコマンドでシリアルデバイスファイルを確認します。(序盤の「USBシリアルの接続確認」の最後に確認したものと同じコマンドです。)

ls -l /dev/serial/by-id

「../../ttyUSB0」 と表示されたら、「/dev/ttyUSB0」がデバイスファイルです。

 

Makefile内のシリアル接続先が書かれている部分

H8WRITE_SERDEV = /dev/cuad0

H8WRITE_SERDEV = [デバイスファイル名]

に変更して保存します。

 

ビルド

ソースコードのあるフォルダ(src/01/bootload)に入り、

make

を実行します。

 

ここで失敗した場合は作成したファイルが誤っていると思われます。

一度、「make clean」 して、makeしたときに作成されたファイルを削除してからファイルを修正しましょう。

 

次に

make image

を実行します。

 

うまくいったらマイコンのスイッチを書籍にあるようにON, ON, OFF, ON にしてから電源に繋いで

sudo make write

を実行します。

 

Hello World! を出力する

フラッシュROMから起動するために一度マイコンの電源を切ってからスイッチをON, OFF, ON, OFF にセットして電源を入れます。

 

シリアル通信にcuコマンドを使用します。

インストールが済んでいない場合はインストールします。

sudo apt install cu

 

次のコマンドでシリアル接続します。

sudo chmod 666 [デバイスファイル名]
cu -s 9600 -l [デバイスファイル名]

"Connected"と表示されれば接続できています。

失敗した場合でも最後のコマンドを2,3回繰り返すとうまくいくと思います。

 

接続できたらリセットボタンを押す度に"Hello World!"が出力されると思います。

ぽちぽち押しまくりましょう!楽しいですね(^_^)

 

 

VSCodeで改行を含む任意の文字列を検索する

Visual Studio Codeでは正規表現を使って検索をかけることができますが、

改行を含む任意の文字列を検索しようとしたところ

少しつまずいたので書き残しておきます。

 

素直に「正規表現 改行を含む任意の文字」などでググると、

[\s\S]*?

がよく紹介されていますが、

VSCodeで検索しても改行を含まない部分しかヒットしません。

f:id:hayariapp:20210131120202p:plain

 

代わりに、

[\w\W]*?

を使うと途中に改行があってもヒットします。

f:id:hayariapp:20210131120429p:plain

 

【参考】

VSCode:正規表現文字セットのエスケープドット