I am using an Arduino SAMD21 controller as an USB Host.
The library I found for this is the following: USB_Host_Library_SAMD.
Maybe there are other libraries that could work - do you know any ??
The USB counter part I would like to read and write to is a custom Controller from a 3rd-party company that normally connects via USB-FTDI COM port to a computer.
I would like to directly connect this 3rd-party Controller to my SAMD21 USB-Host.
By the below code example1, I achieved to read from the 3rd-party controller !!
I used the existing example for a PL2303 from the given USB_Host_Library_SAMD library. And this PL2303 example seemed to work best to interact with my 3rd-party Controller.
However, there are still two problems:
- about every 10th reading is only partially received (i.e. letters in receiving-string are missing)
- I cannot send yet (I can only receive)
As for the first problem: erroneous readings:
Some readings are cut-off parts of the receiving string. Most receiving-communication works. There is just about every 10th cmd from the 3rd-party controller that is only partially transmitted (i.e. partially received). I tried to change the delay in the receiving routine as can be seen in example1 below. But without success.
Do you have any idea what I could do in order to get 100% successful data readings ?
Example1: Receiving data from the 3rd-party Controller to a SAMD21 USB-Host:
#include <usbhub.h>
#include <cdcacm.h>
#include <cdcprolific.h>
class PLAsyncOper : public CDCAsyncOper {
public:
uint8_t OnInit(ACM *pacm);
};
uint8_t PLAsyncOper::OnInit(ACM *pacm) {
uint8_t rcode;
// Set DTR = 1
rcode = pacm->SetControlLineState(1);
if (rcode) {
ErrorMessage<uint8_t>(PSTR("SetControlLineState"), rcode);
return rcode;
}
LINE_CODING lc;
lc.dwDTERate = 115200;
lc.bCharFormat = 0;
lc.bParityType = 0;
lc.bDataBits = 8;
rcode = pacm->SetLineCoding(&lc);
if (rcode) {
ErrorMessage<uint8_t>(PSTR("SetLineCoding"), rcode);
}
return rcode;
}
USBHost UsbH;
PLAsyncOper AsyncOper;
PL2303 Pl(&UsbH, &AsyncOper);
void setup() {
Serial1.begin(115200); // receiving from 3rd-party controller and sending to Serial1
delay(2000);
if (UsbH.Init()) {
Serial1.println("USB host did not start");
}
delay( 200 );
}
void loop() {
UsbH.Task();
if( UsbH.getUsbTaskState() == USB_STATE_RUNNING ) {
uint8_t rcode;
uint8_t buf[32];
uint16_t rcvd = 32;
rcode = Pl.RcvData(&rcvd, buf);
if (rcvd) { // more than zero bytes received
String receivedStr = "";
for (uint16_t i=0; i < rcvd; i++ ) {
receivedStr += (char)buf[i];
delay(3);
// delay(5); // ...other delays did not have an effect, unfortunately
// delay(10); // ... but without any delay, every cmd is only received partailly. So I think there must be a delay even tough it makes the entire reading slower....
// delay(20);
// delay(100);
}
Serial1.write(receivedStr.c_str());
}
}
}
Also, I tried to write to the 3rd-party Controller - but this did not work at all. See code-example 2
Example2: Sending data to the 3rd-party Controller from a SAMD21 USB-Host:
#include <usbhub.h>
#include <cdcacm.h>
#include <cdcprolific.h>
class PLAsyncOper : public CDCAsyncOper {
public:
uint8_t OnInit(ACM *pacm);
};
uint8_t PLAsyncOper::OnInit(ACM *pacm) {
uint8_t rcode;
// Set DTR = 1
rcode = pacm->SetControlLineState(1);
if (rcode) {
ErrorMessage<uint8_t>(PSTR("SetControlLineState"), rcode);
return rcode;
}
LINE_CODING lc;
lc.dwDTERate = 115200;
lc.bCharFormat = 0;
lc.bParityType = 0;
lc.bDataBits = 8;
rcode = pacm->SetLineCoding(&lc);
if (rcode) {
ErrorMessage<uint8_t>(PSTR("SetLineCoding"), rcode);
}
return rcode;
}
USBHost UsbH;
PLAsyncOper AsyncOper;
PL2303 Pl(&UsbH, &AsyncOper);
void setup() {
Serial1.begin(115200); // receiving from 3rd-party controller and sending to Serial1
delay(2000);
if (UsbH.Init()) {
Serial1.println("USB host did not start");
}
delay( 200 );
}
void loop() {
UsbH.Task();
if( UsbH.getUsbTaskState() == USB_STATE_RUNNING ) {
uint8_t rcode;
// sending to the 3rd-party controller
if (Serial1.available()) {
uint8_t data= Serial1.read();
rcode = Pl.SndData(1, &data);
}
}
}
There was no data transmission at all. What could be improved ??
Questions:
- Are there other USB-Host libraries for the SAMD21 that might work better ? if yes, which ones ?
- What can I do to improve the data-receiving ? (i.e. how to get rid of missing receive-strings ?)
- What can I do to get data-sending working at all ?
Here is a complete printout of the 3rd-party USB chip that my 3rd-party Controller contains:
String Descriptors:
Manufacturer: Prolific Technology Inc.
Product: USB-Serial Controller D
Device descriptor:
Descriptor Length: 12
Descriptor type: 01
USB version: 0110
Device class: 00
Device Subclass: 00
Device Protocol: 00
Max.packet size: 40
Vendor ID: 067B
Product ID: 2303
Revision ID: 0400
Mfg.string index: 01
Prod.string index: 02
Serial number index: 00
Number of conf.: 01
Configuration descriptor:
Total length: 0027
Num.intf: 01
Conf.value: 01
Conf.string: 00
Attr.: 80
Max.pwr: 32
Interface descriptor:
Intf.number: 00
Alt.: 00
Endpoints: 03
Intf. Class: FF
Intf. Subclass: 00
Intf. Protocol: 00
Intf.string: 00
Endpoint descriptor:
Atr:oint address03 81
axpktsie 00
olin iteva: 0
ndpin dsrito:
npontaddes:02
At.: 0
Polig ntrvl 000
Enpintdecrpor
Atr.t ddes: 0
Polig ntrvl:0 000
Adr1(.01)