概要
・PC(USB)⇔相手機器(RS485)という形式で接続しシリアル通信を行っています
・PCからコマンドを送信すると相手機器はそれに反応し、結果をPC側に送信する仕様となります
・コマンドによって送信データのサイズは変動し、受信するデータのサイズもそれに合わせて変動します
・boost::asio::write関数で同期送信し、boost::asio::async_read関数で非同期受信をします
・現状のコードだとwriteによる送信で相手機器に反応はありますが、async_readのコールバック関数が呼ばれません
該当のソースコード
C++
1#include <iostream> 2#include <iomanip> 3#include <boost/thread/thread.hpp> 4#include <boost/asio.hpp> 5 6class CommSample 7{ 8public: 9 CommSample(const std::string& portname); 10 ~CommSample(); 11 void test(); 12private: 13 boost::thread _thread; 14 unsigned char _receive_data[64]; 15 boost::asio::io_service _io; 16 boost::asio::serial_port _port; 17 void handler(const boost::system::error_code&, size_t); 18}; 19CommSample::CommSample(const std::string& portname) : _io(), _port(_io) 20{ 21 _port.open(portname); 22 _port.set_option(boost::asio::serial_port_base::baud_rate(19200)); 23 _port.set_option(boost::asio::serial_port_base::character_size(8)); 24 _port.set_option(boost::asio::serial_port_base::flow_control(boost::asio::serial_port_base::flow_control::none)); 25 _port.set_option(boost::asio::serial_port_base::parity(boost::asio::serial_port_base::parity::none)); 26 _port.set_option(boost::asio::serial_port_base::stop_bits(boost::asio::serial_port_base::stop_bits::one)); 27 boost::asio::io_service::work w(_io); 28 boost::thread t(boost::bind(&boost::asio::io_service::run, &_io)); 29 _thread = boost::move(t); 30} 31CommSample::~CommSample() 32{ 33 _io.stop(); 34 _thread.join(); 35} 36void CommSample::test() 37{ 38 constexpr int receive_size = 8; 39 unsigned char send_data[6]{0x01, 0x02, 0x03, 0x04, 0x05, 0x06}; 40 boost::asio::async_read(_port, 41 boost::asio::buffer(_receive_data), 42 boost::asio::transfer_exactly(receive_size), 43 boost::bind(&CommSample::handler, 44 this, 45 boost::asio::placeholders::error, 46 boost::asio::placeholders::bytes_transferred)); 47 boost::asio::write(_port, boost::asio::buffer(send_data)); 48} 49void CommSample::handler(const boost::system::error_code& error, size_t bytes_transferred) 50{ 51 for (size_t i = 0; i < bytes_transferred; i++) 52 { 53 std::cout << std::uppercase << std::setfill('0') << std::hex << std::setw(2) << (int)_receive_data[i]; 54 } 55} 56int main() 57{ 58 CommSample a("COM3"); 59 while (true) 60 { 61 char c = getchar(); 62 if (c == 'q')break; 63 if (c == 'a')a.test(); 64 } 65 return 0; 66}
試したこと
ネットで調べますとio_service::run関数は処理するものがないと終了するそうで
見様見真似ですがboost::asio::io_service::work w(_io);というものをスレッド作成前に呼んでいます
しかしio_service::stopped()関数はコンストラクタを呼んだ直後には既にtrueを返してしまいます
async_readではなく
read(_port,boost::asio::buffer(_receive_data),boost::asio::transfer_exactly(receive_size));
の同期関数に変更すると受信したいデータがちゃんと_receive_dataに格納されています
write関数の後にこれは書きました
どこを修正したら良いでしょうか?
write関数は今回の目的が実現できるのであればasync_write関数に変更可能です
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。