Serial data initially wrong, XBee to PC

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.

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.

No, it doesn't. What it does is open the serial port correctly, which, apparently, your program doesn't.

We can't see how your program is opening the serial port, nor can we see the code on the Arduino. Or even which Arduino it is.

So, I guess you'll just have to keep using X-CTU to get the connection opened properly.

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;
		}
	}
}

Thanks in advance for any help you can give.

In addition to what @PaulS has said, what is XCTU ?

(Sounds like something with a very unpleasant smell :slight_smile: )

This line won't work

serial1.write("55.134~");

And should it not be Serial.write() - i.e. without the "1"
And why .write() rather than .print()

...R

XCTU is a program that allows you to configure and monitor XBee's.

This page will explain it better than I can!

@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

...R

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.

Cheers

SoftwareSerial serial1(8, 9); // RX, TX

So, you connected a serial1 to the Arduino? Why are you not using names that make sense?

	port.open("COM4");
	//set baud rate match that of the transmitting device
	port.set_option(asio::serial_port_base::baud_rate(9600));

Most people set the options first (and there are LOT more than that that need to be considered) and THEN open the port.

			std::cout << "Received: " << readLine() << std::endl;

If you don't care what was sent, why send anything specific, like "55.134~"?

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.

...R

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.

	port.set_option(asio::serial_port_base::baud_rate(9600));
	port.set_option(asio::serial_port_base::character_size(8));
	port.set_option(asio::serial_port_base::flow_control(asio::serial_port_base::flow_control::none));
	port.set_option(asio::serial_port_base::parity(asio::serial_port_base::parity::none));
	port.set_option(asio::serial_port_base::stop_bits(asio::serial_port_base::stop_bits::one));

Thanks for the help guys

So "55.134~" was to simulate a length followed by a delimiter.

You could have made that clearer:

   string whatCameIn = readLine();
   // Do something with the data...
   std::cout << "Received: " << whatCameIn << std::endl;

That way, we assume that you WILL do something with the data, when you get data properly and reliably, in a known format.

Of course, the readLine() function assumes that the data is delimited by carriage return/line feed, so the ~ isn't really needed.