2023年7月31日月曜日

[RasberryPi Pico W] Debian on VirtualBox on Windows の環境で CLionを使う

Debian on VirtualBox on Windows の環境でRasberryPi Pico Wの開発環境を作った。

使用したソフトウェアのバージョンと機器は以下の通り。

  • Windows 11
  • VirtualBox 7.10
  • Debian 12.1
  • CLion 2023.2
  • Debug probe 
  • RasberryPi Pico W

VitualBoxを使うのは、Windows環境を汚さないためである。

CLionでコードを書き、ビルドしてRasberryPi Pico Wにプログラムをアップロードし実行する。デバッガも使えることを確認した。

基本的な設定手順

Raspberry Pi本家サイトに Raspberry Pi Picoをセットアップしようというドキュメントがあるので、それに従えばよい。
ファイルはRaspberry Pi Datasheetsにある。
直接リンクはこちら。
第章 1. Pico のクイックセットアップ
第章 2. SDK
第章 3. C 言語で LED を点滅させる
第章 4. C 言語で「Hello World」というテキストを表示する
第章 5. SWD を使用してフラッシュプログラミングを行う
第章 6. SWD を使用してデバッグを行う

お好みに応じて3章、4章をやりつつ6章のGDBが動くことが確認できればOK。

注意点をいくつか。

(1)USBデバイスの認識
マシンに接続したあとに、VirtualBoxのUSBデバイスフィルターの設定画面で認識したデバイスを追加すること。追加しないとDebian側では認識しない。

注意点: 追加後、一度抜き差ししないと認識しなかったかも?
認識したかの確認は dmesgコマンドか lsusbコマンドを使えばよい。

(2)Debug probeのUARTの接続
TX-RX, RX-TX とクロス接続する。

(3)Hello, world送信のシリアル接続の確認
gihyo.jpのサイト(以下の参考を参照)では picocomを使っていたので、同様に使ってみた。
dialoutグループに所属しないとsudoを使わなければならないので注意。
# piccomインストール
$ sudo apt install picocom
# dialoutグループに追加
$ sudo usermod -a -G dialout $USER
# 通信確認
$ picocom /dev/ttyACM0 -b 115200

Debug probe経由では私の環境では /dev/ttyACM1 となったかな?

(4)cmakeで Pico Wの指定

cmake -DPICO_BOARD=pico_w .. 

デバッグ版でビルドする場合

cmake -DPICO_BOARD=pico_w -DCMAKE_BUILD_TYPE=Debug ..

Debug probe

付録 A: Picoprobeを使用する - OpenOCDのビルド に従いOpenOCDをインストールする。
./configure にはオプション不要。

(1)プログラムの転送
blick.elfファイルの転送例
sudo openocd -f interface/cmsis-dap.cfg -f target/rp2040.cfg -c "adapter speed 5000" -c "program blink.elf verify reset exit"
(2)デバッグ時
sudo openocd -f interface/cmsis-dap.cfg -f target/rp2040.cfg -c "adapter speed 5000"

Pico WでのLチカ

Wifiモジュール経由でLEDが接続されているようで Picoのように単純にはLチカできないようだった。
外部LEDなら簡単なので、次のような回路でLチカした。

 


プログラムこちら。
#include "pico/stdlib.h"

void init_led_pin(const uint pin) {
    gpio_init(pin);
    gpio_set_dir(pin, GPIO_OUT);
}

int main() {
    const uint LED_RED_PIN = 21;
    const uint LED_GREEN_PIN = 20;
    init_led_pin(LED_RED_PIN);
    init_led_pin(LED_GREEN_PIN);
    const uint sleep_time_ms = 500;
    while (true) {
        gpio_put(LED_RED_PIN, 1);
        sleep_ms(sleep_time_ms);
        gpio_put(LED_RED_PIN, 0);
        sleep_ms(sleep_time_ms);
        gpio_put(LED_GREEN_PIN, 1);
        sleep_ms(sleep_time_ms);
        gpio_put(LED_GREEN_PIN, 0);
        sleep_ms(sleep_time_ms);
    }
}


 CLionの設定

上記ドキュメントの 
第章 10. 別の統合開発環境を使用する 
10.2. CLion を使用する
に従う。
pico-examplesにあるプログラムが一通りビルドできるはず。

デバッガの設定

Settings - Embedded Development
OpenOCD Locationに /usr/local/bin/openocd を設定する。
実行プログラムの設定
Run/Debug Configurations でスクリリーンショットのように設定
※Board config fileに ~/pico-debug.cfg を設定したが、これが具体的に何を意味するのかはまだ分かっていない。
→正しいパスは /home/satoshi/pico/openocd/tcl/board/pico-debug.cfg

デバッグモードでの実行例
少し遅いがブレークポイントで止まり、ステップ実行できることは確認した。
Linux機で新しい開発環境を作って気がついた。
上の手順だけではデバッグ時に
Error: unable to find a matching CMSIS-DAP device
が出てしまいデバッガが起動できない。バイナリも転送できない。
openocdが参照するデバイスの権限の問題のようだ。
以下の設定をすればよい。
/etc/udev/rules.d ディレクトリに以下のファイルを作る。
❯ cat 99-debugprobe.rules 
# Raspberry Pi Pico
ATTRS{idVendor}=="2e8a", ATTRS{idProduct}=="[01]*", MODE:="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"

# CMSIS-DAP compatible adapters ◆こちらの設定は不要かも?コメントアウトした。
#ATTRS{product}=="*CMSIS-DAP*", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
設定を反映する。
sudo udevadm trigger

これにより openocdコマンドはsudo不要となり、CLionからも扱えるようになった。 
以前の環境ではPlatformIOも使おうとしていてudevの設定をしていたのをすっかり忘れていた。

2021年10月1日金曜日

[Debian]AwesomeでSSD(NVMe)とCPUの温度表示

引き続きDebianを入れたASUS PN50のAwesome Window Managerのステタースバー表示を設定。

SSD(NVMe)とCPUの温度表示を追加した。

こうなった。

SSD(NVMe)とCPUの温度表示

ソースこちら。


compo_temp_widget = wibox.widget.textbox()
vicious.register(compo_temp_widget, vicious.widgets.hwmontemp, " $1°C" .. status_sep, 5, {"nvme"})

cpu_temp_widget =  wibox.widget.textbox()
vicious.register(cpu_temp_widget, vicious.widgets.hwmontemp, " $1°C" .. status_sep, 5, {"k10temp", 1})

温度監視対象の名称は /sys/bus/pci/drivers 配下の名称を指定する。

参考

vicious.widgets.hwmontemp


2021年9月30日木曜日

[Debian]Awesome Window ManagerでCPUの稼働状況をカラフルに表示する

Debianを入れたASUS PN50はRyzen 4700Uで、CPUコアが8個ある。 Awesome Window Managerを使っているのだけど、それぞれのコアの稼働状況がカラフルに見られると楽しいのでスクリプトを書いてみた。
負荷が高くなるほど赤くなるようにした。 負荷をかけるとピコピコ表示が変わるので良い感じ。

ステータスバー

ソースはこちら。
Lua言語は初めて使ったので、rc.lua内で使われていたfunction, if, return くらいしか知らないのですごく冗長。

  vicious = require('vicious')
-- cpu widget
cpuwidget = wibox.widget.textbox()

function load_color(rate)
    local color
    if rate >= 80 then
        colro = "#FF0000"
    elseif rate >= 70 then
        color = "#FF4000"
    elseif rate >= 60 then
        color = "#FF8000"
    elseif rate >= 50 then
        color = "#FFBF00"
    elseif rate >= 40 then
        color = "#FFFF00"
    elseif rate >= 30 then
        color = "#BFFF00"
    elseif rate >= 20 then
        color = "#80FF00"
    elseif rate >= 10 then
        color = "#40FF00"
    else
        color = "#0000FF"
    end
    return color
end

function load_html(rate)
    local color = load_color(rate)
    return string.format('<span bgcolor="%s">%d</span>', color, rate)
end

vicious.register(cpuwidget, vicious.widgets.cpu,
                 function(widget, args)
                     local all = args[1]
                     local cpu1 = args[2]
                     local cpu2 = args[3]
                     local cpu3 = args[4]
                     local cpu4 = args[5]
                     local cpu5 = args[6]
                     local cpu6 = args[7]
                     local cpu7 = args[8]
                     local cpu8 = args[9]
                     return string.format('<span color="#cccccc"> | </span>CPU <span color="#cccccc">%s (%s %s %s %s %s %s %s %s)</span><span color="#cccccc"> | </span>',
                                          load_html(all),
                                          load_html(cpu1), load_html(cpu2), load_html(cpu3), load_html(cpu4),
                                          load_html(cpu5), load_html(cpu6), load_html(cpu7), load_html(cpu8))
                 end)
  

2021年9月29日水曜日

[Debian]xrdpでキーボードレイアウトが日本語になってしまう

引き続きASUS Mini PC PN50 (Ryzen 4700U)にDebianをインストールして環境構築中。

HHKBを使っているが、xrdpを利用しリモートデスクトップで接続した場合に、キーボードのレイアウトが日本語(jp)になっていた。

次のコマンドで英語(us)レイアウトに変更できるが、リモートデスクトップに接続しなおすと、jpに戻ってしまう。

$ setxkbmap -layout us

なんとかならんのかと、/etc/xrdp 配下を眺めてみると、reconnectwm.shがあり、コメントの通りにコマンドを追加したところ、再接続してもレイアウトはusのままとなった。

#!/bin/sh

# Write procedures here you want to execute on reconnect

setxkbmap -layout us 

これで解決。


[Debian]xrdpでawesomeを利用できない

ASUS Mini PC PN50 (Ryzen 4700U)にDebianをインストールして環境構築中。

ディスプレイとキーボードを接続せずに、xrdpをインストールしてリモートデスクトップ経由で使えるようにした。

いつもWindow managerにはawesomeを利用しているので、今回もインストールしたのだけど、XFce4を先にインストールしたら、リモートデスクトップ経由では常にXFce4になり、awesomeを使うことができなくなってしまった。

$ sudo update-alternatives --install /usr/bin/x-window-manager x-window-manager /usr/bin/awesome 70

でXFce4よりも優先度を上げてみたりしたが切り替えることができなかった。

仕方がないので/etc/xrdp配下のファイルを眺めていたら、startwm.shなるファイルを発見。
このファイルの下のほうを次のように awesome固定で起動するようにしたら、awesomeが使えるようになった。

/etc/xrdp/startwm.sh

# comment out (2 lines)
#test -x /etc/X11/Xsession && exec /etc/X11/Xsession
#exec /bin/sh /etc/X11/Xsession

# add
if test -r $HOME/.xsessionrc; then
	. $HOME/.xsessionrc
fi
exec /usr/bin/awesome

いったんはこれで良し。


2021年9月25日土曜日

[Emacs]#BEGIN_SRC,#END_SRCを入力するELisp

 org mode使っていて、コードを囲う#BEGIN_SRC,#END_SRCをいちいち入力するの面倒だなと思っていたのだけど、数年越しでやっとつくった。さっさと作っておけば良かった。

何てことないコードだけどペタっとな。

(defun org-util-insert-source-section ()
  (interactive)
  (beginning-of-line)
  (insert "#+BEGIN_SRC\n")
  (insert "#+END_SRC\n")
  (forward-line -1))

(global-set-key (kbd "C-x 5 s") 'org-util-insert-source-section)

コードの通り、C-x 5 s に割り当てた。


2021年9月20日月曜日

[OCaml]merlinが参照するcmiファイルの自動更新

OCamlの開発環境として Emacs + Merlin + Tuareg を使用しているが、自ファイル以外のモジュールを参照するためには、cmiファイルを生成しなければならなかった。

dune を使用していれば、プロジェクトディレクトリ配下で

$ dune build @check

を実行すれば生成されるのだけど、ファイルの更新でいちいちこれを実行するのは面倒なのでスクリプトを作成した。

Linuxはファイル更新の検知に inotifywaitコマンドがあるのでそれを利用した。
inotifywaitコマンドはinotify-toolsパッケージにあるのでインストールしておく。

$ sudo apt install inotify-tools

スクリプトはこちら。

dune_build_check.sh

#!/usr/bin/env bash

# for test
#set -euo pipefail

USAGE(){
    echo "usage: dune_build_check.sh <dir>"
    exit 1
}

[ "$#" -eq 0 ] && USAGE >&2

cd "$1"

while : ; do
    result=$(find -type f -name '*.ml' -o -name '*.mli' | xargs inotifywait -q -e modify)
    if [ $? -eq 0 ]; then
        echo "$result"
        dune build @check
    fi
done

duneコマンド実行後に、再度、監視対象とするmlファイル、mliファイルを取り直しているので、新規ファイル追加時は既存ファイルを一度編集すればよい。

自動でやってくれるようなオプションがduneにありそうに思ったが無さそうだった。

参考

2021年9月12日日曜日

[AutoHotkey][VMware]VMware Workstation Playerのウィンドウサイズの自動調整

Remote Desktop経由で使っているせいなのか、VMware Workstation Playerのウィンドウの変更で枠を捕むのが非常にシビアでウィンドウサイズの変更に手間取っていた。

スクリプト一発でサイズ変更できないものか?と、こういう類の処理はAutoHotkeyでいけるかなーと思って調べてみたら、簡単だった。

(1)AutoHotkeyをここでダウンロードする。

(2)次のスクリプトをファイル名vmware_resize.ahkで任意の場所に保存する。

WinMove ahk_class VMPlayerFrame,,110,33,1500,1300
ExitApp

(3)VMWare Workstation Playerを起動後、ダブルクリックするなりして(2)のスクリプトを実行する。

WinMove命令の第一引数ではウィンドウのクラス名を指定している。
AutoHotkeyにはウィンドウ情報を調べるWindowSpy.ahkが付属しているので、それを使って調べるとよい。

参考

2017年4月19日水曜日

[真空管アンプ]6N6Pミニワッターの製作 (11) ラグ板の取り付けと音出し

ラグ板を取り付け、配線完了。

真空管はまだ差さないで、ドキドキしながら、初火入れ。
各部の電圧を計り、特に問題がないことを確認。

ちなみに、このような電圧になった。
AC100V電源103.0V
V+電源271.0V
出力段カソード電圧L:60.2V R:56.7V
初段カソード電圧L:1.490V R:1.526V
初段プレート電圧L:54.2V R:50.0V
出力段バイアス電圧L:-6.0V R:6.7V
特に問題なさそうなので、ヘッドホン端子とステレオ端子の配線をおこなった。

DACの出力を真空管アンプのライン入力に接続し、夜遅くなったのでヘッドホン端子にヘッドホンを接続する。アンプのスイッチオン、プレイボタンをクリック。
おぉぉ!!音がする。綺麗。
ノイズまったくなし。素晴しい!!
作って良かった。

ぼんやり光る真空管を見ていると、心が癒されます。

スピーカーのテストと裏蓋の取り付けは明日にしよう。

2017年4月16日日曜日

[真空管アンプ]6N6Pミニワッターの製作 (10) ラグ板の部品取り付け(その2)とヘッドホン端子のまわりの配線

ラグ板にコンデンサとトランジスタを取り付けた。

続いて、ヘッドホン端子まわりを配線した。
抵抗は空中配線に。配線がすこしややこしい。

ラグ板を取り付ける前に、真空管ソケットとラグ板それぞれに接続用の配線をしておく。
念のため、配線が正しいか実装図面を見ながら、再度確認。
今日、接続してしまおうかと思ったが、次回にしよう。
あと一息だ。


2017年4月15日土曜日

[真空管アンプ]6N6Pミニワッターの製作 (9) ラグ板の部品取り付け

まずは、ラグ板の端子に接続先を書いておく。
次に、ジャンパ線を取り付け。
ジャンパ線には、0.6mmのすずめっき線を使用したが、少し太すぎたかもしれない。0.5mmの方がちょうど良さそう。

ここまで作って、10uF/400Vが1つ足りないことが分かり、秋葉原まで行ってきた。
部品屋巡りをしているとついつい、色々買ってしまうなぁ。
ヘッドホンアンプでも作ろうかとオペアンプを買ってしまった。
それはさておき、今日はここまで作成した。
横から見るとこうなっている。
明日、余分な足を切ろう。

あとは大きいコンデンサを付ければ、ラグ板は完成だ。
配線間違いやイモはんだが無ければ良いのだけど。

2017年4月14日金曜日

[真空管アンプ]6N6Pミニワッターの製作 (8) 真空管ソケットまわりの配線

真空管ソケットまわりの配線と抵抗を付けた。
抵抗をまたいで、抵抗を空中配線し、少し込み入った配線となった。

やっと次からラグ板に部品取り付けだ。

2017年4月9日日曜日

[真空管アンプ]6N6Pミニワッターの製作 (7) 出力トランス、アース母線、ボリュームの配線

音量調節ボリュームの軸の切断と配線が少し面倒だった。

軸の切断

万力が無いので、ボリュームをシャーシに取り付けてから、軸をペンチで挟み、金ノコで切断。
100円ショップで金ノコのせいか、なかなか切れなかった。今度は、もう少しまともなのを買うことにしよう。
つまみを付けてみた。なかなか様になってきた。
ちなみにこのつまみは千石通商で購入。300円くらいだったかな。

音量調節ボリュームの配線

一つの端子に抵抗と導線をつけなくてはならないので、少々てこずりながら、こうなった。

今日の製作では、最終的にこうなった。まだまだ完成まで先は長い。

[真空管アンプ]6N6Pミニワッターの製作 (6) 導通確認と違う型番の真空管

昨日作成したところまでで、真空管のヒーターに電圧をかけることができるようになったので、導通確認した。

まずは真空管を差さないで導通確認する。

AC電源ケーブルのコネクタ部分で、電源スイッチを切り替えた場合の抵抗を測定する。
電源スイッチOFF → ∞
電源スイッチON → 9.1Ω
良さそうだ。

電源をつなぎ、電源スイッチON。
LEDが付いた。
各部電圧を測定。

AC電源電圧(ACインレット部分で測定)102.9V
出力トランス2次側 185V端子206.7V
出力トランス2次側 195V端子217.9V
出力トランス2次側 12.6V端子13.99V
出力トランス2次側 6.3V端子7.00V
若干電圧高めだけど、無負荷なので問題なさそう。

真空管を差してみる。

ん?右側は6H6Пはだけど、左側の真空管の型番を良く見ると、6H6П-И と表面に書かれている...
6N6Pを6本買ったのだけど、一本だけ、別の型番のものが紛れたのか。
良いのかこれ?と思ったけど、気にせず差してみる。

左: 6H6П-И
右: 6H6П
少し眺めていたら、右の6H6Пが、ずいぶん明るくなってきた。

なんだか、まずそうな雰囲気なので、電源OFF。
両方6H6Пにして、再度電源ON。
今度は、両方ともだいたい同じ明るさで問題なし。
ヒーターを付けた状態で、電圧測定。

出力トランス2次側 12.6V端子13.36V
真空管4,5番端子6.62V / 6.71V

6H6П(6N6P)と6H6П-И(6N6P-I)の違い

検索してみると、6N6P-Iのほうがスペックが良いようだ。
ヒーター電流も多い。

2つの真空管のヒーターを直列に接続した回路で、6N6Pと6N6P-Iを混在した場合、6N6Pのほうが明るくなってしまったのは、6N6P-Iのほうがヒーターの抵抗が低くて、6N6Pのほうの電圧が大きくなってしまったのが原因だろうか。

テスタ

いままで使っていたテスタがあまりにもへなちょこなアナログテスタなので、今回、SANWA デジタルマルチメータ CD772に新調した。
少し安いCCD771でも十分かと思ったが、温度測定できるのは便利かと思い、こちらを選択。デジタルテスタは、いちいち細かくレンジを選ばなくて良いし、零調整しなくてすむので便利だ。

2017年4月8日土曜日

[真空管アンプ]6N6Pミニワッターの製作 (5) 電源スイッチまわりの製作と真空管ヒーターの配線

電源スイッチまわりの製作と、真空管ヒーターの配線をした。

電源スイッチが付いた。

電源スイッチまわりの配線はこのようになった。
真空管ヒーターの配線はこうなった。

全体的に配線を長めにしてしまった。
今日はここまで。導通チェックは明日にしよう。
問題が無ければ、真空管も差してみる予定。

2017年4月2日日曜日

[真空管アンプ]6N6Pミニワッターの製作 (4) AC100Vインレットとヒューズボックスの取り付け

ノイズの影響を受けないようにするために、ツイストペアにするのがポイントですね。
はんだ付けする順番を良く考えないと、ヒューズボックスを取り付けてから、はんだ付けすることになって、やりにくくなるので注意。
電源スイッチまで取り付けようと思ったが、今日はここまで。

今回のアンプ作成では、導線の皮剥き多くて大変そうだったので、ワイヤストリッパを購入した。

このワイヤストリッパは握るところが少しペタペタする。以前に使っていたHOZANのほうが、使い心地が良かったように思う。(でも、こちらのほうが安かった。)

2017年4月1日土曜日

[真空管アンプ]6N6Pミニワッターの製作 (3) 穴開け

部品の取り付けとヘッドホン端子用のシャーシ穴開け

今のところ、こうなった。

シャーシの穴開け

シャーシにヘッドホン端子用の穴を開けた(おおよそ11.5mm)。初めて穴開けたが、以下の手順で綺麗に穴が開いた。
  1. 穴を開ける中心に、油性ペンで点を打つ。
  2. 点に合わせて、ポンチで窪みを作る。
  3. ドリルで穴開け。2.5mm→3.5mm→4.5mmの順で徐々に穴を大きくする。
  4. テーパーリーマーを使い、少しずつ穴を広げる。
  5. 毛羽立った部分をやすりで削る。
当初は手動ドリルを使うつもりであったが、どれを買おうか検索しているうちに電動ドリルが欲しくなって、結局、電動ドリルを購入した。電動ドリルもピンからキリまで、いろいろあって、どれにしようか悩んだが、機能・値段も手頃だったRYOBI CDD-1020を選んだ。


ドリル刃はダイソーで購入。装着部分が6.35mm幅の六角形のもので、いろいろなサイズのものがあったので、2.0~4.5mmのものを適当にピックアップ。このサイズは何かの規格なんだろうか。何の問題もなく、電動ドリルに装着できた。

テーパーリーマーはこれを使っている。部品の買い出しにいったついでに、秋月で買ってきた。


このように、綺麗に穴を開けることができた。


穴開けは楽しいので、もっとあちこちに穴を開けたくなる衝動が...
次回アンプを作るときはシャーシの加工も自分でやってみよう。

穴開けがうまくいって満足したので、今日はここまで。

[真空管アンプ]6N6Pミニワッターの製作 (2) 仕様

製作するミニワッターの仕様

ほぼ書籍の6N6Pを用いた製作事例の通り。
複数入力、スピーカー4Ω出力は不要なので付けない。
ヘッドホンとスピーカーの出力切り替え回路は、一般的な切り替え方式とする。

真空管6N6P
電源トランス春日無線 KmB90F
出力トランス春日無線 KA-5730
ヘッドホン出力あり
スピーカ出力8Ωのみ

KA-5730は、水平に対するコアの中心線は0度という点が、ノイズが大きくなるのではないかと心配なところである。ネット上の製作事例を検索すると、特にハムノイズは乗らなかったという情報があり、いったん気にしないで製作することにする。

電源トランスと出力トランスの購入

どちらも春日無線からネット通販で購入した。
送料、代引手数料込みで、\14,652 であった。

ヘッドホンコネクタ

絶縁タイプのスイッチ付きヘッドホンコネクタを使用。
型番不明でネットで見つけられず、秋葉原で購入(なかなか見つからず、結構探した)。
その後、分かったが、この商品のようだ。

[真空管アンプ]6N6Pミニワッターの製作 (1) はじめに

はじめに

きっかけは、つい、

これを買ってしまったからなんですよ。
このアンプの効果ですが、音質は良くなったような、何も変わらないような、どこらへんが真空管の音なのか、あまりよく分かりません。
でも、この真空管がとても気に入ってしまったのですよね。
目の前で、ほのかに光る真空管。とても心がなごみます。
本格的な真空管アンプが欲しくなったので、製品や自作キットをネットで見ているうちに、一から自作したくなりました。何か良い設計本が無いかなと、Amazonで検索してみると、ありました。

「真空管の素」。この本は、出力1W未満のミニワッターの製作ガイドになっています。回路の解説はもちろんのこと、製作に必要な器具や部品の説明が網羅されています。
どうせ自作するなら、単に組み立てるだけでなく、動作を理解してからのほうが楽しいです。何度か読んでだいたい理解しました。何度か読まないと理解が難しい箇所もありましたが、とても分かりやすく良い本です。

この本を日々読みつつ、真空管6N6Pを購入し、シャーシと部品のほとんどは頒布を利用して入手し、製作に必要な器具・部品を一通り揃えたので製作を開始しました。

2016年6月8日水曜日

[OCaml]cursesで文字化け

OCamlでcursesを使ってピコピコゲームでも作ろうかと思い、以前にcursesを使ったコードを動かしてみたら、 日本語が文字化けするようになっていた。
Cライブラリのsetlocale(LC_ALL,"")を実行した後に、cursesを使えば文字化けしないことが分かった。
setlocale関数の呼び出しは ctypesを使うと簡単に呼び出すことができる。
opamでパケージが用意されているので、以下のコマンドでインストールできる。
$ opam install ctypes ctypes-foreign

コードはこちら。
open Core.Std
open Ctypes
open PosixTypes
open Foreign

let time = foreign "time" (ptr time_t @-> returning time_t)

(* char *setlocale(int category, const char *locale); *)
let setlocale = foreign "setlocale" (int @-> string @-> returning string)

let () =
  let locale_str = setlocale 6(*LC_ALL*) "" in
  let module C = Curses in
  let main_window = C.initscr () in
  let err = C.mvwaddstr main_window 10 2 "hello, world!" in
  let err = C.mvwaddstr main_window 11 2 "こんにちは、世界!" in
  let err = C.refresh () in
  Unix.sleep 5;
  C.endwin ();
  printf "locale_str=%s\n" locale_str

ビルドはお手軽なcorebuildを使った。
$ corebuild -pkg curses -pkg ctypes.foreign sample.native
Debian Jessie 64bit では、LC_ALL = 6 だったので、直接コード中に書いたが、このようなヘッダで定義されている定数はどのように定義するのが正しいのだろうか。

参考