I am sending data between an XBee transceiver and my pc.
The issue is that, initially (in my program) the data is random characters. Only after opening a serial connection in XCTU does it work.
So the serial data is being sent correctly, but XCTU does something to synchronise my pc to the XBee. Baud rates are set at 9600 both sides.
Does anybody know what XCTU is doing? Or how I can replicate it within my C++ program?
Hopefully the images below explain what is happening more clearly.
Apologies, I was trying to avoid just code dumping.
Arduino Uno, with an XBee shield and 1mW Xbee transceiver. Communicating with another 1mW Xbee transceiver mounted on an XBee Explorer USB.
The arduino code is just a read, delay and write:
#include <SoftwareSerial.h>
// XBee's DOUT (TX) is connected to pin 8 (Arduino's Software RX)
// XBee's DIN (RX) is connected to pin 9 (Arduino's Software TX)
SoftwareSerial serial1(8, 9); // RX, TX
void setup()
{
Serial.begin(9600);
serial1.begin(9600);
}
void loop()
{
while(serial1.available()){
Serial.print(char(serial1.read()));
delay(1000);
//Where ~ is the EOT character
serial1.write("55.134~");
Serial.println(" |data sent");
}
}
My programs code (C++, using boost) is as follows:
#include<iostream>
#include <boost/asio.hpp>
#include <boost/asio/serial_port.hpp>
char read_char();
std::string readLine();
void writeString(std::string s);
using namespace boost;
asio::io_service io;
asio::serial_port port(io);
int main(int argc, char* argv[])
{
//The usb port to serially read from
port.open("COM4");
//set baud rate match that of the transmitting device
port.set_option(asio::serial_port_base::baud_rate(9600));
while (true){
//serial send 'A'
std::string output = "A";
writeString(output);
//try to serial read
try{
std::cout << "Received: " << readLine() << std::endl;
}
catch (boost::system::system_error& e)
{
std::cout << "Error: " << e.what() << std::endl;
return 1;
}
}
}
/**
* Write a string to the serial device.
* \param s string to write
* \throws boost::system::system_error on failure
*/
void writeString(std::string s)
{
boost::asio::write(port, boost::asio::buffer(s.c_str(), s.size()));
std::cout << "sent:" << s << std::endl;
}
/**
* Blocks until a line is received from the serial device.
* Eventual '\n' or '\r\n' characters at the end of the string are removed.
* \return a string containing the received line
* \throws boost::system::system_error on failure
*/
std::string readLine()
{
//Reading data char by char, code is optimized for simplicity, not speed
using namespace boost;
char c;
std::string result;
for (;;)
{
asio::read(port, asio::buffer(&c, 1));
//std::cout << c << std::endl;
switch (c)
{
case '~':
return result;
default:
result += c;
}
}
}
@calco, we are overlapping - I have added to Reply #3
And I was mistaken. I thought XCTU was the problem, but it seems to be the solution.
But now I am more confused (or still confused).
Is the Xbee communicating between the Arduino and the PC or is the Xbee communicating between device D and the Arduino and the Arduino communicating with the PC using the USB connection ?
If the Arduino - PC comms is via the USB connection it may be useful to see how the serial port is managed in this Python demo. The same principles will apply in any language
serial1 is the SoftwareSerial object, whereas the serial calls were for the IDE's serial monitor.
The Arduino has the XBee mounted on it, this XBee is then communicating with another XBee which is plugged via USB in the pc.
So:
Arduino -> XBee <~wireless~> XBee ->USB to pc
I'll check out that Python demo this evening to see if I can pull anything from it.
The name was serial1 as it is still the same from an example sketch I found here
Good point reference the options and opening. I'll do some digging into any extra options that are needed.
The final result of this project is to transmit length data read from a sensor, this stage is just setting up reliable communication. So "55.134~" was to simulate a length followed by a delimiter.
calco:
serial1 is the SoftwareSerial object, whereas the serial calls were for the IDE's serial monitor.
The Arduino has the XBee mounted on it, this XBee is then communicating with another XBee which is plugged via USB in the pc.
So:
Arduino -> XBee <~wireless~> XBee ->USB to pc
It always amazes me how easy it is for people to communicate poorly usually by making assumptions about what the other person knows or thinks.
(not intended as a criticism of you - just a fact of life that one should always be aware of).
In your diagram there is no USB connection between the Arduino and the PC - is that correct? If so I doubt if my Python code is relevant, or at least not the part I was thinking about which deals with the Arduino resetting when the serial port is opened.
Robin2:
It always amazes me how easy it is for people to communicate poorly usually by making assumptions about what the other person knows or thinks.
I'm with you there, it's difficult to succinctly describe a problem when there's so many different factors that could be influencing it.
As for the serial comms issue I was having, @PaulS was dead on. I was dangerously assuming default settings with my boost serial_port object. After setting the following options it works reliably.