題名は当面の最終目標。
今はまだUDPでのMBED(LPC1768およびSTmicro NUCLEOとの通信確認までしかできてない)
1)RaspberryPiに64bitのblueseyeを導入
錬金術師見習いの部屋 » RaspberryPiで遊ぶ :RaspberryPi4化 (ddo.jp)
上のとおり、普通に公式のイメージャーで入れればいいんですが、ひとつ注意点があります
現状最新のOSバージョン「blueseye」から、今までデフォールトで設定されていたユーザー名:pi、初期パスワード(デフォルトパスワード):raspberryが、必ず手動設定することになったようで、例えば設定せずに進めると、初期のユーザーは「pi」になるようですが、パスワードは後から”sudo raspi-config”>>1 System Options>>S3 Passwordで設定しないとsshやRDTで困ることになります。
2)基本的なアプリを入れる
錬金術師見習いの部屋 » RaspberryPiで遊ぶ :RaspberryPi4化 (ddo.jp)
3)RaspberryPiの通信設定
有線LANをマイコンとの通信に、Wifi側をRDT/SSH/Inet接続に使うように設定する。
3-1)NIC2つを設定しやすいように管理ソフトを入れ替える。
Ubuntuなんかで使っているソフトに入れ替える。以下参照。
RaspberryPiのネットワーク周りをNetworkManagerで構成する – Qiita
①ネットワークマネージャーをインストールとdhcpcd5の削除を行います。
$ sudo apt-get install -y network-manager
$ sudo apt-get install -y network-manager-gnome
$ sudo apt-get remove -y dhcpcd5
その後、面倒なんで再起動。
②今ある設定の削除
/etc/network/interfacesをすべてコメントアウトし、 /etc/wpa_supplicant/wpa_supplicant.conf に追加したものをすべて削除します。
※最近のRaspberrypiOSには最初から入っているので切り替えればいいらしい
Raspberry Pi OSのWi-Fi設定ツール「Network Manager」の追加 | ラズパイダ (raspida.com)
3-2)ネットワーク設定
有線設定:IPV4settingタブでMethodをshared to other comuterにして、IPとネットマスクを設定
∵マイコンと通信する際は大抵IPをターゲットに通信するので
固定しておいた方がいいし、固定することが多い
無線設定:お使いのルータに合わせて設定
3-3)優先設定(ここでプチ悩んだ)
再起動してみる
このままだと多分有線LANの方が優先された挙句、ネットからいろんなもんをお取り寄せできない事態になる。
ip route
で確認すると、たぶん有線LANのmetricの方が小さい値。(なので、そうならないように有線のデフォルトゲートウエイをあえて指定していないので、Wifi優先になっていたらラッキー。ここ飛ばしてよし。)
なので、wifiのmetricを下げて有線を上げて優先順位を変える
参考:Linux(Ubuntu) で複数NICを指している場合に、ネットワーク経路の優先度を指定する | パソコン鳥のブログ (sarakura.net)
以下のソフトで順位変更。
apt-get install ifmetric
3-4)sshとrdtでwifi側から接続できるか試してみて。
できればOK
いままで旧OSを使ってきた方々がよく陥るのは、たぶんパスワード入力ではねられる事態。
このページの一番上に書いてあるデフォルトパスワード設定ちゃんとやったかどうか確認汁。
4)Pi3延命措置
4-1)(クロックアップ)(笑)
Pi4、Pi3B+はまた今度
4-2)SWAP領域設定
gpartedで領域をごにょごにょやって確保
gpartedで空いた領域をlinux-swapで確保
sudo nano /etc/fstabで末尾にこんな感じで追加。
/dev/の部分はgpartedでswap領域の場所の名前を確認して入力すること
/dev/mmcblk0p3 swap swap defaults 0 0
再起動してswapon -sでスワップ領域を確認すると、上で登録したのが見えるはず。
5)通信試験
参考HP:Mbed OS 6上でNUCLEO-F767ZIでUDP通信を実装し、ROSと通信する(前編) – Qiita
(ハードウエアの接続はこちらを参照のこと:mbedでUDP通信する – Re: note (hatenablog.jp))
ちなみに僕はWIZnet W7500ECO付属のshieldにLPC1768をぶっさしてつかっています。(笑)
∵当初、お安いw7500でudp通信をやろうとしたんだけど癖が強くて挫折した。
なるべく抽象化して話してきたけどそろそろ限界なんで以下の前提を置きます
Raspiの有線IP:192.168.11.3
MCU側の有線IP:192.168.11.2
MCU側(MBED側)コードは以下。
以下はLPC1768でLEDだけでステートが見れるように微量変更しているけど、STMicroのF767ZIや、そのファミリーのNICついている奴なら上述の参考HPに書いてあるオリジナルコードをそのまま書けば全部行けると思う。
なお、これからの時代はMBEDはOS6で起債を前提にすべきです。
過去のものは「過去書いたソースコードやライブラリを使いまわしたい」時に限定すべきでしょう。と、強く推奨します。
自分の経験上。ええ。
いつかは使えなくなる資産を増やしてもしょうがないってのと、今後ROS2になっていくうえで、MBEDやっている人はみんなOS6前提でコード書いてくるから、それにライドオンしたければ、自分も倣うしかない。
/* mbed Microcontroller Library
* Copyright (c) 2019 ARM Limited
* SPDX-License-Identifier: Apache-2.0
*/
#include "mbed.h"
#include "EthernetInterface.h"
#include "rtos.h"
// Blinking rate in milliseconds
#define BLINKING_RATE 500ms
DigitalOut led1(LED1);
DigitalOut led2(LED2);
DigitalOut led3(LED3);
DigitalOut led4(LED4);
void receive(UDPSocket *receiver);
int main()
{
// 送信先情報
const char *destinationIP = "192.168.11.3";//raspiの有線ip
const uint16_t destinationPort = 4000;
// 自機情報
const char *myIP = "192.168.11.2";//MBEDのIP
const char *myNetMask = "255.255.255.0";
const uint16_t receivePort = 5000;
// 送信データ
const char sendData[100] = "Hello world!";
led1=1;
// イーサネット経由でインターネットに接続するクラス
EthernetInterface net;
// IPアドレスとPortの組み合わせを格納しておくクラス(構造体でいいのでは?)
SocketAddress destination, source, myData;
// UDP通信関係のクラス
UDPSocket udp;
// 受信用スレッド
Thread receiveThread;
led2=1;
led1=0;
/* マイコンのネットワーク設定 */
// DHCPはオフにする(静的にIPなどを設定するため)
net.set_dhcp(false);
// IPなど設定
net.set_network(myIP, myNetMask, "");
// printf("start\n");
led2=1;
led1=1;
// マイコンをネットワークに接続
if (net.connect() != 0)
{
// printf("network connection Error\n");
return -1;
}
else
{
// printf("network connection success\n");
}
led3=1;
led2=0;
led1=0;
// UDPソケットをオープン
udp.open(&net);
led3=1;
led2=0;
led1=1;
// portをバインドする
udp.bind(receivePort);
// 送信先の情報を入力
destination.set_ip_address(destinationIP);
destination.set_port(destinationPort);
// 受信用のスレッドをスタート
receiveThread.start(callback(receive, &udp));
while (1)
{
if (const int result = udp.sendto(destination, sendData, sizeof(sendData)) < 0)
{
// printf("send Error: %d\n", result);
}
ThisThread::sleep_for(1s);
led4 = !led4;
}
receiveThread.join();
udp.close();
net.disconnect();
return 0;
}
void receive(UDPSocket *receiver)
{
SocketAddress source;
char buffer[100];
while (1)
{
memset(buffer, 0, sizeof(buffer));
if (const int result = receiver->recvfrom(&source, buffer, sizeof(buffer)) < 0)
{
// printf("receive Error : %d", result);
}
else
{
// printf("from IP:%s port:%d data received:%s", source.get_ip_address(), source.get_port(), buffer);
led2 = !led2;
}
}
}
PC側:MCUのNICとRaspberryPiのNICをダイレクトにつなげて、Raspi側から
nc -4lu 192.168.11.3 4000
ncなんて知らんって言われたら「sudo apt-get install netcat」でインストール。
これは超簡易的なサーバを立てるソフト。
これでudpサーバを立てて信号を聞くなり信号を出すなりしようってことです。
上のコマンドは 4がipv4だよっていう明記、lはlistenするよってこと、uがudpだよってこと、で、その操作を行う対象のipとポート。
これで正しければMUCが送信し続けている「Hello world!」という文字が、画面を埋め尽くしていくはずです。
逆に送信をするには
nc -4u 192.168.11.2 5000
これでraspiのコンソールで何か入力して送信すると、そのたびLPC1768のLED2が点灯消灯繰り返すはず。
とりあえずここまで備忘録。
あとでちゃんと書くつもりですが、とりあえず重要なこと:
・RaspberryPi OS「BluesEye」は64ビットなので、ROS入るっぽい。
・RaspberryPi OSとうとうデフォルトがpi / raspberryだから何もしなくても・・・ではなくなった。
・MBEDはOS6でかけ!
・WIZnet W7500ECOは一見よさげだが、癖が強くEthernet周り初めての人は無理ぽ。
・俺には無理だったんでShieldだけ流用ウマーした。
・その点やはりNUCLEOはスゲー。互換性、というかkeilとの親和性半端ない。
・とりあえずUDP通信できたんで最悪これでPiからMCUをコントロールできるね!。