PICNICおぼえ書き

PICNICTristate社製(販売:秋月電子)の超軽量ネットワーククライアントです。
PIC16F877にネットワークインターフェイスをつけた *だけ* という面白い構成。
まとまった資料がトランジスタ技術のバックナンバーしかない状態で、とても不便なのでまとめてみます。

ピンアサイン

26 25 24 23 22 21 20 19 18 17 16 15 14
GND GND GND GND GND GND GND GND GND GND GND GND GND
RA0 RA1 RA2 RA3 RB0 RB1 RB2 RB3 RB4 RB5 RB6 RB7 +5V
1 2 3 4 5 6 7 8 9 10 11 12 13

プロトコル

液晶表示(LcdCmdは使いそうなもののみを抜粋)

コマンド コード データ 詳細
PutString 00 [String] ... カーソル位置よりStringを表示
LcdControl 01 LcdCmd [String] ... LcdCmdを送ってからStringを表示
応答 データ 詳細
Response RA RB TRIS_RA TRIS_RB [AD_H AD_L] 00 00 8bytes
LcdCmd B7 B6 B5 B4 B3 B2 B1 B0 詳細
Clear 0 0 0 0 0 0 0 1 画面を消去しホームポジションへ
Home 0 0 0 0 0 0 1 * ホームポジションへ移動
Entry Mode Set 0 0 0 0 0 1 D S カーソル移動方向/シフトを設定。D=1:インクリメント、S=1:シフト
Display On/Off 0 0 0 0 1 D C B D:表示、C:カーソル表示、B:ブリンク
Cursor/Display Shift 0 0 0 1 S D * * S=1:シフト、S=0:カーソル移動、D=1:右方向、D=0:左方向
Cursor Add 1 Y X カーソルを移動

パラレルインターフェイス

コマンド コード データ 詳細
GetStatus 00 I/Oポートの状態取得
SetHigh/SetInput 01 Port Bit PortのBitを"H"/入力にする
SetLow/SetOutput 02 Port Bit PortのBitを"L"/出力にする
SetWhole 03 Port Size Mask Value [Mask Value] ... 複数のBitに対してBitSet/設定
GetADC 04 Ch Wait 指定のChをA-D変換
応答 データ 詳細
Response RA RB TRIS_RA TRIS_RB [AD_H AD_L] 00 00 8bytes。[AD_H AD_L]はGetADCの応答
Port 05 RA
06 RB
85 TRIS_RA
86 TRIS_RB
Size nn Mask+Valueの対の数(!=0)
Mask mm 現在の値に対するマスク値(AND)
Value VV 現在の値に対する設定値(OR)
Ch 81 RA0
89 RA1
91 RA2
99 RA3
A1 RA5
Wait nn A-D変換前のサンプリング時間=nn*5μs。00のとき100h

シリアルインターフェイス

コマンド コード データ 詳細
GetStatus 00 シリアルポートの状態取得
Register 01 IP addr. Baud Mode データ送信先を登録
Unregister 02 登録を解除
Transmit 03 Data ... データ送信
応答 データ
Response Code Size MAC addr(6bytes) IP addr.(4bytes) Port(2bytes) Baud Mode [Data] ...
Baud 129 9600bps
64 19200bps
32 38400bps
21 57600bps
10 115200bps
Mode 00 00固定

ブートストラップモード

JP2をクローズドにして起動すると、RC232C経由で各種設定が可能なブートストラップモードに入る。
設定は、9600bps、8bit、パリティなし、ストップビット長1bit。

変数 意味 備考 デフォルト
i IP addr. "0.0.0.0"を入力するとDHCPから取得 192.168.0.200
n netmask 255.255.255.0
g gateway "0.0.0.0"でも構わない 0.0.0.0
h http port 通常は80 80
l LCD port LCDを使用するには0以外を指定する 0(サンプルでは10000)
p pararell port 10001
s serial port 10002

標準ライブラリ

もっともよく使われるのはC用の標準ライブラリであろう(OCXという声は無視!)。
Windows用のpicnic.dllと、Linux用のlibpicnic.aとがある。使い方はほぼ共通だが、下に示すようにLinux版では未サポートの函数が多い。
Windows版ではWinsock2が必要。
以下にリファレンスを示す。

接続
PICNIC *PN_open(char *ip, u_short lcd_port,u_short para_port,u_short serial_port)
PICNICに接続
void PN_close(PICNIC *pn)
PICNICへの接続を閉じる
double PN_settimeout(PICNIC *pn, double sec)
タイムアウト時間設定
LCD
int PN_putlcd(PICNIC *pn, int cx, int cy, char *str)
指定位置より文字列表示
int PN_putlcd2(PICNIC *pn, char*str)
現在のカーソル位置より文字列表示
int PN_lcdclear(PICNIC *pn)
ディスプレイをクリア(カーソルはホームポジションに)
I/Oピン
int PN_dirp(PICNIC *pn, int port, int pin, BOOL direction)
ディジタルI/Oピンの入/出力設定
int PN_getdirp(PICNIC *pn, int port, int pin)
ディジタルI/Oピンの入/出力設定状態取得
int PN_outp(PICNIC *pn, int port, int pin, int level)
ディジタル出力ピンへ出力
※あらかじめPN_dirp()で出力ピンに設定しておくこと。
int PN_inp(PICNIC *pn, int port, int pin)
ディジタル入力ピンの状態を読み取る
※あらかじめPN_dirp()で入力ピンに設定しておくこと。
int PN_adinp(PICNIC *pn, int port, int pin, int wait)
アナログ入力ピンの状態を読み取る
※Linux版には存在しない。
int PN_setwhole(PICNIC *pn, int addr, int cn, ...)
ピン状態を一括設定
※Linux版には存在しない。
int PN_getwhole(PICNIC *pn, PICNIC_PARA_PACKET *pack)
ピン状態を一括読取
※Linux版には存在しない。
int PN_pbpu(PICNIC *pn, int enable)
内蔵プルアップOn/Off
※Linux版には存在しない。
シリアルポート
int PN_transmit(PICNIC *pn, int ch)
1byte出力
※Linux版には存在しない。
int PN_transmits(PICNIC *pn, char *str)
文字列出力
int PN_receive(PICNIC *pn, char *buff, int size)
文字列入力(タイムアウト付き)
int PN_getstatus(PICNIC *pn)
シリアルポートの状態取得
int PN_register(PICNIC *pn, long baud, int mode)
シリアルポート入力を登録
baudは9600,19200,38400,57600,115200より選択。modeは0固定。
int PN_unregister(PICNIC *pn)
シリアルポート入力登録を解除

特にシリアルポート入力は使いにくいので、わたしは次のようなラッパを使用している。

static unsigned char buf[8192];
static int nr=0;

int PN_getc(PICNIC *pn){
    if(!nr){
        if(PN_wait(pn)<=0)
            return -1; /* error */
        np=buf;
        nr=PN_receive(pn,buf,sizeof(buf));
    }
    nr--;
    return *np++;
}

追記:Linux用ライブラリ(libpicnic)について、2002年7月15日版がtristateのWebページにアップデートされている。ざっと見たところ、アナログ入力などいくつかの函数が追加されているが、シリアル関係の函数はなくなっているように見える。ドシタン???

Ruby用ライブラリ

以上の情報を踏まえて作ったライブラリがこれ

LCD制御メソッド(LcdDisp,LcdDispAt,LcdClear,LcdHome)及び、
パラレル用メソッド(GetStatus,GetRA,GetRB,SetHigh,SetLow,GetADC,GetTemp)を持つ。
シリアル用メソッドは後程。

PICNICを制御するには、PICNICクラスのインスタンスを生成し、そのインスタンスに対してメソッドを発行する。
ひとつのインスタンスがひとつのPICNICに対応する。
(つまり、複数のPICNICを同時に制御したい時はその数だけ生成すればよい)
PICNICクラスのインスタンスの生成方法は次のとおり:

p = PICNIC.new(address, lport, pport, sport)
ここで、
 address : PICNICのIPアドレス
 lport : LCDのポート(0のとき使用不能)
 pport : パラレルポートのポート
 sport : シリアルポートのポート(現在は使っていない)
各portの値はPICNICのWeb画面またはシリアルケーブルをつないでのブートストラップモードにて確認/変更できる。

メソッドは次のとおり:

LcdDisp(str)
 strをLCDに表示する。

LcdDispAt(x,y,str)
 x桁y行目からstrをLCDに表示する(x,yは0 origin)

LcdCur(on)
 LCDのカーソルON/OFF制御。on=1のときカーソルON、on=0のときカーソルOFF。
 (嗚呼、なんと酷いインターフェイスだ...)

LcdClear
 LCD画面消去。

LcdHome
 LCDのカーソルをホームポジション(0桁0行)に移動。

GetStatus
 パラレルポートの状態を読み込む(筈だがbugってるような気がする...)

GetRA
 GetStatusを呼んだ後に、RAポートの内容を返す。

GetRB
 GetStatusを呼んだ後に、RBポートの内容を返す。

SetHigh(port,bit)
 portには'RA'または'RB'を指定。各ポートのbitをHighに設定。

SetLow(port,bit)
 portには'RA'または'RB'を指定。各ポートのbitをLowに設定。

GetADC(ch,wait)
 chには'RA0'〜'RA4'を設定。アナログ入力を読み込む。

GetTemp
 内蔵温度計LM35DZの温度を返す。単位は℃。

例:LCDの0行目に文字列を、1行目に温度を表示する。

require 'picnic'

addr = '192.168.0.200'
p = PICNIC.new(addr,10000,10001,10002)
p.LcdClear
p.LcdCur 0
p.LcdDisp 'Hello, PICNIC!'
temp = p.GetTemp.to_i.to_s
p.LcdDispAt 0,1, temp + "\xdfC"

"\xdf"とあるのは、半角カナの「°」である。

サンプルプログラムを用意した。カレントディレクトリに"accounts"というファイルを用意し、
hoge,hoge.somewhere.jp,110,user,pass
の書式でPOP3アカウント情報を書いておくと、定期的にメイルチェックをしてLCDに表示する。
その他、時刻表示、温度表示も行なう。


ご意見・ご感想、お待ちしてます。
e-mail:shig@esprix.net

計算機のお部屋に戻る

ホームに戻る