とりあえず、環境のほうをざっくり書いときます。
環境
MacBook Air (11-inch, Mid 2011)
・プロセッサ 1.6 GHz Intel Core i5(多分3世代?)
・メモリ 4 GB 1333 MHz DDR3
・グラフィック Intel HD Graphics 3000 384 MB
・シリアル番号…っと危ない危ない(;´∀`)
macos Sierra 10.12.5(16F73)とUbuntu 16.04.2を
デュアルブートさせてます。
Ubuntu 16.04ということでROS界でのLTS版とされる
Kinetic KAMEを使用しています。
まずディレクトリ構造から
※いじる必要のないフォルダ、ファイルは非表示にしています。
├── catkin-ws │ ├── build │ ├── devel │ └── src │ ├── CMakeLists.txt │ ├── USBUART_comm │ │ ├── CMakeLists.txt │ │ ├── include │ │ │ └── USBUART_comm │ │ ├── package.xml │ │ └── src │ │ └── USBUART_comm.cpp │ └── └──
下はUSBUART_comm.cppのソースです。
#include <ros/ros.h> #include <string> #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/ioctl.h> #include <fcntl.h> #include <termios.h> #include <unistd.h> int str_counter (char *str){ int counter = 0; while(*str++){ counter++; } return counter; } int main(int argc, char **argv){ std::string dev = "/dev/ttyACM0",str_str; int baudrate = B9600; char str[64] = "Hello ROS & PSoC"; ros::init(argc, argv, "UART_comm"); ros::NodeHandle arg_nh("~"); ros::NodeHandle nh; arg_nh.getParam("device", dev); arg_nh.getParam("baudrate", baudrate); arg_nh.getParam("message",str_str); strcpy(str,str_str.c_str()); //-------シリアルポート設定------------------------- int fd; /* ファイルディスクリプタ */ struct termios oldtio, newtio; /* シリアル通信設定 */ int baudRate = B57600; fd = open(dev.c_str(), O_RDWR); /* デバイスをオープンする */ ioctl(fd, TCGETS, &oldtio); /* 現在のシリアルポートの設定を待避させる */ newtio = oldtio; /* ポートの設定をコピー */ newtio.c_cflag = baudRate | CS8 | CREAD; newtio.c_iflag = IGNPAR | ICRNL; newtio.c_oflag = 0; newtio.c_lflag = 0; /* ポートの設定をおこなう 詳細はtermios参照 */ ioctl(fd, TCSETS, &newtio); /* ポートの設定を有効にする */ //-------------------------------------------------------- while(ros::ok()){ printf("%s\n%d\n",str, str_counter(str)); if(str_counter(str)>64){ ROS_INFO("Warning!! \nThe amount of data that PSoC5 can receive is up to 64bytes."); //PSoC5のUSBUARTは一度に最大64バイトまでしか受け付けない。 } if(fd<0){ ROS_INFO("Error ! serialport open error!"); return -1; } write(fd,str,sizeof(str)); //送信 ros::spinOnce(); } ioctl(fd, TCSETS, &oldtio); /* ポートの設定を元に戻す */ close(fd); /* デバイスのクローズ */ return 0; }下はUSBUART_commフォルダー内のCMakeLists.txtです。
cmake_minimum_required(VERSION 2.8.3) project(USBUART_comm) add_compile_options(-std=c++11) find_package(catkin REQUIRED COMPONENTS roscpp std_msgs ) catkin_package( INCLUDE_DIRS include LIBRARIES USBUART_comm CATKIN_DEPENDS roscpp std_msgs DEPENDS system_lib ) include_directories( include ${catkin_INCLUDE_DIRS} ) add_executable(${PROJECT_NAME}_node src/USBUART_comm.cpp) add_dependencies(${PROJECT_NAME}_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS}) target_link_libraries(${PROJECT_NAME}_node ${catkin_LIBRARIES} )あとは記述する必要はなさそうですが、 一応USBUART_commフォルダー内のpackage.xmlも晒しときます。
<?xml version="1.0"?> <package> <name>USBUART_comm</name> <version>0.0.0</version> <description>The USBUART_comm package</description> <maintainer email="yukimakura@todo.todo">yukimakura</maintainer> <license>TODO</license> <buildtool_depend>catkin</buildtool_depend> <build_depend>roscpp</build_depend> <build_depend>std_msgs</build_depend> <run_depend>roscpp</run_depend> <run_depend>std_msgs</run_depend> <export> </export> </package>ソースコードを見たら一目瞭然ですが、 ROSのソースにそのままlinuxのシリアル通信のソース乗っけただけという簡単なものです。 ですが、応用すれば別ノードやサービスから購読したデータをPSoCや別のシリアル通信できる マイコンと通信することができます...
えぇ、そうですとも。
絶対同等以上のことできるパッケージってもう存在してますよね!?
というわけでもし誰かご存知でしたら
教えてくださるとすごくありがたいです...m(_ _)m
あと素人ながら書かせて頂いたのでぜひご指摘等ございましたらビシバシ叩いていただくと光栄です。
参考にさせていただいたサイト様
FAQ : シリアル通信をおこなうプログラムを作成するには?
https://armadillo.atmark-techno.com/faq/serial-programming
do you have de code for psoc? i need comunication ros and psoc for drive a stepper motor
返信削除Thank you for your comment!!
削除https://yukihurumakura.blogspot.com/2017/11/rospsoc5lpusbuartpsoc.html
↑This article is about PSoC.
However, it is not recommended for reference.
Because it ’s not very robust.
translated by google translate
質問です。このnodeを実行すると0がずっと表示されるのですが、どのような挙動を見せれば正しく通信できているのでしょうか?
返信削除環境としてはUbuntu18.04,ros melodicです。
GR-PEACHとUSBUART通信をさせようとしています。
/catkin_ws/src/hellow/src/hellow.cpp
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define SERIAL_PORT "/dve/ttyACM0"
int str_counter (char *str){
int counter = 0;
while(*str++){
counter++;
}
return counter;
}
int main(int argc, char **argv){
std::string dev = "/dev/ttyACM0",str_str;
int baudrate = B9600;
char str[64] = "Hello world";
ros::init(argc,argv,"hellow");
ros::NodeHandle arg_nh("~");
ros::NodeHandle nh;
arg_nh.getParam("device",dev);
arg_nh.getParam("baudrate",baudrate);
arg_nh.getParam("message",str_str);
strcpy(str,str_str.c_str());
//-------シリアルポート設定-------------------------
char buf[255];
int fd; /* ファイルディスクリプタ */
struct termios oldtio, newtio; /* シリアル通信設定 */
int baudRate = B57600;
fd = open(dev.c_str(), O_RDWR); /* デバイスをオープンする */
ioctl(fd, TCGETS, &oldtio); /* 現在のシリアルポートの設定を待避させる */
newtio = oldtio; /* ポートの設定をコピー */
newtio.c_cflag = baudRate | CS8 | CREAD;
newtio.c_iflag = IGNPAR | ICRNL;
newtio.c_oflag = 0;
newtio.c_lflag = 0; /* ポートの設定をおこなう 詳細はtermios参照 */
ioctl(fd, TCSETS, &newtio); /* ポートの設定を有効にする */
//--------------------------------------------------------
//ros::Rate rate(1);
while(ros::ok()){
printf("%c %d\n",str, str_counter(str));
//SERIAL_PORT.printf("%s\n%d\n",str, str_counter(str));
write(fd,buf,sizeof(buf));
if(str_counter(str)>64){
ROS_INFO("Warning!! \nThe amount of data that PSoC5 can receive is up to 64bytes.");
//PSoC5のUSBUARTは一度に最大64バイトまでしか受け付けない。
}
if(fd<0){
ROS_INFO("Error ! serialport open error!");
return -1;
}
write(fd,str,sizeof(str)); //送信
ros::spinOnce();
}
ioctl(fd, TCSETS, &oldtio); /* ポートの設定を元に戻す */
close(fd); /* デバイスのクローズ */
return 0;
}
GR-PEACH側にHello worldという文字列を送りたいです。
お返事遅れてごめんなさいm(_ _)m
削除(まじでブログの管理が雑)
結論から申し上げますと、このコードはあまりおすすめしません。
今の私ならBoostというC++ライブラリのASIO経由でシリアル通信とか、TCPIP通信をするでしょう。
こちらのサイトをご参考ください。
https://blog.myon.info/entry/2015/04/19/boost-asio-serial/