USB Host Shield cannot receive data from CDC-ACM Device

I am using an Arduino Pro Mini connected to a M5Stack M020 USB Host Module. The M020 uses a MAX3421E which is the same chip as the genuine Arduino USB host shield uses.

I am trying to interface with a scientific datalogger. The only available interface on the datalogger is a USB port. The USB port exposes a serial console which I can connect to with Putty on Windows with no special drivers required. The device manager in Windows shows that the COM port is using the usbser.sys driver which tells me the device is detected as a CDC-ACM device.

I have tried using the acm_terminal example in the USB Host library but I cannot receive any data from the datalogger. I know my hardware is hooked up correctly and working as I have tested it with a PL2303 serial adapter and it works as expected. I am also able to send a "restart" command to the datalogger and I can see the status LEDs on the logger change, indicating it is restarting. So I am able to send commands to the datalogger, just not read data back.

In normal operation, the datalogger should echo back any sent characters over the serial port. However, I am getting nothing back. Using a logic analyzer on the USB data lines, I can see that the OUT tokens and data are being send from the host module to the datalogger. However, the logger responds with NAK to any IN tokens.

Repeating this same logic analyzer capture with the logger connected to a PC, the characters are echo'd back to the IN tokens. So the datalogger works as expected which means the problem is in the usb host library.

My question is what is the usbser.sys driver in Windows doing that allows me to communicate with the device that the USB host library is not doing? Is there something in the cdcacm library that needs to be changed to initialize the device properly?

Any help is appreciated and I can provide USB logic analyzer traces of specific tests if required.

Thanks

I was able to solve the issue and figured I would post the solution for completeness.

Using the logic analyzer, I took a capture of the USB bus when plugging the datalogger into a Windows laptop, connecting with PUTTY, and sending \r which gets a prompt back from the datalogger.

I then pulled and modified some commands from the USB host shield library to allow me to hard code in every packet that was sent from the laptop in my logic analyzer trace with the exact same timing.

After getting the Arduino to mimic the communication from the laptop exactly, the datalogger finally responded back with the expected data. I then started removing commands one by one to see which packet(s) were critical to getting the datalogger to respond.

I found the one packet that was key to get data back was a "GetLineCoding" setup packet. Without this packet, the datalogger refuses to output data.

I then reloaded an unmodified version of the ACM terminal example program with one modification: I sent a "GetLineCoding" packet during the setup right after the "SetLineCoding" packet which is part of the example sketch. Everything now works perfectly.

For whatever reason, the datalogger expects you to ask it for the line coding (baud rate, start/stop bits, parity) in order to send out data. Even if you manually set the line coding in the first place. Very odd behavior.

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.