ユニバーサル基板でネットワーク接続IO(もしくはイーサネットシリアルコンバータ)を作る(AVR web server)

Last-modified: 2016-11-07 (月) 05:51:30
初出 2013-7-21
最終更新 2016-3-3
 

ネットワーク接続IOというと、「細かい配線があるのでプリント基板のキットを利用する」という例が多いわけですが、ユニバーサル基板でも充分簡単に作成可能です。

 

本ページでユニバーサル基板上の回路を簡単にしたミソは2点あります。1つはSPI接続でDIPのENC28J60を使用すること。2つめはRJ-45ジャックの周辺回路をジャックの上の空中配線で完結させてしまうことです。

 

ところで、私自身のこのネットワークIOの作成目的は、Wake on LAN非対応のPCを強引にネットワーク経由で起動させることです。具体的にはソニーの古いコンシューマ用ノート(ウチのリビングPC)を遠隔起動する為に使用しています。もちろんスイッチ周辺に2本の線を取り付ける改造を施してあります。
ロームの無線LANモジュール等を使えば遥かに簡単にネットワークIOは実現できるわけですが、それらはまだ高いし(2015-11-16追記)無線LANならESP-WROOM-02のような激安鉄板商品がありますが、有線LANならではの良さもあるので、本ページの工作のようなものもまだまだ価値があると思います。同じくネットワークIOとしても使えるArduino EthernetやArduino+イーサネットシールド等と比べても、遥かに安上がりです(Arduinoのイーサネット関連品が高すぎるだけだと思いますが)。

 

(2015-10-19追記)
本ページのものはちょっとした改造で簡易「Serial over Ethernet」的な運用が可能です。
参考URL1:http://www.hw-group.com/products/hw_vsp/index_en.html
参考URL2:http://www.hw-group.com/supp_rem_serial_en.html
参考URL3:https://developer.mbed.org/users/hudakz/code/Serial_over_Ethernet/
上記URLでやっている中身は、技術的には実は本ページのものと、(言いようによっては)そう大して変わりません。本ページのものも、PCからネットワーク越しにコマンド文字列を送り、それをAVRのシリアルポートから出力するような改造は簡単におこなえます。その逆方向の、AVR側からPCに定期的に収集データを送信するような場合はPC側でCGIサーバを動かす方法でおこなう方法が元々用意されています。
(2015-11-8追記)
で、実際にイーサネット→シリアルコンバータ化したものをページ後半に掲載しています。

 

外観

見ればわかると思いますが、本ページの作例では1ピンしか動作させていなくて、せっかくのネットワークIOを非常に勿体ない使い方をしています。このページを参考になさる方は、mega328等や連携チップを使って遠隔リモコンに仕立てる等、もっとリッチなインターフェースや高度な機能を実現してみて下さい。
(2013-11-22追記)2機目を作りました。1機目は実運用していて遊びに使えないからです。2機目は気楽に、回路図もほとんど見ず、1機目の回路を丸ごと写して作りました。そして(もちろん(遊び用だから))ICSP回路を追加しました。本家の応用例を見ると、遠隔計測用途等が多いようです。

 

network-io_on_universal_circuit_board_1_s.jpg
クリックすると大きな画像で表示されます
RJ-45ジャックはピンソケットと抜け防止用の打ち抜き加工の部分を利用して固定しています。適度な堅さで脱着できます。

基板

チップとRJ-45ジャックを外した状態です。
network-io_on_universal_circuit_board_2_s.jpg
クリックすると大きな画像で表示されます
ICSP回路は省略しています。

 

いつもは出来る限りメッキ線のみで配線しようとする私ですが、今回は2本ビニール線を使いました。
network-io_on_universal_circuit_board_3_s.jpg
クリックすると大きな画像で表示されます

RJ-45ジャック周辺回路

この部分の回路は、ARM基板をEthernetに接続する - CQ出版社を参考にしました。ただし抵抗値は50Ωではなく、ジャックのデータシートにある75Ωを採用しています。あとコンデンサ容量は見てのとおり0.1μFです。実際のところ基板はピンヘッダ・ピンソケットの位置を定めるくらいにしか役立っていません。この部分は秋月にキット化して欲しいです。あと、この部分の回路ではありませんがENC28J60のバイアス抵抗も同pdfを一部参考にして2.32kΩにしました。
network-io_on_universal_circuit_board_4_s.jpg
クリックすると大きな画像で表示されます
秋月の300円のパルストランス内蔵モジュラージャックを使用しています。200円のジャックもピン配置は全く同じです。1個目はそちらを用いて高さを気にせずに作り、2個目は300円のジャックである程度低く仕上げることを目標にして作りました。

 

上の写真の接続の概略です。
network-io_on_universal_circuit_board_5_s.png
クリックすると大きな画像で表示されます
無精して書きこんでませんが、実際にはもちろん他にいろいろな追加部品(75Ωx4、104x2、フェライトビーズ、追加配線)がつきます。また、GREEN A、YELLOW Aからそれぞれ下向きに伸びる線は実際には270Ωの抵抗です。
(2013-7-29追記)LANコネクタDIP化基板はパルストランス付きジャックに合いません。使えません。何とか無理やり使えないかと思い、買って試してみましたがやっぱり駄目でした。200円タイプ、300円タイプどちらとも、無理やりすら合わすことはできません。

いろいろやってみる

 

(1)まず、純正リモートスイッチ版ファームウェアを試用してみる

ダウンロードしたアーカイブにはserver-www-dnstest, server-www-simple, server-www-remswitch等、いくつかのパターンが含まれていますが、試用状況を紹介するならやはりserver-www-remswitch(リモートスイッチ)版でしょう。
とりあえず私がコンパイルを試みた時点ではVersion5系列(eth_tcp_client_server-dhcp-5.3.tar.gz)はWindowsではコンパイルできず、Linuxでコンパイルしました。また、コンパイルはできてもmega328p以外では動作しませんでした。事実上mega328専用のようです。Version4系列(eth_tcp_client_server-4.5.tar.gz)はmega88指定ではコンパイルできませんでした。事実上mega168以上専用のようです。ということで、mega88、mega88pを使用する場合は自動的にVersion3系列(eth_tcp_client_server-3.6.tar.gz)の採用となります。

 

ソースを読まずに回路を作ったので出力ポートがノーマルHiだと勘違いしていました。なのでソースの方をノーマルHiに書き換えました。リレー駆動用トランジスタはPNPを使用しています。修正版回路図は載せるほどでも作成するほどでもないので本家の回路図を参照して下さい。

 

ダウンロード fileeth_tcp_client_server-3.6_main.c.patch
(2015-12-2追記)このパッチの中の「1>>(PORTD & (1<<PORTD7))」という部分(2箇所)についてですが、2年前に自分が新規で書いたか何処かからコピペしたものの筈ですが、今しらふで眺めてみると不思議です。普通の処理系の常識で判断すると正しく動作しないように見えます。普通の処理系だとこう「(1<<PORTD7) & ~(PORTD & (1<<PORTD7))」書かないと正しく動作しないと思います。でも現実にはAVRでは正しく動作します。その正確な理由はAVR-Studioのシミュレータなんかを動かすか、生成されたアセンブラコードを調べれば正確にわかると思いますが、机上だけで考えると、この場合、関数の引数にキャリービットが含まれ、それが非ゼロ、ゼロの判定に使われているということなのだと思います。
ということで、“この変なコード”、何かの時にまた役に立つかもしれないので、忘れない為にも、削除せずにそのままにしておきます。多分ほぼ確実に、意図的な仕様でしょう。多分この仕様を盛り込むと、短く書けるしアセンブラ命令に都合よく変換できてコンパクト化、高速化が図れるからでしょう。私は何処かで見つけたのでしょう。
あと、このほどeth_tcp_client_server-dhcp-5.10(2015-11時点で最新版は5.10)ベースに変更したので、そちらのパッチも一応アップしておきます。以前よりコンパクトになったみたいで88pでもVersion5系列が利用できるようになっています。パッチの実質的な中身は前のと同じです。
ダウンロード filePNP_eth_tcp_client_server-dhcp-5.10_server-www-remswitch_main.c.patch

 

それ以外の修正は何もおこなわず、

#!/bin/sh
udpcom secret,t=1 192.168.1.18
sleep 0.5
udpcom secret,t=0 192.168.1.18

このようなスクリプトを使って当該のノートPCをリモート起動しています。リレーを使って「スイッチを押し、離す」という動作をエミュレートしているわけです。このスクリプトはx86Linux版ですが、WindowsからもDD-WRTからもほぼ同じで、違いはsleep 0.5の箇所がsleep 1になってるくらいです。ブラウザからも操作できます。

 

おまけとして私がコンパイルしたDD-WRT版のudpcomを載せておきます。こちらで(は)動作確認済みです。
ダウンロード fileudpcom_mipsel
ダウンロード fileudpcom_mipsel_static  スタティック版(2013-9-1追加)
スタティック版だと、外部ストレージを持たなくてライブラリを追加できないDD-WRTでも、より確実に使用できるでしょう(JFFS2利用)。
もう一つおまけとして、上のスクリプトをもう少し確実なものへと修正したものを載せておきます。DD-WRTで使用できる文法で記述しています。(2013-9-1追加)

#!/bin/sh -x
UDPCOM=/opt/udpcom
IP=192.168.1.18
line="`${UDPCOM} secret,t=? ${IP}|tail -1`"
RET=$?
if test ${RET} -eq 0; then
	STATUS="`echo "${line}"|cut -d\" \" -f3|cut -b3`"
	if test "${STATUS}" = "0"; then
		${UDPCOM} secret,t=1 ${IP}
		RET=$?
		if test ${RET} -eq 0; then
			sleep 1
			${UDPCOM} secret,t=0 ${IP}
		fi
	fi
fi
 

あと、指定のFUSE設定はクロックソース設定が外部発振回路onlyなので、私のようにICSP回路を省略する場合には注意が必要です。私の場合はこのような対策をとっています。

(2)リモートスイッチ版ファームウェアを改造してみる

(2014-2-23追記)
下記の、リセットや電源ON等に共通した動作:「ON→0.5秒保持→OFF」をワンクリックでおこなえるようにwebインターフェースを修正してみました。

 

network-io_on_universal_circuit_board_6_s.png
OK画面も追加しています。操作後に何らかの画面変化が欲しいのと、(GETメソッドを使用しているので)最後にアクセスしたURLをパラメータなしの状態にする為には別のURLが必要な為です。

 

ソースのパッチです。
ダウンロード fileeth_tcp_client_server-dhcp-5.3_server-www-remswitch_main.c.patch
このソース(パッチ)では(下記と異なり)オリジナルままのノーマルLowとなっています。
Version5系をベースとしていますが、多分Ver3系でも適用可能でしょう(未確認)

 

(2014-3-21追記)
上記パッチをVer3系にあててみると「1 out of 8 hunks FAILED」でした。失敗するのは冒頭の宣言セクションだけなので簡単に手パッチでリカバリーできます。ただし、mega88だとサイズオーバーです。
(ここまで2014-3-21追記分)

 

(2016-3-3追記)
今更の報告ですが、このセクション「(2)リモートスイッチ版ファームウェアを改造してみる」は企画倒れに終わりました。トリッキーな手法を採っている為、ブラウザのキャッシュが残っていると正常に動作しないんです。

 

他に回避方法がないかひと通り試してみましたが、やはり、キャッシュが残っている可能性がある場合は、操作しようとする度にプライベートタブもしくはウインドウを開くか、ブラウザの設定でキャッシュを無効にする必要があります(そもそもキャッシュ機能を持っていないガラケーのiモードブラウザ等を使う場合はその限りではありません)。

(3)簡易「Serial over Ethernet(Ethernet to Serialコンバーター)」版ファームウェアを作成

(2015-11-8追記)
作成したといってもライブラリが充実しているので作業量としては“ちょっとした改造”程度です。

 

ダウンロード fileeth_tcp_client_server-dhcp-5.X_serial-over-ethernet.main.c
このファイルをmain.cとリネームし、eth_tcp_client_server-dhcp-5.X.tar.gz(2015-11時点で最新版は5.10)内の、server-www-remswitch/main.cと差し替えてビルドして下さい。UDP対応機能を削除したのでATmega88(p)でもビルドできます。

 

使い方その1
AVR・WebServerのURLをブラウザで開き、送りたい文字列をテキストエリアに入力します。
送信すると、入力した文字列がAVRの3番ピン(DIP28パッケージの場合)から9600bpsで出力されます。
network-io_on_universal_circuit_board_7_s.png
許容される最大の長さは240字余りです。この入力された文字列をGETでAVR側に送信するにも関わらず、AVR側はURLデコードに対応していないので、使用できる文字はかなり制限されます。URLデコード処理はメモリを大きく消費し、mega2560あたりを必要とすると思われるにも関わらず、私自身が特に必要としていないので実装していません。半角スペースは使用できます(+に置換されて送られ、AVR側で半角スペースに再置換されます)。
つまりは、文章の送信については非常に制限的です。本当に向いている用途は16進コードなんかの送信です。基本的に私はエアコンの赤外線リモコンのデータが16進文字列で送信できれば十分、との考えの元、実装をおこないました。
1文字列(1行)送信する度にシリアル側にはCRLFを追加出力します。適宜LFのみに変更する等カスタマイズして下さい。

 

使い方その2

$ wget 192.168.1.19/secret/0A50504FB020DF900980000C154DB >/dev/null 2>&1

もしくは

$ curl 192.168.1.19/secret/0A50504FB020DF900980000C154DB >/dev/null 2>&1

これらが実利用する場合の標準の使い方になると思います。スマホではボタンとcurlコマンドを紐付けるだけでアプリが作成できます。
もちろん実際にはこの何倍も長い文字列を送信できます。

 

上掲の…….main.cは簡単なつくりで、サブ基板側からの受信機能を実装していません。ということもあり、上記で紹介する使い方ではAVR側からの戻りを/dev/nullに捨てていますが、サブ基板側からの受信機能を実装して、戻りに反映する改良をおこなってもいいと思います。また、シリアル接続からI2C接続に変更してもいいでしょう。

 

使い方その3
下記のように、ブラウザのアドレスバーに直接入力する。

http://192.168.1.19/secret/0A50504FB020DF900980000C154DB

動作確認等の際に利用できると思います。

 


※自宅LAN内からの操作であれば、上記説明例のように直接このAVRのハードに接続して操作してもいいんですが、外部からはセキュリティ上、FWとポートフォワードを噛ませるのみでAVRハードに接続させることは推奨できません。最低限、SSLリバースプロキシ+BASIC認証あたりを追加する必要があります。それらはRaspberry Piだとごく簡単に構築できます。でも「Raspberry Piが必要」ということになると、「何のために単体稼働可能なAVR・webサーバを作るのか?」という矛盾が生じてしまいます。まあRaspberry PiはLAN内に一台でいいのでAVR・webサーバを複数設置する場合はそのような場合においても存在価値はありますけどね。

開発用基板(通算2枚目のAVR Web Server基板)

network-io_on_universal_circuit_board_8_s.jpg
クリックすると大きな画像で表示されます
1枚目を横に置いて作成したので殆ど同じです。でも1行ずれていたりして、細部が少し違います。
左端の、トランジスタとか2ピンコネクタがある部分は、(2)の開発で使用した回路です。
今回の「Ethernet to Serialコンバーター」としてのシリアルの出力はその上の4ピンヘッダの部分に出てきます。ピンの並びは下から3.3V、TX、RX、GNDです。
RJ-45ジャックの上の(写真では手前側の)様々な部品が固められた部分は、上記にあるように、最初に作った分なので、高さがかなりあります。

 

network-io_on_universal_circuit_board_9_s.jpg
クリックすると大きな画像で表示されます
1本の黒い線を除くビニール線は全てICSP用の配線です。なので実質的には1枚目よりもメッキ線の使用率が高いです。

応用例:ネットワークから操作できる赤外線リモコン

network-io_on_universal_circuit_board_10_s.jpg
クリックすると大きな画像で表示されます
シリアル接続赤外線リモコン・トランスミッターの基板を取り付けて、ネットワーク経由でPCやスマホから操作できる赤外線リモコンに仕立ててみました。外部からの接続用ゲートウェイを立てなくても、家の中であれば、どこにいてもスマホから操作できます。

(サブ基板の)PIC16F886採用シリアル接続赤外線リモコン・トランスミッター

pic16f886-ir-transmitter_s.jpg
クリックすると大きな画像で表示されます
あり合わせの1000uFのコンデンサを付けてしまっていますが、これは大きすぎると思います。
まあとりあえずこの回路は調子が良くて、赤外線LEDを部屋のどこに向けていても対象機器が反応してくれます。

(サブ基板の)PIC16F886採用シリアル接続赤外線リモコン・トランスミッターの基板

pic16f886-ir-transmitter_circt_s.png
クリックすると大きな画像で表示されます
回路的には採用チップは異なりますが、当サイト中の別のページのRaspberry Pi用のシリアル接続赤外線リモコン・トランスミッターと殆ど同じです。受け取る16進コードの仕様も同じです。ただしファームウェアは(今のところ)こちらの方が流用元が新しい為、新しい仕様を盛り込んでいます。

  • PIC16F886の最大動作周波数は正規の仕様では20MHzですが、32MHzで動作させています。
  • 32MHzと動作周波数が高いのは、48MHz動作を前提に書かれたビット・トレード・ワン社のUSB接続赤外線リモコンのソースコードを一部流用する為です。
  • PIC16F886は最新世代のチップではなく、連続した大きな受信バッファを確保できませんが、今回の場合、処理時間に余裕があり、2分割が可能だったので特にハンディは生じていません。
  • PIC16F886は最新世代ではない為、秋月のライタ等でファームウェアを書き込むことができます。
  • 最新世代(Enhanced Mid-Range PIC)のチップ、たとえばPIC16F1827に変更すれば、外部発振子なしで、32MHzで動作せせることができます。PIC16F1827のプログラムメモリ容量はPIC16F886の半分(RAM容量は同じ)ですが、現行ソースコードはPIC16F886の20%しか使用していませんので、PIC16F1827で十分足りると思います。
  • シリアル接続でhexデータをやり取りする場合、I2C接続の場合の2~3倍のRAM容量が必要ですが、今回のPIC16F886は384バイトと比較的RAM容量に余裕があるので、問題になりませんでした。

(サブ基板の)PIC16F886採用シリアル接続赤外線リモコン・トランスミッターのファームウェア

今回用意したファームウェアはアップツーデートなXC8用です。
最新の日立エアコンのウェークアップコード(プレ・リーダーコード)にも対応しています。

 

ダウンロード  filepic16f886-ir-transmitter.c
※このソースコードを使用する為にはコンバーター側の改行コードをLFのみに変更する必要があります。

赤外線リモコンのウェークアップコード(プレ・リーダーコード)対応

「ウェークアップコード」、「プレ・リーダーコード」共に仮称で、今回私が勝手に名づけたもので、日立の最近のエアコンで見つけたものです。多分、家電業界的には、あるいは日立内部的には、正式な名称があると思います。ただし通称としては、実際にも、前記2つの仮称と似たものがつけられているものと想像します。

 

で、その中身がどういうものかと言うと、従来の赤外線リモコンのフォーマットについてご存知の方であれば、仮称を聞くだけで、ほぼどういうものか想像がつくと思います。リーダーコードの前に、リーダーコードをずーっと長くしたようなものがリーダーコードの直前に付加される(出力される)というものです。具体的には30ミリ秒オン、50ミリ秒オフです。

 

その役割、意味についても既に想像が付いていると思います。スリープモードから起こす(ウェークアップする)ことが役割だと思われます。実験ですぐにそのようなことが裏付けられます。

 

赤外線出力に毎回ウェークアップコードが付加されている、純正リモコンもしくは今回作成したウェークアップコード対応済みの自作版赤外線リモコンを使うと、前回正常に操作した後、どれほど時間が経っていても操作することができますが、ウェークアップコードを付加して出力しないリモコンを使うと、前回正常に操作した後、数分以内の範囲でしか、操作することができません。

 

当該機の赤外線リモコンフォーマットは、ウェークアップコードを除けば、従来の日立の赤外線リモコンフォーマットと互換性があり、長さの違いを除けば同一です。従って、当該機に対応する為には、従来の、日立エアコンに対応した赤外線リモコンのソースコードに、ウェークアップコード(プレ・リーダーコード)を付加する機能を追加すればいいということになります。

 

上掲のソースコードとこれは対応済みです。
修正内容はだいたい以下のようなものです。

 

ダウンロード  filewakeup-code.patch.txt

 

ご要望、ご意見、質問を下のフォームにどうぞ
(でもここより、掲示板書き込みフォームのページに書いて頂いた方が気づき易いと思います。)