// // Created by casic on 25-2-25. // #include "serial_port_wrapper.hpp" #include <iomanip> #include <iostream> serial_port_wrapper::serial_port_wrapper( boost::asio::io_service &io_service, const std::string &port_name, const int baud_rate ): io_service_(io_service), port_(io_service, port_name), timer_(io_service, std::chrono::seconds(3)) { port_.set_option(serial_port_base::baud_rate(baud_rate)); port_.set_option(serial_port_base::character_size(8)); port_.set_option(serial_port_base::parity(serial_port_base::parity::none)); port_.set_option(serial_port_base::stop_bits(serial_port_base::stop_bits::one)); } void serial_port_wrapper::handle_data(const std::vector<uint8_t> &buffer) { const auto x = buffer[2] & 0xFF; const auto y = buffer[3] & 0xFF; const auto z = buffer[4] & 0xFF; const auto result = x * 65536 + y * 256 + z; std::cout << "methane concentration: " << result << " ppm" << std::endl; //http上传数据 } void serial_port_wrapper::read_from_port(boost::asio::streambuf &buffer) { async_read_until( port_, buffer, static_cast<char>(0x96), //结束位,一定要注意匹配 [this,&buffer](const boost::system::error_code &error, const size_t bytes_transferred) { if (!error) { // 获取接收到的数据 std::istream is(&buffer); std::vector<uint8_t> received_data(static_cast<std::streamsize>(bytes_transferred)); is.read( reinterpret_cast<char *>(received_data.data()), static_cast<std::streamsize>(bytes_transferred) ); std::cout << "received " << bytes_transferred << " bytes: "; for (size_t i = 0; i < bytes_transferred; ++i) { std::cout << std::hex << std::uppercase << std::setw(2) << std::setfill('0') << static_cast<int>(received_data[i]) << " "; } std::cout << std::endl; handle_data(received_data); // 递归调用以继续读取数据 read_from_port(buffer); } else { std::cerr << "error: " << error.message() << std::endl; } } ); } void serial_port_wrapper::write_to_port(std::vector<uint8_t> command) { const size_t bytes_to_send = command.size(); if (bytes_to_send == 0) { std::cout << "Empty command, nothing to send." << std::endl; return; } try { const size_t bytes_sent = boost::asio::write(port_, boost::asio::buffer(command)); if (bytes_sent == bytes_to_send) { std::cout << "sent successfully" << std::endl; } else { std::cerr << "only " << bytes_sent << " bytes sent out of " << bytes_to_send << std::endl; } } catch (const boost::system::system_error &e) { std::cerr << "error sending data: " << e.what() << std::endl; } } void serial_port_wrapper::start_periodic_send() { timer_.async_wait([this](const boost::system::error_code &error) { if (!error) { write_to_port(query_methane_command); timer_.expires_at(timer_.expiry() + std::chrono::seconds(3)); start_periodic_send(); } }); }