テクニカルノート04: シリアル通信

April 2, 2003

Copyright NS BASIC Corporation

Go to English page.
マイクロソフト社のドキュメントも参考にして下さい。

NS Basic/CE に於けるシリアル通信は、Microsoftの標準COMMオブジェクトを利用しており、すっきりとした分かりやすいものです。COMMオブジェクトがお使いのWindows CEデバイスにインストールされ、レジストリに正しく設定されていることを確認して下さい。

COMMオブジェクトのプロパティを設定することにより、通信の全てのコントロールを行います。これらのプロパティはポート設定をコントロールし、さらに、文字の入出力の為に使われます。

COMMオブジェクトは、プログラムにインフォメーションを送り返す必要がある場合は、comm_onCommサブルーチンを呼びます。その後、このサブルーチン(引数を持たない)は、comm.commEventプロパティをチェックし、なぜコールバックが上がってきたのかを確認します。最も一般的な理由は、入力バッファに文字があることを、プログラムに伝える為です。

コミュニケーション設定パネル内のCommunicate with PCの指定を外すことを忘れないで下さい。忘れた場合、Windows CEが既にポートを開いていた場合、それを開くことが出来なくなります。

COMMオブジェクトを初期化する為に、以下のラインをプログラム内に入れて下さい。ここに書かれている全ての引数を渡さない場合は、onCommは呼ばれません。

addObject "Comm","comm",0,0,0,0

メモ

From Kostas Bouzianas

テキストモードではIn/Outバッファーは文字列として認識します。バイナリーモードでは、これらはBYTE配列として認識します。これはComm.InputMode=0/1とした時にVarType(Comm.Input または Output)で確認できます。問題は、VBScriptの曖昧な変数宣言の為、確実にバイト配列を定義できないことです(Array(cbyte(&HXX),....)などの明らかな関数でも・・・)。VarTypeで確認すると8204(バリアント型の配列)を返します。

これですと、出力は動作しません(OutBufferCount: 0、OnCommイベント無し)。入力は通常タイプ不一致エラーになります。

最後に、バイナリーモードでの送信/受信は以下をすることによって影響されます。

InputMode=0 'Text
NullDiscard=False

送信:CHR関数で送信するバイトを変換

1つの文字列変数でバイトの連結(全てのバイトを1度に送信)

受信:InputLen=1 (1バイト単位で受信)

ASC関数を使って受信した文字列を数値に変換し、配列に保管

周辺機器用の開発をしている方へ:あなたのアプリケーションは動作するかもしれませんが、ハンドヘルドの低レベル信号は、周辺機器のRS232ポートを呼ばないかもしれません。テストの目的で、デスクトップ上でアプリケーションを作ると良いでしょう。

From Juan Garlos Garrido

Kostas Bouzianasのメモを読みましたが、バイナリーモードでcommコントロールを動作させる唯一の方法はinputlenを1にセットし、1バイト毎に受信すると言っていますが、これは正しくないようです。

commの".input"メソッドはバイト配列を返します。あなたがしなくてはならないのは、これをバリアントに代入し、配列として使用します。わたしはこれをバージョン2.10で試し、問題なく動作しました。(もちろん、全ての文字を受信する為に、inputlenは0です。)

以下は、私のプログラムから抜き出したサンプルプログラムです。これは1つのパケットを受信する関数です。スタートタイムアウト、キャラクタータイムアウト、および関数結果の定数はこの関数の外で定義しなければなりません。Com_portはcommです。オブジェクトは関数の外で作成され開かれていると仮定しています。

Function Receive(nr,s)
'Receives a packet, stopping when  nr characters are received or
timeout 
's contains the packet received, and  the function returns
'Result_err_TOUT or Result_OK constants
'Timeout for first character= st_tout* 20 ms
'Timeout betwen characters= c_tout* 20 ms
'st_tout and c_tout are global constants

    Dim B 'pointer to input buffer
    Dim ncr, i,Tim
    On Error Resume Next   
    Tim=1
    Do 
    'Waits until some characters are avalaible
        sleep (20) 
        ncr = com_port.InBufferCount
        Tim=Tim+1
    Loop  Until (ncr > 0) Or (tim>st_tout)
    s = ""
    If ncr = 0 Then 'time-out
        receive = Result_err_TOUT        
        Exit Function
    Else 'there are characters in the buffer
        B = com_port.Input
        For i = 0 To ncr - 1
            s = s & Chr(b(i))
        Next
    End If
    Tim=1
    Do Until (Len(s) >= nr) Or (Tim>c_tout)
    ' Receives full packet
        sleep(20)
        ncr = com_port.InBufferCount
        If ncr > 0 Then
            Tim=1 'Resets timeout timer
            B = com_port.Input
            For i = 0 To ncr  1 'get all characters from input buffer
                s = s & Chr(b(i))
            Next
        End If
    Loop 
    Erase B ' dispose memory of input buffer
    If  Len(s) >= nr then 'Reception completed	
      receive = Result_OK  ' Pck
    Else
       receive = Result_err_TOUT 'Tout
    End If
End Function

プロパティ

comm.commEvent

最後のイベントの整数コード。書き込み禁止。

comm.commID

commデバイスのハンドル。書き込み禁止。

comm.commPort

commポート(com1, com2, ...)。整数。Casio PPCの例、この値を1に設定。

comm.DSRHolding

DSRラインの状態。

comm.DTREnable

DTRラインの状態。True または False。

comm.Handshaking

ハンドシェークプロトコル(handshaking protocol)
0 - 無
1 - XON/XOFF
2 - ハードウエア
3 - ハードウエア およびXON/XOFF

comm.inBufferCount

入力バッファ内の文字数。書き込み禁止。

comm.input

入力バッファからの文字を返し、バッファをクリア。

comm.inputLen

comm.inputが返す文字数。

comm.inputMode

入力タイプ
0 - テキスト
1 - バイナリ(二進)

comm.nullDiscard

null文字を排除すべきか? true または false。

comm.output

出力文字列。書き込み専用。

comm.OutBufferCount

出力バッファ内の文字数。書き込み禁止。

comm.portOpen

ポートの開閉
0 - comm ポートを閉じる
1 - comm ポートを開く

comm.RThreshold

onComm イベントが引き起こる前に受け取る文字数。
0 - onComm の動作を起こさせない。

comm.Settings

"BBBB,P,D,S"にフォーマットされた文字列。BBBBはボー(baud)、Pはパリティ(parity)、Dはデータビット数、Sはストップビット数。デフォルト値は "9600,N,8,1"。
有効なボーレートは 110, 300, 600, 1200, 2400, 9600, 14400, 28800, 38400, 56000, 128000, 256000。
有効なパリティ値は E,M,N,O,S (Even, Mark, None, Odd, Space)。
有効なデータビット値は 4, 5, 6, 7, 8。
有効なストップビット値は 1, 1.5, 2。

comm.sThreshold

onComm イベントが引き起こる前に送る文字数。
0 - onComm の動作を起こさせない。

comm.RTSEnable

RTSラインの状態。True または False。

comm.settings

文字列内のボー、パリティ、データビット、ストップビット。

CommEvent エラー

定数

内容

comNoError

0

エラー無し

comEventBreak

1001

ブレークシグナルを受信した

comEventCTSTO

1002

Clear To Send Timeout. Clear To Sendラインが文字を送信する時に使われるシステム定義された時間より短い。

comEventDSRTO

1003

Data Set Ready Timeout. Data Set Readyラインが、文字を送信する時に使われるシステム定義された時間より短い。

comEventFrame

1004

Framing error. ハードウェアがフレームエラーを検出した。

comEventOverrun

1006

Port overrun. 次の文字が届いた時に、前の文字がハードウェアから読まれておらず失われた。

comEventCDTO

1007

Carrier detect timeout. Carrier detectラインが文字を送信する時に使われるシステム定義された時間より短い。Carrier detectは、receive line signal detectとも呼ばれる。

comEventRxOver

1008

Receive buffer overflow. 受信バッファーがオーバーフロー。

comEventRxParity

1009

Parity error. ハードウェアがパリティーエラーを検出した。

comEventTxFull

1010

Transmit buffer full. 文字をキューに入れようとした時、送信バーファーが一杯だった。

comEventDCB

1011

ポート用のデバイスコントロールブロック取得時に予期せぬエラーが発生した。

CommEvent イベント

定数

内容

comEvSend

1

送信バッファーにはSThreshold以下の数の文字がある。

comEvReceive

2

RThreshold長の文字を受信。Inputプロパティを使って受信バッファーからデータを抜き取るまで、このイベントは継続的に発生する。

comEvCTS

3

Clear To Sendラインに変更

comEvDSR

4

Data Set Readyラインに変更。このイベントはDSRが1から0に変更された時にのみ発生する。

comEvCD

5

Carrier detectラインに変更。

comEvRing

6

リングを検出。いくつかのuniversal asynchronous receiver-transmitters (UARTs)はこのイベントをサポートしない。

comEvEOF

7

End Of File (ASCII character 26) 文字を受信。

Example

このプログラムは、標準同期接続を使用してPC上で動作している、HyperTerminalなどのターミナルエミュレーションプログラムと対話します。プログラムが正常に動くように、いくつかの設定が必要ですので、心に留めておいて下さい。

1. デバイス上で、Settings...Communication Properties...PC Connectionと操作して下さい。"Allow connection with desktop computer when H/PC is attached"がチェックされていない事を確認して下さい。

2. PC上で、 ActiveSyncがアクティブ状態にないことを確認して下さい。

3. ローカル接続用に、ターミナルエミュレータをデバイスが接続しているシリアルポートにセットして下さい。以下のプログラムを実行する時、ボー(baud)、パリティ(parity)、データビット(databits)、ストップビット(stopbits)をプロパティに書かれているのと同様に設定して下さい。また、ハンドシェークも同様に設定して下さい。

 

rem Demonstrate serial communications
'see Tech Note for complete details
Option Explicit
dim selection,myString
addObject "comm","comm",0,0,0,0
selection=0
myString=""

while selection<>9
  selection=inputbox("Choose Operation:" & chr(13) & "1. Open" & chr(13) & "2. Write" & chr(13) & "3. Properties " & chr(13) & "4. Read" & chr(13) & "5. Close" & chr(13) &  "9. End Program", "COMM Demo")
  select case selection
  case 1
    open_click
  case 2
    write_click
  case 3
    properties_click
  case 4
    read_click
  case 5
    close_click
  case else
    selection=9
    Comm.PortOpen = 0
  end select
wEnd

Private Sub Close_Click()
  Comm.PortOpen = 0
End Sub

Private Sub Comm_OnComm()
  Dim InString
  Select Case Comm.CommEvent
  Case 2 ' character In - collect until return is received
    InString = Comm.Input
    if asc(InString)=13 then
      msgBox myString
      myString=""
    else
      myString=myString & InString
    end if
  case else
    msgbox "Other CommEvent Received:" & comm.commEvent
  End Select
End Sub

Private Sub Read_click()
  dim sRead
  sRead=comm.input
  msgbox sRead
end Sub
 
Private Sub Open_Click()  
  Comm.Rthreshold = 1 'event on every character in
  Comm.InputMode = 0 'text mode
  Comm.handshaking=1 '0=none, 1=XON/XOFF, 2=HW
  Comm.RTSEnable=true
  comm.DTREnable=true
  Comm.PortOpen = True
  if err<>0 then
    msgbox "Open Comm: " & err.description
    err.clear
  end if 
End Sub

Private Sub Write_Click()
  Dim myString
  myString = "This is being sent from CommCtl Test."
  Comm.Output = myString
End Sub

Private Sub properties_click()
  dim sOut, tab, CR
  tab=chr(9)
  CR=chr(13)
  sOut="CommEvent:" & chr(9) & comm.commEvent & space(40) & CR
  sOut=sOut & "CommID:" & tab & comm.commID & tab & "InputLen:" & chr(9) & comm.inputLen & CR 
  sOut=sOut & "CommPort:" & tab & comm.commPort & tab & "InputMode:" & comm.inputMode &  CR
  sOut=sOut & "Handshaking:" & tab & comm.Handshaking & tab & "CTSHolding:" & CR
  sOut=sOut & "InBufferCount:" & tab & comm.inBufferCount & tab & "DSRHolding:" & comm.DSRHolding & CR
  sOut=sOut & "OutBufferCount:" & comm.OutBufferCount & tab & "DTREnable:" & comm.DTREnable & CR
  sOut=sOut & "PortOpen:" & tab & comm.portOpen & tab & "RTSEnable:" & comm.RTSEnable & CR
  sOut=sOut & "RThreshold:" & tab & comm.RThreshold & tab & "NullDiscard:" & comm.nullDiscard & CR
  sOut=sOut & "Settings:" & comm.settings
  msgbox sOut,0,"COMM Properties"
end Sub