はじめに
『MSX0 Stack』付属の IoT BASIC サンプルを『Turbo Pascal』へ移植してみます。
DHT_KNJ.BAS
◆温度湿度センサ
項目 | 説明 |
---|---|
概要 | 温度湿度センサから取得した値を表示します。 |
ファイル名 | DHT_KNJ.BAS |
対応デバイス | DHT11 (水色) DHT20 (黒色) |
コメント | MSX0 起動時に Port A に DHT20 が接続されていれば DHT20 を利用します。そうでなければ Port C に DHT11 が接続されている想定で動作します。 |
このサンプルを動作させるには外部センサーが必要です。
See also:
MSX0 Stack での挙動
まず事前にセンサーをつないでおきます。
右中央のセンサーが温湿度センサーなのですが、 『Grove Beginner Kit for Arduino』の製造ロットによって、センサーの種類と MSX0 への接続先が異なります。具体的には 2022/04 以降製造分に DHT20 が付属するようです。
センサー | 接続方法 | Grove ポート |
---|---|---|
[D3] DHT11 (水色) | Digital | Port C (水色) |
[I2C] DHT20 (黒) | I2C | Port A (赤) |
『Grove Beginner Kit for MSX0』には DHT20 が付属します。
DHT_KNJ.BAS
をロードして、
実行してみました。
プログラムは〔Ctrl〕+〔Stop〕(リモートコントロールパネルからは〔Ctrl〕+〔F12〕)で中断できます。
See also:
Turbo Pascal へ移植
別途、MDL-LIB と SYSUTILS.LIB
、IOT.LIB
が必要です。
DHT_ANK.PAS
漢字はおいといて、とりあえず ANK で表示できるものを作ってみましょう。
program DHT_ANK;
{$I MDLLIB.LIB}
{$I SYSUTILS.LIB}
{$I IOT.LIB}
type
Str8 = string[8];
var
A: Integer;
function GetTime: Str8;
var
i: byte;
s: Str8;
begin
s := '';
for i:=0 to 5 do
begin
if i in [2, 4] then
s := ':' + s;
LibRegs.C := i;
SubROM($01F5);
s := Chr($30 + LibRegs.A) + s;
end;
GetTime := s;
end;
begin
ClrScr;
while not KeyPressed do
begin
GotoXY(1, 4);
Writeln('TIME : ', GetTime);
A := IoTGetInt('device/dht/humidity');
Writeln('HUM. : ', A, '%');
A := IoTGetInt('device/dht/temperature');
Writeln('TEMP.: ', A, #$DF'C');
Delay(100);
end;
end.
実行してみました。
センサーが正しく接続されていれば温湿度で値が変動します。
任意のキーで中断できます。
解説 (DHT_ANK.PAS)
GetTime()
MDL-LIB には時刻を持ってくるルーチンが存在しないため、SubROM()
で CLOCK-IC にアクセスし、値を読み出しています。後日、日付時刻用のライブラリを作るかもしれません。
GotoXY()
GotoXY()
は 1 オリジンなので、X / Y 座標が +1 されています。
#$DF
文字 0xDF
は Shift_JIS の半角カナ半濁点 (゚
) です。CP/M-80 版の Turbo Pascal は 8bit 文字が通らないので、ソースコード中にカナや漢字は使えません 1。ですが、#$
を使った制御文字で記述する事は可能です。
See also:
- 6章 CLOCKとバッテリバックアップ・メモリ - 6部 標準周辺機器のアクセス (MSX Datapack wiki化計画)
- 8bit 文字 (CP/M 80 版) - Turbo Pascal 3.0 の使い方 (Qiita)
DHT_KNJ.PAS
センサー部分は動いたので、漢字表示にチャレンジしてみます。
BASIC プログラム中の CALL KANJI
と CALL ANK
は KMODE
相当なので、漢字ドライバの拡張 BIOS をコールすれば実現できます。別途、EXTBIOS.LIB
が必要です。
・BASIC で初回実行時の CALL KANJI
は漢字ドライバの読み込み&漢字モード変更です。
・BASIC で2回目以降実行時の CALL KANJI
や CALL ANK
は漢字モード変更です。
・MSX-DOS2 での KMODE
実行は漢字モード変更です。漢字ドライバの読み込みを行うコマンドは存在しません。
漢字ドライバが組み込まれると TPA (Transient Program Area) が減少するのですが、デフォルトのままコンパイルすると、TPA が減少する前の情報を参照してしまうため、漢字モードで実行形式ファイル (*.COM
) を実行するとメモリ不足のエラーになります。
BASIC で事前に CALL KANJI
を実行しなかった場合には、コンパイラオプションで End Address
を CF42 以下にすればメモリ不足にはなりません。
program DHT_KNJ;
{$I MDLLIB.LIB}
{$I EXTBIOS.LIB}
{$I SYSUTILS.LIB}
{$I IOT.LIB}
type
Str8 = string[8];
var
A: Integer;
C, K: Byte;
function GetTime: Str8;
var
i: byte;
s: Str8;
begin
s := '';
for i:=0 to 5 do
begin
if i in [2, 4] then
s := ':' + s;
LibRegs.C := i;
SubROM($01F5);
s := Chr($30 + LibRegs.A) + s;
end;
GetTime := s;
end;
begin
C := sys_textwidth;
K := GetKMode;
SetKMode(1);
sys_textwidth := 26;
ClrScr;
while not KeyPressed do
begin
GotoXY(1, 4);
Writeln(#$8E#$9E#$8D#$8F#$81#$40#$81#$40, GetTime);
Writeln;
A := IoTGetInt('device/dht/humidity');
Writeln(#$8E#$BC#$93#$78#$81#$40#$81#$40, A, ' '#$81#$93);
Writeln;
A := IoTGetInt('device/dht/temperature');
Writeln(#$89#$B7#$93#$78#$81#$40#$81#$40, A, ' '#$81#$8E);
Writeln;
Delay(100);
end;
SetKMode(K);
sys_textwidth := C;
end.
実行してみました。
解説 (DHT_KNJ.PAS)
GetKMode() / SetKMode()
EXTBIOS.LIB
にある拡張 BIOS をコールして現在の漢字モードを取得/設定するルーチンです。プログラム開始時に漢字モードを取得して、終了時に戻しています。
一行文字数
漢字モード同様、プログラム開始時に一行文字数を取得して、終了時に戻しています。
See also:
おわりに
漢字モードについてはもう少し調査が必要かも。最悪、バッチファイルでどうにかできるからいいかな (^^;A