Faster way to print data over USB on Nano 33 BLE Sense

I set up a test (similar to the one from my previous question) to time how long a basic Serial.println("HELLO WORLD") takes on the Arduino Nano 33 BLE Sense; 160.2 us...

#include "mbed.h"
#include "nrf_delay.h"
#include "nrf_gpio.h"

#define OUTPUT_PIN NRF_GPIO_PIN_MAP(1,11)

uint32_t startClock;
uint32_t stopClock;
uint32_t arithmeticMinuend = 4294967295;
uint32_t arithmeticSubtrahend = 2147483648;
uint32_t arithmeticDifference = 0;
uint32_t timeDifference1 = 0;
uint32_t timeDifference2 = 0;

void setup() {
  delay(1000);
  Serial.begin(115200);
  delay(1000);
  while (!Serial);
  delay(1000);

  nrf_gpio_cfg_output(OUTPUT_PIN);
  us_ticker_init();
  startClock = us_ticker_read();
  stopClock = us_ticker_read();
}

void loop() {
  Serial.println("Starting program:");
  timeDifference1 = microsecondsToSubtract2LongsOnce();
  timeDifference2 = microsecondsToSubtract2LongsAndPrint();
  us_ticker_free();
  Serial.print("timeDifference1 = ");
  Serial.print(timeDifference1);
  Serial.print(" us.\ntimeDifference2 = ");
  Serial.print(timeDifference2);
  Serial.println(" us.");

  us_ticker_init();
  microsecondsToSubtract2LongsOnceMeasuredWithScope();
  us_ticker_free();
  delay(10);
  us_ticker_init();
  microsecondsToSubtract2LongsTwiceMeasuredWithScope();
  us_ticker_free();
  delay(10);
  us_ticker_init();
  microsecondsToToggleOutputPinMeasuredWithScope();
  us_ticker_free();
  
  while(1) {
    
  }
}

//Prints 0-1 us:
uint32_t microsecondsToSubtract2LongsOnce() {
  startClock = us_ticker_read();
  stopClock = us_ticker_read();
  return stopClock - startClock;
}

//Prints 214-348 us:
uint32_t microsecondsToSubtract2LongsAndPrint() {
  startClock = us_ticker_read();
  Serial.println("HELLO WORLD1");
  stopClock = us_ticker_read();
  return stopClock - startClock;
}

//Measured 1.8 us on scope:
void microsecondsToSubtract2LongsOnceMeasuredWithScope() {
  nrf_gpio_pin_toggle(OUTPUT_PIN);
  startClock = us_ticker_read();
  stopClock = us_ticker_read();
  nrf_gpio_pin_toggle(OUTPUT_PIN);
}

//Measured 162 us on scope:
void microsecondsToSubtract2LongsTwiceMeasuredWithScope() {
  nrf_gpio_pin_toggle(OUTPUT_PIN);
  startClock = us_ticker_read();
  Serial.println("HELLO WORLD2");
  stopClock = us_ticker_read();
  nrf_gpio_pin_toggle(OUTPUT_PIN);
}

//Measured 500 ns on scope:
void microsecondsToToggleOutputPinMeasuredWithScope() {
  nrf_gpio_pin_toggle(OUTPUT_PIN);
  nrf_gpio_pin_toggle(OUTPUT_PIN);
}

I understand that the NRF52840 has native USB so maybe this could be exploited directly to get faster print times?

:cry: It takes 85 us just to write a single byte over USB:

#include "mbed.h"
#include "nrf_delay.h"
#include "nrf_gpio.h"

#define OUTPUT_PIN NRF_GPIO_PIN_MAP(1,11)

const byte PRINT_BYTE = 254;

uint32_t startClock;
uint32_t stopClock;
uint32_t arithmeticMinuend = 4294967295;
uint32_t arithmeticSubtrahend = 2147483648;
uint32_t arithmeticDifference = 0;
uint32_t timeDifference1 = 0;
uint32_t timeDifference2 = 0;

void setup() {
  delay(1000);
  Serial.begin(115200);
  delay(1000);
  while (!Serial);
  delay(1000);

  nrf_gpio_cfg_output(OUTPUT_PIN);
  us_ticker_init();
  startClock = us_ticker_read();
  stopClock = us_ticker_read();
}

void loop() {
  Serial.println("Starting program:");
  timeDifference1 = microsecondsToSubtract2LongsOnce();
  timeDifference2 = microsecondsToSubtract2LongsAndPrint();
  us_ticker_free();
  Serial.print("timeDifference1 = ");
  Serial.print(timeDifference1);
  Serial.print(" us.\ntimeDifference2 = ");
  Serial.print(timeDifference2);
  Serial.println(" us.");

  us_ticker_init();
  microsecondsToSubtract2LongsOnceMeasuredWithScope();
  us_ticker_free();
  delay(10);
  us_ticker_init();
  microsecondsToSubtract2LongsTwiceMeasuredWithScope();
  us_ticker_free();
  delay(10);
  us_ticker_init();
  microsecondsToToggleOutputPinMeasuredWithScope();
  us_ticker_free();
  
  while(1) {
    
  }
}

//Prints 0-1 us:
uint32_t microsecondsToSubtract2LongsOnce() {
  startClock = us_ticker_read();
  stopClock = us_ticker_read();
  return stopClock - startClock;
}

//Prints 406 us:
uint32_t microsecondsToSubtract2LongsAndPrint() {
  startClock = us_ticker_read();
  Serial.write(PRINT_BYTE);
  stopClock = us_ticker_read();
  return stopClock - startClock;
}

//Measured 1.8 us on scope:
void microsecondsToSubtract2LongsOnceMeasuredWithScope() {
  nrf_gpio_pin_toggle(OUTPUT_PIN);
  startClock = us_ticker_read();
  stopClock = us_ticker_read();
  nrf_gpio_pin_toggle(OUTPUT_PIN);
}

//Measured 85 us on scope:
void microsecondsToSubtract2LongsTwiceMeasuredWithScope() {
  nrf_gpio_pin_toggle(OUTPUT_PIN);
  startClock = us_ticker_read();
  Serial.write(PRINT_BYTE);
  stopClock = us_ticker_read();
  nrf_gpio_pin_toggle(OUTPUT_PIN);
}

//Measured 500 ns on scope:
void microsecondsToToggleOutputPinMeasuredWithScope() {
  nrf_gpio_pin_toggle(OUTPUT_PIN);
  nrf_gpio_pin_toggle(OUTPUT_PIN);
}

did you try higher baud rate?

I read that baud rate setting doesn’t even do anything on the Arduino Nano 33 or Portenta H7 boards because their Arm based MCUs have native usb which is functioning as virtual com…

I can try lower baud rate setting and see if it is slower.

What I want is a more direct way to achieve the print though. Like using mbed os code or NRF SDK code.