Go Down

Topic: Visual Studio C++ (Read 2001 times) previous topic - next topic

blueice89

Hi I'm working with Visual Studio 2005 C++.
All I want to do is be able to communicate to the Arduino board.  I just need to print to a text file each time a push button is pushed from teh Arduino board.

Is there a way to do this using Visual Studio 2005??
I keep getting lost because I tried the C code they offered on the Arduino playground site, but it doesn't compile and asks me about termios.h and unistd.h.  I even downloaded these from solarish unix site, and still was getting compilation errors.

Please let me know if this is possible to do.

mellis

#1
Jan 22, 2007, 09:32 am Last Edit: Jan 22, 2007, 09:32 am by mellis Reason: 1
It is possible; you probably need to use the Win32 API for serial communication (e.g. http://msdn2.microsoft.com/en-us/library/ms810467.aspx).  Using the Win32 API for anything, however, can be (to put it kindly) a nightmare.  If all you need to do is write data from the Arduino to a file, you might try Processing (it can even generate standalone executables).  There's a bit of info here: http://www.arduino.cc/playground/Interfacing/Processing

blueice89

Why is it such a nightmare??
Hmm can processing used be in conjunction with C++?  I need to at some point integrate this data logger with a Open GL envioronment, because I am trying to create a mirror, where teh data logger will just take data about the movements, and then the Open GL environment will feature a 3d character that will mirror the physical sensor movements.

So if I was trying to work on a big project like this, for integration purposes and simplicity of code, what would be the best language to work for this type of project?

CosineKitty

I don't think doing serial communications in Visual C++ is a nightmare, so long as you stay away from some of the more advanced features like "overlapped I/O".  You just open a handle to the port using CreateFile.  The name of the port will look like:  "\\.\COM1".  Because this is C++, you need to escape the backslashes, so in your code it will look like "\\\\.\\COM1".  (Thanks Microsoft for not using forward slashes like every other O/S on the planet!)  Then use ReadFile to read from the device, WriteFile to write to it.  If you are an experienced programmer, you may want to create a separate thread to run your serial monitor code in, so that your main dispatch thread doesn't get stuck waiting for stuff to happen on the serial port.  If you aren't used to multithreaded programming, then yes, you are in for a nightmare!  :)

mellis

Okay, maybe it's not such a nightmare.  CosineKitty, do you have any pointers to more documentation (e.g. setting the baud rate)?

blueice89

Can some1 answer my secondary question about using processing??
I think I might rather try this processing language, if it does the trick, and I am able to some how integrate it with Open GL environement.  Thanks!

Hmm can processing used be in conjunction with C++?  I need to at some point integrate this data logger with a Open GL envioronment, because I am trying to create a mirror, where teh data logger will just take data about the movements, and then the Open GL environment will feature a 3d character that will mirror the physical sensor movements.

So if I was trying to work on a big project like this, for integration purposes and simplicity of code, what would be the best language to work for this type of project?

CosineKitty

#6
Jan 22, 2007, 09:00 pm Last Edit: Jan 22, 2007, 09:01 pm by CosineKitty Reason: 1
Here is a good place to start:

http://msdn2.microsoft.com/en-us/library/aa363436.aspx

To set the baud rate (and other parameters), you fill in the DCB structure and pass it to SetCommState.  This assumes you have already successfully opened a handle to the comm port with GENERIC_READ | GENERIC_WRITE access.

maiow

#7
Oct 21, 2008, 04:25 am Last Edit: Oct 21, 2008, 04:25 am by wmaiouiru Reason: 1
Are there any sample code by any chance to use the serial communication with visual C++?

dcb

#8
Oct 21, 2008, 04:46 am Last Edit: Oct 21, 2008, 04:47 am by dcb Reason: 1
Couple notes:

1. it might be interesting to make a keyboard like device out of your arduino and just read it directly from cin (or whatever windows makes you go through to read the keyboard)
http://code.rancidbacon.com/ProjectLogArduinoUSB

2. A visual C++ forum might also be a good resource.

3. Gotta plug the open source mingw and eclipse options for C++ on windows here.  
Also obligatory whoWouldWantAnythingButJavaOnTheirPC plug too :)

4. This isn't really an Exhibition forum post.  More of a Interfacing forum post.

dcb

#9
Oct 22, 2008, 04:23 am Last Edit: Oct 22, 2008, 04:23 am by dcb Reason: 1
what the???  This thread got 2754 "views"?  Must be a keyword thing :)

Handi

perhaps because it's 1 year old  ;)

dcb

Thank you :)  That would explain it very nicely.

GlacialWanderer

Here is a simple serial class I wrote to talk to a motor controller.  I've never used it to talk to Arduino, but it should work fine.  I use vs2005 so it should work for you.

Serial.h
Code: [Select]

#ifndef __SERIAL_H__
#define __SERIAL_H__

#include <Windows.h>
#include "RbTypes.h"

// Copied from winbase.h
#define NOPARITY            0
#define ODDPARITY           1
#define EVENPARITY          2
#define MARKPARITY          3
#define SPACEPARITY         4

#define ONESTOPBIT          0
#define ONE5STOPBITS        1
#define TWOSTOPBITS         2

class CSerial
{
public:
  CSerial();
  ~CSerial();

  RBbool Open( char *portName, int baud, int bufSize, int portByteSize, RBubyte portParity, RBubyte portStopBits );
  RBbool Close();

  int ReadData( void *buffer, int limit );
  int SendData( const char * buffer, int size );

protected:
  HANDLE      m_hCom;
  BOOL        m_portOpen;
  int         m_serialBufSize;
};

#endif


Serial.cpp
Code: [Select]

#include "Serial.h"
#include <stdio.h>

CSerial::CSerial()
{
  m_hCom = NULL;
  m_serialBufSize = 0;
  m_portOpen = FALSE;
}

CSerial::~CSerial()
{
  Close();
}

RBbool CSerial::Open( char *portName, int baud, int bufSize, int portByteSize, RBubyte portParity, RBubyte portStopBits )
{
  DCB            dcb;
  BOOL           portReady;
  DWORD          error;
  COMMTIMEOUTS   commTimeouts;

  if( m_portOpen )
  {
     return RB_TRUE;
  }

  m_hCom = CreateFile( portName,
                       GENERIC_READ | GENERIC_WRITE,
                       0,                               // exclusive access
                       NULL,                            // no security
                       OPEN_EXISTING,
                       0,                               // no overlapped I/O
                       NULL );                          // null template
  if( (m_hCom == NULL) || (m_hCom == INVALID_HANDLE_VALUE) )
  {
     error = GetLastError();
     printf( "COM open failed: Port=%s Error=%d\n", portName, error );
     return RB_FALSE;
  }

  portReady = SetupComm( m_hCom, bufSize, bufSize ); // set buffer sizes
  if ( !portReady )
  {
     error = GetLastError();
     printf( "SetupComm failed: Port=%s Error=%d\n", portName, error );
     CloseHandle( m_hCom );
     return RB_FALSE;
  }

  dcb.DCBlength = sizeof( DCB );
  portReady = GetCommState( m_hCom, &dcb );
  if ( !portReady)
  {
     error = GetLastError();
     printf( "GetCommState failed: Port=%s Error=%d\n", portName, error );
     CloseHandle( m_hCom );
     return RB_FALSE;
  }

  dcb.BaudRate      = baud;
  dcb.ByteSize      = portByteSize;
  dcb.Parity        = portParity;
  dcb.StopBits      = portStopBits;
  dcb.fAbortOnError = TRUE;
  portReady = SetCommState( m_hCom, &dcb );
  if ( !portReady )
  {
     error = GetLastError();
     printf( "SetCommState failed: Port=%s Error = %d\n", portName, error );
     CloseHandle( m_hCom );
     return RB_FALSE;
  }

  portReady = GetCommTimeouts ( m_hCom, &commTimeouts );
  if ( !portReady )
  {
     error = GetLastError();
     printf( "GetCommTimeouts failed: Port=%s Error = %d\n", portName, error );
     CloseHandle( m_hCom );
     return RB_FALSE;
  }

  commTimeouts.ReadIntervalTimeout         = 50;
  commTimeouts.ReadTotalTimeoutConstant    = 50;
  commTimeouts.ReadTotalTimeoutMultiplier  = 10;
  commTimeouts.WriteTotalTimeoutConstant   = 50;
  commTimeouts.WriteTotalTimeoutMultiplier = 10;
  portReady = SetCommTimeouts ( m_hCom, &commTimeouts );
  if ( !portReady )
  {
     error = GetLastError();
     printf( "SetCommTimeouts failed: Port=%s Error = %d\n", portName, error );
     CloseHandle( m_hCom );
     return RB_FALSE;
  }

  m_serialBufSize = bufSize;
  m_portOpen = RB_TRUE;
  return( m_portOpen );
}

RBbool CSerial::Close()
{
  BOOL pass;

  if( !m_portOpen || m_hCom == NULL )
  {
     return RB_TRUE;
  }

  pass = CloseHandle( m_hCom );
  if ( !pass )
  {
     printf("Failed to close the serial port\n");
     return RB_FALSE;
  }

  m_portOpen = FALSE;
  m_hCom = NULL;
  m_serialBufSize = 0;
  return RB_TRUE;
}

int CSerial::SendData( const char *buffer, int size )
{
  BOOL pass;
  DWORD bytesWritten;

  if( !m_portOpen || m_hCom == NULL )
  {
     return 0;
  }

  bytesWritten = 0;
  pass = WriteFile( m_hCom, buffer, size, (LPDWORD)&bytesWritten, NULL );
  if ( !pass || (bytesWritten != size) )
  {
     DWORD error = GetLastError();
     printf( "Write of length query failed: Bytes Written=%d, Error=%d\n", bytesWritten, error);
     return 0;
  }

  return bytesWritten;
}

int CSerial::ReadData( void *buffer, int maxSize )
{
  BOOL readStatus;
  DWORD bytesRead;
  //DWORD errorFlags;
  //COMSTAT comStat;

  if( !m_portOpen || m_hCom == NULL )
  {
     return 0;
  }

  //ClearCommError( m_hCom, &errorFlags, &comStat );
  //if( !comStat.cbInQue )
  //{
  //   return 0;
  //}

  readStatus = ReadFile( m_hCom, buffer, maxSize, &bytesRead, NULL );
  if ( !readStatus )
  {
     DWORD error = GetLastError();
     printf( "Read length failed: Bytes read=%d, Error=%d\n", bytesRead, error );
     return 0;
  }

  return bytesRead;
}


RbTypes.h
Code: [Select]


#ifndef __RBTYPES_H__
#define __RBTYPES_H__

#include <assert.h>

#define RB_TRUE 1
#define RB_FALSE 0

typedef char RBbyte;
typedef unsigned char RBubyte;
typedef int RBint;
typedef unsigned int RBuint;
typedef int RBbool;

#define RB_MIN( a, b )  (( a < b ) ? a : b )
#define RB_MAX( a, b )  (( a > b ) ? a : b )

#define RB_ASSERT assert
#endif

azi

hello,
I am not sure if this is in VS2005 but there is in VS2008, I wrote that in C#, but in Visual C++, there is the same component in tool box, its called SerialPort, and it's damn easy to send some bytes to arduino... try with that, if you don't know how to use it, let me know I can help you out

Go Up