INTRODUCTION: Hello there. I am working on a project that requires the connection of a USB device and communication through its virtual serial port. Unfortunately, it does not have a HW serial connection. I purchased a USB Host Shield (version 2) and implemented the USB Host Shield Library 2.0 (repo link). The protocol used is ACM. Original Arduino Mega is used under the shield. I am using code snippets from the official example on cdcacm communication.
PROBLEM: The USB connection is initialized properly when the Arduino is connected via the main USB port to my computer. In other words, there is an existing USB connection already. When I disconnect it and power it just from a voltage source, the connection isn't established.
ALREADY TRIED: I've checked the HW regarding power. The shield is properly set to 5 V, and the input voltage is 12 V. I am not using any pins used by the shield. In fact, I've stripped the project of everything except the shield. So now it is Arduino Mega + the shield and one connected USB device.
DETAILS: The USB device is a radio controller for LED light props. It takes simple commands in an ASCII manner. It is clearly visible on my lights when the commands are coming through or not. No acknowledgment or other synchronized communication processes are needed. I include the code snippets below.
SUMMARY: Everything works properly when connected to a PC; otherwise, it does not. I suspect incorrect library services that make various USB connections somehow dependent. I am not advanced enough to understand the communication interface services. Please help.
FT2remote.cpp
#include <FT2remote.h>
USB Usb;
ACMAsyncOper AsyncOper;
ACM Acm(&Usb, &AsyncOper);
FT2remote::FT2remote() {};
void FT2remote::begin() {
if (Usb.Init() == -1)
Serial.println("USB: OSCOKIRQ failed to assert");
}
void FT2remote::sendPacket(String packet) {
Serial.println("FT2: Sending command: " + packet);
Usb.Task();
if (Acm.isReady()) {
Serial.println("ACM ready.");
//String str = "lprog 0x00000002,mMeCOcBL\n"; // test string
String str = packet;
char charArr[str.length()+1];
str.toCharArray(charArr, str.length()+1);
Acm.SndData(str.length(),(uint8_t*)charArr);
}
}
FT2remote.h includes ACMAsyncOper.h
ACMAsyncOper.h
#include <Arduino.h>
#include <cdcacm.h>
class ACMAsyncOper : public CDCAsyncOper{
public:
uint8_t OnInit(ACM *pacm);
};
ACMAsyncOper.cpp
#include <ACMAsyncOper.h>
uint8_t ACMAsyncOper::OnInit(ACM *pacm) {
uint8_t rcode;
// Set DTR = 1 RTS=1
rcode = pacm->SetControlLineState(3);
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;
}
main.cpp
FT2remote ft2; // object servicing the FT2 remote controller
void setup() {
Serial.begin(9600);
ft2.begin();
delay(200);
void loop() {
ft2.setColor(true,1); // this calls a lot of functions constructing the final string command and calling void FT2remote::sendPacket(String packet)
delay(1000);
ft2.setColor(true,2);
delay(1000);