I am trying to get the ACM/USB to work in conjunction with the software serial port of the bluetooth using an arduino but combining both codes causes both functions to break.
At first, I developed the code for the bluetooth part of the application, and I was able to properly send and interpret commands sent through a software serial (on pin 10 and 11).
After that, I added an arduino USB shield in order to connect it to an MRC12 USB barcode scanner. After a bit of fiddling with it, I managed to make a code which was able to receive the data sent using an ACM and then print it to the Serial port (connected computer) for debug purposes.
Doing so separately resulted for both codes working properly, but when I attempted to do so, the code stopped working.
Here is a part of the bluetooth control code with setup. This one detects if an admin code was sent and triggers a response.
char data; //Recived data will get stored in this variable
int i = 0; //count pour tabnumbers
int e = 0; //count pour firstchar
String test;
String win = "0000";
const int PowerPin1 = 4;
const int PowerPin2 = 5;
// software serial #1: RX = digital pin 10, TX = digital pin 11
SoftwareSerial portBluetooth(10, 11);
void setup() //The setup function will only run once, after each powerup.It initializes and sets the initial values
{
Serial.begin(9600); //Sets the baud for serial data transmission (Bits Per Second)
portBluetooth.begin(9600);
pinMode(PowerPin1, OUTPUT);
pinMode(PowerPin2, OUTPUT);
}
void loop() {
if (portBluetooth.available()) //Here We're checking whether data is available or not
{
test = ""; //store assembled string
data = ""; //store incoming data
delay(50);
while (portBluetooth.available()) {
data = portBluetooth.read(); //Data received
if ((byte) data == 13) {
if (test.equals(win) == true) {
portBluetooth.println("secret code acknowledged: opening all doors, sending current loaded numbers to serial");
for (int k = 0; k < TabSize; k++) {
portBluetooth.println("import: " + ImpTab[k]);
portBluetooth.println("export: " + ExpTab[k]);
}
digitalWrite(PowerPin1, LOW);
digitalWrite(PowerPin2, LOW);
delay(5000);
digitalWrite(PowerPin1, HIGH);
digitalWrite(PowerPin2, HIGH);
} else if (test.equals("1111")) {
portBluetooth.println("secret code acknowledged: clearing tracking number list");
for (int k = 0; k < TabSize; k++) {
ImpTab[k] = "";
ExpTab[k] = "";
}
}
} else {
test.concat(data);
portBluetooth.println(test);
}
}
}
}
Some other functions of the code have been removed, but this should give an idea on how it works.
This is the section that manages the USB input. The shield is unable to natively setup a serial comunication, I used an ACM to do it. This one is more complex (and probably the source of the problem), here is the integral code.
#include <cdcacm.h>
#include <usbhub.h>
#include "pgmstrings.h"
// Satisfy the IDE, which needs to see the include statment in the ino too.
#ifdef dobogusinclude
#include <spi4teensy3.h>
#endif
#include <SPI.h>
class ACMAsyncOper : public CDCAsyncOper
{
public:
uint8_t OnInit(ACM *pacm);
};
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 = 9600;
lc.bCharFormat = 0;
lc.bParityType = 0;
lc.bDataBits = 8;
rcode = pacm->SetLineCoding(&lc);
if (rcode)
ErrorMessage<uint8_t>(PSTR("SetLineCoding"), rcode);
return rcode;
}
USB Usb;
//USBHub Hub(&Usb);
ACMAsyncOper AsyncOper;
ACM Acm(&Usb, &AsyncOper);
void setup()
{
Serial.begin( 9600 );
#if !defined(__MIPSEL__)
while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection
#endif
Serial.println("Start");
if (Usb.Init() == -1)
Serial.println("OSCOKIRQ failed to assert");
delay( 200 );
}
void loop()
{
Usb.Task();
if( Acm.isReady()) {
uint8_t rcode;
delay(50);
/* reading the USB
/* buffer size must be greater or equal to max.packet size */
/* it it set to 64 (largest possible max.packet size) here, can be tuned down
for particular endpoint */
uint8_t buf[64];
uint16_t rcvd = 64;
rcode = Acm.RcvData(&rcvd, buf);
if (rcode && rcode != hrNAK)
ErrorMessage<uint8_t>(PSTR("Ret"), rcode);
if( rcvd ) { //more than zero bytes received
for(uint16_t i=0; i < rcvd; i++ ) {
Serial.print((char)buf[i]); //printing on the screen
}
}
delay(10);
}//if( Usb.getUsbTaskState() == USB_STATE_RUNNING..
}
Combining the 2 codes looked easy in theory, I just added all the neccessary configs and then added the USB section after the bluetooth checks with a small pause.
I expected the code to do one, then the other, and produce similar results. The code compiled correctly, but upon uploading the whole process broke. the setup "startup" printed alright, but then the code started entering into the incoming bluetooth signal despite the bluetooth card being inert, as well as printing a lot of blank spaces. there was also no way for me to send or receive anything through bluetooth through the serial interface, even through regular println