C++ Interface in windows

Hi guys

Despite trying for hours I can't send a simple serial command to arduino with c++. I found the c++ lib, however I blatantly fail to use it. Adopting more or less what I found in this lib I was able to connect to my arduino, but I can't send a command. Here is what I have so far of which only the writefile part doesn't work:

Thanks a lot!

//AML

#include <windows.h>
#include <stdio.h>


int main()
{

HANDLE ArduinoSerial;
DWORD tmp;
COMSTAT status;
DWORD errors;
char *buffer = "L"; //what to write
int nbChar = 1; // how many chars


while(1) 
{

if(GetAsyncKeyState(VK_F8)& (1==1)) { // to open serial port to arduino

ArduinoSerial = CreateFile( "COM4",  
                    GENERIC_READ | GENERIC_WRITE, 
                    0, 
                    0, 
                    OPEN_EXISTING,
                    FILE_FLAG_OVERLAPPED,
                    0);
if (ArduinoSerial == INVALID_HANDLE_VALUE)
{
   MessageBox(NULL, "failed, either wrong device or port is in use", "lc", MB_OK);
}
else 
{
            //If connected we try to set the comm parameters
            DCB dcbSerialParams = {0};
            //Define serial connection parameters for the arduino board
            dcbSerialParams.BaudRate=CBR_9600;
            dcbSerialParams.ByteSize=8;
            dcbSerialParams.StopBits=ONESTOPBIT;
            dcbSerialParams.Parity=NOPARITY;

             //Set the parameters and check for their proper application
             if(!SetCommState(ArduinoSerial, &dcbSerialParams))
             {
                MessageBox(NULL, "Could not set Serial Port parameters", "lc", MB_OK);
             }
             else
             {
                 MessageBox(NULL, "Successfully connected to Arduino", "lc", MB_OK);
             }
        }
    
    if(!WriteFile(ArduinoSerial, (void *)buffer, nbChar, &tmp, 0))
    {
        ClearCommError(
        ArduinoSerial,      // handle to communications device
        &errors,   // pointer to variable to receive error codes
        &status);

        MessageBox(NULL, "error", "lc", MB_OK);
  
    }
    else
        MessageBox(NULL, "Data sent", "lc", MB_OK);
}
}
}

One annoying thing about the arduino, is that opening the serial-port in software may restart the arduino. You have to allow for the time the arduino would need to reboot after opening the serial port.

You are probably writing the data while the Arduino is still rebooting. To fix this you can physically disable the auto-reset feature of your Arduino or just wait for it to reboot.

Looking at your code, you seem to have other problems. You are using Microsoft specific stuff, so I don't know what exactly those functions do, but you appear to be constantly re-opening the serial-port file, which is a big no-no.

It is too bad that Microsoft seems to not give a damn about serial ports anymore. It's unlikely that MS will ever implement ioctl so that you can go above 115kbaud, and the .Net serial-port stuff leeks memory :frowning:

With the limitations of normal Windows serial-port programming, you may just want to ditch it. There are two other options:

I tried to add a 10 second delay to my code but it doesn't work either. I won't initialize the serial connection every time in the end, it's merely to test if i am able to send a command over it, which i don't seem to be able to.

The FTDI lib seems promising but can't get it to work either, the FTDI test utility fails too...

If someone would find the mistake in my code or show me with an example in c++ how to send a command through any other method from windows I would be really grateful. As I'm a starting c++ programmer I think an example would be the best way for me to learn. This c++ serial thing is still a bit beyond me.

Cheers!

You should probably walk before you run.

The Windows interface you are using is C, not C++. How about writing some C code to do what you want. Then once that works you can wrapper with a C++ GUI. That way you can get one piece of code working at a time.

I would suggest separating out the function into a C file and interface so it can be reused by both the command line C and the GUI C++. Here is an example of my serial.h header file.

extern void clearQueue(HANDLE port);
extern void closeSerialPort(HANDLE port);
extern HANDLE openSerialPort(int serialPort, long baudRate, unsigned long timeOut);
extern int readSerialPortBuffer(HANDLE port, unsigned char *buffer, int len);
extern int readSerialPortByte(HANDLE port, int timeout, unsigned char *byte);
extern int setSerialTimeout(HANDLE port, unsigned long timeout);

There are lots of examples in the playground:
http://www.arduino.cc/playground/Main/InterfacingWithSoftware
(I added the VBscript one).

Thanks guys, finalyl managed FTDI and serial in C++, have to say FTDI is way more confortable, and faster =D

I was trying to push the Duemilanove's USART/serial to its extremes. This is what I have learned.

The FTDI chip is capable of the following baud-rates:

  • 3000000 baud

  • 2000000 baud

  • and then pretty much everything between 1000000baud and 300baud.

  • baud = 24000000/n : where n = 24 or greater

  • You can not set the FTDI chip to any baud rate between 3Mbaud, 2Mbaud, and 1Mbaud. Pretty much anything under 1Mbaud is possible.

The Arduino/AVR has 4 modes with the following baud rate limits:

  • async normal

  • baud = cpu_hz/(16*n) : where n=1 to 4096

  • for 16Mhz:

  • 1000000 baud

  • 500000 baud

  • 333333.3 baud

  • etc

  • async double

  • baud = cpu_hz/(8*n) : where n=1 to 4096

  • for 16Mhz:

  • 2000000 baud

  • 1000000 baud

  • 666666.6 baud

  • etc

  • sync master

  • baud = cpu_hz/(2*n) : where n=1 to 4096

  • for 16Mhz:

  • 8000000 baud

  • 4000000 baud

  • 2666666.6 baud

  • 2000000 baud

  • etc

  • the baud rate will be output on the XCK pin(Arduino pin 4). You are supposed to hook this pin to a device in slave-sync mode.

  • sync slave

  • You have to provide a clock on the XCK pin(Arduino pin 4) at the baud-rate you want. Any baud can be used, but the recommended maximum is (cpu_hz/4) and probably should be less than (cpu_hz/8).

The primary differences between the Arduino USART modes are:

  • async-norm samples every incoming bit 16 times
  • async-double samples every incoming bit 8 times
  • the sync modes sample every incoming bit 2 times and uses the XCK pin(Arduino pin 4) to synchronize the flow.

The extra sampling is to detect as the baud rates on each side of the connection drift apart. This shouldn't happen when you have the clocks tied together in the sync modes.

I'm not sure how much extra sampling the FTDI chip does, but it says it can deal with up to 3% aliasing of the baud rate, which is similar to normal-mode on the Arduino.

I only have 16Mhz Arduinos and I have tried:

  • using a 16Mhz Arduino at 3Mbaud in sync-slave mode, but I had a lot of corrupted bytes(~5% were corrupted). This could have been because of something bad in my setup.
  • using sync-master to do 2Mbaud, but it doesn't have any advantage over async-double at 2Mbaud and a severe disadvantage when sending data to the Arduino. I had no corruption problems though.
  • using sync-master to do 2.66Mbaud with the FTDI chip at 3Mbaud, and it doesn't work at all.

If you have a 12Mhz Arduino, you could clock the USART at 3Mbaud in sync-master mode and get a LOT more bandwidth. There wouldn't be a disadvantage for sending data to the PC, but you would have problems sending data to the Arduino.

Links to relevant docs:

P.S.
The FTDI driver won't throw an error if you try to select a baud-rate that is aliased VERY badly (i.e. select 2.666Mbaud and it aliases to 3Mbaud). It only errors when you select too high or too low a baud rate. The Arduino Serial.begin() doesn't take into account aliasing either; at least as of Arduino-16.