I wrote my own serial functions in windows and sometimes it will blue screen Windows when you remove the USB cable the arduino uses. I was wondering if anyone can help spot where/what is causing this:
#include <windows.h>
#include <stdio.h>
#define SERIAL__
#define PORT_SIZE 5
#define maxports 7
int serial_params(HANDLE hSerial);
HANDLE Init_Serial(char *portname);
char* Gen_Port_Name(void);
int Wait_Ready(HANDLE hSerial);
HANDLE find_board(int *board_detected);
int write_data(HANDLE hSerial, char *data, DWORD buffsize);
char* Gen_Port_Name(void)
{
/* Return ERROR if Max Ports Reached */
char ports[] = {'1','2','3','4','5','6','7'};
static int currentport = 0;
char portname[PORT_SIZE];
strcpy(portname, "COM");
portname[3] = ports[currentport];
portname[4] = '\0';
if(currentport > maxports)
return ("ERROR"); // No more ports to try
else
currentport++; // Update to next port
return( portname );
}
HANDLE Init_Serial(char *portname)
{
static HANDLE temp;
printf("\n\nPortName: %s\n\n", portname);
temp = CreateFile( portname, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, 0);
if(temp == INVALID_HANDLE_VALUE)
{
FlushFileBuffers(temp); // flush buffers to tell Ardunio to bark it's data
CloseHandle(temp); // Prevent Handle leaks
return INVALID_HANDLE_VALUE; // Move on to next port since this one doesn't exist
}
else
{
int attempt = serial_params(temp);
if( attempt != (-1) )
return temp;
else
{
FlushFileBuffers(temp); // flush buffers
CloseHandle(temp); // Prevent Handle leaks
return INVALID_HANDLE_VALUE;
}
}
}
int serial_params(HANDLE hSerial)
{
DWORD testWrote = 0;
DWORD testRead = 0;
DCB dcbSerialParams = {0};
COMMTIMEOUTS timeouts = {0};
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
if(!GetCommState(hSerial, &dcbSerialParams)) {
printf("\nError Getting Com Port State!\n\n");
return (-1);
}
dcbSerialParams.BaudRate = CBR_1200;
dcbSerialParams.ByteSize = 8;
dcbSerialParams.StopBits = ONESTOPBIT;
dcbSerialParams.Parity = NOPARITY;
if(!SetCommState(hSerial, &dcbSerialParams)) {
printf("\n\nError Setting Serial Port STATE!\n\n");
return(-1);
}
// To Prevent Timing out the serial port Tell Windows not to wait up for us
timeouts.ReadIntervalTimeout = 50;
timeouts.ReadTotalTimeoutConstant = 50;
timeouts.ReadTotalTimeoutMultiplier = 10;
timeouts.WriteTotalTimeoutConstant = 50;
timeouts.WriteTotalTimeoutMultiplier = 10;
if(!SetCommTimeouts(hSerial, &timeouts)){
printf("\n\n Serious Timeout error occured!!\n\n");
return(-1);
}
return 0;
}
int write_data(HANDLE hSerial, char *data, DWORD buffsize)
{
DWORD testWrote = 0;
WriteFile(hSerial, data, buffsize, &testWrote, NULL);
FlushFileBuffers(hSerial); // flush buffers to tell Ardunio to bark it's data
do{
Sleep(1);
}while (testWrote < buffsize);
printf("\nWrote %ld BYTES\n", testWrote);
return testWrote;
}
int Wait_Ready(HANDLE hSerial)
{
/* This function waits for the ready Status of the Arduino Board */
// TODO ERROR HANDLING FOR WRITE AND READFILE FUNCTIONS
const int buffsize = 32;
int Read_Timeout = 0;
DWORD testRead = 0;
DWORD testWrote = 0;
char readystatus[buffsize] = {0};
WriteFile(hSerial, "~READY~", buffsize, &testWrote, NULL);
FlushFileBuffers(hSerial); // flush buffers to tell Ardunio to bark it's data
do{
Sleep(1);
}while (testWrote < buffsize);
printf("\nWrote %ld BYTES\n", testWrote);
do
{
ReadFile(hSerial, readystatus, buffsize, &testRead, NULL);
Sleep(1);
Read_Timeout++;
}while((testRead < buffsize) && (Read_Timeout <= 20));
readystatus[buffsize - 1] = '\0';
printf("\n\nREADY STATUS: %s\n\n", readystatus);
if(strstr(readystatus, "READ1") != NULL)
return 1; // Board Detected
else
return 0; // Board not here
}
HANDLE find_board(int *board_detected)
{
char use_port[PORT_SIZE];
int i = 0;
*board_detected = 0;
static HANDLE hSerial = 0;
for(; (i < maxports) && (*board_detected != 1); i++)
{
strcpy(use_port, Gen_Port_Name());
hSerial = Init_Serial(use_port);
if (hSerial != INVALID_HANDLE_VALUE)
*board_detected = Wait_Ready(hSerial);
else
{
FlushFileBuffers(hSerial); // flush buffers to tell Ardunio to bark it's data
CloseHandle(hSerial); // Prevent Handle leaks
continue;
}
}
return hSerial;
}
Thanks