本ライブラリは、PC,MCU(Arduino,Mbed,STM32)間でUART,CAN FDによるシリアル通信を行うためのライブラリです。
用途に合わせて、簡単にパケットデータを割り当てることができる仕組みをとっています。
本ライブラリは、クロスプラットフォーム化のために非STL依存のC++及びC言語によって記述されています。
-
プロジェクトでgit管理を既に用いている場合
submoduleとして利用します- プロジェクトディレクトリに移動します
- terminalで以下のコマンドを実行しsubmoduleとしてクローンします
git submodule add https://github.com/TNCT-Mechatech/SerialBridge.git SerialBridge echo 'commit' git add SerialBridge git commit -m 'Add SerialBridge as a module'
-
プロジェクトにgitを利用していない場合
- プロジェクトディレクトリに移動します
- terminalで以下のコマンドを実行しレポジトリをクローンします
git clone https://github.com/TNCT-Mechatech/SerialBridge.git -
最後にmake allをして静的ライブラリを生成して、リンクさせます
- SerialBridgeディレクトリに移動します
- makeコマンド(下記)により、静的ライブラリを生成します
make all
- ビルド時
- CMakeを用いる場合は、CMakeLists.txtに以下のコードを追加
target_link_libraries(YOUR_PROJECT_NAME ${CMAKE_SOURCE_DIR}/SerialBridge/bin/libSerialBridge.a)
- gccから直接ビルドする場合は、ターゲットと同じディレクトリ内で次のようにコマンドを実行
g++ (target file).cpp (your directory path)/SerialBridge/bin/libSerialBridge.a \ -I (your directory path)/SerialBridge/src
(target file): ビルドターゲットのファイル名
(your directory path): 本ライブラリをクローンしたディレクトリパス
- librariesに移動します
- terminalで以下のコマンドを実行しレポジトリをクローンします
git clone https://github.com/TNCT-Mechatech/SerialBridge.git
- 任意のプロジェクトを作成します
- レポジトリをプログラムにクローンします
- 任意のプロジェクトを右クリック
- Add Mbed Library
- URLにレポジトリのURLを入力し、Next
- 特に理由がなければ、
mainを選ぶ
mbed_app.jsonファイルを作成し、以下の内容を入力
{
"config": {
"serialbridge_for_mbed": {
"help": "Macro",
"macro_name": "MBED",
"value": 0
}
}
}他のIDEやOSと比較して開発難度が高めです。
- 任意のプロジェクトを作成します。
- 任意のフォルダ(例: download)に移動し, 以下のコマンドをcmdで実行します。
git clone https://github.com/TNCT-Mechatech/SerialBridge.git
- エクスプローラーを開いて2. で開いた任意のフォルダを開いてください。
- 生成されたSerialBridgeライブラリを1で作成したSTM32CubeIDEプロジェクトの
Driverフォルダ以下に直接, または任意Driver以下のフォルダにドラッグ&ドロップします。 - cmdで5. でドラッグ&ドロップした先の
SerialBridgeフォルダを開き,make allをします。 - 最後に, コンパイルが通るように, プロジェクトを右クリック>propaties>C/C++ Ceneral>Pathys and Symbolsよりインクルードパスを設定して導入完了です。
CAN FDを使う場合は、SB_CANFDマクロを宣言してください。
Mbedを使う場合は、mbed_app.jsonに追加してください。
{
"config": {
"serialbridge_with_canfd": {
"help": "Macro",
"macro_name": "SB_CANFD",
"value": 0
}
}
}初期化手順のみが各環境に依存します。
SerialDevに渡されるシリアルデバイスのボーレートはデバイス間で同じ速度である必要があります。
またフォーマットは、8データビット、ノンパリティが推奨されます。
#include <SerialBridge.hpp>
// serial driver for linux/ros
#include <LinuxHardwareSerial.hpp>
SerialDev *dev = new LinuxHardwareSerial("/dev/ttyUSB0", B9600);
SerialBridge serial(dev);Serialパスはデバイス接続時に自動生成されるシンボリックリンクも使用できます。
このリンクはUSBの接続位置によって固有になるので、複数の同じデバイスをつないでも識別ができるようになります。
以下に示す例のように、ボードがどのUSBポートに接続されているか確認できます。
$ ls /dev/serial/by-path/
pci-0000:00:1a.0-usb-0:1:1.0-port0 //右側USBポート
pci-0000:00:1d.0-usb-0:2:1.0-port0 //左側手前
pci-0000:00:1d.0-usb-0:1:1.0-port0 //左側奥
pci-0000:00:1d.7-usb-0:1.4:1.0-port0 //左側奥+USBハブ
pci-0000:00:1d.7-usb-0:1.4.1:1.0-port0 //左側奥+USBハブ+USBハブとはいえ可視性が悪いので1個ずつシリアルデバイスを接続して確かめることをおすすめします。
利用する際はマクロ定義で置き換えると引数部分がすっきりする。
ex) 右側USBポートを使用する場合
#define SERIAL_PATH "/dev/serial/by-path/pci-0000:00:1a.0-usb-0:1:1.0-port0"
SerialDev *dev = new LinuxHardwareSerial(SERIAL_PATH, B9600);#include <SerialBridge.hpp>
// serial driver for arduino
#include <InoHardwareSerial.hpp>
// Pass the serial derived class entity for Arduino to SerialDev.
SerialDev *dev = new InoHardwareSerial(&Serial);
SerialBridge serial(dev);
void setup()
{
Serial.begin(9600);
}
- Mbed-os2(Nucleo F303K8, etc.)の場合
#include <SerialBridge.hpp>
#include <MbedHardwareSerial.hpp>
SerialDev *dev = new MbedHardwareSerial(new Serial(USBTX, USBRX, 9600));
SerialBridge serial(dev);- Mbed-os5,6の場合
#include <SerialBridge.hpp>
#include <MbedHardwareSerial.hpp>
SerialDev *dev = new MbedHardwareSerial(new BufferedSerial(USBTX, USBRX, 9600));
SerialBridge serial(dev);プロジェクトルート直下の.iocファイルを開き, 上部のタブのClock Configurationからto USBの項目を48MHzになるように各項目を設定します。
(to USBの項目を指定すれば勝手に整合性を保ちつつ他の項目を操作してくれる機能もあります。)
これが終わったら Ctrl+Sで保存したうえでGenarate Codeをしてください。
#include <SerialBridge.hpp>
#include <STM32BufferedSerial.hpp>
#include <STM32HardwareSerial.hpp>
// ..
// ..
int main(void)
{
// ..
// ..
MX_USART2_UART_Init();
// この下に配置↓
STM32BufferedSerial* buf = new STM32BufferedSerial(&huart2);
SerialDev *dev = new STM32HardwareSerial(buf);
SerialBridge serial(dev);
buf->begin();
while(1)
{
// ..- Messageを用意する
structを使ってMessageの内容を決めます
typedef struct Vector3Type
{
float x;
float y;
float z;
} vector3_t;このようなstructをメッセージとして使ってみましょう
Messageを作成するにはMessage.hppをインクルードする必要があります
Vector3.h
#ifndef VECTOR3_H_
#define VECTOR3_H_
#include <Message.hpp>
typedef struct Vector3Type
{
float x;
float y;
float z;
} vector3_t;
// create message
typedef sb::Message<vector3_t> Vector3;
#endif- SerialBridgeにMessageを登録
作成したMessageを利用するには、フレームとして登録する必要があります
SerialBridge::add_frame(id, msg)を使います。
引数として、id(任意の値)とMessageのポインターを渡す必要があります。
idは重複しないようにしてください。
#include <SerialBridge.hpp>
// your message header
#include <Vector3.h>
SerialBridge serial(...);
// Message
Vector3 msg;
void main(){
serial.add_frame(0, &msg);
}この場合はmsgをid 0番と登録したことになります。
関数
- SerialBridge::write(id) idはadd_frame(id, msg)で追加したものを使用します Vector3に値を入れて送信してみましょう
#include <SerialBridge.hpp>
// your message header
#include <Vector3.h>
SerialBridge serial(...);
// Message
Vector3 msg; // sender
void main(){
serial.add_frame(0, &msg);
msg.data.x = 0.123;
msg.data.y = 0.456;
msg.data.z = 0.789;
}
void loop(){
// write
serial.write(0);
}Messageの値には、Message.data.VARIABLE_NAME でアクセスできます
送信には、serial.write(id)をつかいます
関数
- SerialBridge::update()
受信したパケットをデコードします。
- Message::was_update()
メッセージ内容が更新されたかどうかを確認できます。
#include <SerialBridge.hpp>
// your message header
#include <Vector3.h>
SerialBridge serial(...);
// Message
Vector3 msg; // listener
void main(){
serial.add_frame(0, &msg);
}
void loop(){
// update and read
serial.update();
if (msg.was_updated())
{
printf("%f %f %f \n\r", msg.data.x, mag.data.y, msg.data.z);
}
}- Ubuntu 20.04 LTS
- C++11 (GNU GCC 10.3.0)
- Arduino IDE 1.8.13
- Mbed OS 6.13.0 based
- STM32CubeIDE 1.19.0
- feat: 新機能
- change: 修正・削除
- fix: バグフィックス
- docs: ドキュメントに関する変更
- style: フォーマット等の変更
- refactor: リファクタに関する変更
- debug: デバック用のコード
- test: テストコードの追加・更新
- chore: GitHub Actions等タスクに関する変更
Apache-2.0 License
- TaiyouKomazawa(Project Author)
- testusuke