したらばTOP ■掲示板に戻る■ 全部 1-100 最新50 | |

■■■20レス以内で済むF-BASICの質問はこちらへ■■■

552なりぞう:2012/06/12(火) 20:35:10
F-BASICは、linux mintやUbuntuなどのUNIX系で使えますか?
そのままでは多分、使えないと思うけど、wineなどのソフトを使っても駄目ですか?

553旧人類:2012/06/30(土) 11:16:59
F−Fasicを使用している方でご存知でしたら教えてください。 

「 knj$() で外字コード(jis &H7f21〜) を表示する方法をご存知ありませんか」

どこか設定がおかしいのでしよう、OS は XP です。
N88 の時代より Baic を愛用しております、簡単でそこそこの速度で
使いやすいコンパイラと思っておりまが、消えて行くのが寂しい気がします。

554名無しさん:2012/09/14(金) 08:07:19
>>553
原因はわからないのですが、参考まで。

Windowsの アクセサリ - 外字エディタ を起動して、外字のフォントが表示されるで
しょうか?
あと、外字のリンクが特定の「すべてのフォント」でなく特定のフォントにリンクされて
いるとダメなのかも。
外字エディタのファイル(F) - フォントのリンク で確認してみてください。

外字エディタで作成される既定の外字フォントのファイル名はEUDC.TTEとEUDC.EUFなので、
もしかするとF-BASICはこのファイル名で登録した外字フォントしか対応できないのかも・・。


もし、EUDC.TTEとECDC.EUFのファイルを他から直接コピーしてきたのでしたら、
Windowsが使用中のため、コピーに失敗(ECDC.EUFの方)する場合があります。
その場合、IMEの文字一覧など、外字が正常に表示されるが、外字エディタでは
表示されないという現象が発生します。

555ひろ:2012/09/26(水) 00:20:54
No544で投稿したひろです。
未だにODBCがよくわかりません
FBASICV63のサンプルでODBC.MAKを使ってMS-SQL-Serverに接続できません
'========================================================================
'= 接続/クエリ =
'========================================================================
' 入力:OBJ 結果を設定するコントロール(リストボックス)
' 入力:DATANAME$ データベース名
' 入力:SQL_COMMAND$ SQLコマンド
function EXEC_ODBC( OBJ as object, DATANAME$, SQL_COMMAND$ )
var HDBC as long ' DB HANDLE
var HSTMT as long ' SQL Statement HANDLE
var RCODE as integer ' 復帰コード

' 初期化
if SQL_SUCCESS<>SQLALLOCCONNECT( HENV, HDBC ) then goto *_ERR
if SQL_SUCCESS<>SQLCONNECT( HDBC, DATANAME$, SQL_NTS, "", SQL_NTS, "", SQLNTS ) then goto *_ERR   ->ここで落ちる
if SQL_SUCCESS<>SQLALLOCSTMT( HDBC, HSTMT ) then goto *_ERR
' SQLコマンドの実行
if SQL_SUCCESS<>SQLEXECDIRECT( HSTMT, SQL_COMMAND$, SQL_NTS ) then goto *_ERR

どなたか教えてください。
ODBCの設定はしているつもりです。

556名無しさん:2012/09/26(水) 08:50:52
>>555

SQLCONNECT に渡すパラメータの定義は次のようになっています。
HDBC& 接続ハンドル
SZDSN$ データソース名 <-- DATANAME$
CBDSN% データソース名の文字数 またはSQL_NTS指定
SZUID$ 接続するデータベースのユーザーIDの文字列
CBUID% ユーザーIDの文字数 またはSQL_NTS指定
SZAUTHSTR$ パスワード(認証用文字列)
CBAUTHSTR% パスワードの文字数 またはSQL_NTS指定


まず、DATANAME$ 文字列変数の内容がODBCの設定をされたデータソース名かどうか
確認してみてください。
(サンプルのフォームにデータソース名とODBCドライバ名が表示されているはず)

if SQL_SUCCESS<>SQLCONNECT( HDBC, DATANAME$, SQL_NTS, "", ・・・

サンプル(ODBC.MAK)での接続先データベースはMS-Access (*.MDB)なので、
ユーザーIDとパスワードの文字列はなし("")でよいのですが、
MS-SQL ServerではユーザーIDの指定が必要だと思いますのでサンプルを修正します。

<例> if SQL_SUCCESS<>SQLCONNECT( HDBC, DATANAME$, SQL_NTS, "UserID", ・・・

サンプルではSQLCONNECT に渡す値の最後が「SQLNTS」となっていますが、
これはサンプルの誤りで、SQL_NTSだと思います。
※SQL_NTSは、渡した文字列がNULL文字で終了する文字列であると意味するそうです。

SQLCONNECTが返す値がエラー(SQL_SUCCESS_WITH_INFOまたはSQL_ERROR)の場合
SQLERRORで(ODBC Ver3以降はSQLGetDiagRecを使います)エラーの詳細情報が
取得できます。
FBASICのサンプルはODBC Ver2.0のときのもので、
SQLGetDiagRecの関数宣言はサンプル中のODBC.BIにはありません。

557ひろ:2012/09/28(金) 20:44:29
名無しさん さっそくご教授いただきましてありがとうございます。
SQLNTSはSQL_NTSに変えてみましたがダメでした。
いろいろやってみましたが結局いまだよくわかりません。
DSNの設定での接続テストまではOKなのですが......

558556:2012/09/29(土) 03:33:03
サンプルのSQLNTSの誤りは、未定義変数として初期値ゼロとなり、
パスワードの文字数がゼロと指定したことになります。
パスワードが不要な場合は影響しないことになります。

559556:2012/09/29(土) 04:09:48
>>557
ODBCデータソースの設定のほうに「トレース」機能があります。
ODBCドライバに発行された命令の記録(ログ)をテキストファイルに出力する機能です。
この機能をONしてから実行し、出力されたテキストファイルの中を見ればODBCドライバが
返したエラーがわかると思います。


使用後は必ず「トレース」機能をOFFにして、出力されたテキストファイルを削除
してください。(実行速度が遅くなるなど、後でトラブルになるため。)

560旧人類:2012/10/03(水) 01:08:22
「名無しさん」有難う御座います。
フォントはフリーソフトの「外字コピー屋さん」を利用して駆動時に現フォントを保存して、
使用フォント(外字も含め)をコピーして立ち上がるようにしています、
無論該当ソフトの終了時には逆の動作で元のフォント状態に戻しています。
 (ただ停電の時の復元が少し手間取りますが)

「 knj$() で外字コード(jis &H7f21〜) を表示する」ことは諦めました、
Win95でのFB−Ver6.0 でも同様ですから、多分もともと機能がないのではと。

現在の私の解決策は エディタでIMEより使用する外字を配列文字変数にコピーして
その変数を表示する(symbol or ?)、配列の1番が jis &H7f21 に該当する。
data でソースプログラムに書き込むとか別ファイルで保存するとかしています。
APIを使用するより、こんな馬鹿げた方法が簡単な気がします。
何かいい方法があったら教えてください。

ところで TOKOさんのホームページ[ProgramTips]は閉鎖です移転ですか、
ご存知なら教えてください、APIを随分と参考にさせて頂きましたが。

561554:2012/10/04(木) 02:47:31
>>560 , 553

 「外字コピー屋さん」のWebページのほうを見させていただきました。
勉強になりました。

>
> Win95でのFB−Ver6.0 でも同様ですから、多分もともと機能がないのではと。
>
 Windows 95上でもだめだったとは..。
F-BASICのヘルプでは、knj$()関数で外字を印字できるような記述なのですが..。

 実験してみるとknj$()関数は空文字[""]を返してきました。
対になるjis()関数のほうは動作しました。
また、IMEで外字を文字列定数としてプログラムソースに直接記入すれば、
表示できました。フォント別の外字リンクをされている場合でも表示できました。

 なので、おっしゃるような方法をとるのがやはり簡単ということになります。

 プログラムソースに外字を直接記入してしまうのはあまりよくないので、
knj$()関数をお使いになられようとされたのでしょう。
 ここはknj$()関数を置き換えるように独自の関数を作り、その関数内で
直接記入した外字の文字列(配列)から取り出して返す処理をするのがよいと思います。
外字でない通常のjisコードのときは内部でF-BASIC本来のknj$()関数に
渡して処理させれば、knj$()関数を置き換えられるので可用性が高まります。

562554:2012/10/04(木) 06:04:07
 簡単な方法を忘れてました。
JISコードによるknj$()関数がだめなら、
Shift-JISコードで、上位・下位コードに分けて文字をつなげば
表示できます。

例: chr$(&HF0)+chr$(&H40)

563旧人類:2012/10/20(土) 00:39:48
554さん 
暫く不在していて、確認が遅れてすみません。
なるほど、こんな簡単な方法があるとは思いませんでした。
サブ画面(PICTURE)に自作外字を表示して選択する、方法に戻します。
参考になりもした、有難う御座いました、余分なファイルが減りました。

関連することですが、方法があれば教えてください。
「エデッタ画面でIMEを使用した時にIME側のフォント名を取得する方法」
IMEでは別のフォント名選択でき、そのフォントの文字・記号を選択画面に
表示はしますが、IMEで文字・記号をクリックした時に、そのフォント名を
取得できれば前記の問題もすべて解決するのですが。

564554:2012/10/20(土) 07:24:46
>>560

> ところで TOKOさんのホームページ[ProgramTips]は閉鎖です移転ですか、


こちらでしょうか。

「F-Basic Programming Tips」
[URL] tokovalue.jp

>>563
的を外しているかもしれませんが、ひとつ。
IMEのAPIで、
ImmGetContext()でコンテキストのハンドルを取得。

ImmGetCompositionFont()で取得したLOGFONT 構造体の中に
変換中に表示するフォント名があります。

変換中に表示するフォントの変更は ImmSetCompositionFont()

565554:2012/10/20(土) 07:34:39
>>563
役に立つかどうか、むりやりな方法をひとつ考えてみました。
「IMEの文字パッド(文字一覧)で表示されている(いた)フォント名の取得方法」。

FindWindowEx()で[ひとつめの]IMEの文字パッドのウィンドウを探します。

親ウィンドウのハンドル: NULL (0&)
子ウィンドウのハンドル: 初期値は NULL (0&)
クラス名:"msime98imepad" <--注:IMEのバージョンやOFFICE IMEでは違うかも。

見つかったウィンドウのプロセスIDをGetWindowThreadProcessId()で取得し、
自分のアプリのプロセスIDと比較して一致しなければ他のアプリ用なので、
FindWindowEx()で次を探します。見つかるか戻り値がNULLになるまで繰り返します。

子ウィンドウのハンドル: 先ほど見つかったウィンドウのハンドルに変更

自分のアプリのIMEの文字パッドのウィンドウが見つかったら、次の処理。

FindWindowEx()で子ウインドウを探します。

親ウィンドウのハンドル: 見つかったIMEの文字パッドのハンドル
子ウィンドウのハンドル: NULL (0&)
子ウインドウのクラス名:"ACPAD"

さらに、クラス"ACPAD"の子ウインドウ(コンボボックス)をFindWindowEx()で順次探します。

親ウィンドウのハンドル: 子ウィンドウのクラス"ACPAD"のハンドル
子ウィンドウのハンドル: NULL (0&) または 前回見つけたウィンドウのハンドル
子ウインドウのクラス名:"ComboBox"

(おそらく2つめの)コンボボックスにGetWindowText()でテキストを取得すれば、
IMEの文字パッドで表示されているフォント名が得られます。

566旧人類:2012/11/01(木) 00:47:04
554 さん
TOKOさんのホームページ[ProgramTips] ですが、
当方の「お気に入り」のURLがなぜか書き変わってました、ちゃんと存在してました。
すみませんでした、よく利用してたページなので助かりました。

567旧人類:2012/11/01(木) 01:02:28
554 さん 
追記 「フォント名の取得」の件ですが、成功したら書き込みます、結果は多忙で少し
   時間がかかるかも。

568ねじ:2013/08/25(日) 08:27:51
教えてください。F-BASIC V6.3のソフトを手に入れたいのですが、無理ですかね。

569はぜ:2013/10/23(水) 10:49:41
 はじめまして。PC8001からので移植して 行番号などそのまま
で使っています。
 仕事のデータ シーケンス 一件 12変数の 1万ぐらいを ワードパッド
で保存して やりとりしていますが、読み込むとEOFがききません。
 結局 データのひとつを指標にして 終わりを認識させているので
すが、どういった障害があるのでしょうか。
 同じ型のデータで 少量ならばEOFでおわるのですが。
 どなたか教えいていただければ幸いです。

570名無しさん:2013/10/24(木) 04:49:15
入力命令が INPUT# か LINE INPUT# かで違いますが、

EOF(関数)が効かないということは INPUT# でデータ中の項目の区切りが
途中でずれたということが考えられます。
区切り記号は半角のコンマ、コロンと空白。(空白は数値データで)

また、ファイルの終端であることを示すEOFコードとして
制御コード(16進数で1Ah)がありますが、

Windowsアプリ(メモ帳・ワードパッドやExcelなど)ではEOFコードは
字形がない文字として表示(半角の中点「・」)され、文字として扱わ
れるがゆえに、ワードパッドなどで編集するデータ中にEOFコードが
紛れ込んでいると、問題発生の原因となります。

571はぜ:2013/10/25(金) 09:34:12
さっそくのご返答ありがとうございます。

 LINE INPUT#はつかっていません。データも何度も確認しています。
 読み込むと同時に画面に表示させていますが、 
 最後まで正確に読んでくれますが、最後尾 どうしても 「変数の型
とファイル内のデータ形式があっていません。」がでてしまいます。

 一度 データ量を段階的に減らしたりして試してみたいと思います。
 何か 量的な制限があるような気もしますので。

 しばらく 時間をいただきます。

 目的としては 全体のファイルに 当日出たデータを 自動的にくっつ
けたく、今は、ワードパッドで手動で結合しているのですが、うまい方法が
ないか思考錯誤しています。

572570:2013/10/26(土) 03:13:43
エラー番号:58「変数の型とファイル内のデータの形式が合っていません 」
ですか...。
INPUT# 命令で「数値型」の変数を指定している場合に起きるので
普通にありがちな可能性としては、
ファイルの末尾に空行(改行のみ)や空白文字がある場合とか。

※F-BASICの障害修正パッチのダウンロード (念のため記述)
ttp://www.fmworld.net/product/soft/fbasic/download/


F-BASICのFILECOPY命令では、テキストファイルの結合によるデータ蓄積は
できないので、別の方法としてはバッチ(*.BAT/*.cmd)ファイルを作って
それをSHELL 命令で呼び出すかバッチコマンド一行を直接指定する。

バッチの例) FILE1の末尾にFILE2の内容を追加(FILE2はそのまま残る)
注:失敗するとFILE1などを消失するので事前のバックアップは必須。

COPY /A FILE1.TXT+FILE2.TXT
例2)ファイルの内容を結合した結果をFILE3で新たに作成
COPY /A FILE1.TXT+FILE2.TXT FILE3.TXT

/Aオプションはテキストモード、つまり指定した各ファイルのEOFコードを
認識して処理、末尾にEOFコードを付加します。

かわりに /Bオプションを指定したときにはEOFコードはなにも処理されない
ので実質、EOFコードが【必ず無い】ファイル同士を扱うときのみ指定可能。

573名無しさん:2013/10/26(土) 19:26:17
F-BASIC V6.3 (U003適用済)で単純なテストを実施。

○実施テスト内容
データ内容:12345678,abc, ・・・のくりかえし定型
データ形式:カンマ区切りで「数値,文字列」を12組の計24項目で改行
データ末尾にEOFコードはなし

データ量:3万件(行) 、ファイル総容量 4.49MiB(4,710,000バイト)

データ読み込み終了条件:EOF()関数による検出
データ読み込み内容:数値変数,文字列変数の項順で12組の計24変数に一回で読む
input #1,DTL#(1),DTA$(1), ・・・ DTL#(12),DTA$(12)


実施内容:データ量を2万件および3万件(行)のファイルに対して実施。
実施環境:実行中の空きメモリ(RAM):約80MiB

結果確認方法:
・読み込み回数のカウント値採取
・EOF()関数で検出で終了後、再度input#命令発行でエラー発生(err 54)を確認。

結果:異常検出なし (ランタイム使用型・独立型のコンパイル共に)

574はぜ:2013/10/28(月) 10:01:36
  丁寧な実験 と 提案 ありがとうございます。

 当方 Win 7 で F-basicは ver6.0 L10 とありました。
 プログラムは 下記 です
 eof が 効かないので 232行で 通し番号を拾って 読み込み終わりにしています。
念のため231行で 表示していますが データはきちんと最後までよんでいます。
 
小生 PC8001の名を出したように 高年ですので 基本的なBASIC言語以外は
わかりませんし 挑戦する気力もないのでご容赦ください。

 DOS-V から WIN へ移植するのに 7年もかかりました。
 
 また 解凍など要するアップデイトと 言うんでしょうか ちよっと怖くて
とてもできません。

 今は 少しでも 自動化しようと試みてはいますが。


226 open "tcz2013" for input as #2 'datdat10
227 ta!=0
228 while not eof(2)
229 ta!=ta!+1
230 input #2,DCO#(TA!),DHI(TA!),DNM!(TA!),DDA$(TA!),DNA$(TA!),DBL$(TA!),DNM$(TA!),DNO(TA!),DPR!(TA!),DPZ!(TA!),DCP(TA!),DPL(TA!)
231 'print DCO#(TA!),DHI(TA!),DNM!(TA!),DDA$(TA!),DNA$(TA!),DBL$(TA!),DNM$(TA!),DNO(TA!),DPR!(TA!),DPZ!(TA!),DCP(TA!),DPL(TA!)
232 'if DNM!(TA!)=81118 then 236 'テータの終わりを認識してくれるかどうか
235 wend
236 close #2

575570:2013/10/29(火) 02:22:57
バージョン情報の詳細はF-BASICを起動してメニューの[ヘルプ(H)]−[バージョン情報(A)]
大きく表示されたF-BASICのロゴの左下に 「V6.0L10」の後にあるU00xの有無で
アップデート適用有無が確認できます。V6.0ではV6.0L10 U002が最終版です。

とりあえずF-BASIC 6.0用のアップデートパックをダウンロードしてその中にある
UPDATE.TXT(障害修正一覧の項)を見てみました。
斜め読みですがEOFの件に該当しそうなものは見当たりませんでした。


Windows 7の上でF-BASIC V6.0L10ですか・・。
効果があるかはわかりませんが、Windows 7の機能の
「アプリケーション互換モード」を設定してみてはどうでょうか。

F-BASICで作成(翻訳/コンパイル)した実行ファイルに次の操作を行う。

1. 実行ファイルをマウスで右クリックしてプロパティを選択。
2. 表示されたウィンドウの中の「互換性」のタブを選択。
3. [互換モード]という囲みの中の
 3-1.「□互換モードでこのプログラムを実行する」にチェックを入れる。
 3-2.すぐ下のボックスをクリックして一覧の中から「Windows 98/Windows Me」を選ぶ。
4.[適用(A)]ボタンを左クリック。[OK]ボタンを左クリックして閉じる。

*設定を解除するときは3-1. でチェックを外す操作をしてください。(3-2.は不要)

576570:2013/10/29(火) 02:51:22
最後のデータまで正常に読めているのにかかわらず
EOF()が効かないという障害ということで、
お見せいただいたプログラムに障害回避の追加を試みます。

△var DTEST$

open "tcz2013" for input as #2 'datdat10
△open "tcz2013" for input as #3 'datdat10を二度開く(LINE INPUT用)
TA!=0
while not eof(2)
△line input #3, DTEST$
△if len(trim$(DTEST$))<12 then print "Over!",TA!:exit 'データの終わりをオーバー?
TA!=TA!+1
input #2,DCO#(TA!),DHI(TA!),DNM!(TA!),DDA$(TA!),DNA$(TA!),DBL$(TA!),DNM$(TA!),DNO(TA!),DPR!(TA!),DPZ!(TA!),DCP(TA!),DPL(TA!)
'print DCO#(TA!),DHI(TA!),DNM!(TA!),DDA$(TA!),DNA$(TA!),DBL$(TA!),DNM$(TA!),DNO(TA!),DPR!(TA!),DPZ!(TA!),DCP(TA!),DPL(TA!)
'if DNM!(TA!)=81118 then exit 'テータの終わりを認識してくれるかどうか
wend
close #2
△close #3

補足:
・△がある行を追加しました。
・追加したif文の、[DTEST$変数の長さ<12]とは、1行12項目のデータは、
区切りの文字だけでも11(桁)あるのだから・・・。
・「then 236」(236行へGO TO)は「while - wendループの外へ出る」と解釈し、
exit命令に置き換えました。

577はぜ:2013/10/30(水) 10:30:32
試みてみました。うまくいきました。
 ありがとうございます。感謝申し上げます。

 長年の停滞が解除されて、よりよいソフトにできそうです。
 
 自分で自由に作れるソフトはすばらしいものですね。しかし 今は
頭の奥が痛くなるだけではありますが。

 重ねて御礼申し上げます。

578名無しさん:2013/10/31(木) 03:28:51
>>571
参考プログラムです。機会があればどうぞ。

'**** FILE1の末尾にFILE2の内容(テキストデータ)を追加する。
var L1 as long '読み込んだ行数
var L2 as long '実際に追記した行数
var DTEST$

open "FILE1.TXT" for append as #2 'このファイルに追記する
open "FILE2.TXT" for input as #3 '読み込むデータ
L1=0
L2=0
while not eof(3)
L1=L1+1
if L1>=20000& then print "LoopBreak!":exit '***EOFが効かない?
line input #3, DTEST$
if not (len(trim$(DTEST$))<12) then '空行等でなければ出力
L2=L2+1
print #2,DTEST$
endif
wend
close #2
close #3
'**** F-BASICにより自動付加されたファイル末尾のEOFコードを削除する。
DTEST$=space$(1) '読み込むバイト数の桁の領域確保
open "FILE1.TXT" for binio as #2 '対象(※追記したファイル)
if lof(2)<>0 then 'ファイルの内容が空でないこと
seek #2,-1,2 '***mode 2:ファイルの末尾から -n移動
fread #2,DTEST$ '確認のため一度読み込む
if DTEST$=chr$(&H1A) then 'EOFコードかどうか確認する
seek #2,-1,2 '再度、移動する(※EOFコードの位置)
truncate #2 '現在の位置からファイルの内容を切り捨てる
endif
endif
close #2

579はぜ:2013/12/14(土) 09:48:25
 質問です

 これは 別に不都合を感じてはいないのですが、MX VISTA 7と
すすむほどに BASICの表示枠が だんだん 小さくなっていきます。
 
 そんなものでしょうか。

580570:2013/12/16(月) 06:27:48
>>BASICの表示枠が だんだん 小さくなっていきます。

1. F-BASICのプログラム編集画面の文字が小さいという場合
メニュー:表示(V) - オプション(O) で
表示されたダイアログの[エディタ]タブの中の
フォント(F)とサイズ(S)の、設定がおそらく

「FixedSys」になっていてサイズが選べないと思います。

 これを「MS ゴシック」や「MS 明朝」などに変更すれば
サイズを選べるようになります。
選択したサイズによっては、表示がくずれるなどの問題が起きることが
あるので、その場合は他のサイズに選びなおしてください。
 なお、「MS Pゴシック」や「MS P明朝」はプロポーショナルフォント
ですので、避けたほうがよいでしょう。


2. F-BASICで作成したプログラムの実行画面の場合

旧来の(DOSや8ビットパソコン上)のBASICと同等な「手続き型」で作成した
場合、画面の大きさや背景色などの定義情報がないので新たに
フォームの編集が必要です。
リソースファイル(.RC)を作成してその中の
フォーム − 「MAINFORM」を開き、MAINFORMのプロパティ画面を
表示させて、フォントの項目を変更します。

詳細については、富士通のサポートページの「活用ガイド」
http://www.fmworld.net/product/soft/fbasic/gpib/
にあるワンポイントレッスン集の、
  第一回「実行画面を大きくしよう」 (PDF形式)

この文書(lesson_1.pdf)を表示するかダウンロードして
ご覧ください。

581はぜ:2013/12/19(木) 10:04:41
途中経過報告です

 ありがとうございます。うまくいきました。実行枠です。すみません。

 ただ、

 ①表示速度が かすかに 遅くなる。
 ②実行枠ですが、繊細で、いろいろボタンを押したりすると戻ったりしてしまう。
 ③プログラムの実行するたびに、変更されたモジュールが・・・と出る
 ④何もしていない ほかのプログラムまで ③とおなじになる。

                 以上こんな現象がでます。

582570:2013/12/20(金) 09:32:13
>>581
実行枠が不安定ということには複数の問題がからんでいると思います。
一つづつ解決していきましょう。

まずは、リソースファイル(.RC)のフォームのブロパティ設定から。
F-BASICで、作成済みのリソースファイル(.RC)を開き、フォーム「MAINFORM」を
開いて画面に表示させます。

(a): フォームの「プロパティ」ダイアログを表示させてプロパティ各項目を
設定・確認していきます。

・ダイアログの中の表示内容(P):【クライアントエリア】に切り替え、
マッピングモードを確認・設定します。標準は「テキストモード」です。
テキスト行数とテキスト桁数を確認します。(標準値は80桁、24行)

・ダイアログの中の表示内容(P):【フォント】に切り替え、
フォントとフォントのサイズを任意に設定。

・ダイアログの中の表示内容(P):【フレーム】に切り替え、
ウィンドウの初期位置の項目を設定します。(初期値は「ユーザー設定」)
水平スクロールと垂直スクロールを「あり」に変更。(*F-BASICの初期動作に合わせた。)

・ダイアログの中の表示内容(P):【基本スタイル】に切り替え、
位置X座標および位置Y座標をゼロに設定。(これは任意です。F-BASICの初期動作に合わせた。)
※これをゼロにすると大抵、F-BASIC本体のメニュー部と重なって操作のじゃまになりますが・・。


(b): ここで、フォームの画面枠の大きさを再設定します。表示されているMAINFORMの
枠の右下隅をマウスでドラッグして枠のサイズを縦横とも動く最大まで伸ばします。
(一度左上にドラッグして少し小さくしてから伸ばすとよい)
 MAINFORMの枠にある垂直・水平スクロールバーが消えます。
*別の方法としてはプロパティ【基本スタイル】のサイズの各項に、
わざと大きな数字(3000とか)を入力して自動訂正により枠のサイズを最大にする方法があります。

(c): リソースファイル(.RC)を上書き保存します。

 任意のプログラムにリソースファイル(.RC)を登録して(再)翻訳・実行して
動作を確認します。

583570:2013/12/20(金) 09:40:52
>>581
「変更されたモジュールが・・・」のメッセージが《ほかのプログラムまで》出る件ですが、

リソースファイル(.RC)を登録したことで出るようになったものと思います。

 旧来のBASICの多くは「インタプリタ」方式でしたがF-BASICは
「コンパイラ」方式ですのでプログラムを実行する前に、
コンパイル(F-BASICでいう翻訳)によって実行可能形式( .EXE)のファイルを作ります。

 F-BASIC本体の中から、なんらかのプログラムを実行させると、
まず、コンパイル(翻訳)するべきかどうか個々のファイル(.BASや.RCなど)ごとに
F-BASICが判断して、必要なときは確認のメッセージを出すという内部動作になります。

リソースファイル(.RC)を登録したことで、作成した(一連の)プログラムに変更点が有る
という判断になるため、メッセージが出されています。

続けて過去に作成したほかのプログラムを開いて実行しようとしても同じ結果となります。
*実行可能形式ファイル(.EXE)よりリソースファイル(.RC/.RES)の方の最終更新日付が新しい

 リソースファイル(.RC)の登録内容はF-BASIC本体に記憶されるのではなく、
再度のコンパイル(翻訳)で再作成された個々の実行可能プログラム(.EXE)の
中に埋め込まれます。
 また、F-BASIC本体を再起動すると、リソースファイル(.RC)の登録は解除されてしまいます。
(メニュー:プロジェクト(P) - 環境(E) のダイアログ設定内容)

 このため、リソースファイル(.RC)による画面枠の変更内容が実行開始時に反映されたり
されなかったり、解除しても元に戻らないといった現象が発生します。
 この問題を軽減するためにはプロジェクトファイル(*.MAK)を新たに作成し、これを通じて
F-BASICに認識させる必要があります。(後述)

584570:2013/12/20(金) 09:55:03
>>581
 リソースファイル(.RC)を登録したことにより、
「変更されたモジュールが・・・」の翻訳を促すメッセージが、
BASICプログラムを変更していないのにもかかわらず、毎回出るといった問題についてですが、
これへの対処にはプロジェクトファイル(*.MAK)を一つの実行プログラム毎に作成する必要が
あります。

プロジェクトファイル(*.MAK)の役目はおおまかに、
 ・メニュー:プロジェクト(P) - 環境(E) のダイアログで設定する内容を記録する
 ・一つの実行可能形式ファイル(.EXE)を作るために必要なソースファイル等の一覧を記録
   a. (一つまたは複数の)BASICソースプログラム(.BAS、.SUB)
   b. リソースファイル(.RC)およびアイコンファイルやその他のファイル
   c. 必要な追加ライブラリやオブジェクトファイル
 ・個々のファイルを再コンパイル(翻訳)して実行可能形式ファイルを再作成する
  かどうかの判断材料にする

■プロジェクトファイルの手順説明
 プロジェクトファイル関係について、>>580 で紹介したワンポイントレッスン(第一回)
にはまったく説明されていないため説明不足となったことをお詫びいたします。

 では、既存のBASICプログラムにプロジェクトファイル(*.MAK)を追加作成する手順を
説明します。 ここでは仮に次の各ファイル名として説明します。
 ・既存のBASICプログラムのソース: UNTIL1.BAS
 ・作成済みのリソースファイル: MAINFORM.RC
 ・実行可能形式ファイル(.EXE): UNTIL1.EXE

1. F-BASIC起動後、メニューのプロジェクト(P) - 新規作成(N)を選択。ダイアログの
ファイル名欄を「UNTIL1.MAK」に書き換えてOKボタン。
(「UNTIL1.MAK」と同名でプロジェクトウィンドウが表示されます)
2. メニューのプロジェクト(P) - 環境(E)を選択。ダイアログのファイル(F)ボタンを押して
リソースファイル「MANFORM.RC」を選択。
2-2. ダイアログのプロジェクトと実行形式ファイル欄にあるファイル名を再確認します。
 (必要ならばここでファイル名の指定を変更することができます)
2-3. OKボタンでダイアログを閉じます。
4. メニューのプロジェクト(P) - モジュール(M)を選択。
4-2. ダイアログの「ソース」タブでファイル(I)ボタンを押してBASICプログラムのソースを
選択(登録ボタン)。
  もし、複数のファイルに分かれている場合は再度ファイル(I)ボタンを押す操作を繰り返す。
4-3. ダイアログの右側の「プロジェクトモジュール欄」の一覧にBASICプログラムのソースが
あることを確認してOKボタンでダイアログを閉じます。
5. メニューのプロジェクト(P) - 上書き保存(S)または名前を付けて保存(A)を選択し、
ブロジェクトファイル「UNTIL1.MAK」をファイルに保存します。

6. 後は、通常通りプログラムを翻訳メニューから翻訳するか実行メニューが実行します。

後でこのBASICプログラムを修正・実行する場合はBASICプログラムを直接開くのではなく、
メニューのプロジェクト(P) - 開く(O)を選択してプロジェクトファイルを開きます。
*メニューのファイル(F) - 開く(O)のダイアログで「ファイルの種類(T)」の欄を「プロジェク

ト(*.mak)」に変更してファイルを選択しても同じです。

585570:2013/12/20(金) 11:34:26
リソースファイル(.RC)でフォーム「MAINFORM」を作成してプログラム実行時のウィンドウ
を置き換えた場合、F-BASICの従来のウィンドウと異なるところがいくつかあるようです。

$$ここでは従来のウィンドウを仮に[FB画面]、リソースファイルで作成した
  「MAINFORM」を[RC画面]と表記します。

○実行時のウィンドウのタイトル名
[FB画面]:実行時のプログラムのファイル名が自動で設定される
[RC画面]:「MAINFORM」のプロパティに設定した【フレーム】の「テキスト」項の内容

問題点:複数のプログラムを実行中にウィンドウを最小化したときなどに
表示されている名称が同じ(MAINFORM)になって区別がつかなくなる。

解決方法-1 (F-BASICの標準機能でのみ実現、実用上ほぼ同じに):
 BASICプログラムの先頭に次の文を追加する(2行)。

#include "WINDOWS.BI"

SETWINDOWTEXT "(表示するタイトル名)" '<−プログラム名など任意の文字列を入れる


解決方法-2 (Windowsの機能を利用):
 ここでは例示しませんが、Windows APIの「GetModuleFileNameA」を呼び出して
プログラムのファイル名を取得して設定する方法になります。


○実行時/最小化時のアイコンのイメージ
[RC画面]:[FB画面]のときとアイコンが異なる。

解決方法:
もし、同じアイコンにしたい場合は、F-BASICをインストールしたフォルダ中のBINフォルダ
内にF1A0DFLT.ICOというアイコンファイルがあるのでこれをリソースファイル(.RC)、
「MAINFORM」にアイコンとして登録する。

1.リソースファイル(.RC)を開き、「MAINFORM」を画面に表示させる。
2.メニューの リソース(S) - インポート(R)を選択する。
 もし、グレー色になってメニューを選択できないときは「MAINFORM」のウィンドウを
マウスでクリックしてから、メニューを選択操作する。
3.インポートするファイルを選択するダイアログが表示されるので。
F-BASICをインストールしたフォルダの中のBINフォルダまでたどり、
F1A0DFLTというアイコンファイル(.ICO)を選択して開くボタンを押す。
4.「MAINFORM」のプロパティ ダイアログを表示させる。
ダイアログの中の表示内容(P):【フレーム】に切り替え、アイコンの項の内容から
f1a0dflt (F1A0DFLT)を選択する。
5.リソースファイル(.RC)を上書き保存します。

586570:2013/12/21(土) 03:47:49
>>581
>表示速度が かすかに 遅くなる。


Windows環境では速度が一定しないこともあり、
あくまでひとつの参考値としてですが、
 リソースファイル(.RC)で、おもに以下の状態に設定
 ・フォント:MS 明朝 (サイズの項は変更せず(FixedSysのときと同値))
 ・テキストは80桁,24行のまま
 ・フォームの画面枠を広げる(画面枠はおもに横方向に広がった)
 ・背景色は白色

(a)実行するプログラム:テキストを連続で何行も表示して画面のスクロール多い

このときの画面表示速度の低下は 7%から15%程度

(b)実行するプログラムは(a)と同じでフォント設定はFixedSysに。

この場合は(a)よりも若干速い。


(c)実行するプログラム:テキストを画面全行書き換えるが画面スクロール少ない

このときの画面表示速度は逆に若干速い傾向。


表示速度についてはさまざまな要因があるため推測でしかありませんが、

・テキスト画面のスクロールが多いような場合については、
実行画面全体の表示を書き換えることになるため、画面の面積に比例して
速度が低下する。
・テキスト画面のスクロールが多いような場合はF-BASICの元の画面が速い?
・テキスト画面のスクロールが無く、テキストの書き換えが少ない場合は
リソースファイルの画面の設定次第では若干速い可能性がある。


余談ですが、リソースファイルで画面のマッピングモードを
「テキストモード」からTWIPSなどに変更すると画面の描画速度は高速化します。
これはF-BASICによる画面の互換機能を捨ててWindows互換にするということを意味します。

587はぜ:2013/12/25(水) 08:10:23
ありがとうございます 
繁忙期に入りましたので、しばらく試行を保留させてください。

588名無しさん:2014/04/16(水) 08:27:11
F-basicのMAILSEND関数について教えてください。
WindowsLiveメール環境でMAILSEND関数実行時に添付ファイルを指定しないと2008エラーになります。
F-basicの「メール送信サンプルプログラム」で再現できます。
回避する方法がありましたら教えてください。

589名無しさん:2014/04/20(日) 03:54:52
>>588
現象再現できました。添付ファイル指定無しで、エラーになりました。
原因はなんともわかりませんが状況としては、
・Windows XPやOutlook 2000以降のメールセキュリティ強化
・Outlook 2007以降、Simple MAPI が非サポート対象へ
の要因か?。

いくつか回避案:
(a) (添付ファイルなしは) F-BsaicランタイムのSENDMAILを使わず、
MAPI32.DLLを直接呼ぶ。
 MAPILogon , MAPILogoff , MAPISendMailを直接呼んでプログラムを書く。

 ランタイムはMAPI32.DLLを動的リンクで呼び出し、面倒を引き受けて
くれているがその代わりSENDMAILで指定できるパラメータ以外は隠されて
指定できないため。

(b) メールクライアントに Mozilla Thunderbird をインストールして既定にする。

 Outlook Expressのように Simple MAPIをサポート(?)

(c) .emlファイルとしてテキスト出力で作成してから .emlファイルに関連付けした
メールクライアントに読ませる。(メール作成ダイアログが起動)

(作成例):Outlook Expressでの場合 (文字はANSI、JISコードで)
□From: "test name" <test@example.com>
□To: <sample@example.com>
□Subject: TestTitle
□MIME-Version: 1.0
□Content-Type: text/plain;
□ charset="iso-2022-jp"
□Content-Transfer-Encoding: 7bit
□X-Mailer: Microsoft Outlook Express 6.00.9999.9999
□X-MimeOLE: Produced By Microsoft MimeOLE V6.00.9999.9999

□TEST MAIL TEST MAIL

590名無しさん:2014/04/25(金) 10:40:08
>>588
F-BASICのMAILSEND で、Windows Live メール等に送信メールを発行した
とき、添付ファイルを指定しないとMAILSENDがエラー 2008となる現象について。

どうやらF-BASICのランタイムに少々難があるようです。
ランタイム内の処理では、添付ファイル名を指定しない場合であっても、
MapiFileDesc構造体の配列へのポインタを渡しているため、
MAPI32.DLL か Windows Live メール側の検査で拒否されていると推測します。

以上の推測により、この現象を回避するF-BASICへのパッチを試作してみました。

対象:F-BASIC V6.3 L10 U003 *このバージョン構成以外は不可。
パッチ対象ファイル名: F1A0RI63.DLL   (インターネット拡張ライブラリ)
 タイムスタンプ: 2000/12/18
 ファイルサイズ: 348,160

◆現象回避パッチ リスト *以下のリストに示す箇所をバイナリエディタ等で書換え。
  書換え後はWindowsの再起動が必要。
/アドレス:変更前、変更後/
3139: 89 55
313A: AC E8
313B: 24 85
313C: 8C 00
313D: 00 00
313E: 00 00
313F: 00 5D
:
:
31C4: 90 39
31C5: 90 5C
31C6: 90 24
31C7: 90 30
31C8: 90 75
31C9: 90 6C
31CA: 90 29
31CB: 90 ED
31CC: 90 EB
31CD: 90 68
:
:
3236: 90 89
3237: 90 AC
3238: 90 24
3239: 90 94
323A: 90 00
323B: 90 00
323C: 90 00
323D: 90 C3
--END--
◆注意 
 このパッチによる動作やその結果の影響については何ら保証できません。
 書換えを行ったファイルそのものを頒布・公開したりしないでください。
 また、メーカー等もこれには一切関わりがございません。

591名無しさん:2014/05/03(土) 08:31:33
F-BASICのMAILSENDのエラーに関してご教授ありがとうございます。
検討した結果お教え頂いたMAPI32.DLLを直接呼ぶかソケットを使おうと思っています。

592名無しさん:2014/05/23(金) 00:19:53
>>586
LINE命令などのグラフィックをまったく使わないプログラムであれば
「運用環境ファイル」を作成してプロジェクトに組み込み
「運用環境ファイル」を開いて[動作モード]タブの
[画面の使用]−[グラフィック]のチェックを外して
再翻訳すれば画面の表示速度アップするよ。

593名無しさん:2014/07/29(火) 23:17:16
F-BASIC97を持っているのですが、F-BASIC V6との違いを教えて下さい。

594名無しさん:2014/07/30(水) 03:23:50
■F-BASIC97(V5.0)からの変更点(V6.3/V6.0)
OS:Windows 98(以降)への対応
DOS-BASICソース移行支援機能の搭載
ツールバーのフラット表示
プロパティ項目の追加
翻訳開始前の起動タスク検査
マルチユーザ対応
TRUNCATE命令:ファイルをポインタから以後を削除する(ファイルサイズ縮小)
ファイル存在確認関数:ISEXISTFILE関数/ISEXISTDIR関数
シーケンシャルファイルのOPENモード追加:FOR CREATEモード
環境変数の獲得:ENVIRON$関数
座標原点の変更:AXIS命令 (左下を座標原点に変更)
WIDTH LPRINT命令:LPRINT命令で印字する場合の1行内の文字数を設定
電源管理機能:GETPOWERSTATUS関数/SETWAKEUPTIME/SUSPENDPOWER命令
構造体のサイズ獲得:LEN関数(2)
インテリマウスの対応:マウスのホイール(Windows 98以降)
多重起動の禁止:PREVINSTANCE関数(多重起動の検出支援)
フォームへのシェルドロップ機能:
タスクトレイアイコン制御:SETTASKTRAYICON/DELTASKTRAYICON/SETTASKTRAYICONTIP
UNICODEデータ相互変換:JCONV$関数(JIS、SJIS、EUC、UNICODEの相互変換)


■F-BASICV6.0からの変更点(V6.3)
●F-BASIC統合開発環境
選択範囲の印刷:編集ウィンドウ内の選択した範囲のみを印刷できるようになりました。

●基本命令・関数
FILEATTR関数:ファイルハンドルを獲得できるようになりました。
SHELLの同期サポート:起動したプロセスが終了した時点で命令が終了する同期モードをサポート。
シーケンシャルファイルの高速化:シーケンシャルファイルの読み込みを高速化しました。

●拡張ライブラリ・コントロール・イベント
インターネット対応機能:HTTP、FTP、MAILなどでファイルを扱えるようになりました。
LPRINT印刷属性設定:LPRINTで印刷する際のフォントや文字間隔を設定できるようになりました。
ショートカットメニュー:マウスの右ボタンで利用されるショートカットメニューを作成できるようになりました。
ホットキー:フォームに対してホットキーを設定できるようになりました。
ファイル名操作:ファイル名文字列からドライブ名・パス・ファイル名・拡張子などに分解する
関数などをサポート。

595ひろ:2015/03/31(火) 14:56:32
またしても、皆様のお知恵をお貸し下さい。
pdfファイルを印刷したいのですが、どうすれば良いのでしょうか?

596名無しさん:2015/04/02(木) 06:41:10
Adobe ReaderかAcrobatが導入済みとして、

シェル拡張の「ファイルの関連付け」まかせとして
もっとも簡単な方法は

#include "WINDOWS.BI"
var A$
A$= "C:\TEMP\test.pdf"
SHELLEXECUTE A$,,8,0,"print"

これでAdobe ReaderかAcrobatが起動して
「通常使うプリンタ」で印刷されると思います。

597k5:2015/06/05(金) 11:18:23
こんにちは、FBASIC6.3を使っています。

いつも実験でRS-232Cポートに接続されている計測機器から出力されるデータを読み出しているのですが、今回使う機器がバイナリデータしかサポートしていないそうで困っています。データは24バイト固定でx,y,zが8バイト倍精度浮動小数点で出力されます。このデータをテキストデータに変換して計算したいのですが、FBASICではどのように扱うのかよくわかりません。どなたかよろしくご教授ください。

598名無しさん:2015/06/06(土) 07:36:59
>>597
 バイナリデータの受信ではINPUT$関数を使用します。
1組のバイナリデータ24バイトを A$=INPUT$(24, #1)で文字変数に格納してから
データを個々に切り分け(MID$関数)、数値に変換します。
INPUT$関数を複数回実行して個々のデータ1個づつ変数に格納してもかまいません。

 もし、次の組のバイナリデータとの間に区切り用のデータがあるなら忘れずに
受信処理してください。


 ここで問題となるのが、数値データが8バイトの倍精度浮動小数点であること。
浮動小数点形式には過去にいくつかの規格とデータのバイト格納(受信)順序の違いが
あるため、適した変換を行う必要があります。
(おそらくは数値形式そのものはIEEE754だと思います。)

F-BASICでは変換関数が用意されているので対応するものを使います。

・倍精度浮動小数点用の変換関数(CVDxx)
CVD関数、
CVDV関数、CVD2関数、CVD98関数

注意:CVD関数以外は「#include "F1A0LWIC.BI"」の記述が必要です。
そして、数値変換拡張ライブラリ「F1A0LC63.LIB」を
プロジェクトファイルにBASICプログラムとともに登録して翻訳する必要があります。


ヘルプファイルの次の各ページあたりを参照してください。
・「MS-DOS BASIC プログラム資産の移植」の章の 「数値データの格納形式について」、
   「各種データ形式への対応方法」、「数値変換拡張ライブラリ(F1A0LC63.LIB)」
・「他言語プログラム」の章の 「倍精度実数の格納形式」


それから、
 RS-232Cの回線速度やフロー制御などの通信モードの設定を
よく確認して計測機器側と合わせてください。

 設定はOPEN命令中で記述するか、「運用環境ファイル」を作成して設定します。
 「運用環境ファイル」を使う場合はF-BASICのプロジェクトファイルを作成
してBASICプログラムといっしょに登録する必要があります。
・運用環境ファイルの「回線」タブ - 「回線パラメータの設定」ボタン から。

599598:2015/06/06(土) 07:41:31
>>597
サンプルプログラムを例示します。(「構造体」を使った例)
 倍精度浮動小数点が、x86系CPUのWindowsアプリでよく使われる形式であると
みなし、受信データを「構造体」を使って倍精度浮動小数点型の変数に、
メモリ上でバイナリそのままで転記して取り出しています。

※CALLEVENT と#include "WINDOWS.BI" は必要なければはずしてください。

[注]:字下げのために全角空白を使ってます。半角に置き換えてください
#include "WINDOWS.BI"
#include "F1A0LWIC.BI" '<--ライブラリが必要な場合

'24Byte長レコード(8Bytex3)
type T_RCVDT
  X as double
  Y as double
  Z as double
end type

'データ受入用(バイナリ24Byte)
type T_RCVDT_WK
  DT as string * 24
end type

var RCVDT as T_RCVDT
var BUFWK as T_RCVDT_WK

baud 0,9600
open "COM0:" for input as #1

do while eof(1) '受信開始待ち
  CALLEVENT
loop

'1件分データ入力(24Byte)までループ
do
  if lof(1) >= 24 then
    ' 1件の受信データ読み込み(バイナリ)
    BUFWK.DT = INPUT$(24, #1)
    ' 構造体を通してバイナリを各変数に格納
    LSET RCVDT = BUFWK

    exit do 'ループ脱出
  end if
  CALLEVENT
loop

close #1
'データを画面に表示
print "X="; RCVDT.X
print "Y="; RCVDT.Y
print "Z="; RCVDT.Z


 浮動小数点の形式が異なるため、エラーや数値がでたらめになる場合はとりあえず、
「X as double」などを「X as string * 8」などに書き換え、
変換関数のどれか適切なものを使って「CVD(RCVDT.X)」、倍精度の実数に変換
してみてください。
注意:CVD関数以外は数値変換拡張ライブラリ「F1A0LC63.LIB」が必要。

600k5:2015/06/08(月) 16:25:02
こんにちは

レスが遅れて、申し訳ありません。
そして、丁寧な解説をありがとうございます。
とても感謝しております。

多分、倍精度浮動小数点はIEEE754だと思います。
ただ、ビックエンディアンかリトルエンディアンかは不明です。
取り合えず、サンプルプログラムを参考にして、
データを読み出すプログラムを書いてみます。
結果は必ずここに報告します。

こういった処理を書くのにはBasicは最強ですね。
もう15年ほど使っておりますが、Windows7(64bit)でも快適に使っています。

601k5:2015/06/11(木) 22:09:42
こんにちは

なんとかお世話になってデータを読み出せそうです。
ところで、基本的な質問があります。

A$=INPUT$(24, #1)
このA$をファイル(#2)に書く時に、

open "xyz.bin" for binout as #2

Print #2,A$ または、
write #2,A$

とかやると、A$にCR/LF(0d0a)が追加で書き込まれますよね。
これを24バイトだけバイナリーモードでで書き込むようにしたいのですが、
なにかいい方法はないでしょうか。

602598:2015/06/12(金) 04:05:25
>>597
PC側のRS-232CのI/FはUSB変換タイプだったりするのでしようか。
もしそうならば、差しつかえなければ品番などを開示いただけると。
F-BASICで実際に動作するI/Fの情報は貴重なので。

>>601
> open "xyz.bin" for binout as #2

 バイナリモードでの出力では FWRITE# 命令があります。

fwrite #2,A$

出力には変数を指定します。この変数には構造体全体を指定することもできます。
数値型変数も指定できます。ただし文字列定数・数値定数は指定できません。
構造体を使えばランダムファイルのレコードのような扱い方ができるわけです。

 ただ、FWRITE# では PRINT#のような多様性はありません。PRINT#の場合は、

print #2,A$;

のように末尾にセミコロンを付けると、復帰改行(CR/LF)コードの出力を抑止できます。


#openモードがバイナリモードでもPRINT# WRITE# 使えるとは・・。F-BASICの柔軟性ゆえか。
#バイナリ出力モードもシーケンシャルの一種、ということはEOFコードの問題が解決する?

603名無しさん:2015/06/12(金) 09:41:20
>PC側のRS-232CのI/FはUSB変換タイプだったりするのでしようか。
>もしそうならば、差しつかえなければ品番などを開示いただけると。
>F-BASICで実際に動作するI/Fの情報は貴重なので。

そうなんですか、それで動かなかったんですね。
今はシリアルポート付のPCでログをとっています。

ダメだったのは、RATOCのREX-USB60(ProlificのPL2303)とArvel SRC06-USB(FTDIのFT232BM)です。
もう1本、ELECOMのUC-SGT(ProlificのPL2303)があるのですが、これも無理かもしれませんね。

ここにいろいろなケーブルがあります。
http://smart.diipedia.net/usb-cable.html#usb-serial


Alcor MicroのAU9720とWinChipHeadのCH340Tを使った、
USBシリアル変換ケーブルはまだ試せていません。

F-BASICで動作可能なUSBシリアル変換ケーブルってあるのでしょうか?

604名無しさん:2015/06/12(金) 11:14:20
>>602

いつもありがとうございます。

そういうと、fwriteというのがありました。
これを使ったらうまくゆきました。
ついでに、freadを使ったら、全体にすっきりしました。


F-BASICのバイナリモードは強力ですね。
EOFも出力されないので、Linuxなどに持って行くときも便利です。

605598:2015/06/13(土) 03:14:57
>>603
変換I/Fのレポートありがとうございます。

>>604
UNIX系とのやりとりに限らず、Windows上でもEOFコードは問題なので
バイナリ出力モードでprint# やwrite# が使えるとなれば、
for OUTPUTをfor BINOUTにソースを変更するだけで済むので大きな収穫です。

seek命令・seek関数とも使えるようなので、活用の幅がありそうです。

こうなると改行コードが0AHの場合、テキスト入力系命令が使えないのが残念です。

606k5:2015/10/19(月) 12:18:58
こんにちは

またお世話になります。


MXD-4660AというデジタルマルチメータのデータをF-BASICで読み込もうと思っています。マニュアルにあるサンプルプログラムはこのようなものです。

レート:9600bps
データ長:7ビット
パリティ:なし
ストップビット:2

10 open "com1:9600,n,7,2,rs,cs,ds,cd" as #2
20 print #2,"D"
30 in$=input(4*14,#2)
40 print in$
50 close #2

多分QBASICで書かれていると思います。

これをF-BASICに書き直そうと思っているのですが、うまく動きません。「システムに異常があります」とエラーが出ます。

baud 0,9600

CM$="COM0:(S7N2N7NNN)

open CM$ for output as #2
open CM$ for input as #2

print #2,"D"

line input#1,R$

print R$

close

stop

多分、comポートをオープンするこの部分が間違っているのだと思うのですが、

"com1:9600,n,7,2,rs,cs,ds,cd"

なにかヒントになるようなことをお気づきでしたら、アドバイスいただけると助かります。

607598:2015/10/20(火) 11:17:30

--- for input as #2 → ... as #1
line input#1,R$ → は受信データしだい(改行コード必要)

オプションはたぶん合っているような。
ハードウェアフロー制御なしかな?。どちらでもOPEN自体はできるはず。


「[27]システムに異常があります」だとAPIから想定外のエラーが返されて
いるのかも?

普通ありがちなエラーメッセージは---
[60]指定の入出力装置は使用できません ← 指定番号のポートが無い
[53]入出力装置に異常が発生しました ← 通信(条件設定)異常でエラー
[78]入出力装置でタイムアウトが発生しました ← RS-232Cの通信タイムアウト設定有


とりあえずどこまで動くのか状態切り分けが必要かと---

・Windowsのハイパーターミナル(があれば)で通信できるか確認する。
(注:既定で「ローカルエコー」はOFFなのでキー入力した送信文字列は表示されない)

・デバイスマネージャの方でシリアルポートの通信条件を設定しておき、
 F-BASICでは通信条件を指定しない。「運用環境設定ファイル」も無し。

・USB―シリアル変換の構成の場合はデバイスマネージャか機器付属ツールで
 ポート番号を変更してみる。(ポート3 から 5: F-BASIC="COM2:"から"COM4")

608k5:2015/10/20(火) 14:48:57
ありがとうございます。

すいません、環境をお知らせしていませんでした。
通信はPCのシリアルポートで行っており、OSはWindows2000です。

ご指摘のとおりソースが間違っていますね。
正しくはこうです。

baud 0,9600
CM$="COM0:(S7N2N7NNN)
open CM$ for output as #2
open CM$ for input as #1
print #2,"D"
line input#1,R$
print R$
close
stop

その後、ハードウェアフロー制御をON、CM$="COM0:(S7N2N7EN)としたら、「[27]システムに異常があります」は出なくなりました。今は、
print #2,"D"の後のline input#1,R$で反応しなくなります。つまり、"D"を計測機に送った後の応答待ち状態です。

整理すると、

CM$="COM0:(S7N2N7NN)の場合
line input#1,R$で「[27]システムに異常があります」が出る。input$やinput#でも同じ症状

CM$="COM0:(S7N2N7EN)の場合
print #2,"D"の後に無反応

ハイパーターミナルやteratermでもやってみたのですが、"D"を送っても無反応です。デバイスマネージャでシリアルポートの通信条件設定もしてみました。

ちなみに元のソースをGW-BASICで走らせてみると、これがちゃんと動くんですね。うーん。

609598:2015/10/21(水) 05:44:32
>>608
 詳しいご報告ありがとうございます。
Windows 2000でPCオンボードのシリアルポート …普通ですね。

 環境としては、F-BASICのUpdateバージョンはU003でよろしいでしょうか?。
U003の場合のランタイムは、F1A0RN63.DLL 2000/12/07

それと、Windowsのカーネルは、
KERNEL32.DLL 2007/04/16 : 5.00.2195.7135
 C Runtime Libraryは、
MSVCRT.DLL 2003/06/19 : 6.1.9844.0
 シリアルドライバは、
%SystemRoot%system32\drivers\serial.sys 2003/06/19 : 5.0.2195.6655
%SystemRoot%system32\drivers\serenum.sys 2003/06/19 : 5.0.2195.6655


今回の判明点は、
・エラー「[27]システムに異常があります」はデータ入力段階で発生している。
 入力命令の種類によらず、かつ、フロー制御なしの場合。
・ハードウェアフロー制御(RTS/CTS)有効ではPRINT#で送信待ちになる。


次のテストプログラムでどの段階まで進むか確認していただけませんか。
通信条件設定は次の各パターンで・・・
* CM$="COM0:(S7N2N7NNN)" '制御なし
* CM$="COM0:(S7N2N7ENN)" 'フロー制御(RTS/CTS)有効
* CM$="COM0:(S7N2N7NEN)" 'フロー制御(DTR/DSR)有効

※応答待ち状態に陥った場合はCTRL+CキーでBASICプログラムを強制中断してください。
※もし、while eof(1)... の行でエラー「システムに異常があります」が発生した場合は
直前にWAIT命令を追加してみてください。


var CM$, R$
baud 0,9600
CM$="COM0:(S7N2N7NNN)"
open CM$ for output as #2 : open CM$ for input as #1
WAIT 100
print"!!送信始!!" : print#2,"D" ' コマンド送信
while eof(1) :print"*"; :wend ' 受信開始までループ
R$=input$(1,#1) :print:print"!!受信あり!!"
WAIT 100
if LOF(1)>0 then R$=R$ + input$(LOF(1),#1)
close
stop : end

610k5:2015/10/21(水) 17:45:07
丁寧にありがとうございます。

こちらの環境は下記のとおりです.

F-BASICのランタイム
c:\winnt\system32\F1A0RN63.DLL
F1A0RN63.DLL 2000/12/07 6.3.10.10131

Windowsのカーネル
c:\winnt\system32\KERNEL32.DLL
KERNEL32.DLL 2011/07/05 : 5.00.2195.7144

C Runtime Libraryは、
c:\winnt\system32\MSVCRT.DLL
MSVCRT.DLL 2003/06/19 : 6.1.9844.0

シリアルドライバ
c:\winnt\system32\drivers\serial.sys
serial.sys 2003/06/19 : 5.0.2195.6655
シリアルドライバ
c:\winnt\system32\drivers\serenum.sys
serenum.sys 2003/06/19 : 5.0.2195.6655


下記のコードで実行してみました.
(行番号を付けています)

1 var CM$, R$
2 baud 0,9600
3 CM$="COM0:(S7N2N7NNN)"
4 open CM$ for output as #2 : open CM$ for input as #1
5 WAIT 100
6 print"!!送信始!!" : print#2,"D" ' コマンド送信
7 while eof(1) :print"*"; :wend ' 受信開始までループ
8 R$=input$(1,#1) :print:print"!!受信あり!!"
9 wait 100
10 if LOF(1)>0 then R$=R$ + input$(LOF(1),#1)
11 close
12 stop : end


フロー制御をした場合、

CM$="COM0:(S7N2N7ENN)" 'フロー制御(RTS/CTS)有効
CM$="COM0:(S7N2N7NEN)" 'フロー制御(DTR/DSR)有効
!!送信始!!は表示されるが、そのまま送信待ちの状態、



CM$="COM0:(S7N2N7NNN)"の場合

!!送信始!!
!!受信あり!!

中断しました test2.bas[12行]
任意のキーを押して下さい.

となります。

「!!受信あり!!」の後に何か文字が返ってきているので調べたら(asc(R$))、NULL(00)でした。
その後に「中断しました」となるようです。このNULLがシステム異常の原因なのかもしれません。
明日、時間を作って、チャレンジしてみます。

611k5:2015/10/21(水) 21:32:39
ちなみにこれが、MXD-4660Aというデジタルマルチメータのプロトコルについて書かれたものです。

http://www2.produktinfo.conrad.com/datenblaetter/100000-124999/123730-an-01-en-Schnittstellenbeschreibung_M_4660A.pdf

612598:2015/10/22(木) 05:00:26
>>610,611
> KERNEL32.DLL 2011/07/05 : 5.00.2195.7144
カーネルが新しい・・?。


 資料拝見しました。ハードウェアフロー制御はなしで正解ですね。
機器側の端子を見ると。

資料から読み解くと、
・データはASCIIの文字列(7bit)で行端コードはCRのみとなります。
・機器へのコマンド送信は1秒間に1回程度。
・受信データは、1フレーム(行)が14文字(CRコード含む)長さ固定。
・受信データは1回に4フレーム固定(?)で送られる。


テストサンプルを作り直しました。
・F-BASICでは行端コードの種別の設定がないので、print# を変更します。
・入力の方は行端コードがCRのみでも可能だと思いますので、LINE INPUT#を選択します。

※ヌルキャラクタの問題がまだわからないので、サンプルでは後段で空白に置き換える
処理を加えています。
※受信応答待ち状態に陥った場合はCTRL+CキーでBASICプログラムを強制中断してください。


var CM$, R$(4-1), I%, J%
baud 0,9600
CM$="COM0:(S7N2N7NNN)"
open CM$ for output as #2
open CM$ for input as #1
WAIT 100

if not eof(1) then print "Error:受信バッファが空でない!":close:stop:end

print"!!送信始!!"
print#2,"D";chr$(13);
wait 50

while eof(1) :print"*"; :wait 5 :wend ' 受信開始までループ
print:print"!!受信始!!"
wait 5
while lof(1) < 14*4 :print"."; :wait 5 :wend ' 全フレーム受信までループ
print:print"!!受信終!!"

line input#1,R$(0) :print "!!Frame-1入力終"
line input#1,R$(1) :print "!!Frame-2入力終"
line input#1,R$(2) :print "!!Frame-3入力終"
line input#1,R$(3) :print "!!Frame-4入力終"
close

for I%=0 to 4 - 1
if len(R$(I%))=0 then R$(I%)=space$(14 - 1)
for J%=1 to len(R$(I%))
' もし、ヌルキャラクタがあれば空白に置き換え
if asc(mid$(R$(I%),J%,1))=&H0 then mid$(R$(I%),J%,1)=" "
next J%,I%
print "1):";R$(0) ;"<"
print "2):";R$(1) ;"<"
print "3):";R$(2) ;"<"
print "4):";R$(3) ;"<"

stop : end

 ちなみに特殊な書き方として「open CM$ as #1」と書くとopen命令を1本にできます。

613k5:2015/10/22(木) 09:00:47
丁寧にありがとうございます。

この機器は"D"を送ると、4行(1行がバイト)のデータが送られてくる単純なものだと理解しています。GW-BASICでも確認しています。

さっそくテストサンプルを実行してみました。

「受信バッファが空でない!」

の表示で終了してしまいます。

この行をコメントアウトして実行すると、!!受信始!!のループに入りますが、データの送信が始まらないので、ここから先には進みません。

これは、デジタルマルチメータのバッファに何か残っているということなのですね。ケーブルの結線を調べてみます。

614598:2015/10/23(金) 05:13:57
>>613
 その通り単純なもので、"D"文字列を受けて計測データを文字列で送信する
仕組みで、PC側の状態はおかまいなしで送信するものと思われます。

※GW-BASICの",rs"オプションが気になりますが。
(RS suppresses detection of RTS(Request To Send))


 「受信バッファが空でない!」の行は念のため入れたもので、動作テストを連続で
行った場合とか、まあ無くは無いかと・・。それにNUL charを受信したとのご報告の
件もあるので。 引っかかるとは思いませんでしたが。
本当に入っているのかは「?」ですけど。OPEN時にバッファをフラッシュしないのか?

 とりあえずその行は次のように変更して、画面にそのデータを表示させてみましょう。

if not eof(1) then R$(0)=input$(LOF(1),#1):print "受信??";R$(0):R$(0)=""

 次にコマンド送信ですが、送信バッファに溜まったままで測定器へは送信されていない
可能性も考えられなくはありません。これはprint# を前の形に戻すと変わるかもしれません。

print#2,"D" '←←←print#2,"D";chr$(13);

 そして、print#を変更しても戻しても「!!受信始!!」後のループで進まない
場合は一度、受信チェックのループ行を外してみます。

'while lof(1) < 14*4 :print ... ←コメントアウト


 そして、ここまで変更して、print#を変更しても戻してもうまく受信できない場合は、
さらに変更します。

※表示される受信データはうまく改行されないためおそらく表示がおかしくなると思います。
※もし「wait 100」を外すと「データバイト数」の値が増えるようなら・・考えます..。

print:print"!!受信始!!"
wait 100
R$(0)=input$(LOF(1),#1)
print "データバイト数=";len(R$(0))
print R$(0)
close
stop :end

615名無しさん:2015/10/23(金) 23:44:35
本当にいろいろとありがとうございます。

ケーブルを調べてみたのですが、普通のストレートでした。


今日は別の計測機で、F-BASICでデータが取る出せるか見てみました。

その計測器に送るコマンドはこのようなものでした。

asc(22)asc(02)[命令]asc(03)asc(13)asc(10)
<SYN><STX>[命令]<ETX><CR><LF>

これを文字列(TEST$)で作って

print#2,TEST$

としたのですが、残念ながら何も表示されません。

ただ、これをファイルに保存して、teratermでファイル転送(バイナリ)とすると計測器からのデータが表示されます。仰るように、「送信バッファに溜まったままで測定器へは送信されていない」のかも知れません。次は"D"だけのバイナリファイルを作って、teratermのファイル転送(バイナリ)をしてみます。

616598:2015/10/24(土) 06:34:13
>>615
Win32 APIを使ってCOM1シリアルポートに“残っている”通信条件設定を
取得するプログラムです。(ただし一部表示していない情報があります)
※なお、送受信バッファサイズなどは取得できません(別のAPI関数が必要なので)。

このプログラムを次の各段階毎に実行して、設定状態に違いがあれば、
なにか手がかりになるかもしれません。
1.Windows 起動直後
2.GW-BASICの受信サンプル実行で正常受信した後
3.F-BASICで一回オープン"COM0:(S7N2N7NNN)"クローズした後

注意:declare文は長いため途中で改行してますので、つないで
一行にして翻訳してください。


#define NULL BYVAL 0

'// fBitFields as long のビット定義
#define FBinary &H1 '//0 BINARY MODE, WINDOWSでは常に1
#define fParity &H2 '//1 パリティチェック
#define fOutxCtsFlow &H4 '//2 CTS output フロー制御
#define fOutxDsrFlow &H8 '//3 DSR output フロー制御
#define fDtrControl &H30 '//4:2 DTR フロー制御タイプ
'-DTR_CONTROL_DISABLE 0
'-DTR_CONTROL_ENABLE 1
'-DTR_CONTROL_HANDSHAKE 2
#define fDsrSensitivity &H40 '//6 DSR sensitivity
#define fTXContinueOnXoff &H80 '//7 XOFF continues Tx
#define fOutX &H100 '//8 XON/XOFF output フロー制御
#define fInX &H200 '//9 XON/XOFF input フロー制御
#define fErrorChar &H400 '//10 enable error replacement
#define fNull &H800 '//11 NULL BYTES 受信を破棄する
#define FRTSCONTROL &H3000 '//12:2 RTS フロー制御タイプ
'-RTS_CONTROL_DISABLE 0
'-RTS_CONTROL_ENABLE 1
'-RTS_CONTROL_HANDSHAKE 2
'-RTS_CONTROL_TOGGLE 3
#define fAbortOnError &H4000 '//14 abort reads/writes on error
'fDummy2 '//15:17 reserved

Type T_DCB
DCBlength As Long
BaudRate As Long
fBitFields As Long ' Bits
wReserved As Integer
XonLim As Integer
XoffLim As Integer
ByteSize As Byte
Parity As Byte
StopBits As Byte
XonChar As Byte
XoffChar As Byte
ErrorChar As Byte
EofChar As Byte
EvtChar As Byte
wReserved1 As Integer
end type

declare function CREATEFILE lib "kernel32" alias "CreateFileA" (byval LPFILENAME as string,
byval DESACC as long, byval SHAREMODE as long,
byref LPSECUATTR as any, byval CREDISPOS as long,
byval FLAGSATTR as long, byval HTEMPLFILE as long) as long

declare function CLOSEHANDLE lib "kernel32" alias "CloseHandle" (byval HOBJECT as long) as long
declare function GETCOMMSTATE lib "kernel32" alias "GetCommState" (byval NCID as long,
LPDCB as T_DCB) as long
declare function SETCOMMSTATE lib "kernel32" alias "SetCommState" (byval HCOMMDEV as long,
LPDCB as T_DCB) as long

#define GENERIC_READ (-CLNG(&HFFFFFFFF - &H80000000)-1)
#define GENERIC_WRITE &H40000000
#define OPEN_EXISTING 3
#define FILE_SHARE_READ &H1
#define FILE_SHARE_WRITE &H2
#define INVALID_HANDLE_VALUE -1

617598:2015/10/24(土) 06:36:18
>>616 の続きです。

declare function TEST1_CBIT(V as long,B as long) as long
function TEST1_CBIT(V as long,B as long) as long
var I as long,J as long
TEST1_CBIT=V
if B=0 then error 5:exit function
if B<0 then error 11:exit function '未実装
I=B :J=1
do while (I mod 2 = 0)
J=J * 2 : I=I \ 2
loop
TEST1_CBIT=(V and B) \ J
if ((V and B) mod J) <> 0 then error 21
end function

declare sub TEST1_GetState()
sub TEST1_GETSTATE()

var RES as long
var hfile as long
var DCB as T_DCB
var F as long

HFILE=INVALID_HANDLE_VALUE
HFILE = CREATEFILE("COM1", (GENERIC_READ or GENERIC_WRITE), 0, NULL, OPEN_EXISTING, 0, NULL)
if HFILE= INVALID_HANDLE_VALUE then print "Error:open失敗":exit sub

RES=GetCommState(hfile, DCB)
if RES=0 then
print "Error:GetCommState"
RES=CLOSEHANDLE(HFILE)
else
RES=CLOSEHANDLE(HFILE)

if DCB.DCBLENGTH<>len(T_DCB) then print "!!DCBlength(hex)=";DCB.DCBLENGTH
'**取得結果の表示**
F=DCB.FBITFIELDS '*bit分解必要
print "fBitFields(16進数)=";hex$(DCB.FBITFIELDS)
print "fOutxCtsFlow=";TEST1_CBIT(F, FOUTXCTSFLOW)
print "fOutxDsrFlow=";TEST1_CBIT(F, FOUTXDSRFLOW)
print "fDtrControl=";TEST1_CBIT(F, FDTRCONTROL);"(DTR フロー制御タイプ:0..2)"
print "fDsrSensitivity=";TEST1_CBIT(F, FDSRSENSITIVITY)
print "fErrorChar=";TEST1_CBIT(F, FERRORCHAR) ;"(エラー時文字置き換える)"
print "fNull=";TEST1_CBIT(F, fnULL) ;" (NULL BYTES 受信を破棄する=1)"
print "fRtsControl=";TEST1_CBIT(F, FRTSCONTROL) ;" (RTS フロー制御:0..3)"
print "fAbortOnError=";TEST1_CBIT(F, FABORTONERROR)
print
print "ByteSize=";DCB.BYTESIZE
print "StopBits=";DCB.STOPBITS ;" (stopビット:0=1,1=1.5,2)"
print "ErrorChar(16進)=";hex$(DCB.ERRORCHAR)
print "EofChar(16進)=";hex$(DCB.EOFCHAR)
print "EvtChar(16進)=";hex$(DCB.EVTCHAR)
endif
end sub

'-----
TEST1_GETSTATE '←取得処理の実行
print "終了します。なにかキーを押してください。"
while inkey$="":wend
end

618598:2015/10/24(土) 06:51:23
追伸、実行結果の画面のテキストをクリップボードにコピーできます。
操作方法はALT+SPACEキー入力でコントロールメニューが表示
されるので、一番下の「コピー(Y)」-「テキスト(T)」を選択。

619598:2015/10/24(土) 08:17:56
>>615

>>616 の手順を一部訂正します。
>このプログラムを次の各段階毎に実行して、設定状態に違いがあれば、
>なにか手がかりになるかもしれません。
--
1.Windows 起動直後
2.(1回目)F-BASICで一回オープン"COM0:(S7N2N7NNN)"クローズした後
3.GW-BASICの受信サンプル実行で正常受信した後
4.(2回目)F-BASICで一回オープン"COM0:(S7N2N7NNN)"クローズした後
--以上、訂正です。

620名無しさん:2015/10/24(土) 16:54:52
ありがとうございます
(なんとお礼をしたらいいか)

早速、月曜日に研究室に行ったらやってみます。

これまで違う計測機器やモデムの簡単な制御をF-BASICでやったことはあるのですが、

PRINT #2,"D"

を実行すると

D(CR)(LF)
44 0d 0a

の3バイトのコードがCOMに送らると思っていました。処理系によって違うのか不思議に思っています。それ以外にタイミングなどの問題があるのかもしれません。シリアル制御は奥が深そうです

621名無しさん:2015/10/24(土) 23:32:36
>※GW-BASICの",rs"オプションが気になりますが。
>(RS suppresses detection of RTS(Request To Send))
QuickBasicのマニュアルにも"RTSを抑制する"とありましたが、「抑制」とはどういう意味で使われているのでしょうね。いままでよくわからずに使っていました。

RTS信号をめぐる混乱
http://d.hatena.ne.jp/licheng/20130530/p1
http://www15.atpages.jp/limz80msx/program/rs232c.html

622名無しさん:2015/10/25(日) 04:32:44
>>620

行端(行末)コードで使われている制御コード(コントロールコード)
CRはキャリッジリターン、LFはラインフィード。

これらはテレタイプ端末(電動機械式タイプライタ)の時代にまで遡り、
TTY通信とか言ってましたっけ。

CR+LFで「復帰改行」。これはタイプライタ(プリンタ)の動きの制御のため、
キャリッジ(紙をはさんで左右に動く機構)を1行の先頭の方へ戻し、
次に紙を送り出す(紙を次の行へ進める)。

今の時代、画面での改行や単に1行分のデータの末端を示すのなら
コード1つで十分なので、CRかLFのみにすれば通信量(費用・時間)が節約できると。

そのため、通信ソフト類ではどの改行コードを使うか設定する機能を持つ。

その昔、CP/Mが改行コードに「CR+LF」採用したので結果的に、MS-DOSも
「CR+LF」になったらしい。
MS-DOS上のF-BASICも当然そうなったと。

623名無しさん:2015/10/25(日) 12:08:17
行末コードはよるトラブルの元になりますね。MACはCR,UnixはLF,MS-DOSはCR/LFですが、CP/MはPDPの影響でCR/LFを採用したんでしたっけ。

F-BASICもCOMポートをバイナリモードでopenして、fwriteとかfreadが使えると嬉しいのですが。

624名無しさん:2015/10/26(月) 10:00:09
おはようございます

さっそく、COM1の通信条件設定を調べるプログラムを実行してみました。


1.Windows 起動直後
2.(1回目)F-BASICで一回オープン"COM0:(S7N2N7NNN)"クローズした後
3.GW-BASICの受信サンプル実行で正常受信した後
4.(2回目)F-BASICで一回オープン"COM0:(S7N2N7NNN)"クローズした後
5.GW-BASICの受信サンプル実行で正常受信した後


あれれ、STOP BITが1になっていますね。


1回目

fBitFields(16進数)=1011
fOutxCtsFlow= 0
fOutxDsrFlow= 0
fDtrControl= 1 (DTR フロー制御タイプ:0..2)
fDsrSensitivity= 0
fErrorChar= 0 (エラー時文字置き換える)
fNull= 0 (NULL BYTES 受信を破棄する=1)
fRtsControl= 1 (RTS フロー制御:0..3)
fAbortOnError= 0
ByteSize= 7
StopBits= 0 (stopビット:0=1,1=1.5,2)
ErrorChar(16進)=0
EofChar(16進)=0
EvtChar(16進)=0
終了します。なにかキーを押してください。


2回目
fBitFields(16進数)=1011
fOutxCtsFlow= 0
fOutxDsrFlow= 0
fDtrControl= 1 (DTR フロー制御タイプ:0..2)
fDsrSensitivity= 0
fErrorChar= 0 (エラー時文字置き換える)
fNull= 0 (NULL BYTES 受信を破棄する=1)
fRtsControl= 1 (RTS フロー制御:0..3)
fAbortOnError= 0
ByteSize= 7
StopBits= 2 (stopビット:0=1,1=1.5,2)
ErrorChar(16進)=0
EofChar(16進)=0
EvtChar(16進)=0
終了します。なにかキーを押してください。

625名無しさん:2015/10/26(月) 10:00:50
3回目
fBitFields(16進数)=1
fOutxCtsFlow= 0
fOutxDsrFlow= 0
fDtrControl= 0 (DTR フロー制御タイプ:0..2)
fDsrSensitivity= 0
fErrorChar= 0 (エラー時文字置き換える)
fNull= 0 (NULL BYTES 受信を破棄する=1)
fRtsControl= 0 (RTS フロー制御:0..3)
fAbortOnError= 0
ByteSize= 5
StopBits= 0 (stopビット:0=1,1=1.5,2)
ErrorChar(16進)=0
EofChar(16進)=0
EvtChar(16進)=0
終了します。なにかキーを押してください。

4回目
fBitFields(16進数)=1011
fOutxCtsFlow= 0
fOutxDsrFlow= 0
fDtrControl= 1 (DTR フロー制御タイプ:0..2)
fDsrSensitivity= 0
fErrorChar= 0 (エラー時文字置き換える)
fNull= 0 (NULL BYTES 受信を破棄する=1)
fRtsControl= 1 (RTS フロー制御:0..3)
fAbortOnError= 0
ByteSize= 7
StopBits= 2 (stopビット:0=1,1=1.5,2)
ErrorChar(16進)=0
EofChar(16進)=0
EvtChar(16進)=0
終了します。なにかキーを押してください。



5回目
fBitFields(16進数)=1011
fOutxCtsFlow= 0
fOutxDsrFlow= 0
fDtrControl= 1 (DTR フロー制御タイプ:0..2)
fDsrSensitivity= 0
fErrorChar= 0 (エラー時文字置き換える)
fNull= 0 (NULL BYTES 受信を破棄する=1)
fRtsControl= 1 (RTS フロー制御:0..3)
fAbortOnError= 0
ByteSize= 7
StopBits= 0 (stopビット:0=1,1=1.5,2)
ErrorChar(16進)=0
EofChar(16進)=0
EvtChar(16進)=0
終了します。なにかキーを押してください。

626598:2015/10/26(月) 11:22:21
>>625
えーと、
3回目(GW-BASIC1回目)と5回目(GW-BASIC2回目)、なんか違ようですが
なぜなんだろう?。

fDtrControl= 0 (DTR フロー制御タイプ:0..2)
fRtsControl= 0 (RTS フロー制御:0..3)
ByteSize= 5

fDtrControl= 1 (DTR フロー制御タイプ:0..2)
fRtsControl= 1 (RTS フロー制御:0..3)
ByteSize= 7

1回目(起動直後)と5回目(GW-BASIC2回目)が同じなので、
これは初期状態に戻ったということかな・・。

次に、F-BASICと3回目(GW-BASIC1回目)との違い。

[FB]
fDtrControl= 1 (DTR フロー制御タイプ:0..2)
fRtsControl= 1 (RTS フロー制御:0..3)
ByteSize= 7
StopBits= 2 (stopビット:0=1,1=1.5,2)

[GW]
fDtrControl= 0 (DTR フロー制御タイプ:0..2)
fRtsControl= 0 (RTS フロー制御:0..3)
ByteSize= 5
StopBits= 0 (stopビット:0=1,1=1.5,2)


うーーーん、fRtsControlがカギなんだろうか。

このデジタルマルチメータ側のシリアル端子の動作を勘違いしていたのかも。
 PC側の状態を見ないのではなくて、PC側の状態で測定データを送信するか
どうかを決めるが、PC側には自分の状態を知らせないから無視してコマンド送信
しなさいということかもしれない。

するとRS-232C間を、半二重通信でやりとりしなさいということかもしれない。

627名無しさん:2015/10/26(月) 17:17:01
ありがとうございます。

もう一度やってみました。

最初ににポートのopen/closeをした後にGW-BSIACを実行し、シリアルポートの状態を調べ、その後にポートのopen/closeをした後にシリアルポートの状態を調べ、さらにGW-BSIACを実行した後にシリアルポートの状態を調べています。

ポートのopen/close

var CM$
baud 0,9600
CM$="COM0:(S7N2N7NNN)"
open CM$ for output as #2
open CM$ for input as #1
close
end

1回目
fBitFields(16進数)=1
fOutxCtsFlow= 0
fOutxDsrFlow= 0
fDtrControl= 0 (DTR フロー制御タイプ:0..2)
fDsrSensitivity= 0
fErrorChar= 0 (エラー時文字置き換える)
fNull= 0 (NULL BYTES 受信を破棄する=1)
fRtsControl= 0 (RTS フロー制御:0..3)
fAbortOnError= 0
ByteSize= 5
StopBits= 0 (stopビット:0=1,1=1.5,2)
ErrorChar(16進)=0
EofChar(16進)=0
EvtChar(16進)=0


2回目
fBitFields(16進数)=1011
fOutxCtsFlow= 0
fOutxDsrFlow= 0
fDtrControl= 1 (DTR フロー制御タイプ:0..2)
fDsrSensitivity= 0
fErrorChar= 0 (エラー時文字置き換える)
fNull= 0 (NULL BYTES 受信を破棄する=1)
fRtsControl= 1 (RTS フロー制御:0..3)
fAbortOnError= 0
ByteSize= 7
StopBits= 2 (stopビット:0=1,1=1.5,2)
ErrorChar(16進)=0
EofChar(16進)=0
EvtChar(16進)=0


3回目
fBitFields(16進数)=1011
fOutxCtsFlow= 0
fOutxDsrFlow= 0
fDtrControl= 1 (DTR フロー制御タイプ:0..2)
fDsrSensitivity= 0
fErrorChar= 0 (エラー時文字置き換える)
fNull= 0 (NULL BYTES 受信を破棄する=1)
fRtsControl= 1 (RTS フロー制御:0..3)
fAbortOnError= 0
ByteSize= 7
StopBits= 0 (stopビット:0=1,1=1.5,2)
ErrorChar(16進)=0
EofChar(16進)=0
EvtChar(16進)=0


fDtrControl= 0 (DTR フロー制御タイプ:0..2)
fDtrControl= 1 (DTR フロー制御タイプ:0..2)
fDtrControl= 1 (DTR フロー制御タイプ:0..2)

fRtsControl= 0 (RTS フロー制御:0..3)
fRtsControl= 1 (RTS フロー制御:0..3)
fRtsControl= 1 (RTS フロー制御:0..3)

ByteSize= 5
ByteSize= 7
ByteSize= 7

StopBits= 0 (stopビット:0=1,1=1.5,2)
StopBits= 2 (stopビット:0=1,1=1.5,2)
StopBits= 0 (stopビット:0=1,1=1.5,2)


うーん、なんでこんなに設定が変わるのかわかりません。
変わっていないのは、StopBitsが1になっていることだけです。

628名無しさん:2015/10/26(月) 19:28:10
こんばんは

元のGW-BASICに返ってみました

open "com1:9600,n,7,2,rs,cs,ds,cd" as #2

QuickBasicのマニュアルによる、これらのオプションの意味は下記の通り

rs:RTSの検知を抑制
cs:CTSのタイムアウトを抑制
ds:DSRのタイムアウトを抑制
cd:DCDのタイムアウトを抑制


この中で、csとcdのオプションは省いてもデータは読み取れました。

open "com1:9600,n,7,2,rs,ds" as #2

これをF-BASICにすると、


OPEN "COM0:(S7N2N7NN,CS0,DS0)" as #2

となると思うんですが、これでもまだ読めません。
うーん、近くまで来ていると思うのですが、また明日挑戦してみます

629598:2015/10/27(火) 04:22:26
>>628
F-BASICがopen時設定したCOMポートへの通信条件設定を強制変更する
プログラムです。fRtsControlの設定を変更しています。

注:これは >616 のプログラムの後ろに続きます。(つまり >617 を差し替える)

#define RTS_CONTROL_DISABLE &H0
#define RTS_CONTROL_TOGGLE &H3

private declare function ADDR(byref A as long) as long
function ADDR(A as long) as long
'print "test=";hex$(varadr(A))
ADDR=A
end function
declare function _PBGETDCBNO alias "_$PbGetDCBNo@4" (byval FILENO as long) as long
declare function _PBGETDCB alias "_$PbGetDCB@4" (byval FBDCBNO as long) as long
declare function FB63_GETFILEHANDLE bdecl (byval FILENO as integer) as long
function FB63_GETFILEHANDLE (byval FILENO as integer) as long
var FBDCBNO as long, FBDCBDATA as long
FB63_GETFILEHANDLE= INVALID_HANDLE_VALUE
select case FILENO
case 1 to 255
FBDCBNO= -1
FBDCBNO= _PBGETDCBNO(clng(FILENO))
if FBDCBNO = -1 then error 57:exit function
FBDCBDATA=0
FBDCBDATA=_PBGETDCB(FBDCBNO)
if FBDCBDATA = 0 then error 60:exit function
FB63_GETFILEHANDLE=FBDCBDATA
FBDCBDATA=FBDCBDATA+&H108 'オフセット
FB63_GETFILEHANDLE=ADDR(byval FBDCBDATA)
case else
error 50
end select
end function

declare sub TEST2_SETSTATE(byval FILENO%)
sub TEST2_SETSTATE(byval FILENO%)
var RES as long
var DCB as T_DCB, HFILE as long
var F as long, M as long

HFILE= FB63_GETFILEHANDLE(FILENO%)
if HFILE=0 or HFILE=-1 then HFILE=INVALID_HANDLE_VALUE

if HFILE= INVALID_HANDLE_VALUE then print "Error:open":exit sub
RES=GetCommState(hfile, DCB) 'ポートの設定取得
if res=0 then
print "Error:GetCommState"
else
if DCB.DCBLENGTH<>len(T_DCB) then print "!!DCBlength(hex)=";DCB.DCBLENGTH
print "fBitFields(16進数)変更前=";hex$(DCB.FBITFIELDS)

'**ここで設定を変更する**
F=DCB.FBITFIELDS '*bit毎設定必要
'----fRtsControl----
F=F and (not FRTSCONTROL) 'ビット消去
M=FRTSCONTROL :M=M and (M \ 2) '※下位ビットを残す
M=M * RTS_CONTROL_TOGGLE '設定値
F=F or M 'ビット設定
print "fRtsControl書換";RTS_CONTROL_TOGGLE ;" (RTS フロー制御:0..3)"
'--------
DCB.FBITFIELDS=F '設定
'****
print "fBitFields(16進数)変更後=";hex$(DCB.FBITFIELDS)

'設定を強制更新する
RES=SetCommState(hfile, DCB)
if res=0 then
print "Error:SetCommState"
endif
endif
end sub

'--------
var CM$, R$(4-1)
baud 0,9600
CM$="COM0:(S7N2N7NNN)"
open CM$ for output as #2 : open CM$ for input as #1
TEST2_SETSTATE 2 '←ファイル番号のCOM設定を強制変更する
WAIT 100

if not eof(1) then print "!!受信バッファが空でない!"

print"!!送信始!!"
print#2,"D";chr$(13);
wait 50
while eof(1) :print"*"; :wend ' 受信開始までループ
print:print"!!受信始!!"
wait 5
while lof(1) < 14*4 :print"."; :wait 5 :wend ' 全フレーム受信までループ
print:print"!!受信終!!"
line input#1,R$(0) :print "!!Frame-1入力"
line input#1,R$(1) :print "!!Frame-2入力"
line input#1,R$(2) :print "!!Frame-3入力"
line input#1,R$(3) :print "!!Frame-4入力"
close
stop:end

630名無しさん:2015/10/27(火) 09:14:21
ありがとうございました。
作成していただいたプログラムでデータを計測器から読み込むことができました。

これが実行結果です。

fRtsControl書換 3 (RTS フロー制御:0..3)
fBitFields(16進数)変更後=3011
!!受信バッファが空でない!
!!送信始!!
!!受信始!!
!!受信終!!
!!Frame-1入力
!!Frame-2入力
!!Frame-3入力
!!Frame-4入力
AC 096.01 V 13
13
FR 00.060 kHz 13
dB 041.86 dBm 13
中断しました com_cond2.bas[165行]
任意のキーを押してください

もし、可能でしたら、計測器と通信できなかった理由を教えていただけると勉強になります。


ここからは報告です。

連続したデータが欲しいので、FOR NEXTのループを作りました。
下記がその中の命令です。

>print#2,"D";chr$(13);
>line input#1,R$(0) :print "!!Frame-1入力"
>line input#1,R$(1) :print "!!Frame-2入力"
>line input#1,R$(2) :print "!!Frame-3入力"
>line input#1,R$(3) :print "!!Frame-4入力"

実行すると、一番最初に読み込んだデータ(R$(0))の先頭に00(NULL)が2バイト付いていました。

(00)(00)AC 096.01 V 13

R$(1)〜R$(3)は問題ありません。

そして、2番目ループ以降は00(NULL)が1バイトになりました。
(00)AC 096.01 V 13

R$(1)〜R$(3)は問題ありません。

プログラムで取ってしまえば問題ないのですが、このNULLが少し気になります。

今回はありがとうございました。
本当に助かりました。

631名無しさん:2015/10/28(水) 12:02:26
>>630  まずは原因の方から。
最初に推定するための情報を列挙します。
通信条件設定の表示テスト結果 >624-625 >626 から違いを見ると、
[fDtrControl]
0=DTR_CONTROL_DISABLE (DTRは常にOFF)←[GW-BASIC]
1=DTR_CONTROL_ENEBLE (DTRは常にON) ←[F-BASIC]
[fRtsControl]
0=RTS_CONTROL_DISABLE (RTSは常にOFF)←[GW-BASIC]
1=RTS_CONTROL_ENABLE (RTSは常にON) ←[F-BASIC]
そして >611 のデジタルマルチメータのデータ通信資料、(コネクタに無い信号線がある)
そして >621 のRS-232Cの関連情報、QuickBasicの通信条件オプション(,rs)

 次に通信条件設定の内容とテストの状況から、要因を探ります。

・F-BASICで受信時に「[27]システムに異常があります」原因不明エラーで受信不能。
ただ、ヌル(00h)が受信されていた。とりあえず受信不可能ではないらしい。
・ケーブルは普通にストレート。問題なし。
・ポートはマザーボードのものでUSB変換ではないし、GW-BASICで使えている。
・デジタルマルチメータ側端子には無い信号線がある。
・ハードウェアフロー制御はなし。→(通信量的に必要ないし無用な製品製造コスト)
・DSRの状態はPC側で無視している。
・CTSは?。PC側でCTS監視による送信フローはしない設定。→たぶんPC側ですべて無視。
・DTRはON/OFFどちらでも反応(受信)はする。→たぶん無視している。
・GW-BASICの通信条件オプション(,rs)→PC側でRTS関連のなにかを無視して通信している。
・RTSが常時OFFでもGW-BASICで正常通信できる。→無視しているのか?
・RTSが常時ONのF-BASICではデータ受信できない。→なぜ?。では完全無視ではない!。

可能性1-コマンド送信ができないまたは送信したが無視される。
$A-送信ができない。→DSRは無視、CTSは見ない。だから送信できないことはないだろう。
$B-送信したコマンドが無視される。→なぜ?。print# は変更しても変わらなかった。
$→それでは別の要因でABいずれかの問題が発生か?→要因は何か?設定違いはRTS、DTR。
可能性2-データ受信ができないまたは送って来ない。
$A-受信ができない。→RTS常時ONだから?。そもそも受信できないはずがない・・。
$B-データを送って来ない。→RTS常時ONだから?。なぜ?。
$C-送って来たデータをPC側が無視した?。→DSRは無視しているはずだし、Aに同じ。
$→要因は何か?設定違いはRTS、DTR。

 これらから原因を推測すると、
DTRの可能性は低そう。DTR常時OFFで動くし、フロー制御なし設定なのだから。
ただしDTRをONにしていると(PC側の機種の判断材料)動作が変更されるのなら話は別だが…。
RTSの可能性が濃厚。それにF-BASICには",rs"オプションに当てはまりそうなものは無い。

RTSの違いが原因だと仮定して、とりあえずRTSをGW-BASICと同じく常時OFFに設定すればよい。
RTSがONだと送信または受信に支障が出るとすると、
  送 受
OFF○ ○(これは成功)
ON × - 送信で失敗と仮定だと→コマンド送信失敗ではデータが来ない…。
ON ○ × 受信で失敗と仮定だと→ONでも送信できるが、受信は失敗。
ON × × 両方失敗と仮定→常時OFFでなければ失敗。

ただ、送信時と受信時でON/OFFが異なれば受信成功するという可能性もまだある。
そのような場合のRTS(Request To Send)の動きは半二重通信方式の場合が考えられる。
半二重通信では送信と受信を同時には行えず、送信する時にはONにする。
これに該当しそうな設定は、次のものらしい。
3=RTS_CONTROL_TOGGLE (トグル)
(有効な送信用Bytes(データ)があればRTSをONにする。バッファのデータを
すべて送信した後、RTSをOFFにする。)

 とりあえずの結論としては、RTS_CONTROL_TOGGLEに設定してみるか、
RTS_CONTROL_DISABLE (RTSは常にOFF)にできれば通信はできると予想。

632名無しさん:2015/10/29(木) 02:57:36
>>630
 今回の問題は、GW-BASICというよりIBM PC初期の時代に依存している
・RS-232Cの制御線をほとんど無視して使わない、簡略化した通信。
・IBM PCが世界のすべて。IBM PCの都合(制約)にあわせる。
(IBM PCのシリアルポートは「シリアルポート」であって厳密にはRS-232C準拠ではない。)
・機器側に省略された制御線があるので普通の全二重通信はできないし、
使う前提ともしていない。(RS-232C準拠と言えない)
・通信電文は短かく、ハードウェアフロー制御(全二重通信)はない。
・送出した通信電文が欠落などしないという前提。

・通信は必ずPC側から始まる。(だから全二重通信なんていらない)
・半二重通信もどきで十分だ。(さらに簡略化している)
・簡略化しているので相手の通信状態なんて原則無視。
・この簡略化した通信方法は低い製造コストでIBM PCと通信できるように最適化。
(その方法がバッドノウハウで長年継承されている。)

・F-BASICは半二重通信方式をサポートしない。
(たとえば半二重モデム側が問題吸収する必要がある)
・F-BASICはRS-232C準拠といえない通信手順は使用する前提としていない。


ゆえに通信条件設定をF-BASICから強制的に変更しなければならない。
[fRtsControl]
0=RTS_CONTROL_DISABLE (RTSは常にOFF)←[GW-BASIC]
1=RTS_CONTROL_ENABLE (RTSは常にON) ←[F-BASIC]

633598:2015/10/29(木) 03:43:08
>>630
>プログラムで取ってしまえば問題ないのですが、このNULLが少し気になります。

 00(NULL)についてですが、いくつか可能性を挙げてみると、

・RTSをONにすると送ってくる。(なにかの対策のための動作?)
・RTSの変化に応じて送ってくる。(制御線を使わないので、代替の応答としている。)
・測定データ送信時の先触れとして送っている。(データ受信取りこぼしを防ぐため?)
・PC側から送信したコマンドを受領した意味で応答している。
・なにかのタイミングで定期的に送っている。(制御線を使わないので、生存証明。)

 おそらくGW-BASICなどでは内部の処理で、受け取った00(NULL)を捨てているので、
表にあらわれないのではないかと推測します。

 対策として次の個所(TEST2_SETSTATEの中)にプログラムを追加してください。
#'**ここで設定を変更する**
#F=DCB.FBITFIELDS '*bit毎設定必要
#'----fRtsControl----
##(省略)#

$$←←←ここに挿入$$
DCB.FBITFIELDS=F '設定

$$
'----fNull----
M=fnULL '設定値
F=F or M 'ビット設定
print "fNull書換";" (NULL BYTES 受信を破棄する)"
$$

 つぎにデータ受信本体プログラムのこの行を変更。
(変更前)if not eof(1) then print "Error:受信バッファが空でない!"
(変更後)if not eof(1) then R$(0)=input$(LOF(1),#1):R$(0)="" '最初のNULL受信破棄

 つぎにclose命令の後にこの1行を追加。
#close
TEST1_SETSTATE_NULLCHAR CM$ 'COMポートのfNull設定解除する

 最後に、以下のプログラムを追加します。(TEST2_SETSTATE〜end subの後ろ、var CM$, R$(4-1)の前)

declare sub TEST1_SETSTATE_NULLCHAR(FDSCRP$, byval SW%= 0)
sub TEST1_SETSTATE_NULLCHAR(FDSCRP$, byval SW%)
var RES as long, DCB as T_DCB
var HFILE as long
var F as long, M as long
var DEVNAME$

if SW%<0 then SW%=0
if SW%> 1 then SW%=1
select case ucase$(left$(FDSCRP$,5))
case "COM0:"
DEVNAME$="COM1"
case "COM1:"
DEVNAME$="COM2"
case "COM2:"
DEVNAME$="COM3"
case "COM3:"
DEVNAME$="COM4"
case "COM4:"
DEVNAME$="COM5"
case else
error 55 :exit sub
end select

HFILE=INVALID_HANDLE_VALUE
HFILE = CREATEFILE(DEVNAME$, (GENERIC_READ or GENERIC_WRITE), 0, NULL, OPEN_EXISTING, 0, NULL)
if HFILE= INVALID_HANDLE_VALUE then print "Error:open失敗":exit sub

RES=GetCommState(hfile, DCB)
if res=0 then
print "Error:GetCommState"
RES=CLOSEHANDLE(HFILE)
else
if DCB.DCBLENGTH<>len(T_DCB) then print "!!DCBlength(hex)=";DCB.DCBLENGTH

'**ここで設定を変更する**
F=DCB.FBITFIELDS '*bit毎設定必要
'----fNull----
F=F and (not fnULL) 'ビット消去
M=fnULL
M=M * clng(SW%) '設定値
F=F or M 'ビット設定

if DCB.FBITFIELDS <> F then
print "fBitFields(16進数)変更前=";hex$(DCB.FBITFIELDS)
DCB.FBITFIELDS=F '設定
print "fBitFields(16進数)変更後=";hex$(DCB.FBITFIELDS)

'設定を更新する
RES=SetCommState(hfile, DCB)
if res=0 then
print "Error:SetCommState"
endif
endif
RES=CLOSEHANDLE(HFILE)
endif
end sub

634名無しさん:2015/10/29(木) 18:31:47
丁寧な説明ありがとうございます。

ちょっとバタバタしていて、ちゃんとした返信が返せません。
すぐに落ち着きますので、すこしの間失礼します。

635名無しさん:2015/10/30(金) 03:12:00
>>630
>>633
修正です。 >633 の説明の「TEST1_SETSTATE_NULLCHAR CM$」から最後までは
取り消します。替わりに再オープン/クローズしてください。

#close
open CM$ for output as #2 :close #2 ' 通信設定を再初期化

 むだに見えますが、fNull の設定は解除しておいたほうがよいので。

636名無しさん:2015/10/30(金) 16:36:49
遅くなって申し訳ありません。

#632のまとめがとても参考になりました。

つまり、この計測器は簡略化された半二重通信でPCと通信をする仕様になっているので、F-BASICから通信条件を変更する必要がある。

このプログラムを実行すると、

fRtsControl書換 3 (RTS フロー制御:0..3)

と表示されるので、

3=RTS_CONTROL_TOGGLE

ということで、RTSフロー制御にTOGGLEが指定されています。

このTOGGLEというモードは(恥ずかしながら)知らなかったので調べてみたところ、

http://www.geocities.jp/terukat/_geo_contents_/win/comm.html
トグルの場合、 受信バッファにデータがなければ RTS がOFFになり、 データがあればONになります。

とあります。つまり、ここでRTSをOFFにしているという理解でよろしいでしょうか。

月曜日に、新しくコーディングしていただいたプログラムを走らせてみます。

637598:2015/10/31(土) 03:56:11
>>636
>つまり、この計測器は簡略化された半二重通信でPCと通信をする仕様になっているので

 はい、そのいう状態だと判断しました。
通信用LSIチップとしては同時に送・受信バッファの処理はできるのでしょうけれど。

>このプログラムを実行すると、fRtsControl書換 3 (RTS フロー制御:0..3)

 はい、fRtsControlという項目を RTS_CONTROL_TOGGLE(値は3)に書き換えて
Windows API のSetCommState (kernel32.DLL内)を実行してWindows経由でシリアルドライバを
設定します。

 「RTS_CONTROL_TOGGLE(トグル)モード」については、わたしもまったく知りませんでした。

で、このモード、
Windows“では”サポートされているらしく、 >624 のテスト結果ご報告にあるように
GW-BASICでは、RTS_CONTROL_DISABLE(値はゼロ)つまり、RTSは常時OFFに設定しています。
GW-BASICやQBASICでも、トグルモードは持っていないと思われ、
RTS_CONTROL_DISABLEにしています。昔はOUT命令でI/Oポートをじかに叩く制御方法が
とられたこともあるようです。

 常時OFFでいいのなら、F-BASICで問題が起こらなくてもと思うのですが、実態は
計測器側が受け取ったRTSの状態を見て、通信を保留していると推察されます。
常時ONのときだめになるので、おそらくは測定データ送信時。
PCからコマンド送信は制御線無視してのいきなり送りつけOKだが
測定データ送信は制御線を(ちゃんと?)見てから送り返していると。

 ならば常時OFFで実用上問題ないと。通信規約上はおかしいけど。
 そのいう状態だと判断しました。


>トグルの場合、 受信バッファにデータがなければ RTS がOFFになり、

 それは参照先記載の誤りで「送信バッファ」だと解釈しました。
たぶん「ハンドシェイク」の説明文につられて書き間違えていると。
 ( >621 の参照Webページ参照)

 原文はつぎのとおりです。
RTS_CONTROL_TOGGLE (0x03): トグルモード
Specifies that the RTS line will be high if bytes are available for transmission.
After all buffered bytes have been sent, the RTS line will be low.


テストプログラム >633 (+ >635 訂正)では、設定にさらにfNullの項をONにするよう
追加します。ただ、設定前に受信したNULL(00h)はそのままでしょうから、
「!!受信バッファが・・」への対処は必要なままでしょう。

※「fn」で始まる変数名はF-BASICの言語仕様上、使用できません。この追加部分にある
fnULLは(変数でもFN関数(*に見えるが)でもない)、#define 文によって
プリプロセッサで処理されているため、成立しています。

638名無しさん:2015/10/31(土) 11:30:55
おはようございます
詳細な解説ありがとうございます。

私なりに今回の通信手順を考えてみたのですが、

PCはRTSをONにする
PCは計測機に"D"を送る

PCの送信バッファが空になるので、RTSはOFFになる
計測機は"D"を受け取った後にPCのRTSがOFFになっていれば計測値をPCに送る
PCは計測値を受け取る

PCはRTSをONにする
PCは計測機に"D"を送る(print "D")

以下、繰り返し

*最初(最後)の2つステップはPRINT "D"の際に連続して行われる

たしかに半二重通信になっているので、これがRTSを使った半二重通信ということになるんでしょうね。

今回は全二重通信を前提としたWindowsのRS-232で半二重通信を行うために、工夫していただいたと思うのですが、最初から、RS-485のインターフェイスを使えば、そのままcomポートにアクセスが可能なのでしょうか。

http://www.ratocsystems.com/products/subpage/usb70.html
http://www3.contec.co.jp/B2B/ConIWCatProductPage_B2B.process?Merchant_Id=1&amp;Section_Id=6&amp;Catalog_Id=6&amp;Product_Id=1429

639名無しさん:2015/10/31(土) 13:38:02
このサイトでは、このような通信手順を「ゲート制御」とよばれています。

http://webcache.googleusercontent.com/search?q=cache:nR9WV32YowQJ:https://social.msdn.microsoft.com/Forums/ja-JP/2922a81b-d439-4a70-aaa6-28c43a63833f/com%3Fforum%3Dvcgeneralja%2Bwindows+rts+rs-485+RTS_CONTROL_TOGGLE&amp;lr=lang_ja&amp;client=safari&amp;rls=en&amp;hl=ja&amp;tbs=lr:lang_1ja&amp;prmd=ivns&amp;strip=1&amp;vwsrc=0

たしかに、PCではなくマイコンで制御するならその方がシンプルですよね。パソコン(当時はPC-98)を使いはじめて、30年も経とうとしているのに知りませんでした。

640名無しさん:2015/10/31(土) 14:25:23
このサイトでは、このような通信手順を「ゲート制御」とよばれています。

http://webcache.googleusercontent.com/search?q=cache:nR9WV32YowQJ:https://social.msdn.microsoft.com/Forums/ja-JP/2922a81b-d439-4a70-aaa6-28c43a63833f/com%3Fforum%3Dvcgeneralja%2Bwindows+rts+rs-485+RTS_CONTROL_TOGGLE&amp;lr=lang_ja&amp;client=safari&amp;rls=en&amp;hl=ja&amp;tbs=lr:lang_1ja&amp;prmd=ivns&amp;strip=1&amp;vwsrc=0

たしかに、PCではなくマイコンで制御するならその方がシンプルですよね。パソコン(当時はPC-98)を使いはじめて、30年も経とうとしているのに知りませんでした。

641598:2015/11/01(日) 05:04:14
>>638
>WindowsのRS-232で半二重通信を行うために、工夫していただいたと思うのですが、
>RS-485のインターフェイスを使えば、そのままcomポートにアクセスが可能なのでしょうか。

 RS-485(EIA-485)は、二本線一組とする平衡型伝送路で差動式の信号でやりとりし、
電気的特性はまったく異なる。
コネクタ形状やピン配置は別規格に分かれて定義。

 通信規約(プロトコル)は、RS-232から流用したものが多いものの製品次第というところで
しょうか。

 また、半二重と全二重についてもどこを指しているのかによって意味合いが異なるので、
要注意です。(RS-232でもそうですが)

仮想COMポート側から見て全二重通信のハードウェアフロー制御ONでも使用可能であれば
普通に使えるということになるかと思います。

参考情報:(アイ・ビー・エス・ジャパン株式会社、サイト内)
http://www.ibsjapan.co.jp/tech/details/rs-422-485/rs-422-485-double.html


 ソフトウェアの条件としては、
・仮想COMドライバにより、アプリケーションからは通常のCOMポートのように見えること。
(専用デバイスドライバのプロパティまたは専用ユーテリティで、COMポート番号割り当てが
固定で設定できること。)
・Win32 APIのコミュニケーション関数系(SetCommStateなど)やCreateFile関数などで
使用できること。(あるいはVB6のコントロール(MSComm)対応ならたぶんOK)

・RTS_CONTROL_TOGGLEモードが使用可能かどうかは問い合わせ確認が必要だと思います。
(もし対応不可でかつRTS_CONTROL_TOGGLEモードが必要な場合は、RTS等をその都度個別に
ON/OFF制御する処理を行う必要があり、その場合のF-BASIC実行時の影響は不明です。)

・専用デバイスドライバ(仮想COMドライバ)や専用ユーティリティの対応OSをご確認ください。
・F-BASICで使用できるCOMポートは1から5まで。(F-BASIC中の指定は"COM0:"から"CON4:")
・通信ボーレートが普通のCOMポートを越える高速レートはF-BASICで使用できないかも
しれません。(未確認事項)


○REX-USB70
※機器側I/Fは、ハード実験用向けネジ式端子台(計7ピン)。
〜〜抜粋〜〜(注:2012年2月版より)
本製品は内部でRTS/CTS DTR/DSRが処理されており、ドライバ・レシーバのON/OFF制御に
RTSとDTRを次のように設定します。
RS-455(半二重):送信時 RTSをON。受信時 RTSをOFF、DTRをON。※「RTSモード」時の場合
RS-455(全二重):送信時 RTSをON。受信時 DTRをON。

〜〜抜粋〜〜
RS485の場合はDTRを常時OMにして通常自分が送信したデータを自分で受けて
送信したデータが正しいかを確認します。
〜〜〜〜〜〜

●2015年3月出荷分からの新機能
半二重使用時、トランスミッターの自動制御モードをサポート。
 半二重通信での送信設定は、トランスミッターをRTS信号により制御する「RTSモード」の
ほか、トランスミッターが自動で送信可能状態になる「自動制御モード」の選択も可能。
本体側面のDIPスイッチ3にてモードの切り替えをおこないます。(出荷時はOFF(RTSモード))


○COM-1PD(USB)H
9ピンD-SUBコネクタ(オス)の採用により、9ピンD-SUBコネクタ(メス)のケーブルに
接続できます。
データ伝送モード(全二重、半二重)は、スイッチ(DIP SW)を切り替えることで設定を
変更できます。

〜〜抜粋〜〜
半二重、全二重の切り替えや全二重時のRTS/CTSの切り替えは、データ伝送モード用
設定スイッチ(DIP SW)で設定できます。設定は、ビット1 - 6で設定します。

半二重:
 データラインはTxDだけとなり本製品のRTS信号により、送信/受信モードを
切り替えることができます。
全二重/RTS,CTSを自己ループさせる:
 接続機器にRTS, CTS信号が無い場合、この設定にすると本製品のRTS信号をアクティブに
することで、CTS信号がアクティブになります。
全二重/RTS,CTSを相手装置と接続する:
 接続機器のRTS, CTS信号と接続して使用します。

〜〜抜粋〜〜
RTS+, RTS-, CTS+, CTS-の制御線をソフトウェアで制御や監視が可能です。
〜〜〜〜〜〜

642名無しさん:2015/11/01(日) 05:30:43
>>639
「ゲート制御」ですか...

知らないことなのでわからないのですがEIA-485の向こう側、伝送路と言えばいいので
しょうか、そこのドライバ・レシーバの切り替え(送受信の切り替え)の制御のことを
指しているのではと愚考いたします。
送信の一組(TxD+,TxD-)のみで、送信も受信も行う場合の切り替えることかと。

643名無しさん:2015/11/01(日) 10:41:56
ありがとうございます。

実際に製品を借りるか買って試してみる必要がありそうですね。
しばらく、RTS_CONTROL_TOGGLEを使いこなせるか、F-BASICのプログラムをしてみます。この手法は、計測器で使うにはノイズにも強そうですね。

644名無しさん:2015/11/02(月) 11:32:50
おはようございます。

プログラムを実行してみました。

1回目に出てくる(null)(null)は(null)になりましたが、やはり1レコードの最初にくっついているnullはそのままです。これはいつも行頭についているので、trimで取れますので問題ありません。それからフローのタイミングが合わなくなるのか、時々、"!!送信始!!"の表示後にハングします。下記が新たに633書いていただいたコードです。

declare sub TEST2_SETSTATE(byval FILENO%)
sub TEST2_SETSTATE(byval FILENO%)
var RES as long
var DCB as T_DCB, HFILE as long
var F as long, M as long

HFILE= FB63_GETFILEHANDLE(FILENO%)
if HFILE=0 or HFILE=-1 then HFILE=INVALID_HANDLE_VALUE

if HFILE= INVALID_HANDLE_VALUE then print "Error:open":exit sub
RES=GetCommState(hfile, DCB) 'ポートの設定取得
if res=0 then
print "Error:GetCommState"
else
if DCB.DCBLENGTH<>len(T_DCB) then print "!!DCBlength(hex)=";DCB.DCBLENGTH
print "fBitFields(16進数)変更前=";hex$(DCB.FBITFIELDS)

'**ここで設定を変更する**
F=DCB.FBITFIELDS '*bit毎設定必要
'----fRtsControl----
F=F and (not FRTSCONTROL) 'ビット消去
M=FRTSCONTROL :M=M and (M \ 2) '※下位ビットを残す
M=M * RTS_CONTROL_TOGGLE '設定値
F=F or M 'ビット設定
print "fRtsControl書換";RTS_CONTROL_TOGGLE ;" (RTS フロー制御:0..3)"
'--------
DCB.FBITFIELDS=F '設定

'----fNull----
M=fnULL '設定値
F=F or M 'ビット設定
print "fNull書換";" (NULL BYTES 受信を破棄する)"

'****
print "fBitFields(16進数)変更後=";hex$(DCB.FBITFIELDS)

'設定を強制更新する
RES=SetCommState(hfile, DCB)
if res=0 then
print "Error:SetCommState"
endif
endif
end sub

645名無しさん:2015/11/03(火) 01:43:50
>>644
えっ? プログラム「'----fNull----」〜〜 の挿入位置が違っているのでは。

#DCB.FBITFIELDS=F '設定  ←この行の手前(上側)です。

設定すべき値は、「fBitFields(16進数)変更後」の表示値が3811になります。


ハングアップについては、
先頭のNUL(00h)読み飛ばしの後にWAIT 50をいれてみてください。

直らない場合は、一旦、先頭のNUL(00h)読み飛ばしをやめてみてください。
(元に戻す)if not eof(1) then print "Error:受信バッファが空でない!"


TRIM$関数系では00hは排除できないと思うのですが。

646名無しさん:2015/11/03(火) 10:23:16
おはようございます。

>プログラム「'----fNull----」〜〜 の挿入位置が違っているのでは。
すみません、「$$←←←ここに挿入$$」の意味を読み切れませんでした。
明日、そこを直してみます。

こんな感じでprint文を使って送受信バッファの内容を見ているんですが、問題はないようです。WAITは入れています。

print eof(1), eof(2)
print #2,"D"
print eof(1), eof(2)
line input#1,R$(0)
print eof(1), eof(2)

ハングアップはこの2行の間です。
(eofは両方とも-1を返す)

print eof(1), eof(2)
line input#1,R$(0)

> TRIM$関数系では00hは排除できないと思うのですが。
そうでしたか。TRIM$は20hだけでしたか。

647名無しさん:2015/11/03(火) 12:05:03
>>646
 あ、“$”が「この間、省略」に見えたんですね、すみません。

>print eof(1), eof(2)
 確認がとれていないのですが、EOF関数・LOF関数はたぶん受信バッファしか取れないはず。

 TRIM$関数系は日本語対応で、半角空白および全角空白に作用します。

それで、ハングアップについてですが、可能性についていくつか。
・EOF(1)で真が返される間(空)はLINE INPUT#1 の実行は避けなければならない。
(とりあえずは受信タイムアウトの設定をしない限り)
・PRINT#2,"D" で処理後、ただちにデータが送り返されるわけではない。
(測定値確定と送信用測定データ作成、送受信切り替えのタイムラグ)
・コマンド"D"[CR]とコマンド"D"[CR/LF]とで、計測機側の動作の影響が不明。
・コマンド送信後、すべてのデータ受信を完了しないうちに次のコマンドを送ると問題の可能性。
・もし、コマンド送信-データ受信を一度に複数回おこなっている場合は、
計測機側の処理限界を超えた可能性。
・コマンド送信後、測定対象物や計測機側の問題で「欠測」した場合。この動作は不明。

・「コマンド送信 〜 データ受信完了」の一連のサイクルを高速で繰り返してはならない。
資料( >611 )より、
Caution:
For exact measurement and good communication with PC, use “data request” signal
once per one second.
Data Conversion time:
Data Conversion time is based on conversion time of ADC included in DMM and is 2 or
3 times per one second.
[翻訳]
注意:正確な測定とPCとの良好な通信のためには、1秒に1度「データ要求」信号を使用する。
データ変換時間:データ変換時間は、DMM内蔵ADC(訳注:アナログ-デジタル変換)の変換時間を
基本として、1秒あたり2〜3回である。
[了]


 最後に文字列先頭のNUL(00h)を除去する関数プログラム例を。(空白は除去しません)
(使用例): R$(0)=LTRIMCTRL$(R$(0))


declare function LTRIMCTRL bdecl (S as string) as string
function LTRIMCTRL$ (S$)
'機能:引数で指定された文字列の左側の制御コード等を取り除きます。
var I as long ,P as long ,N as long
LTRIMCTRL$=S$
N=len(S$)
if N=0 then exit function
P=0 :I=0
do
I=I+1
select case asc(mid$(S$,I,1))
case is < &H20
case &H7F,&HFF
case else
exit do
end select
P=P+1
loop while I < N
if P > 0 then LTRIMCTRL$=mid$(S$,P+1)
end function

648名無しさん:2015/11/04(水) 13:18:39
いつもありがとうございます。

そっそく、プログラムを修正しました。

NULLも取れ、ハングアップも少なくなりました
wait 50 --> wait 100 にすればもっとよくなりそうです。
長い間、お世話になりました。

ところで、マルチメーターの箱の中にFDを見つけました。これは計測をするためのGUIソフト(DMM_4660)が入っていて、これを使った後のシリアルの状態をみてみました。fBitFieldsの値(0811)をみると、fRtsControlはしていないみたいです。気づくのが遅れてすみません。


新プログラム実行後
fBitFields(16進数)=3811
fOutxCtsFlow= 0
fOutxDsrFlow= 0
fDtrControl= 1 (DTR フロー制御タイプ:0..2)
fDsrSensitivity= 0
fErrorChar= 0 (エラー時文字置き換える)
fNull= 1 (NULL BYTES 受信を破棄する=1)
fRtsControl= 3 (RTS フロー制御:0..3)
fAbortOnError= 0
ByteSize= 7
StopBits= 2 (stopビット:0=1,1=1.5,2)
ErrorChar(16進)=0
EofChar(16進)=0
EvtChar(16進)=0
終了します。なにかキーを押してください。


DMM_4660実行後
fBitFields(16進数)=811
fOutxCtsFlow= 0
fOutxDsrFlow= 0
fDtrControl= 1 (DTR フロー制御タイプ:0..2)
fDsrSensitivity= 0
fErrorChar= 0 (エラー時文字置き換える)
fNull= 1 (NULL BYTES 受信を破棄する=1)
fRtsControl= 0 (RTS フロー制御:0..3)
fAbortOnError= 0
ByteSize= 7
StopBits= 2 (stopビット:0=1,1=1.5,2)
ErrorChar(16進)=0
EofChar(16進)=0
EvtChar(16進)=0
終了します。なにかキーを押してください。

649名無しさん:2015/11/04(水) 21:44:18
今日、他の計測器を使っていて気づいたことなのですが、計測器からデータを読み出す時に、line input#でやるとハングアップする(待ち状態が続く)のですが、INPUT$でやると問題なく読み出せました。

その時も、INPUT$で指定したバイト数が、受信データと同じか少なければ読み出せるのですが、多いとline input#と同じになりました。

明日、もう一度、チェックしてみます。

650名無しさん:2015/11/05(木) 01:11:10
>>648
>これを使った後のシリアルの状態をみてみました。fBitFieldsの値(0811)をみると、fRtsControlはしていないみたいです。

 GUIソフト(DMM_4660)、これはfRtsControlはDisable(RTS常時OFF)です。
GW-BASICの場合と同じです。違いはfNullが有効になっていますね。
あ、fDtrControl=1も違いますね。

GW-BASICではMS-DOS環境が対象であり、DMM_4660はWindows環境が対象であることが、
違いに出ています。

純正品といってもよいサンプルGUIソフト(DMM_4660)の設定がこうなっているということは
fRtsControlの設定が何であれ、NUL(00h)は送られてくるという証左かもしれません。


 fNullを有効にした場合は、使用後無効にするようにしてください。
これは他のソフトの安全のためです。
F-BASICの場合はとりあえずOPEN/CLOSEを再度行えば無効に再設定されます。


>>649
 それは正常な動作です。通信相手の区別はありません。
LINE INPUT#は。改行コードを得る(かたぶんEOFコードを得る)まで処理が戻ってきません。
ゆえにもしも通信時改行コードが文字化けした場合は、永久的に処理が戻ってこなくなります。
INPUT$関数は通信時指定された文字数(バイト数またはオクテット数)を得るまで処理が
戻ってきません。

通信においてはいつ相手が残り(続き)のデータを送信してくるかは事前にわからないため
そのような動作になっています。

651名無しさん:2015/11/05(木) 15:49:54
いつもありがとうございます。

>GW-BASICではMS-DOS環境が対象であり、DMM_4660はWindows環境が対象
うーん、考察が深いです。そこまで考えませんでした。

>LINE INPUT#は。改行コードを得る(かたぶんEOFコードを得る)まで処理が戻ってきません。
>INPUT$関数は通信時指定された文字数(バイト数またはオクテット数)を得るまで処理が戻ってきません。
恥ずかしながら、これまで、INPUT$、LINE INPUT#、INPUT#の違いはあまり考えておりませんでした。

いろいろとお世話になって、とりあえずデータのロギングは問題なくなりました。
ハングアップもほとんどなくなりました。
ありがとうございました。
もう一つ相談したいことがあるのですが、それは別にします。
今後とも、よろしくお願いします。

652名無しさん:2015/11/06(金) 03:34:39
>>651
 こちらこそテスト調査に協力いただきありがとうごさいます。
おかげでRS-232C問題の回避策を実証できました。

653名無しさん:2015/11/06(金) 08:37:38
こちらこそ、勉強になりました。

ここも参考にさせていただきました。
http://infoseek_rip.g.ribbon.to/spectrum123.at.infoseek.co.jp/vb/vb_2/vb_2.htm

EscapeCommFunctionを使うと直接RTSのON/OFFができるみたいです。

ここのP.32にF-BAISCのサンプルもあったので、時間が取れたらやってみようと思います。
http://www.fmworld.net/product/soft/fbasic/faq/faq.pdf

654名無しさん:2015/11/06(金) 09:26:45
F-BASICを使って、1秒とか、0.5秒間隔で計測器からデータを読み出しています。
今はwaitを使っているのですが、もう少し精度(1/100〜1/1000程度)が欲しい。
GPSを接続して、PPSをもらうという方法もあるのですが、いつも衛星にアクセスする必要があります。
何か簡単に使える方法をご存知でしたら、教えてください。

655598:2015/11/06(金) 09:48:04
>>653
あら、FILEATTR関数があったのね。車輪の再発明しちゃいました。

656名無しさん:2015/11/06(金) 11:03:33
>>654
WindowsやPC/AT機に時刻正確性を求められても・・

WAIT命令は100分の1秒単位ですが、

とりあえずはAPIのSleepEx関数を使うとか。一応は1ミリ秒単位の指定ですが。
https://msdn.microsoft.com/ja-jp/library/cc429359.aspx


計測間隔をできるだけ正確にということであれば、次のような感じでどうでしょう

・まず、プログラム変更
1.受信バッファを大きくする。
CM$="COM0:(S7N2N7NNN,RB4096)"
open CM$ for output as #2 : open CM$ for input as #1

2.送信コマンドをWAIT命令をはさんで一定間隔で連続で送る。
最低限の送受信時間からコマンド送信間隔を試算すると、
スタートビット(1)+データ長(7)+ストップビット(2)=計10bit
受信データ14*4フレーム+送信コマンド(2)=計58キャラクタ
580÷9600bps=約6〜7/100秒
※実際は計測器側の測定データ作成時間も必要なので、当然これよりは
時間がかかる。

for I%=1 to 50
print#2,"D";chr$(13);
wait 10
next I%

3.あとで一括して受信バッファから取得する。
for I%=1 to 50
line input#1,R$(0, I%)
line input#1,R$(1, I%)
line input#1,R$(2, I%)
line input#1,R$(3, I%)
next I%

・次に実行時
1.プログラムを起動する。ただし、まだ計測開始しない。
(このとき、F-BASIC開発環境経由ではなく、実行プログラムを直接起動すること)

2.タスクマネージャを呼び出して、[プロセス]のタブから当該実行プログラムを
探して、右クリック-[優先度の設定]-[高(H)]とか[リアルタイム(R)]に設定。
※少しでも正確性をあげるため。

3.計測開始を指示。

657名無しさん:2015/11/06(金) 11:20:29
>>654
>>656
http://www.tokineko.net/realtime/page1.html

658名無しさん:2015/11/06(金) 21:14:59

>受信バッファを大きくする
あ、これいいですね。
さっそく試してみます。

>送信コマンドをWAIT命令をはさんで一定間隔で連続で送る。
これもやってみます。

今は、waitで微調整しています。

計測データは時系列なので内挿してもいいかなと思っています。
そうなると、times$の分解能が1/100秒くらいならいいんですが。
と思って、ヘルプを見たらMILLITIMEという関数があるんですね。
これを使ったら何とかなるかもしれません。

659名無しさん:2015/11/07(土) 05:07:31
MILLITIMEはミリ秒単位に再計算しているので場合によるけど
直接GetLocalTimeで要るとこだけ記録したほうが無駄がないかも。

660名無しさん:2015/11/09(月) 04:56:41
waitで調整するより「タイマーコントロール」使う方法も考えてみては

661名無しさん:2015/11/09(月) 14:44:25
ご教授、ありがとうございます。

>直接GetLocalTimeで要るとこだけ記録したほうが無駄がないかも。
すいません、Windows APIはほとんど使ったことがないのですが、マニュアルを読んでみます。

>waitで調整するより「タイマーコントロール」使う方法も考えてみては
これも初耳なのですが、ヘルプに「タイマーコントロールへの操作」という項がありますので、これを使えばいいのかな。これはGUIでしか使えないのでしょうか?もうちょっと情報を調べてみます。

662名無しさん:2015/11/10(火) 03:37:28
>>661
F-BASIC/Winの場合はGUIと非GUIというような単純な区分けではありません。
WindowsのGUIの上で、従来互換のテキスト・グラフィック画面をエミュレートする
「テキストモード」と互換性をなくすかわりにWindowsの基本機能に近い形で従来命令を
使うモードとに分かれます。

F-BASICでは従来の「手続き型」とGUIで使う「イベント駆動型」のどちらの書き方も
できます。
極端なことをすれば混在させることもある程度はできます。
テキスト画面にGUIの「ボタン」があるなんてことも。
従来の手続き型のみで似たようなことをするとON MOUSE命令やMOUSE関数やINKEY$関数を
駆使してあれこれプログラムをすることになってしまいます。

本題に戻りまして、
「タイマーコントロール」ですが、『コントロール』とはいってもそれは便宜上の
ことで、Windowsの側から発生するタイマー通知の経路をウィンドウメッセージとして
受けているためです。
F-BASIC実行環境がタイマー通知を受けるための環境作りを裏方として準備してくれる
わけです。

従来BASICでいえば、インターバル割り込み命令(INTERVAL ON命令・ON INTERVAL GOSUB命令、
INTERVAL命令)とWAIT’I’命令を使う方法と基本的な考え方は同じです。

タイマーコントロールを使うにはまず「空の」フォームを作らないといけません。
(もし、すでに作って使っているならそれ(のコピー)を使えばいいです。)
そのフォームの中のどこでもいいのでタイマーコントロールを置きます。

次にフォームに置いた(見た目そっけない)タイマーコントロールをダブルクリックする
と中身が空のプログラム(イベントプロシージャ)が作成されます。
それを丸ごとコピーして、自分のプログラムに挿入します。元のイベントプロシージャは
不要なので保存せずに閉じてください。

これが言わば「ON INTERVAL GOSUB」の飛び先の中身に相当します。

とりあずフォームを作るための参考資料
http://www.fmworld.net/product/soft/fbasic/gpib/
 ワンポイントレッスン集  第一回「実行画面を大きくしよう」

663名無しさん:2015/11/10(火) 17:15:04
ありがとうございます。

フォームは作ったことがないので一から勉強してみます。
たしかにこれができると、世界が広がりそうですね。
マニュアルはあるんですが、CD付きの参考書が見当たらないので、これを探してみます。

>そのフォームの中のどこでもいいのでタイマーコントロールを置きます。
フォームは作れそうなんですが、ここから勉強のはじまりです。

664598:2015/11/11(水) 06:54:30
サンプルです。動くかどうかは謎ですが。実行時間26秒
(TEST2_SETSTATEサンプル必須)
なお、処理時間最優先のため、実行経過の表示はありません。
#include "windows.bi"

var FRUN as long,FEND as long
var TT&(50), RR$(4-1, 50) as string * 13 'データ保管領域確保
var TIMER1 as object
var CM$, R$(4-1), CNT1&, CNT2&, I&
TIMER1.ATTACH GETDLGITEM("TIMER1")
TIMER1.SETINTERVAL 50 ' (10ms単位)

baud 0,9600
CM$="COM0:(S7N2N7NNN)"
open CM$ for output as #2 : open CM$ for input as #1
TEST2_SETSTATE 2 '←ファイル番号の対応COM設定を強制変更する
wait 100
if not eof(1) then R$(0)=input$(lof(1),#1):R$(0)="" '最初の(00h)を捨てる
while CHECKEVENT :CALLEVENT :wend
TIMER1.ENABLE -1 'タイマー通知開始

*LOOP1
'イベント発生して処理されるまで待つ(かつ変数FRUNでタイマーイベントを待つ)
while FRUN=0 :WAITEVENT :wend
if FEND then *ENDING '中止して終了する
CNT1&=CNT1&+1
print#2,"D";chr$(13);
TT&(CNT1&)=millitime ' 00:00:00からの通算時間の値(1ms単位)

if CHECKEVENT then CALLEVENT
wait 10 '受信データ作成待ち
while eof(1) and FEND=0 :CALLEVENT :wend ' 受信開始までループ
if FEND then *ENDING

if lof(1) < 14 and FEND=0 then wait 5 :CALLEVENT ' 1行受信までもう少し待つ
if CHECKEVENT then CALLEVENT
if lof(1) < 14 then
print "!!データ受信エラー!!";lof(1)
R$(0)="":if lof(1) <> 0 then R$(0)=input$(lof(1),#1)
R$(1)="":R$(2)="":R$(3)=""
else
line input#1,R$(0) :if CHECKEVENT then CALLEVENT
line input#1,R$(1) :line input#1,R$(2) :line input#1,R$(3)
endif
RR$(0,CNT1&)=R$(0):RR$(1,CNT1&)=R$(1):RR$(2,CNT1&)=R$(2):RR$(3,CNT1&)=R$(3)
CNT2&=CNT2&+1

while CHECKEVENT :CALLEVENT :wend '未処理イベントの処理
FRUN=0 '次のタイマー通知へ
if CNT1& < 50 then *LOOP1 '繰り返し

*ENDING
if CHECKOBJECT(TIMER1) then TIMER1.ENABLE 0 'タイマー停止
if CHECKEVENT then CALLEVENT
if CHECKOBJECT(TIMER1) then TIMER1.DETACH 'オブジェクトと切り離し
close

gosub *SAVEDATA 'データ保存の作業
erase TT&, RR$ :CNT1&=0:CNT2&=0
while CHECKEVENT :CALLEVENT :wend
stop:end

*SAVEDATA
'**このサブルーチンでデータを保存 例:バイナリ形式で
'**for I&=1 to CNT2&:fwrite #3,TT&(I&)
'**fwrite #3,RR$(0,I&)
'**fwrite #3,RR$(1,I&):fwrite #3,RR$(2,I&):fwrite #3,RR$(3,I&):next

'これはテスト:データ画面表示
for I&=1 to 50:print TT&(I&),RR$(0,I&);RR$(1,I&);RR$(2,I&);RR$(3,I&):next
return

'================================================================
' タイマーイベント プロシージャ
declare sub TIMER1_TIMER edecl ()
sub TIMER1_TIMER()
shared FRUN as long, FEND as long
shared TIMER1 as object
var RES as long
'print "Test:タイマー";time$
if FRUN then
TIMER1.ENABLE 0 'タイマー停止
FRUN=-1:FEND=-1 '終了
RES=MESSAGEBOX("TIMER1","処理時間があふれました!",0,0)
exit sub
end if
FRUN=-1 'タイマー通知があった
end sub
'================================================================
' メインフォーム が閉じられようとしている
declare sub MAINFORM_QUERYCLOSE edecl ( CANCEL%, byval MODE% )
sub MAINFORM_QUERYCLOSE( CANCEL%, byval MODE% )
shared FRUN as long, FEND as long
FRUN=-1
FEND=-1 '処理終了させる
end sub

665名無しさん:2015/11/11(水) 10:22:32
ありがとうございます。

いきなり本題に入るのは敷居が高いので、作成していただいたプログラムに入る前に準備をしてみたいと思い、下記を参考にしてフォームを作ってみました。これはOK.
http://www.fmworld.net/product/soft/fbasic/gpib/

次に時計マークのアイコン(タイマーコントロール)を選択してフォームに貼りつけ。
[TIMER]と書かれたアイコンがフォームに表示されます。
これをダブルクリックすると、ウィンドウが開いて、プログラムが書けるようになりました。
ここに print "hello" としても画面に表示されない。
ちょっとマニュアルを探して勉強してみます。早く参考書も探さなくては。

666名無しさん:2015/11/12(木) 04:31:17
>>665
>ここに print "hello" としても画面に表示されない。

 ヘルプの「タイマーコントロールへの操作」にあるようにATTACHやENABLEをしているなら
たぶんイベントチェックのループを実行していないから。
 いちから作成する場合は、プロジェクト ウィザードで作成すると一通り新規作成されます。
(メニュー:プロジェクト(P)-ウィザード(W)) 注:既存の.BASファイルとかつぶさないように。
ヘルプで「イベント駆動処理プログラムの作成手順」を検索して参照。

#include "windows.bi"

while 1:WAITEVENT:wend

これが作成されたイベントチェックするループです。これを見て疑問に思うでしょう。
『あれ、無限にループしているのにこれを実行するとタイマーが動くの?』
WAITEVENTは、WAIT“I”命令(割り込み処理発生まで停止する)に似ています。

 イベントチェックのループ(メッセージ処理)とは何か、たとえ話をすると、

 あなたはWindowsさんからのはがき(タイマー通知)が郵便配達されてくるのを待っています。
でもいつ到着するかなんてわかりません。郵便受けの前で待ちつづけるわけには・・。
 そこである人(イベントチェックするループ)に依頼します。
「郵便受けで待って届いたら持ってきて。」その人は根気よく待ちました。
やがて配達人がきてあちこちの郵便受けに、はがきを一枚づつ投函していきます。
 自分の郵便受け(自分が作成したプログラム)の中にはがきの束を見つけたので、
その人はその束を持って戻り、はがきの到着した順番に宛て名を見て、皆に配り始めました。
(*順番にとはいっても「至急」とスタンプされたものは優先し、「新装開店」だとか
後まわしでいいようなものは最後にしたり、「同じ割引券のはがき」は一つにまとめたりと、
この人、できる秘書さんかも)
「これはAさん..これはBさん、これはまたAさん宛てです・・」やがてあなたの前にきて、
「はがき(タイマー通知)が届いてました、速やかに処理してください。」あなたははがきを
待ってはいたのですが、いろいろとほかにやることがあるのでその後で見ようとしました。
 ですが、この人はあなたの前から一歩も動こうとしません。不思議に思い理由を問うと
『あなた様がはがきを読んだことをしかと確認し、必要であればご返事をいただくまでが
私の役目です。速やかに処理してください。』と言われてしまいした。
その強い意思に射抜かれあわてる、あなた。
モタモタしていると、向こうの方からCさんやDさんたちの声が漏れてきました。
「まだはがきがあるじゃないか、おれたち宛てのものはあるのないの、どうなってるの!?」

667名無しさん:2015/11/16(月) 08:32:19
こんにちは

返信が遅くなって申し訳ありません。
そして、わかりやすいイベントチェックのループのたとえ話ありがとうございます。

>いちから作成する場合は、プロジェクト ウィザードで作成すると一通り新規作成されます。
これでやってみます。

とりあえず、少しまとまった時間が取れれば。ダイアログにタイマーの設定時間:1/100単位と実行回数を書き換えられるようにして、実行ボタンを押せばtime$を画面に表示するプログラムを作ろうと思います。

668名無しさん:2015/11/16(月) 09:20:25
>>667
タイマー間隔をシビアにした場合、画面に表示することが、
時間間隔の乱れの要因になることがあるかもしれません。
フォームを作成したF-BASIC/Winのテキスト表示は遅い
ということもありますし。
(画面表示速度改善については586番,592番あたり参照)

669名無しさん:2015/11/17(火) 02:09:42
ハード・ソフト両面で環境の差の影響が大きいのですが、参考値として
PRINT命令でMILLITIME関数で取得する数値に影響する度合いを
試してみました。条件はフォームを作成してフォント変更・サイズを大きくします。
80桁24行の互換モードで画面のグラフイックの機能設定はONのまま。
PRINT命令で4文字出力(改行なし)を連続実行してどの程度で
MILLITIME関数の値が変わるかテスト。
なおテストした環境でのMILLITIME関数の計測分解能は10msでした。

テスト結果、最大でも、PRINT命令 70回程度。平均としてはその半分程度。

なお、テキストのスクロールを発生させた場合は、即影響が出ます。

670k5:2016/01/06(水) 11:51:33
こんにちは

昨年はたいへんお世話になりました。

ずっと他の仕事に追いまくられて、F=BASICのイベント型プログラムに取り掛かれません。
もちろん、頭の切り替えができないという情けない現状もあります。

少しだけ時間ができたので、「ON INTERVAL GOSUB」を使ってみました。
INTERVALを5秒くらいにして実行させてみると、1時間で5〜10秒ほどずれました。

cls

interval 5.0 '60秒毎に割り込みます.
on interval gosub *KAKE
interval on
do
loop
interval off
stop
end
'

*KAKE

print date$,time$

return

これでもいいのですが、もう少し何とかならないだろうかと、こんな簡単なプログラムにしました。
(とても稚拙でお恥ずかしい)


cls

KANKAKU=5.0

OWARI = (date*86400+millitime/1000.0)+KANKAKU

do

NOW =(date*86400)+(millitime/1000.0)

if NOW >= OWARI then print date$,time$,millitime:OWARI=NOW+KANKAKU

loop

input AAA$

stop
end

これで実行すると、前よりはましみたいです。
もう少し、頑張ってみますので、
今年もよろしくお願いします。

671名無しさん:2016/01/08(金) 12:49:18
>>670
>INTERVALを5秒くらいにして実行させてみると、1時間で5〜10秒ほどずれました。

確かにずれていきますね。TIME割り込み命令の方で毎回つぎの5秒後を設定する方法にして
みましたが同じ結果でした。

> NOW =(date*86400)+(millitime/1000.0)

これは単精度変数だと有効桁数が足りないので、数ヵ月後には数値が狂うのでは?
millitimeも秒未満の桁が削れていく?

そこは、こんな感じでしょうか。年越しもできるし。

OWARI =(millitime/1000.0)
do
NOW =(millitime/1000.0):if NOW < OWARI then NOW=NOW+86400
if NOW >= OWARI+KANKAKU then print date$,time$,millitime :OWARI=NOW
loop


5秒で数百万回時計を見にいくというのも・・・ CPU100% ...。

672名無しさん:2016/01/08(金) 13:16:19
>>670
長くなってしまいましたが..。millitimeの時刻読み取りを減らして見ました。
---それでも数万回、時刻読み取りするけど。
(例えるとゴルフでパターを刻んでいくようなもの)
1. interval割り込みで、4秒(以内)待ち。
2. WAITで0.1秒単位待ち。
3. 回数限定無限ループで時間つぶし。(for MUGEN_CC=・・)←※外した方が定時性はあがる。
4. 豪腕でループぶん回してmillitimeを読み続けて時刻合わせ。


deflng A-Z 'ここから暗黙の型を32bit整数型にします。
var KANKAKU, OWARI, NOW
var MUGEN_CC, MUGEN_NN, MUGEN_NN2
var KAISU%

cls
gosub *MUGENSENS

KANKAKU=5
print time$, millitime/1000#
gosub *JUSTTIME
print time$, millitime/1000#

KAISU%=0 :do while KAISU% < 720 '実行回数
gosub *JUSTTIME '時刻合わせ
print date$,time$,millitime

'*** input AAA$

KAISU%=KAISU%+1 :loop
'
stop:end
*KAKE: print date$,time$ :return
'
*JUSTTIME2:return
*JUSTTIME
OWARI=KANKAKU-(time mod KANKAKU)
if OWARI >= 2 then '差が2秒以上あるならば、
interval OWARI-1 '秒単位の割り込み。ただし1秒残す。
on interval gosub *JUSTTIME2
interval on
waiti '設定している割り込みが発生するまで停止します。
interval off
end if
OWARI=1000-(millitime mod 1000)
if OWARI >= 100 then
wait (OWARI \ 100)*10 '1/100秒単位:0.1秒粗く待つ
endif
OWARI=1000-(millitime mod 1000)
if MUGEN_NN then for MUGEN_CC=(MUGEN_NN / 1000)*(OWARI \ 10)*10 to 0 step -1:MUGEN_NN=MUGEN_NN:next

if KANKAKU-((millitime \ 1000) mod KANKAKU)>= 2 then print "Time Over!!"
OWARI=1000-(millitime mod 1000)
MUGEN_CC=0
do 'ループしてmillitimeを秒単位チェック待ち
MUGEN_CC=MUGEN_CC+1
NOW=(millitime \ 1000) mod KANKAKU
loop until NOW=0
return
'
*MUGENSENS2 :MUGEN_NN=MUGEN_CC :return
*MUGENSENS
interval 1
on interval gosub *MUGENSENS2
MUGEN_CC=0:MUGEN_NN=0
interval on
waiti '1回目発生待ち
for KAISU%=1 to 3
do '2回目以降でループ回数カウント
MUGEN_CC=MUGEN_CC+1
loop until MUGEN_NN
if MUGEN_NN < MUGEN_NN2 or MUGEN_NN2=0 then MUGEN_NN2=MUGEN_NN
MUGEN_NN=0:MUGEN_CC=0
next KAISU%
MUGEN_NN=MUGEN_NN2
interval off
return
end

673k5:2016/01/09(土) 19:59:19
こんにちは

今年もよろしくおねがいします。

>これは単精度変数だと有効桁数が足りないので、
書き込んだ後で、倍精度に直しました。
そうすると、大体1/250秒ほどの精度で時間を取れるようです。

if NOW >= OWARI+KANKAKU
この方法の場合、計測間隔の精度はいいのですが、時間的確度はだんだん正の方にずれて行ってしまいます。やはり、millitimeを基本に計測間隔±0.005秒とかの設定にした方がいいみたいです。ただし、この方法では一度ずれてしまうと、戻らなくなる可能性があります。

考え付くのは、最初に計測間隔と計測のトータル時間を決め、millitimeのリストを作って、±閾値で決めて行く方がいいのかな。あるいは、

if NOW >= OWARI+KANKAKU

のあとで、差分を求めて、その差分を次の間隔から差し引くということです。
つまり、5.1秒だったなら、次は4.9秒にするということです。

>millitimeの時刻読み取りを減らして見ました。
これ頂きます。waitだけ使うともっと簡単になりますね。

>(例えるとゴルフでパターを刻んでいくようなもの)
あ、いい例えですね。

それにしてもBASICは素晴らしい。
これで、USBシリアル変換のケーブルが使えれば、もっといいんですけど。

674671:2016/01/10(日) 04:27:34
>>673
>millitimeを基本に計測間隔±0.005秒とかの設定にした方がいいみたいです

そのようですね。PCの時計は使用状況(連続稼動時間・休止時間)によりますが、
だいたい月差30秒程度だと思うので。

時刻精度はOS・ハード構成によって違うでしょうから。Windows Vista以降だと
ハードウェアで「高精度イベントタイマー」を使えますが。

>millitimeのリストを作って、±閾値で決めて行く ・・・

>if NOW >= OWARI+KANKAKU のあとで、差分を求めて、その差分を次の間隔から差し引く

方法はどちらでもいいと思いますが、
「時刻(定刻)」、「時間(間隔)」のどちらを重視するかということですね。
基準となる時刻はなにを採り、どうやって取得するのか、
取れないのならどうやって近似値を作り出すか。


毎5秒として、つぎのようなパターンは許容できるのか?
・04.99秒・09.99秒(つまりマイナス方向、-0.01)の振れは許容できるのか
(見た目の1秒差:時刻05秒のはずが04秒に)。
・04.99秒・10.01秒(つまりプラスマイナス両振れ、間隔としては0.01の2倍の差)は。
・たとえば日本標準時から「平均的にほぼ一定」で時刻が進んでいくまたは遅れていく。
・仮定として、他の計測データとのなんらかの照合をすると時刻・時間の基準が違うが。
・millitimeを補正した場合、PC上の日付時刻と、補正日付時刻と、二重に日付時刻が生じるが
何らかの証跡として問題ないか。

差分補正はどう処置するのが問題に。
・04.99秒なので次は+0.01補正したのに、09.95秒だった。次は+0.05か+0.06か+0.04補正か。
・04.97秒なので補正していったら09.98秒、15.99秒、次はいきなり20.50秒になった。
-0.50補正を行うのか。
・04.90秒なので補正したらなぜか11.00秒になった。異常値として破棄するのか

○差分補正の欠点は誤差が蓄積されて長時間はもたないこと。誤差をさらに差分補正…。


>USBシリアル変換のケーブルが使えれば
仮想COMポート(COM1からCOM5まで)で割り当てができてハイパーターミナルから使えるもの
なら使えるかもしれない。

675k5:2016/01/10(日) 10:00:10
>「時刻(定刻)」、「時間(間隔)」のどちらを重視するかということですね。
定刻を基本に、間隔が揃っているのが好ましいです。

たとえば、初期値として「時間(間隔)」と計測期間(回数)を与えると、計測するべき時刻(定刻)」は自ずから決まってくるので、それをmillitimeで見ればいいかなと。この場合、時間の触れが+方向に限定されるのが少し気になるところ。

millitimeを一日まわして気づいたのですが、時間によってmillitimeの揺らぎ精度が違うみたいです。1/100になったり、1/1000になったり。割り込みやデーモンとの関係があるんでしょうね。やはり、目標値を1/100秒程度がいいところなのかも知れません。あくまでもmillitimeとtime$は同じハードから時刻を得ているというのが前提ですが。

仮想COMポートとしては認識しているんですが、相手側のシリアルコントローラと相性が悪いのか。使えないことがおおいです。電圧値が違うからなんでしょうか。間にレベルコンバーターなどを入れれば動くのかな。

676671:2016/01/11(月) 03:20:15
>>675
>それをmillitimeで見ればいいかなと。この場合、時間の触れが+方向に限定されるのが少し気になる

millitimeを見張って『仮に時刻ぴったり』にできたとしても、
結局それは「過ぎ去りし時間」で+方向にだけぶれるのはいたしかないこと。
マイナス方向もありということは、時刻ぴったりの『少し前』に合わせるようなもの。
では『少し前』とはどうやって定義して決めるのかが課題。


>あくまでもmillitimeとtime$は同じハードから時刻を得ているというのが前提ですが。

millitimeとtimeは取得元は同じです。

WindowsではPCのRTCは精度が悪いので起動後、別のハード機構からの情報で
カウントして算出しているそうです。
タイマ割り込みより、millitimeの方が若干精度が高いということ。

タイマ割り込みはWindowsの互換性維持のため、精度は低いままです。


>millitimeを一日まわして気づいたのですが、時間によってmillitimeの揺らぎ精度が違うみたいです。

非リアルタイム系OSの宿命です。そもそもmillitimeを取得する行為そのもの、そして結果を
画面等に出力すること自体が「ゆらぎ」の発生源のひとつなのですから。

>やはり、目標値を1/100秒程度がいいところなのかも知れません

いかに無限ループでmillitimeを観測しようと、プリエンティブなマルチタスクOSなので、
どこかで実行権を剥奪されるので、タスク切り換え単位以下の精度を維持しつづけることは
できないので、計測時間範囲で平均値を維持するのがやっとのはずです。
まあ極論、OSをWindows Ver.3.1、F-BASIC for Windows (V3.1)にすればということですが。


>割り込みやデーモンとの関係があるんでしょうね
そういうことですね、高精度を維持したければ、
割り込みがかかる不要なハードはすべてドライバ無効化(USBなんぞ禁止)、
不要な「サービス」はすべて停止、スクリーンセーバ等禁止、省電力機能禁止、
ウイルス対策ソフトなど常駐モノは完全にキル。
NTPによる時刻同期も当然禁止。ネットワークもハード(NIC)ごと停止。
メモリ(RAM)が大量にあるならば仮想記憶のスワップファイルをゼロに。

計測中は一切画面に経過表示せず、計測データはディスクに書かずメモリに保持、
「ペンキ塗りたて」ならぬ「マウス・キーボード触るな」
張り紙が必要な精度ですね。

>電圧値が違うからなんでしょうか。間にレベルコンバーターなどを入れれば動くのかな。
うーん、USB変換ケーブルタイプはそんな感じなんですか...
電圧に関して規定がゆるいですからね。
PC/AT機のシリアルポートはケープル長が2m〜3mが限界だとかいう虚弱ぶり。
そんなのをみならっているんでしょうかね。

RS-232なら規格限界値15mだったっけ?

677k5:2016/01/11(月) 11:12:39
LinuxでGPSを使ったNTPサーバーを運用する場合、大まかな時間(1秒)はntpであわせて、それ以下はGPSから来るPPSであわせるので、これが簡単でいいところななのかと思っています。

いろいろと考えてみると、計測間隔は1/100〜1/10程度の精度で時刻は1秒以内という辺りがよさそうです。つまり、3日間連続で計測していても、定刻は秒レベルではあっている。time$で確度、millitimeで精度を確保すると。明日にでもやってみます。

>うーん、USB変換ケーブルタイプはそんな感じなんですか...
>電圧に関して規定がゆるいですからね。
USB変換チップとドライバとシリアル機器側のコントローラの組み合わせみたいですが、F-BASICを使うとほとんど動かないみたいです。実験する時は、古いシリアルポート付のノートPCを使っています。

678名無しさん:2016/01/14(木) 09:03:45
こんにちは

昨日は、times$が更新(10秒ごと)された直後のmillitimeを見てみました。
こんな簡単なプログラムです。

cls

do
if right$(time$,1)="0" then gosub *KAKE
if right$(time$,1)<>"0" then flg=1
loop
stop
end
'

*KAKE

if FLG=1 then print time$,millitime:FLG=0

return

8時間ほど走らせた結果、millitimeの末尾4桁はほとんど0000でした。

14:50:50 53450000
14:51:00 53460000
14:51:10 53470000
14:51:20 53480000
14:51:30 53490000
14:51:40 53500000
14:51:50 53510000
14:52:00 53520000
14:52:10 53530000
14:52:20 53540000
14:52:30 53550000
14:52:40 53560000
14:52:50 53570000
14:53:00 53580000
14:53:10 53590000
14:53:20 53600000
14:53:30 53610000

あくまでもPCのタイマーの表示ですが。F-Basicのmillitimeは貴重な命令ですね。

679名無しさん:2016/01/15(金) 01:56:54
>>678
>8時間ほど走らせた結果、millitimeの末尾4桁はほとんど0000でした。


 millitimeとtimeは取得元は同じで、直近上方に丸めることはないと思いますので、
millitimeの末尾3〜4桁(おそらく最後の1/1000の位は除き)がゼロでないというのは
無いはずです。

この場合、注目すべき点は、 ほ・と・ん・ど が0000であること。
ということは、0000でないものが存在しえたということ。

それは単純に豪腕ループでtime$を常時監視続けただけでは回避できないということ。


timeの時刻精度では1〜2時間でGPS取得との差異が許容誤差範囲を超えるのでは?

680名無しさん:2016/01/15(金) 03:01:18
本当に出会える出会い系ランキング
http://bit.ly/1MVgwpz

681名無しさん:2016/01/15(金) 04:13:42
>>680 :名無しさん :2016/01/15(金) 03:01:18
過疎板には貼っても無意味

682名無しさん:2016/01/15(金) 09:04:48
ちなみにprint文の前にwait100を入れると、末尾4桁は0100になりました。
millitimeでやっても同じみたいです。
if millitime mod 10000 = 0 then gosub *KAKE

ただ、print文を入れるとかなり揺らぐみたいです。
あまり深くは考えずに、間隔はtimeでやって、時刻はRTCとNTPに任せます。

>timeの時刻精度では1〜2時間でGPS取得との差異が許容誤差範囲を超えるのでは?
一日で1秒以内とすると、1/10万程度の精度になるんですね。GPS受信機の内蔵時計の精度が30ns程度と言われていますので、これだと1年で1秒くらいですか。たしかに、GPS受信機の大部分が位置情報ではなく時間同期に使われているというのは納得です。

最近は高精度のクロックが売られるようになったので、これでも使ってみるかな(冗談です)
http://www.microsemi.com/products/timing-synchronization-systems/time-frequency-references/chip-scale-atomic-clock

683名無しさん:2016/01/16(土) 04:24:08
>>682
末尾4桁(0000)とは正確なハード環境みたいですね。

>ただ、print文を入れるとかなり揺らぐみたいです。

テキスト画面のスクロールが発生するとかなりのペナルティをくらいます。(>669)

経過表示を入れるのならスクロールをしないように先頭行に戻して上書きで表示する
方法をとる必要があるでしょう。


>GPS受信機の大部分が位置情報ではなく時間同期に使われているというのは納得です。

GPSは基準時刻との時差そのものがカギ。相対性理論による補正を必要とする世界。
位置情報は新鮮な地図(高低差)と補正がカギ。

684k5:2016/01/16(土) 10:12:44
>末尾4桁(0000)とは正確なハード環境みたいですね。
DELLのワークステーションです。

>経過表示を入れるのならスクロールをしないように先頭行に戻して
>上書きで表示する方法をとる必要があるでしょう。
そうします。

>GPSは基準時刻との時差そのものがカギ。相対性理論による補正を必要とする世界。
特殊と一般、両方使われていますね。私のフィールドでは時差も使いますが、位相差も使います。2台のGPSで同じ信号を受信してその位相差で相対位置を求めます。

Linuxでもbasicが動かないかと調べていたら、freeBasicという処理系があるようです。これはQBコンパチみたいなので、少し期待しています。

685名無しさん:2016/01/16(土) 10:50:20
>>684
>2台のGPSで同じ信号を受信してその位相差で相対位置を求めます。

そういう使いかたがあるんですね。

Linuxの方がタイムスライスの粒度が細かいので、向いているでしょうね。

686k5:2016/03/20(日) 13:03:40
また、相談させてください。

GPSから1秒ごとに出力されるデータを読み込んでPCのディスクに書き込んでいます。
データは文字で90バイトほどの固定長です。
プログラムはこんな感じです。


baud 0,9600
open "COM0:" for input as #1
open "nmea.txt" for create as #2

do

line input #1,GPGGA$
open "nmea.txt" for create as #2
print #2,GPGGA$

loop

しばらく(10分ほど)は動くのですが、読み出すタイミングが悪いのか、やがてプログラムがハングアップしてしまいます。フロー制御も、OFF、xon/off、ハードと試してみたのですが同じです。仕方がないので、teratermのログとして保存していますが、やはりプログラムから直接読めた方が便利です。

計測機器から一定時間で流れてくるデータを読む方法って、やはりイベント駆動型にした方がいいんでしょうか。

687名無しさん:2016/03/20(日) 19:31:46
女に年収バレた結果www
http://bit.ly/1R5A6lq

688名無しさん:2016/03/23(水) 04:14:49
>>686
対症療法としては10分たつ前にCOM0: をcloseして再オープンしてみるとか。


ハングアップするならline input# でしょうから、こんなかんじだとどうでしょうか。
(*改行コード含め90バイトとして。)

CHK_TIME%=((time mod 60)+2) mod 60 'リミットをおよそ2秒後に設定
do while lof(1) < 90
if (time mod 60) = CHK_TIME% then print "**受信エラー**" :exit do
loop
if lof(1) < 90 then GPGGA$=input$(lof(1), #1) else GPGGA$=input$(90, #1)

if right$(GPGGA$,1)=chr$(13) then GPGGA$=left$(GPGGA$, len(GPGGA$) - 1)

689k5:2016/03/23(水) 10:24:09
ありがとうございます。教えていただいたコードを組み込んで実行したところ、30分を経過してもまだ止まっていません。今日一日、ログをとり続けてみます。またご報告します。

690k5:2016/03/23(水) 19:44:23
こんばんは

8時間たっても動いています。
このコードは大切に使わせていただきます。
ありがとうございました。

691名無しさん:2016/03/26(土) 03:05:55
【キャリア】40歳になってようやくわかる8つのこと。
http://bit.ly/22ru7TF

692名無しさん:2016/03/27(日) 04:29:54
プログラム(>672)は
KANKAKUを1秒に設定にすると正常に動作しないので、サブルーチンを修正しておきます。
それから*MUGENSENSおよび*MUGENSENS2サブルーチンは削除します。
処理内容は変更しました。
1. interval割り込みで、2秒未満まで待ち。
2. WAITで0.1秒単位待ち。
3. 指定時刻まで残り時間が0.1秒近くある場合は一回WAITで待って、完了とする。
4. 3の処理をしない場合に限り、豪腕でループぶん回してmillitimeを読み続けて時刻合わせ。

ソフト・ハード両環境によるが、次の1行を順次変更することで精度を上げられるかもしれません。
→→ if OWARI>=30 and OWARI < 100 then wait (1+(OWARI \ 10)) :return
1. if OWARI>=30 and OWARI < 100 then wait (0+(OWARI \ 10)) :return
2. if OWARI>=30 and OWARI < 100 then wait (0+(OWARI \ 10))
3.コメントアウトしてプログラムから外す。
※2、3の変更案は、負荷がかかります。


*JUSTTIME2:return
*JUSTTIME
OWARI=millitime
if (OWARI mod 1000)>=900 and KANKAKU>=2 then
OWARI=1000-(OWARI mod 1000)
wait 1+(OWARI \ 10) 'ここは越えるようにする
endif
OWARI=KANKAKU-((millitime \ 1000) mod KANKAKU)
if OWARI >= 2 then '差が2秒以上あるならば、
interval OWARI-1 '秒単位の割り込み。ただし1秒残す。
on interval gosub *JUSTTIME2
interval on
waiti '設定している割り込みが発生するまで停止します。
interval off
end if
OWARI=1000-(millitime mod 1000)
if OWARI >= 100 then
wait (OWARI \ 100)*10 '1/100秒単位:0.1秒粗く待つ
endif

OWARI=1000-(millitime mod 1000)
if OWARI>= 100 then MUGEN_CC=-1:return '←TIME OVER!!
OWARI=millitime
if KANKAKU-((OWARI \ 1000) mod KANKAKU)>= 2 then
MUGEN_CC=-1 :return '←TIME OVER!!
OWARI=1000-(OWARI mod 1000)
else
OWARI=1000-(OWARI mod 1000)
endif

OWARI=1000-(millitime mod 1000)
MUGEN_CC=0
if OWARI >= 100 then return
if OWARI>=30 and OWARI < 100 then wait (1+(OWARI \ 10)) :return
if KANKAKU < 2 then
do 'ループしてmillitimeを秒未満チェック待ち
MUGEN_CC=MUGEN_CC+1
NOW=(millitime mod 1000)
loop until NOW<900
else
do 'ループしてmillitimeを秒単位チェック待ち
MUGEN_CC=MUGEN_CC+1
NOW=(millitime \ 1000) mod KANKAKU
loop until NOW=0
endif
return

693k5:2016/03/30(水) 09:29:23
さっそく、このコードで試してみました、
この精度(確度)で十分です。
ありがとうございました。


deflng A-Z 'ここから暗黙の型を32bit整数型にします。
var KANKAKU, OWARI, NOW
var MUGEN_CC, MUGEN_NN, MUGEN_NN2
var KAISU%

cls
'gosub *MUGENSENS

KANKAKU=5
print time$, millitime/1000#
gosub *JUSTTIME
print time$, millitime/1000#

KAISU%=0 :do while KAISU% < 720 '実行回数
gosub *JUSTTIME '時刻合わせ
print date$,time$,millitime

'*** input AAA$

KAISU%=KAISU%+1 :loop
'
stop:end
*KAKE: print date$,time$ :return
'
*JUSTTIME2:return
*JUSTTIME
OWARI=millitime
if (OWARI mod 1000)>=900 and KANKAKU>=2 then
OWARI=1000-(OWARI mod 1000)
wait 1+(OWARI \ 10) 'ここは越えるようにする
endif
OWARI=KANKAKU-((millitime \ 1000) mod KANKAKU)
if OWARI >= 2 then '差が2秒以上あるならば、
interval OWARI-1 '秒単位の割り込み。ただし1秒残す。
on interval gosub *JUSTTIME2
interval on
waiti '設定している割り込みが発生するまで停止します。
interval off
end if
OWARI=1000-(millitime mod 1000)
if OWARI >= 100 then
wait (OWARI \ 100)*10 '1/100秒単位:0.1秒粗く待つ
endif

OWARI=1000-(millitime mod 1000)
if OWARI>= 100 then MUGEN_CC=-1:return '←TIME OVER!!
OWARI=millitime
if KANKAKU-((OWARI \ 1000) mod KANKAKU)>= 2 then
MUGEN_CC=-1 :return '←TIME OVER!!
OWARI=1000-(OWARI mod 1000)
else
OWARI=1000-(OWARI mod 1000)
endif

OWARI=1000-(millitime mod 1000)
MUGEN_CC=0
if OWARI >= 100 then return
if OWARI>=30 and OWARI < 100 then wait (1+(OWARI \ 10)) :return
if KANKAKU < 2 then
do 'ループしてmillitimeを秒未満チェック待ち
MUGEN_CC=MUGEN_CC+1
NOW=(millitime mod 1000)
loop until NOW<900
else
do 'ループしてmillitimeを秒単位チェック待ち
MUGEN_CC=MUGEN_CC+1
NOW=(millitime \ 1000) mod KANKAKU
loop until NOW=0
endif
return

694k5:2016/03/30(水) 09:44:54
最近の計測器でbluetoothで接続するタイプが増えているみたいです。たしかに配線が楽ですからね。windowsの場合はCOMポート接続ができるようです。このCOMポートをF-BASICからアクセスすることができるか、とても興味があります。

誰か、使ったことはありますか?

週末にでもbluetoothが使えるノートPCとbluetooth I/Fの簡単な温度計が借りられるので、F-BASICで使えるかテストしてみます。

695名無しさん:2016/03/30(水) 23:36:54
帰りにロジテックのBluetoothアダプタを買ってきて使ったところ、問題なくcomポートをF-BASICで使うことができました。これはとっても快適です。

購入したBluetoothアダプタはロジテックのLBT-UAN04C2という製品です。
http://bbs.kakaku.com/bbs/K0000373744/

RS-232CをBluetoothで無線化するアダプターが少々高いですが、コードの引き回しや延長距離などを考えると、これはいいです。興味のある方は、ぜひぜひ使ってみて下さい。

696名無しさん:2016/03/31(木) 06:03:14
>>694,695
試用レポート、ありがとうございます。

無線化すると便利だけれどプログラム上は通信エラーの対応処理の省略が
しづらい。

697名無しさん:2016/03/31(木) 09:42:49
そうなんですか、USBシリアル変換ケーブルが全滅状態で、RS232ポートがついているパソコンも少なくなっている時勢に、シリアル通信が出来るのはとても嬉しいです。

あとは、シリアルをBluetoothで無線化するアダプターがもっと安くなればいいなと。今は2万ほどしますからね。安いのは1万ほどであるみたいです。

Linuxを使ってCとかシェルスクリプトでも書いてみたんですが、やはりBASICは慣れているので、細かいところまで融通が利きます。これでまだしばらく、F-BASICが使えそうです。

698名無しさん:2016/04/01(金) 03:30:42
会社クビになって奨学金返済できなくなったんだが契約書にヤバイ文章が見つかった
http://bit.ly/1R5zV9T

699名無しさん:2016/04/01(金) 03:55:31
>>697
まあ、実際は電波を遮る物体が通るとかしなければ、
シリアル通信の速度程度では障害にはならないでしょうから
通信エラーは無視できるリスクでしょう。

物理的なシリアルポートに接続する無線化アダプターでは、
ケーブルなしの直結(ゼロ距離)なので、結果的に
USB-シリアル変換タイプより問題がおきにくいのかもしれません。

ソフトウェア上はBluetoothのシリアル通信のプロファイル(SPP)で
仮想的なシリアルポートとしてやりとりします。

700名無しさん:2016/04/01(金) 08:46:40
Bluetoothは2.4G帯を使うので、電子レンジとかとの干渉はないかと思っているんですが、今のところ大丈夫みたいです。

ただ、Bluetoothのドライバーが作り出す仮想シリアルポートはよくわからなくて、F-BASICではcom5にしないとアクセスできなかったりします。com3とかにすると、その入力装置は使えないというメッセージが出ます。OSやドライバーを作っている会社などの相性があるのも知れません。この辺りは、しばらく手探りが続いてゆきそうです。

701名無しさん:2016/04/02(土) 04:30:59
周波数ホッピングとか軍採用技術が使われているので速度低下ですむかと。

com1からcom4ポートはBIOS設定の関連もあると思います。
オンボードのポートが1つで(Fax)モデムカード等がないなら、
com2, 4ポートが使えるかも。
F-BASICではcom5ポート("COM4:")までしか対応していません。
ps. 仮想COMポートをオープンするのに "\\.\com9" 形式があるらしいの
ですが、オープンはできてもcomポートとしては使えないだろうし。

702名無しさん:2016/04/03(日) 00:16:16
>周波数ホッピングとか軍採用技術が使われているので速度低下ですむかと。
拡散スペクトラムですね。その昔は、話しに聞いているだけでした。身近なところではGPSが一番最初でしたか。CDMAより早かったと思います。

>com1からcom4ポートはBIOS設定の関連もあると思います。
>オンボードのポートが1つで(Fax)モデムカード等がないなら、
>com2, 4ポートが使えるかも。
うーん、この辺り不は不明です。

さきほど、同じプログラムをWindows10(64bit)で動作させましたが、他のポートでも問題なく動いています。このノートPCはbluetoothが標準装備されているので、純正ドライバーによる仮想comポートによる通信が安定しているみたいです。3rdパーティのドライバーとの相性がよくないのかも知れません。本を取り寄せて、bluetoothのお勉強をしなくては。

703名無しさん:2016/04/09(土) 17:17:33
友人関係全部切った結果
http://bit.ly/1Sepcun

704名無しさん:2016/04/11(月) 00:29:31
本当に出会える出会い系ランキング
http://bit.ly/1OgYRt7

705名無しさん:2016/04/11(月) 09:16:26
>688

CHK_TIME%=((time mod 60)+2) mod 60 'リミットをおよそ2秒後に設定
do while lof(1) < 90
if (time mod 60) = CHK_TIME% then print "**受信エラー**" :exit do
loop
if lof(1) < 90 then GPGGA$=input$(lof(1), #1) else GPGGA$=input$(90, #1)

if right$(GPGGA$,1)=chr$(13) then GPGGA$=left$(GPGGA$, len(GPGGA$) - 1)


いつもお世話になります。
せっかくなんで、このコードの意味を解説していただけると勉強になります。
恥ずかしながら、自分なりに読んでみました。

*ここから始まり

CHK_TIME%=((time mod 60)+2) mod 60 'リミットをおよそ2秒後に設定
*現在の通算秒数を分に換算して、そのあまり秒に2秒を足してを待機する上限時間を求める。最後の(mod 60)の意味がよくわかりません。

do while lof(1) < 90
if (time mod 60) = CHK_TIME% then print "**受信エラー**" :exit do
loop

受信バッファが90バイトに達するまで読み込む。
もし、その間に上限時間を超えたらdoープを抜ける

if lof(1) < 90 then GPGGA$=input$(lof(1), #1) else GPGGA$=input$(90, #1)
もし、受信バッファが90バイトに達していなければGPGGA$に入っているだけ代入する。
そうでなければ、、受信バッファから90バイトをGPGGA$に代入する

if right$(GPGGA$,1)=chr$(13) then GPGGA$=left$(GPGGA$, len(GPGGA$) - 1)
GPGGA$の行末コードを削除する

よろしくお願いします。

706688:2016/04/12(火) 02:57:29
問題の有るコードではあるのですが――。疑問点に回答します。

>>705
>最後の(mod 60)の意味がよくわかりません。

これは通算秒数から剰余計算で秒部分(0〜59秒)を取り出した後、
現在時刻が58〜59秒だった場合、2を加算して2秒後を求めただけだと60秒以上になるため。
ラウンドアップへの対処。

>受信バッファが90バイトに達するまで読み込む。

処理1件分のデータが受信バッファにたまるまで『あえて読まずに』待つ。
2秒程度の時間切れ条件判断はもしもの場合の保険。

>もし、受信バッファが90バイトに達していなければGPGGA$に入っているだけ代入する。

補足説明すると、受信データが90バイト固定長以外のデータが受信された場合や途中までしか
送られてこなかったような場合など、とりあえず処理継続することを優先する意図があります。

本来はIF文で場合分けする必要はない(GPGGA$=input$(lof(1), #1)のみですむ)のですが、
問題原因がデータの形式にあった場合などのための対処への意図を含めた結果です。


実際にデータを読み込む処理をしているこの2行についてですが、

>if lof(1) < 90 then GPGGA$=input$(lof(1), #1) else GPGGA$=input$(90, #1)
>
>if right$(GPGGA$,1)=chr$(13) then GPGGA$=left$(GPGGA$, len(GPGGA$) - 1)
>GPGGA$の行末コードを削除する

90バイトそろっているのであれば、
ごく普通にLINE INPUT#1,GPGGA$ ひとつで済ませてもよいとは思いますが、
問題を確実に回避することを優先して、LINE INPUT# を使わないという選択肢をとりました。

707名無しさん:2016/04/12(火) 09:11:22

丁寧な解説、ありがとうございます。

(mod 60)の意味、そうだったんですね。
理解できました。

シリアル通信がbluetoothなどで仮想化されたり、計測器もコントローラーとセンサー部分が無線モデムを使ったシリアル通信をしていると、パケットの衝突などが起きて、データが一定時間流れてこない状況が時たま発生します。伝統的な実物のシリアルケーブルならLINE INPUT#で苦なく読めたデータもこのように工夫しないといけないのですね。教えていただいてとても勉強になりました。今後ともよろしくお願いします。

708688:2016/04/13(水) 02:44:42
>>707
>計測器もコントローラーとセンサー部分が無線モデムを使ったシリアル通信をしていると、
>パケットの衝突などが起きて、データが一定時間流れてこない状況が時たま発生します。

なるほど、昨今そういった状況になっているのですね。

 ただ、「(ある/一定)時間流れてこない」といった状況でLINE INPUT# が使えない
わけではないはずです。COMポートに対してのLINE INPUT#は、改行コードが流れてくるまで、
「F-BASIC内部でいろいろ処理しながら」待ち続けるのが仕様です。
(ただしopen命令でタイムアウト指定をしない場合)
改行コードが文字化けしない限りは問題ないはずなのです。

問題の発生要因は、RS/CSなどの制御線の制御タイミングが関わっていると見るのが妥当です。

シリアル通信プロファイル(SPP)による通信のエミュレートや、計測器側の動作も含め、
相性問題もあるかもしれません。

709名無しさん:2016/04/13(水) 17:40:05

>なるほど、昨今そういった状況になっているのですね。
PCからはシリアルポートがなくなりつつありますが、周辺機器ではまだまだ現役ですからね。

>シリアル通信プロファイル(SPP)による通信のエミュレートや、
>計測器側の動作も含め、相性問題もあるかもしれません。
SPPの品質はスタックの出来次第らしいです。東芝やモトローラーのが評判いいです。もう東芝は外販していないみたいですが、bluetooth付のdynabookは安定していると聞いています。またもうディスコンになった東芝のusbドングルもプレミアがついて驚くほどの高値です。

710名無しさん:2016/04/15(金) 16:54:56
本当に出会える出会い系ランキング
http://bit.ly/1OgYRt7

711名無しさん:2016/04/20(水) 15:28:30
本当に出会える出会い系ランキング
http://bit.ly/1OgYRt7

712名無し:2017/02/24(金) 23:18:46
何方か教えて下さい、長く使用してなかったのですが、思い付きでfbasicをWidows7に入れてみたら結構動くのが解って、
今いろいろ試して楽しんでいます、使ったことの無い Choosefont(****,0,0) 命令の書き方が解りません。
**** の部分にはガイドでは「フォント」と書いてありますが、何方か詳しく教えて頂けませんか、フォント名の変更に
苦労してます。

713名無しさん:2017/02/27(月) 05:38:49
CHOOSEFONTの 「フォント」にはFONT構造体型の変数を指定します。
フォント選択ダイアログで選択されたフォントの情報がFONT構造体に格納されます。

#include "WINDOWS.BI" '-- FONT構造体の定義が読み込まれます。
var FFONT as FONT '---- 変数名FFONTの「FONT構造体」を宣言

 ヘルプ「プログラミングガイド」の [ダイアログボックス] - [コモンダイアログボックス]の
頁の[フォント選択ダイアログボックス]の説明にプログラム例があります。

SETFONT命令などでフォントの設定をしてから描画命令を実行します。

FONT構造体型の内容です(※ヘルプのどこかの頁には誤記があったような気が)。
type FONT

size as single 'フォントサイズ
bold as integer 'ボールド(太字)指定の有無
italic as integer 'イタリック(斜体)指定の有無
underline as integer 'アンダーライン(下線)指定の有無
strikeout as integer '消し線指定の有無
ffname as string * 32 'フォント名

end type

 なお、このFONT構造体はF-BASIC専用です。Windows APIのFONT構造体等とは違いますので、
F-BASICの組込命令を使用せずにフォント選択ダイアログを呼び出したり、
Windows APIでフォント操作をする場合には適用できません。

714名無し:2017/03/10(金) 21:50:57
ご指導有難う御座いました、不在にしてたので遅くなりました。「プログラミングガイド」に
少し記載がありました。いろいろ試してみます。今でもXPで使用してる古いソフトをリニュウアル
してみようと思っています。また解らないことがあったら投稿します。有難う御座いました。

715keinin55:2017/11/21(火) 08:48:57
F-BASICのBinにあるエラー解析ツールFBANZ63.EXEについてご教授ください。
プログラムでエラーが発生した時、解析ツールのレジストリー読込みで表示されるエラー状況の中に
APIエラーという項目がありますが、この値はどこを参照しているのでしょうか
レジストリーの場所?が解れば教えてください。

716名無しさん:2017/11/22(水) 08:13:29
>715 keinin55 様
FBANZ63.EXEのメニュー[レジリストリ(R) - 読み込み(R)]で表示される内容の参照元は
レジストリ“HKCU\Software\FUJITSU\F-BASIC V6.3\RUNTIME\ERROR”キーらしい。

APIERR [DWORD値] - たぶん「APIエラー」の参照元
CODE [DWORD値] - たぶん「エラーコード」のコード値(F-BASICのERR関数の値)
FUNC [DWORD値] - たぶん「内部関数名」を示すコード値、おそらく3Bytes長範囲値
INFO [DWORD値] - たぶん「補足情報値」おそらく1Byte長範囲値

おそらくはFUNC+INFOとランタイムバージョンとで、F-BASICランタイム内部でエラー
トラップした個所が推定できる。

717k5:2018/09/06(木) 17:35:13
こんにちは

相変わらず頑張ってF-BASICを使っています。

今回はWindows10で動くバッチファイルの中でforループから抜け出す判断をF-BASICで作ったプログラムで行おうと思っています。たとれば、このようなバッチファイルの中でhoge.exeというプログラムをF-BASICで作った場合、コマンドの実行結果としての戻り値(終了コード)を出すような関数はF-BASICに用意されていますでしょうか。

setlocal enabledelayedexpansion
for %%f in (*.txt) do (
call hoge.exe %%f
if !ERRORLEVEL! == 1 @echo %%f:ダメです。>> log.log
if !ERRORLEVEL! == 0 @echo %%f:OKです。>> log.log
)
endlocal

https://qiita.com/OutOfServiceExeption/items/031f9b55f35489624a3b

718k5:2018/09/06(木) 17:55:30
すいません、自己解決しました。

endを使えばでいいんですね。

echo off

setlocal enabledelayedexpansion
for /l %%a in (1, 1, 10) do (
call print_env.exe
if !ERRORLEVEL! == 1 @echo 1です。
if !ERRORLEVEL! == 0 @echo 0です。
)
endlocal

print_env.bas

print "hello"
end 1

719k5:2021/02/16(火) 08:36:51
こんにちは、まだF-BASICで頑張っています。

テキストファイルをシーケンシャルモードでopenして何行か読んだ後に、また少し戻って読み直すのって出来ましたでしょうか。

例えば、

open "test.txt" for input as #1

input #1,line1$
input #1,line2$
input #1,line3$
input #1,line4$
input #1,line5$

とした後に、また3行目のline3$を読みたい場合、現在のファイルポイントから3行前に戻るという命令はなかったでしょうか。

720名無しさん:2021/02/21(日) 04:17:41
いくつか方法はあると思いますが、
1.バイナリモードでオープンすればseek命令/関数が使えますが、FREADで読みこむことになります。
2.open for inputを同時に複数オープンしておき、読込処理行数をカウントしながら読み、
戻る必要がある分についてはもう一方のオープンしたほうで遅れて読み進めることで代替。
3.戻る可能性のある行数分の配列変数を用意しておき、配列に格納しながら読み進めることで代替。


新着レスの表示


名前: E-mail(省略可)

※書き込む際の注意事項はこちら

※画像アップローダーはこちら

(画像を表示できるのは「画像リンクのサムネイル表示」がオンの掲示板に限ります)

掲示板管理者へ連絡 無料レンタル掲示板