1

I'm attempting to send serial messages over USB to an Arduino Uno, using raw WinAPI commands. When using baud rates less than 115200, it works perfectly fine. However, when I send at 115200 baud, two extra bytes are sent prefixing the data I sent, but ONLY for the first message after connecting to the Arduino. For example, if I connect to the Arduino and send two bytes, "Hi", the Arduino receives "ððHi". If I send "Hi" again, the Arduino receives "Hi" like it should. (The extra bytes are usually ð (0xF0), but not always.)

I know that my computer and the Arduino are capable of communicating at 115200 baud, because other programs such as avrdude and the Arduino IDE's serial monitor can do it fine.

I have tried clearing the RX and TX buffers on both sides and also messing the DCB settings, with no effect. Does anyone know what might be causing this?

Thanks!

Here is my code to reproduce the problem:

Computer side:

#include <Windows.h>

int main()
{
    // Open device as non-overlapped
    HANDLE device = CreateFile(L"COM6",
                               GENERIC_READ | GENERIC_WRITE,
                               0,
                               NULL,
                               OPEN_EXISTING,
                               FILE_ATTRIBUTE_NORMAL,
                               NULL);

    // Make sure the device is valid
    if(device == INVALID_HANDLE_VALUE)
        return 0;

    DCB dcb;
    if(!GetCommState(device, &dcb))
        return 0;
    dcb.fOutX = 0;
    dcb.fInX = 0;
    dcb.fDtrControl = DTR_CONTROL_DISABLE;
    dcb.fRtsControl = RTS_CONTROL_DISABLE;
    dcb.fNull = 0;
    dcb.BaudRate = CBR_115200;
    dcb.ByteSize = 8;
    dcb.Parity = NOPARITY; 
    dcb.StopBits = ONESTOPBIT;
    if(!SetCommState(device, &dcb))
        return 0;

    COMMTIMEOUTS Timeouts = { 0 };
    Timeouts.ReadTotalTimeoutConstant = 1000;
    Timeouts.WriteTotalTimeoutConstant = 1000;
    if(!SetCommTimeouts(device, &Timeouts))
        return 0;

    char *buf = "abcdef";
    DWORD written;
    WriteFile(device, buf, 6, &written, NULL);

    DWORD read;
    char inbuf[100];
    ReadFile(device, inbuf, 100, &read, NULL);

    // When I get the result inbuf, it has 8 bytes: {0xF0, 0xF0, a, b, c, d, e, f}
    // Doing a 2nd set of Write/ReadFile, with the same message, gives the correct response
    return 0;
}

Arduino side:

void setup()
{
    Serial.begin(115200);
}
void loop()
{
    if(Serial.available())
        Serial.write(Serial.read());
}
dsolimano
  • 8,870
  • 3
  • 48
  • 63
cat
  • 530
  • 2
  • 7
  • 16
  • Suspect a transmission at 19,200 - maybe an XON (0x11)? – chux - Reinstate Monica Sep 02 '14 at 03:58
  • chux, I'm not sure what you mean by "Suspect a transmission at 19,200". I don't think the the extra bits are XON, since they are (usually) 0xF0. – cat Sep 02 '14 at 04:14
  • 1
    Sounds like you're using a USB serial adapter - try a different one. USB serial adapters have notoriously variable quality. Or try a PCI (or PCI Express) serial port on the Windows machine. Keep in mind that even if you find a set up that works cleanly in your tests, there are going to be times when there is noise on the link for a serial port, particularly when starting up the communications. Your protocol should try to handle this in some way (ie., by not falling over when there's garbage on the line). – Michael Burr Sep 02 '14 at 05:13
  • 1
    0xF0 could be a falling edge being sampled, maybe even something at a lower data rate as chux suggested. Start bit? CTS wired incorrectly? Crosstalk? Other arbitrary noise? Why not take one variable out of the equation and use a battle-hardened third-party program for serial communication like putty or teraterm? – indiv Sep 02 '14 at 05:23
  • I can't use a PCI card, I must use USB for this project. The Arduino Uno doesn't exactly have a USB-Serial adapter, but it has some software-side conversion. I'm pretty sure that's not the problem, because the Arduino IDE's serial monitor works fine (with no error checking) at 115200 baud, and because it only has problems on the first message after the computer connects. I can't use a 3rd party program. – cat Sep 02 '14 at 11:17
  • 1
    1) An XON (0x11) sent at 19,200 may look like 2 0xF0 at 115200. The fact that the errant bytes have 4 sequential on or off bits is the hint. 2) Rather than saying "usually ð (0xF0), but not always.)", mention what those other errant bytes were. (consecutive 1's and 0's?) 3) Adjust your code to look for FRAMING errors (stop bit is 0) and BREAK signals. If you are receiving these, the source signal is likely at the wrong baud. 4) You can use a PCI card for debugging as suggested by @Michael Burr. Certainly you can use 3rd party SW for debugging. – chux - Reinstate Monica Sep 02 '14 at 14:52
  • 1) Okay that makes sense, the bytes could be an XON. I tried changing the XON to another value in the DCB, but it didn't affect the bytes. 2) Sorry, the first byte is sometimes 0x10, but the 2nd is always 0xF0. 3) I'm not sure how to do that, but I'm setting the DCB to 115200 baud, so that's what it should send at, right? 4) I don't have a PCI card slot in computer (laptop). I know other 3rd party software works at 115200 baud. I tried copying the working code from avrdude, but it had no effect. Thanks for helping – cat Sep 02 '14 at 20:29
  • 1) Unclear on how writing and reading the same serial `device` gets you the same data unless the other end is loop-backing. Otherwise if the receiving side is not driven, it is just picking up noise from the transmit side and errant lead bytes is not uncommon. 2) Might want to try reading before writing to see if the extra bytes are part of the transmitted message or come from some earlier initialization. – chux - Reinstate Monica Sep 03 '14 at 16:05
  • I tried the reading before writing, which I thought I had already tried before, but apparently not because it worked! The two 0xF0s are apparently from something else. Thanks! I did try calling PurgeComm on the TX and RX buffers, which should have the same effect as reading the entire buffer, but strangely it didn't work. Post that as an actual answer so I can accept it. – cat Sep 03 '14 at 19:56

0 Answers0