2017年11月14日火曜日

ROSとPSoC5LPでUSBUART通信(PSoC編)

前回の投稿からどれだけだったんでしょうね…(^_^;)
第30回ロボットコンテストから早1ヶ月が経とうとしています。
あまり良い成果を残せずに終わってしまった大会でしたが、今回のロボコンを経て学んだことをすこし備忘録として残そうかと思いました。
そしてこれを来年にも活かせるようにしなければな…と思っているわけです。ハイ。
というわけでブログタイトルのようにやって行きたいと思います。
ではでは…
環境
PSoC Creator 4.1
PSoC 5LP Development Kit
ぐらいでいいですかね?(もちろんPrototyping Kitでもできますよ~)

とりあえずぱぱっとUSBUARTのスケッチとコードを貼り付けときます。
(正直USBUARTではわかってないまま使ってる部分が...(;´∀`))

#include<project.h>
#include<stdio.h>


int main()
{
       CyGlobalIntEnable; /* Enable global interrupts. */

      LCD_Char_Start();

      USBUART_Start(0,USBUART_5V_OPERATION);
      while(!USBUART_bGetConfiguration()){}
      USBUART_CDC_Init();

      int count = 0;
      uint8 buff[64] = "";


      while(1)//main loop
      {   

            if(0 != USBUART_GetConfiguration())
            {

                  if(0 != USBUART_DataIsReady())
                  {
                        count = USBUART_GetAll(buff);
                        if( count != 0){

                        while(0 == USBUART_CDCIsReady()){}

                        USBUART_PutChar(buff[0]);

                        LCD_Char_Position(0,0);
                        LCD_Char_PrintNumber(count);
                        LCD_Char_PrintString(buff);

                        if(64 == count){
                              while(0 == USBUART_CDCIsReady()){}
                              //sent zero packet
                              USBUART_PutData(NULL,0);
                        }      
                  }
            }     
       }
}    
}



配線図は以下の通りです。
超シンプル(*´∀`)


この記事と連携させればこぉんな感じで通信できるはずです...





...次の更新はいつになることやら(;´∀`)

2017年11月12日日曜日

ROSとPSoC5LPでUSBUART通信(ROS編)

今回はROS編です。はい。
とりあえず、環境のほうをざっくり書いときます。
環境
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