Re: note

技術的な知見やポエムなど役に立たない情報を書き連ねる場所

mbedでUDP通信する

f:id:hik0leaf:20190614172133j:plain

前回はmbedでTCP通信を行いました。今回はUDP通信を試してみたいと思います。

1. 準備

以下の部品を用意します。

mbed LPC1768

f:id:hik0leaf:20190614172310j:plain

LANコネクタDIP化キット

秋月電子で購入することができます。

LANコネクタDIP化キット: パーツ一般 秋月電子通商-電子部品・ネット通販

f:id:hik0leaf:20190614172402j:plain
LANコネクタDIP化キット

2. 接続

mbedとLANコネクタDIP化キットを以下のように接続します。

f:id:hik0leaf:20190614172648j:plain
接続図

MBED LANコネクタDIP化キット
RD- pin 6
RD+ pin 3
TD- pin 2
TD+ pin 1

3. コード(mbed側)

ここからTCP記事と異なります。 mbedの公式handbookのページからSocket通信するためのコードとライブラリをインポートします。

UDP Echo Server
Socket - Handbook | Mbed

[Import program]ボタンを押すとmbedコンパイラが開いてコードとライブラリをインポートすることができます。 f:id:hik0leaf:20190614230723j:plain

インポート画面でImport AsがProgramにチェックがはいっていることと、Update all libraries to the latest versionにチェックが入っていないこと( NOT CHECKED )を確認してインポートします。Import Nameは任意の値で構いません。

f:id:hik0leaf:20190614184357j:plain
Import Program

【重要】ライブラリのアップデートは正常動作しなくなるためおすすめしません。

インポートしたらそのままコードを使用しても構いませんが、もう少し動作がわかりやすいように以下のコードをmbedに書き込みます。UDP通信はTCP通信と異なり、サーバ/クライアントの概念がないため今回mbed側をA、相手側のPCをBとします。

/*
 A: 自分(mbed)
 B: 相手(PC)
*/
#include "mbed.h"
#include "EthernetInterface.h" 

const char* A_ADDRESS = "10.0.1.25";// 自分
const int A_PORT = 33333;

const char* B_ADDRESS = "10.0.1.7";// 相手
const int B_PORT = 33333;

int main() {
    printf("starting...\n");
    
    char u_packet[2] = { 0x4F, 0x4B };// "OK"

    EthernetInterface eth; 
    eth.init(A_ADDRESS, "255.255.255.0", "");
    printf("IP : %s\n", eth.getIPAddress());
    
    if (eth.connect() < 0) {
        printf("Failed to connect\n\r");
        return -1;
    }
    
    UDPSocket socket; 
    
    if (socket.bind(A_PORT) < 0) {
        printf("Failed to bind UDP Socket to PORT : %d\n\r", A_PORT);
        return -1;
    } else {
        printf("Bind UDP Socket to PORT : %d\n\r", A_PORT);
    }
    
    socket.set_blocking(false);
    

    Endpoint EndpointB;
    EndpointB.set_address(B_ADDRESS, B_PORT);

    socket.sendTo(EndpointB, (char*)u_packet, sizeof(u_packet));

    while(1) {
        char u_buff[12];

        int n_receive = socket.receiveFrom(EndpointB, (char*)u_buff, sizeof(u_buff));
        if (n_receive > 0) {
            u_buff[n_receive] = '\0';// 終端文字追加(printfしないときは不要)
            printf("Received [%d]: %s\n", n_receive, u_buff);
        }
    } 
}

内容は起動したら"OK"[0x4F, 0x4B]メッセージを相手側(B)に送り、その後は相手側からのメッセージ受け続けます。

4. コード(PC側)

通信相手としてPC側のコードを用意します。UDP通信ができれば何でも構いせませんが、今回はnode.jsを使いました。

const dgram = require('dgram');

const PORT_A = 33333;
const HOST_A = '10.0.1.25';// 相手

const PORT_B = 33333;
const HOST_B = '10.0.1.7';// 自分

const socket = dgram.createSocket('udp4');

var count = 0;

setInterval(() => {
    count++;
    const data = Buffer.from(String(count));
    socket.send(data, 0, data.length, PORT_A, HOST_A, (err, bytes) => {
        if (err) throw err;
    });
}, 500);


socket.on('message', (message, remote) => {
    console.log(remote.address + ':' + remote.port +' - ' + message);
});

socket.bind(PORT_B, HOST_B);

内容は500msec毎に数値をカウントアップしてmbed側に送信しています。

以下のコマンドで上記のサーバ側のコードを実行することができます。

$ npm init
$ npm install dgram
$ node server.js

5. 実行

LANコネクタにLANケーブルを接続し、mbedもシリアル通信でログを確認します。正常に動作していればシリアル通信で以下のようにログを確認することができます。

f:id:hik0leaf:20190614185737p:plain

6. 参考リンク