void close() { if (IsComPortOpen()) { CloseHandle(hComPort); hComPort = INVALID_HANDLE_VALUE; } }
/** * * @brief Send a buffer of data to the serial port * * @param txBufP Pointer to buffer of data to transmit * @param txSize Size of data to transmit * * @return bool Write status (true=success, false=Error) */ bool Instek8261Serial::SendCmd(char *txBufP, int txSize) { bool success = true; bool writeStatus = false; if (!IsComPortOpen()) { printf("SendMsg: WARNING: Serial port has not been opened.\n"); success = false; } if (success) { m_serialPort->write(txBufP, txSize); writeStatus = m_serialPort->waitForBytesWritten(1000); if (!writeStatus) { printf("Write failed\n"); } } return writeStatus; }
/** * * @brief Send a command to the serial port and wait for a * response. Data received is assumed to be terminated * with the TERMINATION charater. If the termination * character is received, it is assumed the receive data * is complete. * @note The byte after the last byte of received data is * terminated with a zero byte (NULL). We assume we are * reading ASCII data back, and want to have a NULL * terminated string in the receive buffer on completion. * @note All TERMINATION characters are replaced with the new * line charater in the receive buffer. * * @param txBufP Pointer to buffer of data to transmit * @param txSize Size of data to transmit * @param rxBufP Pointer to buffer to put response data in * @param maxRxSize Max size of receive buffer * @param timeoutInMs How long to wait for receive data * * @return int Number of bytes received */ int Instek8261Serial::SendCmdAndGetResponse(char *txBufP, int txSize, char *rxBufP, int maxRxSize, int timeoutInMs) { int numReadBytes = 0; int totalReadBytes = 0; bool writeStatus; bool readStatus; volatile bool msgOk = true; if (!IsComPortOpen()) { printf("SendCmdAndGetResponse: WARNING: Instek serial port has not been opened.\n"); return 0; } m_serialPort->write(txBufP, txSize); writeStatus = m_serialPort->waitForBytesWritten(1000); if (!writeStatus) { printf("Write failed\n"); msgOk = false; } while (msgOk) { readStatus = m_serialPort->waitForReadyRead(timeoutInMs); if (readStatus) { numReadBytes = m_serialPort->read(&rxBufP[totalReadBytes], (maxRxSize - totalReadBytes)); totalReadBytes += numReadBytes; if (rxBufP[(totalReadBytes - 1)] == LINE_TERMINATION_CHAR) { rxBufP[(totalReadBytes - 1)] = '\n'; rxBufP[totalReadBytes] = 0; break; } } else { printf("NO SERIAL DATA\n"); msgOk = false; } } if (!msgOk) { printf("Got %d total bytes\n", totalReadBytes); DumpMsgBytes(rxBufP, totalReadBytes); totalReadBytes = 0; } return totalReadBytes; }
void OpenComPort(const char *comport, int baud, bool enableEcho, int byteSize, int parity, int stopBits) { echo = enableEcho; hComPort = CreateFileA( comport, GENERIC_READ|GENERIC_WRITE, 0, // cannot share the COM port 0, // security (None) OPEN_EXISTING, 0, // no flags 0); // no templates if (IsComPortOpen()) { DCB dcb = {0}; if (!GetCommState(hComPort, &dcb)) { close(); // must close before throwing, or we will try to print the error too! throw "GetCommState failed."; } dcb.BaudRate = baud; dcb.ByteSize = byteSize; dcb.fParity = parity; dcb.StopBits = stopBits; if (!SetCommState(hComPort, &dcb)) { close(); // must close before throwing, or we will try to print the error too! throw "SetCommState failed."; } printf("Opened and initialized %s\n", comport); } else { throw "Cannot open serial port."; } }
/** * * @brief Wait for multiple responses from the serial port. Each * response received is assumed to be terminated with the * TERMINATION charater. If the termination character is * received, it is assumed one respnse is complete. * @note The byte after the last byte of received data is * terminated with a zero byte (NULL). We assume we are * reading ASCII data back, and want to have a NULL * terminated string in the receive buffer on completion. * @note All TERMINATION characters are replaced with the new * line charater in the receive buffer. * * @param rxBufP Pointer to buffer to put response data in * @param maxRxSize Max size of receive buffer * @param timeoutInMs How long to wait for receive data * * @return int Number of bytes received */ int Instek8261Serial::GetMultiResponse(char *rxBufP, int maxRxSize, int timeoutInMs, int numExpectedResponses) { int numReadBytes = 0; int totalReadBytes = 0; bool readStatus; volatile bool msgOk = true; int numResponses = 0; if (!IsComPortOpen()) { printf("SendMsg: WARNING: Serial port has not been opened.\n"); return 0; } while (msgOk) { readStatus = m_serialPort->waitForReadyRead(timeoutInMs); if (readStatus) { numReadBytes = m_serialPort->read(&rxBufP[totalReadBytes], (maxRxSize - totalReadBytes)); numResponses += ReplaceCrWithNewLine(&rxBufP[totalReadBytes], numReadBytes); totalReadBytes += numReadBytes; if (numResponses == numExpectedResponses) { break; } } else { printf("NO SERIAL DATA\n"); msgOk = false; } } rxBufP[totalReadBytes] = 0; if (!msgOk) { printf("Got %d total bytes\n", totalReadBytes); DumpMsgBytes(rxBufP, totalReadBytes); totalReadBytes = 0; } return totalReadBytes; }
void print(char c) { if (allUpperOutput) { c = toupper(c); } fputc(c, stdout); if (IsComPortOpen()) { DWORD numBytesWritten = 0; WriteFile(hComPort, &c, 1, &numBytesWritten, NULL); } // Reported issue with a real teletype machine: // The carriage return can take a long time, and the print head has enough mass // that it takes a while to settle down. Without a delay, a long line // can cause the printer to crunch some characters together on the paper. // We provide a configuration option to wait a specified number of milliseconds // after every carriage return. if ((c == '\r') && (carriageReturnDelayMillis > 0)) { ::Sleep(carriageReturnDelayMillis); } }
std::string readline() { const int max = 120; char line[max]; if (IsComPortOpen()) { // If the com port is open, read from it. int index = 0; while (true) { DWORD numBytesRead = 0; char c = 0; if (ReadFile(hComPort, &c, 1, &numBytesRead, NULL) && (numBytesRead == 1)) { if (echo) { print(c); } if ((c >= 'A') && (c <= 'Z')) { // convert to lower case (otherwise move coordinates cannot be parsed) c = (c + 'a') - 'A'; } if (c == '\r') { if (echo) { print('\n'); } line[index] = '\0'; return line; } else if (c != '\n') { if (index < max-1) { line[index++] = c; } } } else { close(); throw "Com port read failure."; } } } else { // If com port is closed, read from the local keyboard. if (fgets(line, sizeof(line), stdin)) { // Remove carriage return and/or line feed at end. for (int i=0; i < max && line[i]; ++i) { if (line[i] == '\r' || line[i] == '\n') { line[i] = '\0'; break; } if (line[i] >= 'A' && line[i] <= 'Z') { line[i] = (line[i] + 'a') - 'A'; // convert to lower case } } line[max-1] = '\0'; return line; } } // lost communication - not much we can do throw "END OF INPUT"; }