With SerialUSB Arduino doesn’t get reset when you open the port (on native port) on the PC side so the host PC software cannot connect the DUE.
However a trick allows the connection: First open the Serial Monitor in Arduino IDE then close it. Open the host software and it connects right away. But this is not a solution of course.
I'm absolutely not familiar with the Due. On boards like the Leonardo, Micro and SparkFun ProMicro you can force a reset by opening and closing the Serial port with a baudrate of 1200. So maybe the same applies to the native port of the Due.
Use a terminal program to test the principle. If that works, you can incorporate it in your host application or write a small application that you run before you run the host application (e.g. using a batch file or bash script).
I observed the behaviour in Windows device manager; before closing the serial monitor.
Before closing serial monitor
After closing serial monitor
A couple of seconds after closing the serial monitor, the boot loader will time outand you will have the normal functionality again.
As said, if that is working, you can go to the next step.
Notes
Serial Monitor is a terminal program. It's quite primitive but it has the advantage that it is controlled by the IDE which makes uploads easier.
You did not mention which OS you're using so I could not advise on another terminal program.
Instead of observing Windows device manager (if you use Windows), you can use a simple sketch that will tell you that the reset happened. Below sketch will flash a led a few times after a reset; on the Due you can probably use LED_BUILTIN instead of pin 17
int pinLed = 17; // The RX LED has a defined Arduino pin
void setup()
{
pinMode(pinLed, OUTPUT); // Set RX LED as an output
}
void loop()
{
static byte counter;
if (counter < 5)
{
digitalWrite(pinLed, LOW); // set the RX LED ON
delay(1500);
digitalWrite(pinLed, HIGH); // set the RX LED OFF
delay(500);
counter++;
}
}
The com port name doesn't change in my PC. It is always "USB Serial Device (COM9". Maybe because the DUE I have is a clone?
I start the LUA script with baud rate 1200 then this COM9 disappears and it becomes COM8. Something is clearly wrong.
I simplified my sketch but added your code. Is it how it suppose to be?
#include "Keyboard.h"
#include <CmdBuffer.hpp>
#include <CmdCallback.hpp>
#include <CmdParser.hpp>
CmdCallback<5> cmdCallback;
CmdBuffer<32> myBuffer;
CmdParser myParser;
int incomingByte = 0; // for incoming serial data
int pinLed = 17; // The RX LED has a defined Arduino pin
void setup() {
SerialUSB.begin(1200);
//while (!SerialUSB);
SerialUSB.println("Starting bridge...\n");
cmdCallback.addCmd("O", &fEcho);
myBuffer.setEcho(false);
pinMode(pinLed, OUTPUT); // Set RX LED as an output
}
void loop() {
static byte counter;
if (counter < 5)
{
digitalWrite(pinLed, LOW); // set the RX LED ON
delay(1500);
digitalWrite(pinLed, HIGH); // set the RX LED OFF
delay(500);
counter++;
}
cmdCallback.updateCmdProcessing(&myParser, &myBuffer, &SerialUSB);
}
void fEcho(CmdParser *myParser) {
//Comms check. An 'O' has been received, send 'K'
SerialUSB.println("K");
}
No idea what LUA is, sorry. I've heard the term but never had the need to research.
What you describe (change of com port) is the expected behaviour when you give your board a reset on the native USB port using the baudrate trick. You don't need anything special at the Due side.
OK the 1200 way doesn't work. It is really pointless adding a native port when there is no way to connect to it.
I can use the programming port but it appears the Keyboard library doesn't work on it. So I can't have both serial communication and Keyboard on the port. Really weird.
It is out of the topic but do you know a keyboard library that works on programming port?
Thanks for your help and time by the way. I'm appreciated.
Wait a second! SerialUSB on native port actually works because the LED blinks when the host connects to it. However SerialUSB.println("K"); fails to send "K".
void fEcho(CmdParser *myParser) {
//Comms check. An 'O' has been received, send 'K'
**SerialUSB.println("K");**
}
Problem is still there. Interestingly this code works in Serial Monitor but doesn't work with my host PC app however if I use the programming port and rename SerialUSB with Serial then it works. Host PC app connects perfectly.
PC app opens tries all serial ports and sends "O". When it sends the "O" to the COM port of the Arduino, the callback method gets called and it replies with a "K". Then the PC app receives the "K" and the connection is established. That's how they connect.
Problem is: the fEcho method gets called but Arduino fails to send a "K" with SerialUSB.println("K");
What I'm missing?
#include "Keyboard.h"
#include <CmdBuffer.hpp>
#include <CmdCallback.hpp>
#include <CmdParser.hpp>
CmdCallback<5> cmdCallback;
CmdBuffer<32> myBuffer;
CmdParser myParser;
int incomingByte = 0; // for incoming serial data
int pinLed = 13; // The RX LED has a defined Arduino pin
bool blinkLed = false;
void setup() {
uint32_t status;
status = (RSTC->RSTC_SR & RSTC_SR_RSTTYP_Msk) >> RSTC_SR_RSTTYP_Pos;
Serial.print("\nRSTTYP = 0b"); Serial.println(status, BIN); // Should be 0b011 after a software Reset see page 23
delay(100);
SerialUSB.begin(115200);
while (!SerialUSB);
Software_Reset();
pinMode(pinLed, OUTPUT); // Set RX LED as an output
//SerialUSB.println("Starting bridge...\n");
cmdCallback.addCmd("O", fEcho);
myBuffer.setEcho(false);
}
void Software_Reset() {
// this also doesn't work
const int RSTC_KEY = 0xA5;
RSTC->RSTC_CR = RSTC_CR_KEY(RSTC_KEY) | RSTC_CR_PROCRST | RSTC_CR_PERRST;
while (true);
}
void loop() {
cmdCallback.updateCmdProcessing(&myParser, &myBuffer, &SerialUSB);
static byte counter;
if (blinkLed) {
if (counter < 50)
{
digitalWrite(pinLed, LOW); // set the RX LED ON
delay(200);
digitalWrite(pinLed, HIGH); // set the RX LED OFF
delay(200);
counter++;
}
}
}
void SerialInit() {
SerialUSB.begin(115200);
while (!SerialUSB);
}
void SerialPortReset(void)
{
// no lock here as well
SerialUSB.flush();
SerialUSB.end();
otg_disable(); // Disable the hardware
delay(10);
otg_enable(); // Enable the hardware
USBDevice.attach(); // Inits the USB serial port
SerialInit(); // My serial port initialization code
}
void fEcho(CmdParser *myParser) {
//Comms check. An 'O' has been received, send 'K'
blinkLed = true;
//This line fails
SerialUSB.println("K");
}
Make sure that no PC application uses the native usb port.
Upload the sketch as you usually do (programming port?).
You should see the led blink.
Open a serial connection with the native port (serial monitor); don't use 1200 baud.
The led should go solid on indicating that a connection was established.
Describe the behaviour that you observe.
Note:
There is a dedicated section for the Due; maybe you have a better chance there as this seems Due specific. You can move your topic by clicking the big fat pencil next to the topic title, selecting the correct category from the dropdown and next clicking the green button.