2.4 とりあえず使ってみる(Ethernet)

mbed+☆Board Orageでできることをしています

Ethernetを使う勉強をする

☆Board OrangeにはEthnernetの端子が付いています。
これは、mbedにEthernetの物理層のICが備わっているからで、端子(トランス付き)を接続すると簡単に使用できるようになっています。

HTTP Server

mbedをHttpサーバとしてmbedのLEDのランプを点灯するプログラムを作ってみましょう。

まず、2つのライブラリを入力する必要がありそう。
CompilerでNewボタンを押し新しいプログラムを作成します。(ここではethernet_test_http)
/media/uploads/yueee_yt/ethernet_http_1.jpg

それから必要なプログラムをライブラリとして追加します。
まずは、/users/donatien/programs/EthernetNetIf/5z422から
/media/uploads/yueee_yt/ethernet_http_2.jpg
のようにImportします。
同様に、/users/donatien/programs/HTTPServer/5yhmtもImportします。
(TextLCDも使用するので、/users/simon/libraries/TextLCD/livod0もImportします)

制御にはどうもRPC/cookbook/Interfacing-Using-RPCを使うらしい
今回はLED1-4まで使用するので DigitalOutのみRPCで使用できるようにします。
RPCで使用するにはPINの名前を定義する必要があるのでDigitalOut LEDx(ledx,"名前")としなければいけない。Defaultは名前がnull
Base::add_rpc_class<DigitalOut>();をコードに追加します。
ここまでのプログラムはここからImportできます。/users/yueee_yt/programs/ethernet_test_http/lqu0cs

#include "mbed.h"
#include "TextLCD.h"
#include "EthernetNetIf.h"
#include "HTTPServer.h"

DigitalOut led1(LED1,"led1");
DigitalOut led2(LED2,"led2");
DigitalOut led3(LED3,"led3");
DigitalOut led4(LED4,"led4");

TextLCD lcd(p24, p26, p27, p28, p29, p30);

#if 1
/*
 * Use DHCP
 */
        EthernetNetIf ethif;
#else
/*
 * Use "static IP address" (Parameters:IP, Subnet mask, Gateway, DNS)
 */
        EthernetNetIf ethif(IpAddr(xxx,xxx,xxx,xxx), IpAddr(xxx,xxx,xxx,xxx), IpAddr(xxx,xxx,xxx,xxx), IpAddr(xxx,xxx,xxx,xxx));
#endif
    
    HTTPServer server;
    LocalFileSystem local("local");

int main(void) {

    Base::add_rpc_class<DigitalOut>();

    lcd.cls();
    lcd.locate(0,0);
    lcd.printf("Program init..  ");

    if (ethif.setup()) {
        error("Ethernet setup failed.");
        return 1;
    }
    IpAddr ethIp=ethif.getIp();
    
    lcd.locate(0,1);
    lcd.printf("%d.%d.%d.%d", ethIp[0], ethIp[1], ethIp[2], ethIp[3]);
    led1=1;
    wait(1);
    server.addHandler<SimpleHandler>("/hello");
    server.addHandler<RPCHandler>("/rpc");
    FSHandler::mount("/local", "/");
    server.addHandler<FSHandler>("/");
    server.bind(80);
    while (1) {
        Net::poll();
    }
    return 0;
}

ここではDHCPで使用し、実験しています。
液晶にDHCPでGetしたIPアドレスを表示するので、web Browserで、そこに接続します。(ここでは192.168.1.4になりました)
SimpleHandlerが/helloになっているので、"http://192.168.1.4/hello"で接続すると次のようになります。
/media/uploads/yueee_yt/ethernet_http_3.jpg
LocalFileSystem(MBED本体のFlashメモリ)は/にマウントされているので、"http://192.168.1.4/MBED.HTM"とするとmbedのホームページに行きます。
RPCは led2を光らすには "http://192.168.1.4/rpc/led2/write 1"とすればLED2が光ります
消すにはもちろん"http://192.168.1.4/rpc/led2/write 0"とします。

これをweb上からするにはcookbookのInterfacing with Javascript /cookbook/Interfacing-with-JavaScriptを参考に作っていきます。 今回はLocalFileSystem(本体のUSBフラッシュメモリ)常にページを構築してみたいと思いますので、/cookbook/Interfacing-with-JavaScriptのmbedRPC.jsをmbedに保存します
/media/uploads/yueee_yt/ethernet_http_4.jpg

次にhtmlのページを作成する。ファイル名は8.3形式しか使用できないので拡張子は"*.htm"になることに注意!

test.htm

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-2022-jp"> 
<title>mbed test web</title>
<script  type="text/javascript" src="mbedRPC.js" language="javascript"></script>
<script type="text/javascript">
			mbed = new HTTPRPC();
			led1 = new DigitalOut(mbed, LED1);
			led2 = new DigitalOut(mbed, LED2);
			led3 = new DigitalOut(mbed, LED3);
			led4 = new DigitalOut(mbed, LED4);
</script>
</head>
<body>
<form action="test.htm" method="get">
<button type="submit" ID="btn_LED1a" onclick="led1.write(1)">LED1点灯</button> <br >
<button type="submit" ID="btn_LED2a" onclick="led2.write(1)">LED2点灯</button> <br >
<button type="submit" ID="btn_LED3a" onclick="led3.write(1)">LED3点灯</button> <br >
<button type="submit" ID="btn_LED4a" onclick="led4.write(1)">LED4点灯</button> <br >
<br>
<button type="submit" ID="btn_LED1b" onclick="led1.write(0)">LED1消灯</button> <br >
<button type="submit" ID="btn_LED2b" onclick="led2.write(0)">LED2消灯</button> <br >
<button type="submit" ID="btn_LED3b" onclick="led3.write(0)">LED3消灯</button> <br >
<button type="submit" ID="btn_LED4b" onclick="led4.write(0)">LED4消灯</button> <br >
<br>
</form>
<script type="text/javascript">
var led_1=led1.read();
var led_2=led2.read();
var led_3=led3.read();
var led_4=led4.read();

document.write("LED1は");
if(led_1==0)document.write("消灯");else document.write("点灯");
document.write("しています<br>");

document.write("LED2は");
if(led_2==0)document.write("消灯");else document.write("点灯");
document.write("しています<br>");

document.write("LED3は");
if(led_3==0)document.write("消灯");else document.write("点灯");
document.write("しています<br>");

document.write("LED4は");
if(led_4==0)document.write("消灯");else document.write("点灯");
document.write("しています<br>");
</script>
</body>
</html>

プログラム中にHTMLを書かずにjavascriptで対応できるのが楽です。

発展

LCDに文字を書いてみましょう。
前のコードにRPCを追加します。CookbookのInterfacing Using RPC/cookbook/Interfacing-Using-RPC の中あたりにあるライブラリをImportします。
/media/uploads/yueee_yt/ethernet_http_5.jpg
でコードを次のようにします。 こちらでプログラムのImportもできます。/users/yueee_yt/programs/ethernet_test_http_2/lqwouc

#include "mbed.h"
#include "TextLCD.h"
#include "EthernetNetIf.h"
#include "HTTPServer.h"
#include "RPCFunction.h"  //ADD Here!!
DigitalOut led1(LED1,"led1");
DigitalOut led2(LED2,"led2");
DigitalOut led3(LED3,"led3");
DigitalOut led4(LED4,"led4");

TextLCD lcd(p24, p26, p27, p28, p29, p30);

#if 1
/*
 * Use DHCP
 */
        EthernetNetIf ethif;
#else
/*
 * Use "static IP address" (Parameters:IP, Subnet mask, Gateway, DNS)
 */
        EthernetNetIf ethif(IpAddr(xxx,xxx,xxx,xxx), IpAddr(xxx,xxx,xxx,xxx), IpAddr(xxx,xxx,xxx,xxx), IpAddr(xxx,xxx,xxx,xxx));
#endif
    
    HTTPServer server;
    LocalFileSystem local("local");
    void LcdWrite(char *input,char *output);    //ADD Here!!
    RPCFunction rpcFunc(&LcdWrite, "LcdWrite"); //ADD Here!!

int main(void) {

    Base::add_rpc_class<DigitalOut>();

    lcd.cls();
    lcd.locate(0,0);
    lcd.printf("Program init..  ");

    if (ethif.setup()) {
        error("Ethernet setup failed.");
        return 1;
    }
    IpAddr ethIp=ethif.getIp();
    
    lcd.locate(0,1);
    lcd.printf("%d.%d.%d.%d", ethIp[0], ethIp[1], ethIp[2], ethIp[3]);
    led1=1;
    wait(1);
    server.addHandler<SimpleHandler>("/hello");
    server.addHandler<RPCHandler>("/rpc");
    FSHandler::mount("/local", "/");
    server.addHandler<FSHandler>("/");
    server.bind(80);
    while (1) {
        Net::poll();
    }
    return 0;
}
void LcdWrite(char *input , char *output)  //ADD Here!!
{
    lcd.locate(0,1);
    lcd.printf("%s",input);
}

HTMLは、

test.htm

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-2022-jp"> 
<title>mbed test web</title>
<script  type="text/javascript" src="mbedRPC.js" language="javascript"></script>
<script type="text/javascript">
			mbed = new HTTPRPC();
			led1 = new DigitalOut(mbed, LED1);
			led2 = new DigitalOut(mbed, LED2);
			led3 = new DigitalOut(mbed, LED3);
			led4 = new DigitalOut(mbed, LED4);
			lcd = new RPCFunction(mbed,"LcdWrite");
</script>
</head>
<body>
<form action="test.htm" method="get">
<button type="submit" ID="btn_LED1a" onclick="led1.write(1)">LED1点灯</button> <br >
<button type="submit" ID="btn_LED2a" onclick="led2.write(1)">LED2点灯</button> <br >
<button type="submit" ID="btn_LED3a" onclick="led3.write(1)">LED3点灯</button> <br >
<button type="submit" ID="btn_LED4a" onclick="led4.write(1)">LED4点灯</button> <br >
<br>
<button type="submit" ID="btn_LED1b" onclick="led1.write(0)">LED1消灯</button> <br >
<button type="submit" ID="btn_LED2b" onclick="led2.write(0)">LED2消灯</button> <br >
<button type="submit" ID="btn_LED3b" onclick="led3.write(0)">LED3消灯</button> <br >
<button type="submit" ID="btn_LED4b" onclick="led4.write(0)">LED4消灯</button> <br >
<br>
</form>
<script type="text/javascript">
var led_1=led1.read();
var led_2=led2.read();
var led_3=led3.read();
var led_4=led4.read();

document.write("LED1は");
if(led_1==0)document.write("消灯");else document.write("点灯");
document.write("しています<br>");

document.write("LED2は");
if(led_2==0)document.write("消灯");else document.write("点灯");
document.write("しています<br>");

document.write("LED3は");
if(led_3==0)document.write("消灯");else document.write("点灯");
document.write("しています<br>");

document.write("LED4は");
if(led_4==0)document.write("消灯");else document.write("点灯");
document.write("しています<br>");
</script>
<input type="text" id="textbox" ></input><button onclick="lcd.run(textbox.value);">送信</button> <br>
</body>
</html>

という感じで、慣れればcodeとHTMLが分離していて楽です。

NTPを使用した時計の作成

NTPサーバから時間を収得して、表示するプログラムを作成します。
33行目あたりのNTPサーバは近いNTPサーバに変更する必要があります。
完成版はここ/users/yueee_yt/programs/NTP_CLOCK/luiipq

#include "mbed.h"
#include "EthernetNetIf.h"
#include "NTPClient.h"
#include "TextLCD.h"

EthernetNetIf ethif; //for DHCP
//EthernetNetIf ethif(IpAddr(xxx,xxx,xxx,xxx), IpAddr(xxx,xxx,xxx,xxx), IpAddr(xxx,xxx,xxx,xxx), IpAddr(xxx,xxx,xxx,xxx)); //for Static IP Address

NTPClient ntp;
TextLCD lcd(p24, p26, p27, p28, p29, p30);

int main() {
    char buffer[17];
    lcd.locate(0,1);
    lcd.printf("Start\n");
    lcd.locate(0,1);
    lcd.printf("Setting up...\n");
    EthernetErr ethErr = ethif.setup();
    if (ethErr) {
        lcd.locate(0,1);
        lcd.printf("Error %d in setup.\n", ethErr);
        return -1;
    }
    lcd.locate(0,1);
    lcd.printf("Setup OK\r\n");
    IpAddr ethIp=ethif.getIp();
    lcd.locate(0,1);
    lcd.printf("%d.%d.%d.%d", ethIp[0], ethIp[1], ethIp[2], ethIp[3]);
    wait(1.0f);

    time_t ctTime;

    Host server(IpAddr(), 123, "ntp.nict.jp"); //near ntp server
    ntp.setTime(server);
//UTC-->JST +9Hour(32400Sec)
    ctTime = time(NULL);
    ctTime+=32400;
    set_time(ctTime);

    lcd.cls();
    while (1) {
        lcd.locate(0,0);
        ctTime = time(NULL);
        lcd.locate(0,0);
        strftime(buffer,17,"%Y/%m/%d(%a)",localtime(&ctTime));
        lcd.printf("%s",buffer);
        lcd.locate(0,1);
        strftime(buffer,17,"%X",localtime(&ctTime));
        lcd.printf("%s",buffer);
        wait(1.0f);
    }
    return 0;
}


2 comments on 2.4 とりあえず使ってみる(Ethernet):

03 Jan 2012

「ここまでのプログラムはここからImportできます。/users/yueee_yt/programs/ethernet_test_http/lqu0cs」からインポートしてコンパイルすると 「statement is unreachable main.cpp Line: 54, col: 4」と「Success!」が出力されます。 unreachableの方は無視しておいても問題ないのでしょうか?

03 Jan 2012

seimei5550さま

プログラム中while(1)で無限ループするしているのに、そのあとに行き着けないreturn文があるのでワーニングが出ます。

Please log in to post comments.