Я только что купил SparkFun Pro Micro (https://www.sparkfun.com/products/12640) и пытаюсь связаться с ним с помощью ReadFile и WriteFile в Windows 10.
Я протестировал и запустил свой код на Stellaris, Tiva, Arduino Mega и даже Arduino Leonardo практически без проблем (это работало). Однако я не смог отправить какие-либо данные из Pro Micro или получить данные на моем компьютере с помощью кабеля micro USB и моей собственной программы. Я могу использовать серийный монитор Arduino для отправки и получения данных просто отлично. Я также могу использовать терминал PuTTY. Скорость передачи данных в Arduino IDE и PuTTY, похоже, не влияет на возможность отправки / получения данных с помощью Pro Micro.
Я хочу иметь возможность отправлять и получать данные, используя мою собственную программу, поскольку я использую ее в качестве сервера для регистрации данных, последующей обработки и отображения / отображения в реальном времени. Если бы этот проект не требовал меньшего аппаратного пакета, я бы использовал Arduino Mega, но это, к сожалению, не вариант.
Я компилирую на Windows 10, используя Visual Studio 2015. Я также использую официальную среду разработки Arduino с надстройкой / драйверами SparkFuns, v1.6.7 (обновлена до 1.6.8 с теми же проблемами).
Это мой код для подключения к COM-порту, я пробовал различные скорости передачи данных, а также макросы BAUD_XXXX:
*port = CreateFile(COM, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); //CreateFile(TEXT("COM8:"), ...
if (*port == INVALID_HANDLE_VALUE){
printf("Invalid handle\n");
return(1);
}
/// COM Port Configuration
portDCB.DCBlength = sizeof(DCB); ///< Initialize the DCBlength member
GetCommState(*port, &portDCB); ///< Get the default port setting information.
/// Change the DCB structure settings
portDCB.BaudRate = 115200; ///< Current baud
portDCB.fBinary = TRUE; ///< Binary mode; no EOF check
portDCB.fParity = FALSE; ///< Disable parity checking
portDCB.fOutxCtsFlow = FALSE; ///< No CTS output flow control
portDCB.fOutxDsrFlow = FALSE; ///< No DSR output flow control
portDCB.fDtrControl = DTR_CONTROL_DISABLE; ///< Disable DTR flow control type
portDCB.fDsrSensitivity = FALSE; ///< DSR sensitivity
portDCB.fTXContinueOnXoff = TRUE; ///< XOFF continues Tx
portDCB.fOutX = FALSE; ///< No XON/XOFF out flow control
portDCB.fInX = FALSE; ///< No XON/XOFF in flow control
portDCB.fErrorChar = FALSE; ///< Disable error replacement
portDCB.fNull = FALSE; ///< Disable null stripping
portDCB.fRtsControl = RTS_CONTROL_DISABLE; ///< Disable RTS flow control
portDCB.fAbortOnError = FALSE; ///< Do not abort reads/writes on error
portDCB.ByteSize = 8; ///< Number of bits/byte, 4-8
portDCB.Parity = NOPARITY; ///< 0-4 = no, odd, even, mark, space
portDCB.StopBits = ONESTOPBIT; ///< 0, 1, 2 = 1, 1.5, 2
if (!SetCommState(*port, &portDCB)){
printf("Error Configuring COM Port\n");
return(1);
}
GetCommTimeouts(*port, &comTimeOut);
comTimeOut.ReadIntervalTimeout = 20;
comTimeOut.ReadTotalTimeoutMultiplier = 10;
comTimeOut.ReadTotalTimeoutConstant = 100;
comTimeOut.WriteTotalTimeoutMultiplier = 10;
comTimeOut.WriteTotalTimeoutConstant = 100;
SetCommTimeouts(*port, &comTimeOut);
Мои функции чтения и записи:
char inChar(HANDLE port){
char output = 0;
DWORD noOfBytesRead = 0;
int retval = ReadFile(port, &output, 1, &noOfBytesRead, NULL);
if (retval == 0) {
return (0);
}
return(output);
}
void outChar(HANDLE port, char output){
DWORD bytesTransmitted = 0;
char buffer[] = { output, 0 };
WriteFile(port, buffer, 1, &bytesTransmitted, NULL);
}
У меня есть это для проверки связи на ПК:
while (1) {
outChar(portHandle, 'b');
inchar = inChar(portHandle);
printf("%c", inchar);
}
На Ардуино:
void setup(){Serial.begin(115200);}
void loop(){
Serial.read();
Serial.println('a');
delay(10);
}
Индикатор Rx мигает, как сумасшедший, на Arduino, но индикатор Tx ничего не делает, показывая, что данные передаются только в одном направлении. Я провел другие тесты и обнаружил, что Arduino читает правильную информацию (проверяется миганием светодиода, если входной символ является конкретным символом), но он просто не отправляет что-либо в мою программу (на стороне ПК, когда Arduino не используется IDE или замазка).
В PuTTY я смог инициировать COM-связь с любой скоростью передачи данных, независимо от Arduinos Serial.begin (). 8 бит данных, 1 стоповый бит, без контроля четности, без контроля потока, так же, как моя установка в Visual Studio.
Редактировать:
Я подумал, что если бы я не настроил его сам, я бы просто воспользовался конфигурацией COM, оставшейся от PuTTy, поэтому я изменил свой код и удалил все лишнее:
/// COM Port Configuration
portDCB.DCBlength = sizeof(DCB); ///< Initialize the DCBlength member
GetCommState(*port, &portDCB); ///< Get the default port setting information.
/// Change the DCB structure settings
portDCB.BaudRate = 115200; ///< Current baud
portDCB.ByteSize = 8; ///< Number of bits/byte, 4-8
portDCB.Parity = NOPARITY; ///< 0-4 = no, odd, even, mark, space
portDCB.StopBits = ONESTOPBIT; ///< 0, 1, 2 = 1, 1.5, 2
/*
portDCB.fBinary = TRUE; ///< Binary mode; no EOF check
portDCB.fParity = FALSE; ///< Disable parity checking
portDCB.fOutxCtsFlow = FALSE; ///< No CTS output flow control
portDCB.fOutxDsrFlow = FALSE; ///< No DSR output flow control
portDCB.fDtrControl = DTR_CONTROL_DISABLE; ///< Disable DTR flow control type
portDCB.fDsrSensitivity = FALSE; ///< DSR sensitivity
portDCB.fTXContinueOnXoff = TRUE; ///< XOFF continues Tx
portDCB.fOutX = FALSE; ///< No XON/XOFF out flow control
portDCB.fInX = FALSE; ///< No XON/XOFF in flow control
portDCB.fErrorChar = FALSE; ///< Disable error replacement
portDCB.fNull = FALSE; ///< Disable null stripping
portDCB.fRtsControl = RTS_CONTROL_DISABLE; ///< Disable RTS flow control
portDCB.fAbortOnError = FALSE; ///< Do not abort reads/writes on error
*/
Работает с закомментированным кодом, но почему? Что отличает этот Pro Micro от других используемых мной микроконтроллеров? Я проверю их все по одному, пока не выясню, кто за это отвечает, поскольку это работает, только если я подключаюсь после первого открытия и закрытия порта в PuTTY (неудобно).
SparkFun Pro Micro не нравится, когда вы отключаете управление RTS в Windows DCB Structure.
Проблема решена с помощью:
portDCB.fRtsControl = RTS_CONTROL_ENABLE; //was RTS_CONTROL_DISABLE
portDCB.fOutxCtsFlow = TRUE; //was FALSE
Как обычно, было ошибкой пропускать важную информацию в таблице данных, я часами читал информацию в реестре, пытаясь подтвердить, где или почему я ошибся, и ответ был прост, как видно из списка функциональных возможностей устройства USART в таблице данных. :
USART:
...
• Flow control CTS/RTS signals hardware management
...
char inChar(HANDLE port){
char output = 0;
DWORD noOfBytesRead = 0;
int retval = ReadFile(port, &output, 1, &noOfBytesRead, NULL);
if (retval == NULL) {
return (NULL);
}
return(output);
}
Это не правильно, так как вы сравниваете retval (который является int) с NULL, и ваша функция возвращает NULL как возвращаемое значение функции char. Хотя я не верю, что это вызывает проблему, о которой сообщают, это должно быть изменено.
Посмотрите на принятый ответ Вот. Я бы посоветовал вам начать с рабочего примера на стороне ПК, а затем сократить его до ваших потребностей.