2016-04-28 9 views
2

Ich habe gerade einen SparkFun Pro Micro (https://www.sparkfun.com/products/12640) gekauft und bin versucht, es mit Readfile und Writefile unter Windows 10.Windows COM Kommunikation über CDC COM Port Arduino

ich getestet habe, zu kommunizieren und mein Code ausführen mit ein Stellaris, Tiva, Arduino Mega und sogar der Arduino Leonardo mit wenig bis keine Probleme (es hat funktioniert). Ich konnte jedoch keine Daten vom Pro Micro senden oder Daten auf meinem Computer mit dem Micro-USB-Kabel und meinem eigenen Programm empfangen. Ich kann den Arduino seriellen Monitor verwenden, um Daten gut zu senden und zu empfangen. Ich kann auch ein PuTTY-Terminal benutzen. Die Baudraten in Arduino IDE und PuTTY scheinen keinen Einfluss auf die Fähigkeit zum Senden/Empfangen von Daten mit dem Pro Micro zu haben.

Ich möchte in der Lage sein, Daten mit meinem eigenen Programm zu senden und zu empfangen, da ich es als Server für Datenprotokollierung, Nachbearbeitung und Echtzeitgraphik/Anzeige verwende. Wenn dieses Projekt kein kleineres Hardware-Paket benötigt, würde ich das Arduino Mega verwenden, aber das ist leider keine Option.

Ich kompiliere auf Windows 10 mit Visual Studio 2015. Ich verwende auch die offizielle Arduino IDE mit SparkFuns Addon/Treiber, v1.6.7 (aktualisiert mit 1.6.8 mit den gleichen Problemen).

Das ist mein Code ist an den COM-Port zu verbinden, habe ich verschiedene Baudraten sowie die BAUD_XXXX Makros versucht:

*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); 

Meine Lese- und Schreibfunktionen:

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); 
} 

Ich habe diese Kommunikation auf dem PC zu testen:

while (1) { 
    outChar(portHandle, 'b'); 
    inchar = inChar(portHandle); 
    printf("%c", inchar); 
} 

auf dem Arduino:

Die Rx-LED blinkt wie verrückt auf dem Arduino, aber die Tx-LED tut nichts, was bedeutet, dass nur Daten in eine Richtung gehen. Ich habe andere Tests gemacht, und ich habe gefunden, dass der Arduino die richtigen Informationen liest (getestet durch Blinken einer LED ein und aus, wenn das Eingabe-Zeichen ein bestimmtes Zeichen ist), aber es sendet einfach nichts an mein Programm (PC-Seite, wenn kein Arduino verwendet wird) IDE oder PuTTY).

In PuTTY konnte ich COM-Kommunikation mit jeder Baudrate initiieren, unabhängig von der Arduinos Serial.begin(). 8 Datenbits, 1 Stoppbit, keine Parität, keine Flusskontrolle, genauso wie meine Einrichtung in Visual Studio.

Edit: Ich dachte, wenn ich es nicht selbst habe konfigurieren, würde ich nur die COM-Konfiguration von PuTTy übrig bleiben Huckepack off so modifiziert ich meinen Code und entfernt alle überschüssigen:

/// 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 
*/ 

Es funktioniert gut mit dem kommentierten Code, aber warum? Was unterscheidet dieses Pro Micro von den anderen Mikrocontrollern, die ich verwendet habe? Ich werde sie alle eins nach dem anderen durchprobieren, bis ich herausfinde was ansteht, da dies nur funktioniert, wenn ich mich nach dem ersten Öffnen und Schließen des Ports in PuTTY verbinde (unbequem).

Antwort

2

Der SparkFun Pro Micro mag es nicht, wenn Sie RTS-Steuerelement in Windows DCB-Struktur deaktivieren.

Das Problem mit behoben ist:

portDCB.fRtsControl = RTS_CONTROL_ENABLE; //was RTS_CONTROL_DISABLE 
portDCB.fOutxCtsFlow = TRUE;    //was FALSE 

Wie üblich, es ist ein Fehler in mit Blick auf wichtige Informationen im Datenblatt war, verbrachte ich Stunden durch die Registerinformationen zu lesen, um zu bestätigen versuchen, wo oder warum ging ich falsch und die Antwort war einfach, wie die Funktionalität Liste der USART Gerät im Datenblatt gesehen ist:

USART: 
... 
• Flow control CTS/RTS signals hardware management 
... 
0
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); 
    } 

Dies ist nicht korrekt, da Sie Retval vergleichen (was int) auf NULL, und Ihre Funktion liefert als Rückgabewert von char Funktion NULL zurück. Obwohl ich nicht glaube, dass dies das gemeldete Problem verursacht, sollte es geändert werden.

Werfen Sie einen Blick auf die angenommene Antwort here. Ich würde vorschlagen, dass Sie mit einem Arbeitsbeispiel auf der PC-Seite beginnen und es dann auf Ihre Bedürfnisse reduzieren.

+0

NULL definiert als 0. ich habe die meisten meiner NULL Anrufe mit 0 ersetzt es klarer zu machen. Danke, dass Sie sich die Zeit genommen haben, meinen Code durchzusehen. – Jarred

+0

Das ist in Ordnung, aber nicht üblich, da NULL beabsichtigte Verwendung mit Zeigern ist. Schauen Sie sich einen Link an, es scheint, dass explizite Einstellungen von Port-Timeouts knifflig sein können ... –

+0

Ja, ich versuche 99% der Zeit mit Zeigern zu verwenden, Sie haben mich dabei erwischt, etwas zu tun, was ich nicht tun sollte. Ich habe das Problem gefunden und fühle mich wie ein Idiot, aber hoffentlich hilft es jemand anderem, wenn sie etwas Ähnliches versuchen. – Jarred