Connecting host software to DUE with SerialUSB

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.

Is there a real solution for this?

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.

Hi,

Can you share a sniped on how you force reset the board when opening the port?

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'm fairly new to Arduino and I have no idea what you are talking about.

This is PC work, not that much Arduino :wink:

I've tested the approach with a ProMicro and serial monitor under Windows

  1. Open serial monitor
  2. Change the baudrate
  3. Close serial monitor

I observed the behaviour in Windows device manager; before closing the serial monitor.
Before closing serial monitor

image
After closing serial monitor

image

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

  1. 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.
  2. 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++;
  }
}

Hi,

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");
}

By the way, the code above works when I use the programming port (replace SerialUSB with Serial) but when I use the native port it doesn't.

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.

But I found that what I described will more than likely not work. From https://www.arduino.cc/en/Guide/ArduinoDue

It erases your code :frowning:

That hurt.

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");
}

Go back to the basics.

const byte pinLed = LED_BUILTIN;

void setup()
{
  byte ledState = LOW;
  SerialUSB.begin(57600);
  pinMode(pinLed, OUTPUT);
  digitalWrite(pinLed, ledState);

  while (!SerialUSB)
  {
    ledState = !ledState;
    digitalWrite(pinLed, ledState);
    delay(200);
  }
  ledState = HIGH;
  digitalWrite(pinLed, ledState);
}

void loop()
{
}
  1. Make sure that no PC application uses the native usb port.
  2. Upload the sketch as you usually do (programming port?).
  3. You should see the led blink.
  4. Open a serial connection with the native port (serial monitor); don't use 1200 baud.
  5. 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.

Hi,
Yes, the LED blinks. It goes solid when I open the Serial Monitor.

However, this is the actual problem.

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