C++ Serial Communication

I made a thread earlier today in which i didnt really get my point across and miscommunicated on several levels and therefore im trying again with actual proper explanation.

Im currently working on serial communicatain from my arduino to a C++ program that is running on my PC.
Currently i just want to send a binary value to the PC when i press a button on my board, however ive found some inconsistencies when i go for anything larger than 2 digits.

My arduino code - which is basically just the original debounce example with an added serial.print():

int inPin = 2;         // the number of the input pin
int outPin = 13;       // the number of the output pin

int state = HIGH;      // the current state of the output pin
int reading;           // the current reading from the input pin
int previous = LOW;    // the previous reading from the input pin

long time = 0;         // the last time the output pin was toggled
long debounce = 200;   // the debounce time, increase if the output flickers

void setup()
{
  pinMode(inPin, INPUT);
  pinMode(outPin, OUTPUT);
  Serial.begin(9600);
}

void loop()
{
  reading = digitalRead(inPin);

  if (reading == HIGH && previous == LOW && millis() - time > debounce) {
    if (state == HIGH){
      state = LOW;
    }
    else {
      state = HIGH;
    }
    Serial.print("1234");   // For showcasing of the example ive not only used 0 and 1. 
                            // This way it is easier to actually see what is going on. 
    time = millis();    
  }

  digitalWrite(outPin, state);

  previous = reading;
}

This example just sends out the value 1234 whenever i press my button (i know this isnt binary, but it is easier to see where it goes from when we have more different symbols).

Now my C++ code is based off of this serial communications class:
http://playground.arduino.cc/Interfacing/CPPWindows

And my main loop looks like this:

int main() {
	Serial* SP = new Serial("\\\\.\\COM3");
	if (SP->IsConnected())
	{
		cout << "We're connected" << endl;
		cout << "________________" << endl;
	}

	char incomingData[256] = "";
	int readResult = 0;

	while (SP->IsConnected())
	{
		readResult = SP->ReadData(incomingData);
		incomingData[readResult] = 0;

		if (strlen(incomingData) > 0) 
		{
			string str(incomingData);
			cout << endl << "String: " << str << endl;

			for (int i = 0; i < strlen(incomingData); i++)
			{
				cout << "Char on place " << i << ": " << incomingData[i] << endl;
			}
			cout <<     "________________" << endl;
		}
	}
}

If we now take a look at the desired console output with an example where i only send the number 1 from the arduino when i press a key it will look something like this:

As we see it registers it completely fine, however, if i use the example from the actual arduino code posted the console looks something more like this:

So as you see it somehow doesnt always put the entire char array into the string before it prints and moves on. I dont know if this is because the char array isnt filled up yet, and i dont know how to account for this.
I hope someone have an idea as to how i can receive the entire string of data every time.

Currently i just want to send a binary value to the PC when i press a button on my board,

Sending 0 or 1 in binary takes just as long as sending '0' or '1', but the '0' and/or '1' are far easier to deal with.

Get over the notation that you will save time/energy/resources sending binary data.

however ive found some inconsistencies when i go for anything larger than 2 digits.

Then you are doing something wrong. NOTHING in the process of sending binary data cares how many digits are in the value.

You do NOT send binary data using print().

You are sending a stream of data with NO delimiters between the bytes that make up each packet.

YoureallyMUSTnotdothat!

The ReadData method reads all data that has arrived. Serial data is sent ssslllooowwwlllyyy. When you read the data, all of one packet will NOT necessarily have arrived.

You absolutely MUST know how much data is in a packet, and STOP ASSuming that you got a full packet and nothing but a packet.

PaulS:
You do NOT send binary data using print().

How do you recommend i can speed it up or handle it differently to alow a full packet to be transmitted?
I can up the baud rate but isnt that a bad fix for the situation?

How do you recommend i can speed it up or handle it differently to alow a full packet to be transmitted?

You do not need to do anything on the Arduino side to allow a full packet to be transmitted.

What you do need to do is define what, EXACTLY, constitutes a "full packet".

Robin2 has a tutorial for receiving serial data on the Arduino. The same process, although with different software, applies on the PC side.

http://forum.arduino.cc/index.php?topic=396450.0

If you send "<1234>", and on the PC side, read and store in a buffer whatever data arrives, one character at a time (using Read(), not ReadData()), then you can do exactly the same stuff that Robin2 recommends, but on the PC side.

As for faster, 9600 baud is the stone ages. Pick up the pace to something a bit more modern, like 115200.

Search for the Serial Input Basics - updated thread by Robin2. It gives ideas about receiving serial data; although aimed at the arduino, the principles can be equally applied at the pc side.

Next adjust the arduino code to send what the pc code expects.

As I see, the chars sent by Arduino are received completely. They just stays somewhere in buffer. The problem is related to Windows program but not to Arduino, I hope at least. To confirm this theory try it with some terminal like PuTTY. It should receive the chars on-time.
If so, the problem could be in the serial class config or in the read manner. It is long time I worked with it but I found in my sources something like this:

/* include */
#include <windows.h>					// master include file for Windows applications
//#include "_debug_ArduinoSerialPort.h"	// self

static HANDLE       hSerial, hSerialReadEvent;
static DCB          dcb;
static OVERLAPPED   ovWrite, ovRead;
static COMMTIMEOUTS cto = { 0, 0, 0, 0, 0 };

// --------------------------------------------------------------------------------------

void SerialBegin(char *port_name, unsigned long baud)
{
	if(hSerial) {
	/* serial line is connected already */
		dcb.BaudRate    = baud;							// new baud rate

		if(!SetCommState(hSerial, &dcb)) {
		}

		return;
	}

	hSerial = CreateFile(port_name,						// file name
						 GENERIC_READ | GENERIC_WRITE,	// access mode
						 0,								// share mode
						 NULL,							// security attributes
						 OPEN_EXISTING,					// how to create
						 0, //FILE_FLAG_OVERLAPPED,		// file attributes
						 NULL);							// handle to template file

	if(hSerial != INVALID_HANDLE_VALUE) {
//		if(!SetCommTimeouts(hSerial, &cto)) {
//		}
 
		dcb.DCBlength   = sizeof(dcb);
		dcb.BaudRate    = baud;
		dcb.fBinary     = 1;
		dcb.fDtrControl = DTR_CONTROL_ENABLE;
		dcb.fRtsControl = RTS_CONTROL_ENABLE;
		dcb.Parity      = NOPARITY;
		dcb.StopBits    = ONESTOPBIT;
		dcb.ByteSize    = 8;

		if(!SetCommState(hSerial, &dcb)) {
		}

		hSerialReadEvent = CreateEvent(NULL,			// security attributes
									   FALSE,			// reset type (automatic/manual)
									   FALSE,			// initial state
									   "RxEvent");		// object name

		ovRead.hEvent = hSerialReadEvent;

//		if(!SetCommMask(hSerial,EV_RXCHAR)) {
//		}
	}
}

// --------------------------------------------------------------------------------------

void SerialEnd()
{
	CloseHandle(hSerial);
	CloseHandle(hSerialReadEvent);
}

// --------------------------------------------------------------------------------------

unsigned int SerialWrite(unsigned char c)
{
unsigned long bytesWritten = 0;

	if(HasOverlappedIoCompleted(&ovRead)) {
		WriteFile(hSerial,			// handle to file
				  &c,				// data buffer
				  1,				// number of bytes to write
				  &bytesWritten,	// number of bytes written
				  &ovWrite);		// overlapped buffer
	}

	return(1);
}

// --------------------------------------------------------------------------------------

int SerialRead()
{
unsigned long bytesRead = 0;
char          c;

//	if(HasOverlappedIoCompleted(&ovRead)) {
		ReadFile(hSerial,			// handle to file
				 &c,				// data buffer
				 1,					// number of bytes to write
				 &bytesRead,		// number of bytes written
				 &ovRead);			// overlapped buffer
//	}

	if(bytesRead == 1) return((int)c);
	return(-1);
}

It should work.

EDIT: Lot of people faster than me :).

My fogged memory remember similar problem. ?
Not sure but try to replace FILE_FLAG_OVERLAPPED with zero in original Serial.cpp in CreateFile function call.

Im trying to take a look at the Serial Input Basic that other people recommended later.

I did try in putty, and i received every character.
Also i dont see anything called FILE_FLAG_OVERLAPPED?

christopherkas:
Also i dont see anything called FILE_FLAG_OVERLAPPED?

?
Widows side, in the code I posted. It is in comment, also in Serial.cpp from the link you posted:

Now my C++ code is based off of this serial communications class:
Arduino Playground - HomePage