/*************ArduSer.C******************* WIN USB COM Communication - Arduino (Fischetti P.) ****************************************/ #include #include #include #include #define BUFF_SIZE 128 const char* DRV_PATH = "\\\\.\\"; char portName[20]; void dump(const unsigned char *data_buffer, const unsigned int length) { unsigned char byte; unsigned int i, j; for (i = 0; i < length; i++) { byte = data_buffer[i]; printf("%02x ", data_buffer[i]); // display byte in hex if (((i % 16) == 15) || (i == length - 1)) { for (j = 0; j < 15 - (i % 16); j++) printf(" "); printf("| "); for (j = (i - (i % 16)); j <= i; j++) { // display printable bytes from line byte = data_buffer[j]; if ((byte > 31) && (byte < 127)) // outside printable char range printf("%c", byte); else printf("."); } printf("\n"); // end of the dump line (each line 16 bytes) } // end if } // end for } void PrintError(const char *msg, DWORD err) { if (msg) fprintf(stderr, "%s%d\n", msg, err); //DWORD err = GetLastError(); LPVOID lpMsgBuf; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language (LPTSTR)&lpMsgBuf, 0, NULL); int sz = lstrlenW((LPWSTR)lpMsgBuf); char *buffer = (char *)calloc(sz + 1, sizeof(char)); wcstombs(buffer, (LPWSTR)lpMsgBuf, sz); fprintf(stderr, "WinAPI Last Error: %s", buffer); // Free the buffer. free(buffer); LocalFree(lpMsgBuf); } void strRemoveNL(char *buffer){ if(buffer) buffer[strcspn(buffer, "\r\n")] = 0; } void strClear(char *buffer){ memset(buffer,0,strlen(buffer)); } char dtTime[BUFF_SIZE]; char * getCurrdtTime(char *dtT) { SYSTEMTIME st; GetLocalTime(&st); sprintf(dtT, "[%d/%d/%d %d:%d:%d:%d] ", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds); return dtT; } HANDLE hComm=NULL; int quit(int iRet){ if(hComm){ hComm=NULL; CloseHandle(hComm); } return iRet; } void handler_quit(int signal){ fprintf(stderr,"BYE!\n"); quit(0); exit(0); } typedef int bool; #define true 1 #define false 0 bool setupComPort( DCB *dcb, DWORD baudRate, DWORD byteSize, BYTE parity, BYTE stopBits, DWORD fDtrControl) { dcb->DCBlength = sizeof(DCB); switch (baudRate) { case 110: dcb->BaudRate = CBR_110; break; case 300: dcb->BaudRate = CBR_300; break; case 600: dcb->BaudRate = CBR_600; break; case 1200: dcb->BaudRate = CBR_1200; break; case 2400: dcb->BaudRate = CBR_2400; break; case 4800: dcb->BaudRate = CBR_4800; break; case 9600: dcb->BaudRate = CBR_9600; break; case 14400: dcb->BaudRate = CBR_14400; break; case 19200: dcb->BaudRate = CBR_19200; break; case 38400: dcb->BaudRate = CBR_38400; break; case 57600: dcb->BaudRate = CBR_57600; break; case 115200: dcb->BaudRate = CBR_115200; break; case 256000: dcb->BaudRate = CBR_256000; break; default: fprintf(stderr, "Error on BaudRate\n"); return false; } dcb->ByteSize = byteSize; //8 data bits switch (parity) { case 0: dcb->Parity = NOPARITY; break; case 1: dcb->Parity = ODDPARITY; break; case 2: dcb->Parity = EVENPARITY; break; case 3: dcb->Parity = MARKPARITY; break; case 4: dcb->Parity = SPACEPARITY; break; default: fprintf(stderr, "Error on Parity\n"); return false; } switch (stopBits) { case 0: dcb->StopBits = ONESTOPBIT; break; case 1: dcb->StopBits = ONE5STOPBITS; break; case 2: dcb->StopBits = TWOSTOPBITS; break; default: fprintf(stderr, "Error on Stop Bit\n"); return false; } switch (fDtrControl) { case 0: dcb->fDtrControl = DTR_CONTROL_DISABLE; break; case 1: dcb->fDtrControl = DTR_CONTROL_ENABLE; break; case 2: dcb->fDtrControl = DTR_CONTROL_HANDSHAKE; break; default: fprintf(stderr, "Error on DTR Control\n"); return false; } return true; } int help(char *proc) { fprintf(stderr,"\t*** RS232 <---> ARDUINO\t(By Fischetti P.) ***\n\n"); fprintf(stderr,"Syntax:\n\t"); fprintf(stderr," -pPORT [-l] [-mMode(R)] [-t]\n\nOptions: -pPortName (e.g.: COM6)\n\t -v Dump RX bytes\n\t" " -mMode is Trasmit(T)/Receive(R) or TrasmitReceive(X)\n\t -t Print TimeStamp\n\t -l enumerate Arduino COM Ports\n"); fprintf(stderr,"\t -nByteSize[8]\n"); fprintf(stderr,"\t -yParity\n"); fprintf(stderr,"\t\t[0]\tNo parity.\n"); fprintf(stderr,"\t\t1\tOdd parity.\n"); fprintf(stderr,"\t\t2\tEven parity.\n"); fprintf(stderr,"\t\t3\tMark parity.\n"); fprintf(stderr,"\t\t4\tSpace parity.\n"); fprintf(stderr,"\t -xStopBits\n"); fprintf(stderr,"\t\t[0]\t1 stop bit.\n"); fprintf(stderr,"\t\t1\t1.5 stop bits.\n"); fprintf(stderr,"\t\t1\t2 stop bits.\n"); fprintf(stderr,"\t -bBaudRate in bps:\n"); fprintf(stderr,"\t\t110"); fprintf(stderr,"\t300"); fprintf(stderr,"\t600"); fprintf(stderr,"\t1200\n"); fprintf(stderr,"\t\t2400"); fprintf(stderr,"\t4800"); fprintf(stderr,"\t[9600]"); fprintf(stderr,"\t14400\n"); fprintf(stderr,"\t\t19200"); fprintf(stderr,"\t38400"); fprintf(stderr,"\t57600"); fprintf(stderr,"\t115200\n"); fprintf(stderr,"\t\t128000"); fprintf(stderr,"\t256000\n"); fprintf(stderr,"\t -dDTRControl:\n"); fprintf(stderr,"\t\t0\tDisable.\n"); fprintf(stderr,"\t\t[1]\tEnable.\n"); fprintf(stderr,"\t\t2\tEnable HandShake.\n"); return -1; } typedef enum { None, RX, TX, X } enmMode; int main(int argc, char *argv[]) { // Handle to the Serial port BOOL Status; // Status DCB dcb = { 0 }; // Initializing DCB structure COMMTIMEOUTS timeouts = { 0 }; //Initializing timeouts structure char SerialBuffer[BUFF_SIZE] = { 0 }; //Buffer to send and receive data DWORD BytesWritten = 0; // No of bytes written to the port DWORD dwEventMask; // Event mask to trigger char ReadData; //temperory Character DWORD NoBytesRead; // Bytes read by ReadFile() unsigned char loop = 0; int i; DWORD errors; COMSTAT status; DWORD BaudRate = CBR_9600; BYTE ByteSize = 8; BYTE StopBits = ONESTOPBIT; BYTE Parity = NOPARITY; DWORD fDtrControl = DTR_CONTROL_ENABLE; bool bTimestamp = false,bDump=false; enmMode mode = RX; signal(SIGINT,handler_quit); signal(SIGABRT,handler_quit); for (i = 1; i < argc; i++) { if (('-' == argv[i][0]) || ('/' == argv[i][0])) { char cp; cp = argv[i][1]; switch (cp) { case 'P': case 'p': { strcpy(portName, DRV_PATH); strncat(portName, &argv[i][2], 6); } break; case 't': case 'T': { bTimestamp = true; } break; case 'v': case 'V': { bDump = true; } break; case 'M': case 'm': { switch (tolower(argv[i][2])) { case 'r': mode = RX; break; case 't': { mode = TX; break; } case 'x': { mode = X; break; } break; default: help(argv[0]); return -1; } } break; case 'l': case 'L': { enmIno(); return 0; } break; case 'b': case 'B': { BaudRate = atoi(&argv[i][2]); } break; case 'n': case 'N': { ByteSize = atoi(&argv[i][2]); } break; case 'y': case 'Y': { Parity = atoi(&argv[i][2]); } break; case 'x': case 'X': { StopBits = atoi(&argv[i][2]); } break; case 'd': case 'D': { fDtrControl = atoi(&argv[i][2]); } break; case 'h': case '?': default: return help(argv[0]); } } } if (0 == strlen(portName)) { fprintf(stderr,"Error: Missing PortName!\n"); return -1; } //Open the serial com port hComm = CreateFile(portName, //friendly name GENERIC_READ | GENERIC_WRITE, // Read/Write Access 0, // No Sharing, ports cant be shared NULL, // No Security OPEN_EXISTING, // Open existing port only 0, // Non Overlapped I/O NULL); // Null for Comm Devices if (hComm == INVALID_HANDLE_VALUE) { PrintError("\n Port can't be opened ",GetLastError()); return quit(-1); } //Setting the Parameters for the SerialPort dcb.DCBlength = sizeof(dcb); Status = GetCommState(hComm, &dcb); //retreives the current settings if (Status == FALSE) { PrintError("\nError to Get the Com state ",GetLastError()); return quit(-1); } /* dcb.BaudRate = CBR_9600; //BaudRate = 9600 dcb.ByteSize = 8; //ByteSize = 8 dcb.StopBits = ONESTOPBIT; //StopBits = 1 dcb.Parity = NOPARITY; //Parity = None*/ //printf("X%d %d %d %d\n",dcb.BaudRate,dcb.ByteSize,dcb.StopBits,dcb.Parity ); setupComPort(&dcb, BaudRate, ByteSize, StopBits, Parity, fDtrControl); //printf("Y%d %d %d %d\n",dcb.BaudRate,dcb.ByteSize,dcb.StopBits,dcb.Parity ); fprintf(stderr,"[%s]BaudRate:%d ByteSize:%d StopBits:%d Parity:%d DTR Ctrl:%d.\n",(mode==RX?"RX":mode==X?"TXRX":mode==TX?"TX":"?"),dcb.BaudRate ,(int)dcb.ByteSize,(int)dcb.StopBits,(int)dcb.Parity, dcb.fDtrControl); Status = SetCommState(hComm, &dcb); if (Status == FALSE) { PrintError("\nError to Setting DCB Structure ",GetLastError()); return quit(-1); } //Setting Timeouts timeouts.ReadIntervalTimeout = 50; timeouts.ReadTotalTimeoutConstant = 50; timeouts.ReadTotalTimeoutMultiplier = 10; timeouts.WriteTotalTimeoutConstant = 50; timeouts.WriteTotalTimeoutMultiplier = 10; if (SetCommTimeouts(hComm, &timeouts) == FALSE) { PrintError("\nError to Setting Time outs ",GetLastError()); return quit(-1); } fprintf(stderr,"Connected on port: %s\n",portName); //Writing data to Serial Port while (ClearCommError(hComm, &errors, &status)){ strClear(SerialBuffer); if(TX==mode || X == mode){ printf_s("#"); if(!fgets(SerialBuffer,sizeof(SerialBuffer),stdin)){ PrintError("\nFail to Written ",GetLastError()); continue; } //strRemoveNL(SerialBuffer); dump(SerialBuffer,sizeof(SerialBuffer)); Status = WriteFile(hComm,// Handle to the Serialport SerialBuffer, // Data to be written to the port strlen(SerialBuffer), // No of bytes to write into the port &BytesWritten, // No of bytes written to the port NULL); if (Status == FALSE) { PrintError("\nFail to Written ",GetLastError()); return quit(-1); } //print numbers of byte written to the serial port fprintf(stderr,"Number of bytes written to the serial port = %d\n", BytesWritten); } if(RX==mode || X == mode){ //Setting Receive Mask Status = SetCommMask(hComm, EV_RXCHAR); if (Status == FALSE) { PrintError("Error to in Setting CommMask ",GetLastError()); return quit(-1); } //Setting WaitComm() Event Status = WaitCommEvent(hComm, &dwEventMask, NULL); //Wait for the character to be received if (Status == FALSE) { PrintError("Error! in Setting WaitCommEvent() ",GetLastError()); return quit(-1); } //Read data and store in a buffer strClear(SerialBuffer); loop=0; do { Status = ReadFile(hComm, &ReadData, sizeof(ReadData), &NoBytesRead, NULL); SerialBuffer[loop] = ReadData; ++loop; } while (NoBytesRead > 0); --loop; //Get Actual length of received data //fprintf(stderr,"nNumber of bytes received = %d\n", loop); strRemoveNL(SerialBuffer); if (true==bTimestamp) printf("%s ",getCurrdtTime(dtTime)); //if (strlen(SerialBuffer)>0) if(bDump) dump(SerialBuffer,sizeof(SerialBuffer)); printf("%s\n",SerialBuffer); fflush(stdout); } /*if (strlen(SerialBuffer)>0)*/ //dump(SerialBuffer,sizeof(SerialBuffer)); } quit(0); }