« 2010年7月 | トップページ | 2010年9月 »

2010年8月の記事

Netduino Get

話題の、.NET Micro Frameworkが動きC#でプログラミングができる、Netduinoをスイッチサイエンスさんから購入しました。初回販売分が残暑見舞い特別価格の2,800円(Arduino Duemilanoveより安い!)ということで速攻でGetしてしまいました。ということで、2日ほどですが触ってみた感想を記載します。

   
Netduinoの特徴

開発環境のインストールなどは、他の方が書いているので、今回は手抜きをしてNetduioの特徴をさらっと...

  • Visual Studio 2010 Expressを使用でき、インテリセンスなどの補助機能でコード入力が楽ちん。mbedのクラウド開発環境も新鮮ですが、高機能IDEの使い心地も捨てがたい    
  • Visual Studioのデバック機能を使って、ソースコードレベルのデバッグが可能。Arduinoやmbedのprintfデバックから開放されて嬉しい    
  • Arduinoとピン互換のため、Arduino用のシールドが使える    
  • 同じくNETMFが動くFEZ Dominoに比べると、CPUはちょっと遅くなりますが(72MHz vs 48MHz)、RAM容量が多いため(96KB vs 128KB)ユーザーエリアが60KBと広い    
  • 何よりお安い(同類のFEZ Dominoに対して半分以下で、通常価格でもArduino並みの安さ!)    
  • ライブラリ(ファームとして提供される部分)の機能は、FEZ Dominoの方が豊富。FEZは、MSが提供していないUSB HostやSDカードなど、便利な機能がライブラリとして提供されているのに対して、Netduino提供ライブラリはA/D変換,PWMなど、現状は最低限の機能のみ。ただし、FEZのライブラリはソースが非公開でGHIの開発に依存してしまうが、Netduinoはライブラリもオープンソースなので、今後のコミュニティーによる開発に期待    
  • コードの実行速度はあまり期待できない(NETMFは中間コードを逐次翻訳するインタープリター方式で、PCで動くFull .NETのようにJITコンパイル機能がないため)。NETMFはC++で書いたNativeコードを呼び出すRLP(Runtime Loadable Procedures)という機能があるのですが、FEZ DominoやNetduinoではメモリー量の制約から現状は未サポート。そのため、FFTのような数値演算系の処理はFEZ Dominoでは手が出ないと思いますが、NetduinoならライブラリにNativeコードとして組み込むことで(力技ですが)処理性能を必要とするプロジェクトに対応できるかも

 
FEZ Dominoのドライバを移植

Netduinoは入出力ピンの配置がArduino互換ですが、使用しているMCUや実行環境が異なるためArduino用のライブラリコードは使えません。手っ取り早く周辺装置を動かす手段として、同じくNETMFを使いかつArduinoとピン互換になっているFEZ Dominoのドライバを拝借することにしました。FEZ Dominoのドライバ(ファームに組み込まれていない部分)はNETMF用のC#で書いてあり、最小限の変更で動作することが期待できます。

先ずは、Arduinoでもおなじみの16x2キャラクタLCDを動かしてみます。手順は以下です;  

  1. FEZ DominoのWebページからLCD & Keypad Shieldを探してドライバをダウンロード    
  2. 新規のプロジェクトを起こし、Program.csと同じフォルダにドライバファイル(FEZ_Shield_KeypadLCD_Red.cs)を格納    
  3. ソリューションエクスプローラーで      
    プロジェクト名を右クリック→追加→既存の項目から、ドライバファイルを指定してVSに登録    
  4. ドライバファイルを開くといくつかエラーが出るので、エラー発生箇所を修正    
  5. Programs.csをコーディング 

4項の修正箇所は以下です; 

①namespaceの変更   
using GHIElectronics.NETMF.Hardware;    
↓    
using SecretLabs.NETMF.Hardware;    
using SecretLabs.NETMF.Hardware.Netduino;    
cpuピン指定のパラメーター名をFEZ(GHI)からNetduino(SecretLabs)に変更するため、namespaceを変更します。 

②OutputPortのピン識別子の変更
LCD_RS = new OutputPort((Cpu.Pin)FEZ_Pin.Digital.Di8, false);    
↓    
LCD_RS = new OutputPort(Pins.GPIO_PIN_D8, false);    
GHIElectronics.NETMF.Hardwareで定義しているFEZ用のPin指定から、SecretLabs.NETMF.Hardware.Netduino名前空間で定義している識別子に変更します。同様に、D9, D7~D4も変更 

③ADCのクラス名を変更   
AnKey = new AnalogIn((byte)FEZ_Pin.AnalogIn.An0)    
↓    
AnKey = new AnalogInput(Pins.GPIO_PIN_A0);    
今回は使用していませんが、KeyPadの値を読み取るためにADCを使っています。FEZとNetduinoでクラス名が異なるため修正します。ピン指定もOutputPortと同様に修正します。 

Keypadやバックライトの制御は使っていないのですが、あえて削除はせず、エラーが出る部分だけ修正しました。コード全体はここです。 

続いて、5項のProgram.csをコーディングします。コードは以下です。 

using System.Threading;
using GHIElectronics.NETMF.FEZ;

namespace NetLCD
{
    public class Program
    {
        public static void Main()
        {
            FEZ_Shields.KeypadLCD.Initialize();

            while (true)
            {
                FEZ_Shields.KeypadLCD.Print("Hello World");
                Thread.Sleep(2000);
                FEZ_Shields.KeypadLCD.SetCursor(1, 0);
                FEZ_Shields.KeypadLCD.Print("Hello Netduino");
                Thread.Sleep(2000);
                FEZ_Shields.KeypadLCD.Clear();
                Thread.Sleep(2000);
            }
        }

    }
}

ドライバは、GHIElectronics.NETMF.FEZという名前空間で定義されているため、2行目のusingで指定します。最初は名前空間を変えようかと思ったのですが、名前空間もAPIの一部と考え、APIを拝借したGHIに敬意を表してそのままにしてあります。同様にドライバのクラス名がFEZ_Shields.KeypadLCDのため、この名前もそのままにしてあります。

このドライバは、static classとして定義してあるため、コンストラクタを呼んでインスタンスを起こす必要がなく、10行目のように、FEZ_Shields.KeypadLCD.メソッド名で処理を呼び出します。

最後にLCDとの結線は以下となります(ドライバの中で決め打ちになっています): 

  • RS --> D8
  • E --> D9
  • RW --> GND
  • LCD_D4 --> D4
  • LCD_D5 --> D5
  • LCD_D6 --> D6
  • LCD_D7 --> D7

めでたく動作しました。

 
Arduino Ethernet Shieldの使用

つぎは、FEZ DominoでもやったArduino Ethernet Shieldを動かすネタです。Ethernet Shieldは純正品ではなく、NKC Electronicsの互換品を使っています。このShieldはArduino Megaでも使えるように、SPIの信号をICSPコネクタから取る作りになっています。NetduinoはICSP接続用のヘッダピンが実装されていないため、手持ちの部品を半田付けしました。

Ethernet ShieldのドライバはFEZ Domino用を使います。こいつは、FEZ Domino+Arduino Ethernt Shieldで動作した実績があります。LCDドライバと同様に、以下の変更を加えます。

①namespaceの変更  
using GHIElectronics.NETMF.Hardware;  
↓  
using SecretLabs.NETMF.Hardware;  
using SecretLabs.NETMF.Hardware.Netduino;

②CS信号用OutputPortのピン識別子の変更 
SPI.Configuration config = new SPI.Configuration((Cpu.Pin)FEZ_Pin.Digital.Di10, false, ....  
↓ 
SPI.Configuration config = new SPI.Configuration(Pins.GPIO_PIN_D10, false, ......

ドライバ全体のファイルをここに置きます。

Program.csのコードは以下で、最小限のHttpクライアント動作を行います。

using System;
using System.Text;
using System.Threading;
using Microsoft.SPOT;
using GHIElectronics.NETMF.FEZ;


namespace NetEthernet
{
    public class Program
    {
        static byte[] IpAddress = { 192, 168, 0, 111 };
        static byte[] Subnet = { 255, 255, 255, 0 };
        static byte[] Gateway = { 192, 168, 0, 1 };
        static byte[] Mac = { 00, 0xXX, 0xXX, 0xXX, 0xXX, 0xXX };  //自分のMACアドレスを設定
        static byte[] RemoteServer = { 192, 168, 0, 10 };

        public static void Main()
        {
            FEZ_Shields.Ethernet.Initialize(IpAddress, Subnet, Gateway, Mac);

            while (true)
            {
                httpGet();
                Thread.Sleep(2000);
            }
        }

        // FEZ Ethernet Sheild用ドライバーを使用したHttpページの取得
        static void httpGet()
        {
            FEZ_Shields.Ethernet.uSocket socket =
                new FEZ_Shields.Ethernet.uSocket(FEZ_Shields.Ethernet.uSocket.Protocol.TCP, 80);
            Encoding enc = Encoding.UTF8;

            socket.Connect(RemoteServer, 80);
            string request = "GET /index.html HTTP/1.0\r\n\r\n";
            socket.Send(enc.GetBytes(request), request.Length);

            int length;
            while ((length = socket.AvilableBytes) > 0)
            {
                byte[] buff = new byte[length];
                socket.Receive(buff, length);
                String printStr = new String(enc.GetChars(buff));
                Debug.Print(printStr);
            }

            socket.Close();
        }
    }
}

基本動作のみの検証になりますが、ちゃんと動いています。

 
おわりに

FEZ Domino用のドライバ2例は、エラーが出た箇所を修正するだけで苦もなく動作してくれ、FEZ DominoとNetduino間の移植性の高さを実感しました。修正が必要な箇所は、GHI, SecretLabs固有ライブラリの差分が染み出す部分ですが、今回の例では僅かでした。

FEZ Dominoをいじった際は、GHI提供のライブラリをチュートリアル通りに動かすだけでしたので、正直ワクワク感が少なかったです。Netduinoでは人様が作ったドライバですが、自前で移植作業を行うことで、開発してる感が増しワクワク感がありました。Netduinoは、ファーム(NETMFのネイティブドライバ類)もオープンソースですので、コミュニティーの成果を借用したりして(あわよくば自分でも何か作って)、内部がいじれるようになればもっと面白くなる予感があります。

これからますます盛り上がってくれるとよいなと期待です。

2010/9/24 修正
GHIのライセンス条件からドライバコードの公開はNGのため、Netduinoへの移植版のダウンロードリンクは削除しました。

2010/10/2 更新
GHI提供ドライバがApacheライセンスになっています(ドライバファイルのソースに記載があります)。改変と再配布(Web公開含む)がこれで許されたと考えられますが、FEZ Ethernet Shieldのドライバは本日時点ではアクセスできなくなっているこもあり、コードの公開はやめておきます。Netduinoフォーラムでも独自のEthernet Shield用ドライバの開発が進んでいますので、Netduinoユーザーはこちらに期待しましょう。

FEZ DominoでArduino用Ethernet Shieldを動かしてみた

.NET Micro Frameworkが使えるプロトタイピングボードFEZ Dominoはシールドのピン配置がArduino互換です。さらに、FEZ Domino用Ethernet ShieldはArduinoと同じW5100チップを使っています。FEZ DominoのMCU(LPC2388)にEthernet Interface機能があるのにわざわざEthernt/TCP-IPチップを使うのは無駄のようにも見えますが、Arduino用Ethernet Shieldが流用できるのではないかという期待が出てきます。

そこで、FEZ DominoでArduino用のEthernet Shieldが動作するかを実験してみました。使用したのはオフィシャルEthernet Shieldです。Arduino Ethernet Shield、FEZ用ドライバとも無修正で正常に動作しました。


ドライバファイルの入手

FEZ Domino用ドライバファイルをここからダウンロードします。現在のβドライバはC#のクラスライブラリとして提供されており、CLR(インタープリタ)で逐次中間コードを翻訳しながらの実行となるため、速度はあまり期待できません。将来的にはファームウェアに統合されたネイティブドライバが提供されるようですので、速度面はそちらに期待。

ドライバファイルに、2箇所ほどDebug.printがコメントアウトされれずに残っていたため、コメントアウトが必要でしたww


FEZ Dominoとの接続

Arduino Ethernet ShieldをFEZ Dominoに取り付けるだけです。

Domino-ArduinoEthSield1

Domino-ArduinoEthSield2

FEZ Domino用Ethernet Shieldは割り込み信号(Di2)を使っているとWebページに記載がありますが、Arduino Ethernet Shieldは割り込み信号の配線がありません(割り込みをつなぐための、半田ジャンパはあるみたい)。ForumのQAによると、現在のドライバでは割り込みは使用していないとのことなので、ジャンパ作業は不要です。


サンプルコード

Webサーバーからhttpページを取得してデバックコンソールに表示するサンプルを作ってみました。

using System;
using Microsoft.SPOT;
using System.Text;
using System.Threading;
using GHIElectronics.NETMF.FEZ;

namespace FezEthernet
{
    public class Program
    {
        static byte[] IpAddress = { 192, 168, 0, 111 };
        static byte[] Subnet = { 255, 255, 255, 0 };
        static byte[] Gateway = { 192, 168, 0, 1 };
        static byte[] Mac = { 00, 0xXX, 0xXX, 0xXX, 0xXX, 0xXX };  //自分のMACアドレス
        static byte[] RemoteServer = { 192, 168, 0, 10 };

        public static void Main()
        {
            FEZ_Shields.Ethernet.Initialize(IpAddress, Subnet, Gateway, Mac);

            while (true)
            {
                httpGet();
                Thread.Sleep(2000);
            }
        }

        // FEZ Ethernet Sheild用ドライバーを使用したHttpページの取得
        static void httpGet()
        {
            FEZ_Shields.Ethernet.uSocket socket =
                new FEZ_Shields.Ethernet.uSocket(FEZ_Shields.Ethernet.uSocket.Protocol.TCP, 80);
            Encoding enc = Encoding.UTF8;

            socket.Connect(RemoteServer, 80);
            string request = "GET /index.html HTTP/1.0\r\n\r\n";
            socket.Send(enc.GetBytes(request), request.Length);

            int length;
            while ( (length = socket.AvilableBytes) > 0)
            {
                byte[] buff = new byte[length];
                socket.Receive(buff, length);
                String printStr = new String(enc.GetChars(buff));
                Debug.Print(printStr);
            }

            socket.Close();
        }
    }
}

サンプルは、socketをオープンし、socket.AvilableBytesで取得した受信データー量分のバッファを用意し、さらにstringクラスのインスタンスに情報をコピーしてDebug.printするというメモリー消費的には厳しいコードになっているため、情報量の多いwebページを取得するとメモリー枯渇になるかもしれません。ローカルPC上で動作するWebサーバーが返す1600byte程度のページは問題なく取得できます。

.NET Micro FrameworkにはSystem.Net.HttpWebRequestやSystem.Net.HttpWebResponseクラスがありますが、FEZ Dominoでは動作しませんでした(ビルドはできますが、実行時に例外を吐いてしまいます)。おそらく、FEZ用のドライバがuSocketクラスという固有のSocketインタフェースで実装しているためだと思います。今後の正式ドライバでは、NETMFが期待するSocketの実装になればこのあたりのHttpクラスも使えるようになるかもしれません。


その他

例によってEthernet Shieldが電源投入時に正しく動作しないことがあり、その場合はマニュアルリセットで動作しました(FEZ DominoはArduinoよりまじめにパワーオンリセット回路が作ってあり、ひょっとすると自分のEthernet Shieldはリセット対策のコンデンサを追加したため、その悪影響が出ているのかも?)。

今回の実験を行って思ったことですが、NETMFにはシリアルポート出力用のクラスがないため、テキスト情報を表示するようなケースがちと不便だと思いました。Debug.printでもよいのですが、必ず改行を入れてしまうため、せめて改行をしないオプションがあるとよいのですが。

サンプルでは、最初はバッファによるメモリ消費を節約しようと思い、socketからの受信データーを、256byteのバッファに分割して読み込むようにしました。Debug.printが引数としてstringクラスしか取らないため、256byte単位でstringに変換してprintするとそのたびに改行が入ってしまうため、最終的にはメモリーを消費してしまうのですが受信バッファの分割を行わないコードにしました。

Full NetのStreanReaderクラスを使ったサンプルでは、
Console.WriteLine(sr.ReadToEnd());
みたいに、「ストリームクラスを起こし、全部読み込んでから一気に表示」的な書き方になるのかと思いますが、NETMFではメモリーを喰わない工夫も必要かと思いました。まあ、NETMFでもグラフィックLCDにWPFを使って表示を行うような使い方では(NETMFがもともとターゲットにした領域でしょうか)、ROM/RAM共に数MBは必要になるため、そこまでケチらなくてもよいのかもしれません。

.NET Micro Framework 4.1を導入

NET MF 4.1を導入して、FEZ Dominoの開発環境を更新しました。NET MF 4.1からVS2010が使えるようになるのですが、NET MF 4.1をインストールしてしまうと、VS2008ではプロジェクトを開くことができなくなる(VS2008で作成したプロジェクトも含めて)ため要注意です。また、執筆時点ではFEZ DominoのファームがNET MF 4.0ベースですが、もうしばらくするとNET MF 4.1対応のファームがリリースされるみたいですので、それまで待つのがよいかもしれません。

TinyCLRのWebでは、VS2010はまだ未サポートと書いてある箇所があるのに、ダウンロードのリンクはNET MF 4.1 + VS2010になっており、なんだか混乱した状態になっています(2010/8/7時点)。


インストール作業

インストール自体は特に注意する点はありません。

  • Visual C# 2010 Expressをここからダウンロード。NET Framework (Full Net) 4.0も同時にインストールされます。VS2008との共存もできています
  • NET Micro Framework 4.1 SDKをここからダウンロード
  • FEZ DominoのファームとGHI NETMF SDKは現時点の最新版(1.0.5)が使えるため、インストールは不要。このファームはNET MF 4.0ベースのため、こいつに足を引っ張られて、現時点ではNET MF 4.0ベースでの解発になります
  • NET Micro Framework Porting Kit 4.0をインストールしている場合、事前にアンインストール


VS2008で作成したプロジェクトをVS2010で開く

NET MF 4.1とVS2010をインストールした後で、VS2008で作成したNET MFのプロジェクトを開くと以下のエラーダイアログが出て、ファイルを開けません。

VS2008_ErrorDlg

FullNetのプロジェクトは、.NET Framework 4.0をインストールした後でもVS2008で開くことができるのですが、NET MFのプロジェクトはNET MF 4.1をインストールするとVS2010が必須になってしまう様です。ひよっとすると、VS2008で開く方法があるかもしれないのですがVS2010に乗り換えることにします。

VS2010でVS2008にて作成したプロジェクトを開くと、プロジェクト形式の変換ダイアログが出ます。インストール直後、いくつかのプロジェクトで、変換エラーが発生するケースがありました。その後エラーが出なくなったため、何か環境要因があったのかもしれません。(実はPorting Kit 4.0をアンインストールしていなかったため、何か影響があったとか・・)

エラーが発生する場合の回避策としては以下が有効でした:

  1. csprojファイルをテキストエディターで開く
  2. <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>をv4.1に変更
  3. 変換を実施
  4. プロジェクトのプロパティを開いて、アプリケーション→対象のフレームワークを4.1→ 4.0に変更
    この変更を行わないと、ビルドでエラーが発生します(DominoのファームがNET MF 4.0ベースのため)

いくつかのプロジェクトで試した限り、VS2010に変換後のビルドや実行で問題が出たケースはありません。

VS2010

« 2010年7月 | トップページ | 2010年9月 »

2018年10月
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31      
無料ブログはココログ