Я только что купил SparkFun Pro Micro (https://www.sparkfun.com/products/12640) и пытаю общаться с его помощью ReadFile и WriteFile в ОС Windows 10.Windows, COM Связь через CDC COM порт для Arduino
Я проверил и запустить свой код 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);
}
на Arduino:
void setup(){Serial.begin(115200);}
void loop(){
Serial.read();
Serial.println('a');
delay(10);
}
Светодиодный индикатор Rx сверкает как сумасшедший на Arduino, но светодиод Tx ничего не делает, означая, что есть только данные, идущие в одну сторону. Я провел другие тесты, и я обнаружил, что Arduino читает правильную информацию (проверяется путем включения или выключения светодиода, если входной символ является определенным символом), но он просто не отправит ничего в мою программу (сторона ПК, когда не используется Arduino IDE или PuTTY).
В PuTTY Я смог инициировать COM-связь с любой скоростью передачи, независимо от Arduinos Serial.begin(). 8 бит данных, 1 стоповый бит, отсутствие контроля четности, управление потоком, то же, что и моя настройка в Visual Studio.
Edit: Я подумал, что если я не настраивал его сам, я бы просто Спекуляцию от конфигурации COM, оставшейся от замазки, так что я изменил мой код и удалить все излишки:
/// 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 (неудобно).
NULL определяется как 0. Я заменял большинство моей NULL вызовов с 0, чтобы сделать его более ясным. Приветствую вас, чтобы посмотреть время на мой код. – Jarred
Это нормально, но не обычный, поскольку NULL предназначен для использования с указателями. Посмотрите на предоставленную ссылку, кажется, что явные настройки тайм-аутов порта могут быть сложными ... –
Да, я пытаюсь использовать NULL с указателями в 99% случаев, вы поймали меня, делая что-то, чего я не должен делать. Я нашел проблему, и я чувствую себя идиотом, но, надеюсь, это поможет кому-то другому, если они попробуют что-то подобное. – Jarred