Communicating with the COM PORT in C++ - c++

I have to write a program sending messages to the UART converter connected on the COM PORT in C++. I'm actually stuck from the very beggining. I haven't ever dome anything like that and I didn't manage to find any examples.
Could anyone help me out?
Appreciate any help ;)

Boost has a nice library and examples for it: https://www.boost.org/doc/libs/1_65_0/doc/html/boost_asio/overview/serial_ports.html
An example for the usage of the boost library was posted here: Clear input data from serial port in boost::asio
#include <boost/asio.hpp>
#include <vector>
#include <iostream>
using namespace std;
using namespace boost::asio;
int main()
{
io_service io_service;
serial_port port(io_service, "/dev/ttyACM0");
port.set_option(serial_port_base::baud_rate(9600));
vector<char> buf(1);
read(port, buffer(buf));
cout << (int) buf[0] << endl;
return 0;
}
same can be done with write:
std::string s;
write(port,buffer(s.c_str(),s.size()));

Related

Not able to compile some shared code using boost::asio sockets in both boost v1.69 and v1.71

I have to maintain two different legacy projects with some shared source code, one of them is tied to boost v1.69 and the other one is tied to boost v1.71.
The problem here is that compiler is working with v1.71 and failing with v1.69 when using some boost::asio sockets class.
The other restriction is to use c++17 or earlier, so sadly c++20 fancy features are not allowed here.
Here is a minimal (really minimal) functional example, just to show the problem. Do not expect this sample code doing anything, not even trying to connect.
Godbolt link: https://godbolt.org/z/fj4E8qhxT
#include <map>
#include <boost/asio.hpp>
namespace tcpsocket
{
using boost::asio::ip::tcp;
class client
{
public:
client(boost::asio::executor executor) : socket(executor) {}
private:
tcp::socket socket;
};
}//namespace tcpsocket
int main()
{
boost::asio::io_context ioc;
std::map<int, tcpsocket::client> clients;
//This is working with boost v1.71 but failing with boost v1.69
auto id{125};
auto[it, ok] = clients.emplace(id, ioc.get_executor());
if (ok)
auto& client = it->second;
}
Is it using a boost::asio::io_context& (watch the reference &) a very naive solution solution to solve this problem? I mean, was there any hidden problem with that in a single threaded application?
Well, there is at least one problem, the change from get_io_context() to get_executor() between versions.
Any help with this?
pre-1.70.0 Asio doesn't support executors in IO objects yet:
Changelog
Added custom I/O executor support to I/O objects.
All I/O objects now have an additional Executor template parameter. This template parameter defaults to the asio::executor type
(the polymorphic executor wrapper) but can be used to specify a
user-defined executor type.
I/O objects' constructors and functions that previously took an asio::io_context& now accept either an Executor or a reference to a
concrete ExecutionContext (such as asio::io_context or
asio::thread_pool).
I'd go with the old interface:
Live On Compiler Explorer
#include <map>
#include <boost/asio/version.hpp>
#include <boost/asio.hpp>
#include <iostream>
namespace tcpsocket
{
using boost::asio::ip::tcp;
using boost::asio::io_context;
class client
{
public:
client(io_context& ctx) : socket(ctx) {}
private:
tcp::socket socket;
};
}//namespace tcpsocket
int main()
{
std::cout << BOOST_ASIO_VERSION << " " << BOOST_VERSION << "\n";
boost::asio::io_context ioc;
std::map<int, tcpsocket::client> clients;
//This is working with boost v1.71 but failing with boost v1.69
auto id{125};
auto[it, ok] = clients.emplace(id, ioc);
if (ok)
auto& client = it->second;
}
Prints either
101202 106900
or
101401 107100

How to use a buffer while writing to a file with c++ boost streams?

I'm trying to write some strings on a txt file using "Boost C++" libraries but i cannot find online a complete guide about how to do that.
The only thing i have been able to do is this:
#include <ostream>
#include <boost/iostreams/device/file.hpp>
#include <boost/iostreams/stream.hpp>
namespace io = boost::iostreams;
using namespace std;
io::stream_buffer<io::file_sink> buf("test.txt");
ostream out(&buf);
out<<"Hello world!"<<flush;
that simply writes a simple string on the file.
How can i set the buffer size? Is there a way to implement an auto flushing cycle?

readdir hangs up if libpocofoundation is linked with my tiny app

I've started debbuging on some app, which hangs up in a loop based on readdir call.
Step by step I've cut everything but problem code, this is it:
So, in basic, it shows name of first entry and nothing more. It even does not exits, just waiting for something.
Also, I've found, that if don't lin it against libpocofoundation, it works.
But I have to do it because it used in the original app.
I'm a little bit confused, I don't use Poco in this example in any way, but it some way hangs it.
Please help me, I'm in panic :D
#include <iostream>
#include <sys/types.h>
#include <dirent.h>
#include <cstring>
#include <string>
#include <fcntl.h>
using namespace std;
int main(int argc, char *argv[])
{
const char TMP_DIR[] = "/opt";
DIR *dir = opendir(TMP_DIR);
std::cerr
<< readdir(dir)->d_name
<< readdir(dir)->d_name
<< std::endl;
return 0;
}
So... I don't know why it was happening. So I just dropped libpoco.

UDP Connect Always Succeeds

I am using Boost ASIO to connect to an Arduino Nano with an Ethernet Shield over ethernet. This is the Arduino setup:
#include <EtherCard.h>
ether.staticSetup("10.0.0.4", "10.0.0.1");
ether.udpServerListenOnPort(&callback_function, 1337);
This is my C++ code that connects to it:
Header
#include <boost/asio.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>
#include <boost/bind.hpp>
#include <boost/thread.hpp>
#include <boost/system/error_code.hpp>
#include <boost/system/system_error.hpp>
boost::system::error_code error_1;
boost::shared_ptr <boost::asio::io_service> io_service_1;
boost::shared_ptr <boost::asio::ip::udp::socket> socket_1;
Initialize
// 1. reset io service
io_service_1.reset();
io_service_1 = boost::make_shared <boost::asio::io_service> ();
// 2. create endpoint
boost::asio::ip::udp::endpoint remote_endpoint(
boost::asio::ip::address::from_string("10.0.0.4"),
1337
);
// 3. reset socket
socket_1.reset(new boost::asio::ip::udp::socket(*io_service_1));
// 4. connect socket
socket_1->async_connect(remote_endpoint, socket_1_connect_callback);
// 5. start io_service_1 run thread after giving it work
boost::thread t(boost::bind(&boost::asio::io_service::run, *&io_service_1));
Callback
function socket_1_connect_callback (const boost::system::error_code& error_1)
{
// 1. check for errors
if (error_1)
{
std::cerr << "error_1.message() >> " << error_1.message().c_str() << std::endl;
return;
}
else
{
INFO << "connection succeeded";
}
return;
}
The socket connects every time, even if the Arduino is not powered. Why does it not fail to connect?
By definition, UDP is connection-less protocol. 'Connecting' a UDP socket is simply a convenience operation, which allows you to than send datagrams on that socket without specifying recipient - it uses the one you gave to a connect call.
But other than that, it does nothing. There is really no way to check if someone is listening on the other side of UDP, unless you implement a request/response scheme yourself.
The fact that you are using Boost.Asio adds nothing to this basic fact.

Make boost http client

I am new to boost library so my question is probably not the first one in this forum but I couldn't find a similar case.
Currently I am trying to implement a simple HTTP client which calls REST API.
I inspired my self from the example given on the boost's web site: HTTP client with boost
The example is clear enough for a newbie like me but I would like to make the client to be able to execute multiple requests one by one because the example is a one shot: the client sends a GET request to the server, than it receives the response and after that the io_service.run() returns.
So my question is what I need to use from boost in way to make my client always waiting for new requests to send.
I read something about a io_service::work but I am not sure if it is the right way.
Does anybody have done something similar to the client I am trying to make?
Thanks in advance !
Best regard,
Anton
I do not know if asynchronous version is a must, so I would recommend you to give a try to synchronous version, since it's easier to follow the execution path:
/*
Compile with
g++ -lpthread -lboost_system -lboost_thread -ohttp http.cpp
*/
#include <iostream>
#include <string>
#include <vector>
#include <cstdlib>
#include <boost/asio.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/thread/thread.hpp>
using std::cout;
using std::endl;
using std::vector;
using std::string;
using boost::asio::ip::tcp;
using boost::asio::ip::address;
using boost::asio::io_service;
using boost::asio::buffer;
using boost::system::error_code;
using boost::system::system_error;
int main()
{
try
{
unsigned int PORT = 80;
const string HOST = "216.58.214.238";
const string HTTP_REQUEST = "GET /index.html HTTP/1.0\n\n";
io_service ios;
tcp::endpoint ip_port(address::from_string(HOST), PORT);
while (true)
{
tcp::socket client(ios);
client.connect(ip_port);
const int BUFLEN = 1024;
vector<char> buf(BUFLEN);
client.send(buffer(HTTP_REQUEST, HTTP_REQUEST.size()));
error_code error;
int len = client.receive(buffer(buf, BUFLEN), 0, error);
cout << "main(): buf.data()=";
cout.write(buf.data(), len);
cout << endl;
boost::this_thread::sleep(boost::posix_time::milliseconds(1000));
}
}
catch (system_error& exc)
{
cout << "main(): exc.what()=" << exc.what() << endl;
}
return EXIT_SUCCESS;
}
The socket is created each time within the loop because Google (it's IP address is used) closes the connection after each request (status 302 is returned).
In some other cases, HTTP connection does not have to be closed by a server, so socket can be reused.