rs232c通信について

ActiveBasicでのプログラミングでわからないこと、困ったことなどがあったら、ここで質問してみましょう(質問を行う場合は、過去ログやWeb上であらかじめ問題を整理するようにしましょう☆)。
返信する
メッセージ
作成者
あべべ

rs232c通信について

#1 投稿記事 by あべべ »

ver.3以降ではwim32APIが必要だということでチャレンジしています。
通信設定は今までの投稿を参考にさせてもらっていたので大丈夫だと思います。
実験で3つ(コントローラー1台(A)、測定器2台(B,C))を動かしたいのですが、違う点はハンドルを複数作った点です。それも正しいかよくわかりません。・・すいません。
結果的には、Aを動かし、BとCから電圧を測定のループをさせるプログラムを作りたいです。
うまくいきません。以下の質問についてご教授よろしくお願いします。

・ハンドルを複数作ったのですが正しいでしょうか?

Dim hComm[8] As Long , num as long

hComm[num] = CreateFile(StrComNom, GENERIC_READ                      OrGENERIC_WRITE, 0, ByVal 0, OPEN_EXISTING,                                  FILE_ATTRIBUTE_NORMAL, 0)
If hComm[num] = -1 Then
Print StrComNom; "が使えません"
' MsgD = lstrcat(comname , "が使えません") 'ポートのオープン失敗時
' MsgBox 0, MsgD '警告メッセージ アイコンを表示
dummy = CloseHandle(hComm[num]) 'シリアルポートを閉じる
Sleep(7999)
End '強制終了
End If

受信側の関係から、通信速度を分けたいのですが、以下のコードのように(hcomm[1])でハンドル名だけ変えるだけでよいですか?


stDCB.BaudRate = 38400 '転送速度の指定 dummy = SetCommState(hComm[1], stDCB)


送信は1回は出来るのですが、2回目から読ませるとバグります。以下のコマンドを繰り返すと何がまずいですか?

Dim wSData As BytePtr
Dim wLen As Long '送信されたデータ長の変数宣言
Dim dLen As Long '送信するデータ長の変数宣言
  Dim cCrLf As BytePtr
buff1 as string, VOLT as string
VOLT="30" 'ここでは30Vにします。

buff1="setv 1 "+ VOLT 'ボルトの設定
wSData=lstrcat(buff1,Chr$(13))
dLen = lstrle (wSData) 'ANSI+DBCS文字でのバイト数に換算
dummy = WriteFile(hComm[1], wSData, dLen, VarPtr(wLen), ByVal 0) 'データの送信


受信もprint文で確認しましたが10と出ます。明らかに測定値のと異なります・・・。
以下は測定コマンドを送信後、受信する為のものです。

Dim rData[300] As Byte ' 受信データの変数宣言(文字変数として定義)
Dim rLen As Long '受信されたデータ長の変数宣言
rData[0] = 0 '100文字分の領域確保

wSData=lstrcat(":meas?",Chr$(13))
dLen = lstrlen (wSData) 'ANSI+DBCS文字でのバイト数に換算
dummy = WriteFile(hComm[7], wSData, dLen, VarPtr(wLen), ByVal 0)

dummy = ReadFile(hComm[7], rData, 100, VarPtr(rLen), ByVal 0) 'データの受信(2番目のパラメータにByvalをつける)
print dummy  '表示させてみる。



[/hide]
あべべ

ハンドルが無効のようです。

#2 投稿記事 by あべべ »

GetLastError()関数を用いたところ、ハンドルが無効のようです。

今でているエラーは全て同じでstring.sbpのファイルの中の下の所をさしています。↓
HeapFree(_System_hProcessHeap,0,BufPtr-4)

デバッグの欄にはこれが書かれています。↓
HEAP[piezo_debug.exe]: Heap block at 00192030 modified at 00192046 past requested size of e
スレッド(&H470)のブレーク ポイント(EPI=&H77F767CD)。

writefileなり、readfileなり2回同じプログラムを読ませるとだめなようです。
色々と試してみましたが、原因が何かわかりません。
どうしてダメなのでしょう?
ゲスト

Re: rs232c通信について

#3 投稿記事 by ゲスト »

コードが歯抜けでコメントしようがないのですが・・・・

> hComm[num] = CreateFile(StrComNom, GENERIC_READ                      OrGENERIC_WRITE, 0, ByVal 0, OPEN_EXISTING,                                  FILE_ATTRIBUTE_NORMAL, 0)

ここは、numとStrComNomを変えて3回実行していますか?
あべべ

歯抜けですみません。。

#4 投稿記事 by あべべ »

お返事ありがとうございます。中途半端に抜き出してすみません。一応下のように定義してnumを選択するようにしています。input文よりnumを選択しています。ONとOFFがみてわかるようになっています。ここは問題はないように感じますがどうでしょうか?長くなりましたがすみません。

'************************
' RS232CのOPEN
'************************
dim num as long ,onn[8] as string ,numm as string
onn[1] ="OFF"
onn[8]="OFF"
onn[7]="OFF"

*open rs232c 'COMポートオープン
cls 3
print "----------------通信設定------------------" :print :print
print "(COM1) . piezo controller "+onn[1] :print
print "(COM8) . keithly 2400 "+onn[8] :print
print "(COM7) . keithly 2182 "+onn[7] :print
print " 4 . 戻る " :print
print "何番を変更しますか?"
10 input num
if num>8 or num<1 then goto 10 'ここではcom1,7,8のみにしました。
if num=4 then goto 200
if num>1 and num<7 then goto 10
if onn[num]="OFF" then goto *comopen else goto *comclose

*comopen
onn[num]="ON"
numm=Str$(num)
StrComNom="COM"+numm


hComm[num] = CreateFile(StrComNom, GENERIC_READ Or GENERIC_WRITE, 0, ByVal 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)
If hComm[num] = -1 Then
Print StrComNom; "が使えません"
' MsgD = lstrcat(comname , "が使えません") 'ポートのオープン失敗時
' MsgBox 0, MsgD '警告メッセージ アイコンを表示
dummy = CloseHandle(hComm[num]) 'シリアルポートを閉じる
Sleep(7999)
End '強制終了
End If


goto *open rs232c
*comclose
onn[num]="OFF"
dummy= CloseHandle(hComm[num])
goto *open rs232c
ゲスト

Re: 歯抜けですみません。。

#5 投稿記事 by ゲスト »

どうも。バリバリのBasicですね。(笑)

Openは大丈夫そうです。
どこかで、メモリーを壊しているみたいですね。
よくわかりませんが、試しに送信部分を下記の様にSubでかこみ、コードの最後に移動て試して、
こんな感じで呼び出してみてはどうでしょう?

コード: 全て選択


'送信
VOLT="10"
COMM1_TX()
Sleep(1000)
VOLT="20"
COMM1_TX()
受信は、送信が解決してからと言うことで。
Tomorrow
記事: 72
登録日時: 2005年6月04日(土) 10:09

Re: 歯抜けですみません。。

#6 投稿記事 by Tomorrow »

wSDataはBytePtr型なのに

コード: 全て選択

    wSData=lstrcat(buff1,Chr$(13))
と、メモリ確保せずに使ってしまっているのがまずいのでは?
mallocを使うか、Byte型にするか、素直にString型でもいいと思うのですが。

コード: 全て選択

修正案:

Sub COMM1_TX()
    Dim wSData As String
    Dim wLen As Long                               '送信されたデータ長の変数宣言
    Dim dLen As Long                                '送信するデータ長の変数宣言
    Dim cCrLf As BytePtr
''  buff1 as string, VOLT as string
'    buff1 as string
''VOLT="30"  'ここでは30Vにします。
    
    wSData = "setv 1 " + VOLT + Chr$(13)   'ボルトの設定                 
    dLen = Len(wSData)          'ANSI+DBCS文字でのバイト数に換算
    dummy = WriteFile(hComm[1], StrPtr(wSData), dLen, VarPtr(wLen), ByVal 0)    'データの送信
End Sub
あべべ

送信の問題解決しました。

#7 投稿記事 by あべべ »

ゲストさん、Tomorrow さん、ありがとうございます!
僕1人では絶対に思いつきませんでした(><)
Tomorrow さんからのご指摘があったようにメモリ確保せずに使ってしまっているのがダメだったようです。勉強になります。
後は受信だけです。
コレもrDataをstringと定義していけばいいだけですね?

ゲストさんがおっしゃったように、実は当初はプログラミングの基礎からをと思い、N88BASICで作っていたのです。しかし、1台の通信速度が38400bpsでしか行なえなかったためあえなく断念しました。(泣)
そこで互換ができるABをと思ったらAPIも理解しないといけなくなり・・・
いまは色々な方のHPから勉強させていただいています!
プロシージャや、APIもしっかり理解していけるようにがんばります★
あべべ

受信なのですが・・

#8 投稿記事 by あべべ »

色々と試してみたのですがうまくいきません。
Dim rData As String ' 受信データの変数宣言(文字変数として定義)
Dim rLen As Long '受信されたデータ長の変数宣言

wSData=lstrcat(":meas?",Chr$(13))
dLen =Len (wSData) 'ANSI+DBCS文字でのバイト数に換
dummy = WriteFile(hComm[7], wSData, dLen, VarPtr(wLen), ByVal 0)

'上までは測定のコマンドを送信。下がそれの受信なのですが・・・。


Dim rData[300] As Byte ' 受信データの変数宣言(文字変数として定義)
Dim rLen As Long '受信されたデータ長の変数宣言
rData[0] = 0 '100文字分の領域確保
dummy = ReadFile(hComm[7], rData, 100, VarPtr(rLen), ByVal 0) 'データの受信(2番目のパラメータにByvalをつける)
print dummy ,rLen 'ここで表示

表示されるのは1 、0です。つまり受信0バイトです。
なぜでしょうか?知恵をおかし下さい。
あべべ

先程のReadFile文hs・・・

#9 投稿記事 by あべべ »

dummy = ReadFile(hComm[7], rData, 100, VarPtr(rLen), ByVal 0)

結局過去の方の投稿をさんこうにしてうえのようにしていました。
Tomorrow
記事: 72
登録日時: 2005年6月04日(土) 10:09

Re: 受信なのですが・・

#10 投稿記事 by Tomorrow »

> wSData=lstrcat(":meas?",Chr$(13))
wSDataをString型にしてるなら、lstrcatは使いません。
lstrcat, lstrlenはByte型配列やBytePtr型が指すメモリ領域に対する文字列処理で使います。
+演算子に変更してみてください。

コード: 全て選択

wSData = ":meas?" + Chr$(13)
あべべ

#11 投稿記事 by あべべ »

すみません。前回のを引用していたので間違えてました。
先ほどのコードはやっており、送信はできているようです。(測定器も反応しています)
なのに受信ができていません。送信はCRを付加させていますが、受信は何かする必要はないのでしょうか?
Tomorrow
記事: 72
登録日時: 2005年6月04日(土) 10:09

#12 投稿記事 by Tomorrow »

> 送信はCRを付加させていますが、受信は何かする必要はないのでしょうか?
デリミタはCR+LFの場合もありますけど、その辺は確認しましたでしょうか?
> 表示されるのは1 、0です。つまり受信0バイトです。
全く受信できてないということですよね。なんででしょう?
とりあえずハイパーターミナル等でデータが来てるか確認してみてはどうでしょう。
もう確認済みかもしれませんが…
過去ログとかも一応探してみたんですけど、うまくいきましたっていう投稿が見つからないんですよね…
参考になりそうなサイトがあったので一応載せておきます↓
http://members.jcom.home.ne.jp/0434383301/vc10.htm

それと、どうでもいいことかもしれないですが、
前々回の投稿で勘違いしてた箇所がありました。
メモリがちゃんと確保されていないのはbuff1の方でしたね。
wSDataの方は問題なかったです。
あべべ

ありがとうございます。

#13 投稿記事 by あべべ »

返事おくれてすみません。実験中だったもので。。
親切にありがとうございます。
デリミタは確認したのですが・・・。もう1度確認してみます。
教えていただいたサイトを参考にこの土日でしあげたいとおもいます!!(絶対に)
>それと、どうでもいいことかもしれないですが、
前々回の投稿で勘違いしてた箇所がありました。
メモリがちゃんと確保されていないのはbuff1の方でしたね。
wSDataの方は問題なかったです。
いえいえ。メモリの確保という概念がなかったので非常に助かりましたので(^^)
あべべ

どうやら・・

#14 投稿記事 by あべべ »

受信の問題についても解決したようです。

コード: 全て選択


Dim rData As string ' 受信データの変数宣言(文字変数として定義) 
Dim rLen As Long     '受信されたデータ長の変数宣言 
rData= zerostring(100)         '100文字分の領域確保
 
dummy = ReadFile(hComm[7], StrPtr(rData), 100, VarPtr(rLen), ByVal 0) 'データの受信(2番目のパラメータにByvalをつける) 
print rData
コレも試したはずなのですが・・今日するとすんなりうまくいきました(苦笑い)
色々とありがとうございました。[/code]
返信する