Problems uploading sketch to Arduino Nano 33 IOT

Hello everybody,

I just got the new Arduino Nano 33 IOT and wanted to know the new board.
Everything worked fine until I uploaded an internal timer interrupt. I found the timer interrupt code in an arduino forum. The sketch works but I cannot upload any other sketch using the Arduino IDE 1.8.8.

Here is the sketch I uploaded:

#include <Arduino_LSM6DS3.h>

unsigned long micro_alt;
unsigned long micro_neu;
unsigned long micro;
int counter = 0;

void setup() {
Serial.begin(230400);
while (!Serial);

if (!IMU.begin(416,416)) {
Serial.println(“Failed to initialize IMU!”);

while (1);
}

Serial.print(“Gyroscope sample rate = “);
Serial.print(IMU.gyroscopeSampleRate());
Serial.println(” Hz”);
Serial.println();
Serial.println(“Gyroscope in degrees/second”);
Serial.println(“X\tY\tZ”);

Serial.print(“Accelerometer sample rate = “);
Serial.print(IMU.accelerationSampleRate());
Serial.println(” Hz”);
Serial.println();
Serial.println(“Acceleration in G’s”);
Serial.println(“X\tY\tZ”);

setup_timer4(5, 1000);
}

void loop() {

}

//https://forum.arduino.cc/index.php?topic=597853.0
void setup_timer4(uint16_t clk_div_, uint8_t count_)
{
// Set up the generic clock (GCLK4) used to clock timers
REG_GCLK_GENDIV = GCLK_GENDIV_DIV(1) | // Divide the 48MHz clock source by divisor 1: 48MHz/1=48MHz
GCLK_GENDIV_ID(4); // Select Generic Clock (GCLK) 4
while (GCLK->STATUS.bit.SYNCBUSY); // Wait for synchronization

REG_GCLK_GENCTRL = GCLK_GENCTRL_IDC | // Set the duty cycle to 50/50 HIGH/LOW
GCLK_GENCTRL_GENEN | // Enable GCLK4
GCLK_GENCTRL_SRC_DFLL48M | // Set the 48MHz clock source
GCLK_GENCTRL_ID(4); // Select GCLK4
while (GCLK->STATUS.bit.SYNCBUSY); // Wait for synchronization

// Feed GCLK4 to TC4 and TC5
REG_GCLK_CLKCTRL = GCLK_CLKCTRL_CLKEN | // Enable GCLK4 to TC4 and TC5
GCLK_CLKCTRL_GEN_GCLK4 | // Select GCLK4
GCLK_CLKCTRL_ID_TC4_TC5; // Feed the GCLK4 to TC4 and TC5
while (GCLK->STATUS.bit.SYNCBUSY); // Wait for synchronization

REG_TC4_CTRLA |= TC_CTRLA_MODE_COUNT8; // Set the counter to 8-bit mode
while (TC4->COUNT8.STATUS.bit.SYNCBUSY); // Wait for synchronization

REG_TC4_COUNT8_CC0 = count_; // Set the TC4 CC0 register to some arbitary value
while (TC4->COUNT8.STATUS.bit.SYNCBUSY); // Wait for synchronization

NVIC_SetPriority(TC4_IRQn, 0); // Set the Nested Vector Interrupt Controller (NVIC) priority for TC4 to 0 (highest)
NVIC_EnableIRQ(TC4_IRQn); // Connect TC4 to Nested Vector Interrupt Controller (NVIC)

REG_TC4_INTFLAG |= TC_INTFLAG_OVF; // Clear the interrupt flags
REG_TC4_INTENSET = TC_INTENSET_OVF; // Enable TC4 interrupts

uint16_t prescale=0;
switch(clk_div_)
{
case 1: prescale=TC_CTRLA_PRESCALER(0); break;
case 2: prescale=TC_CTRLA_PRESCALER(1); break;
case 4: prescale=TC_CTRLA_PRESCALER(2); break;
case 8: prescale=TC_CTRLA_PRESCALER(3); break;
case 16: prescale=TC_CTRLA_PRESCALER(4); break;
case 64: prescale=TC_CTRLA_PRESCALER(5); break;
case 256: prescale=TC_CTRLA_PRESCALER(6); break;
case 1024: prescale=TC_CTRLA_PRESCALER(7); break;
}
REG_TC4_CTRLA |= prescale | TC_CTRLA_WAVEGEN_MFRQ | TC_CTRLA_ENABLE; // Enable TC4
while (TC4->COUNT8.STATUS.bit.SYNCBUSY); // Wait for synchronization
}
//----

uint16_t next_pow2(uint16_t v_)
{
// the next power-of-2 of the value (if v_ is pow-of-2 returns v_)
–v_;
v_|=v_>>1;
v_|=v_>>2;
v_|=v_>>4;
v_|=v_>>8;
return v_+1;
}
//----

uint16_t get_clk_div(uint32_t freq_)
{
float ideal_clk_div=48000000.0f/(256.0f*float(freq_));
uint16_t clk_div=next_pow2(uint16_t(ceil(ideal_clk_div)));
switch(clk_div)
{
case 32: clk_div=64; break;
case 128: clk_div=256; break;
case 512: clk_div=1024; break;
}
return clk_div;
}
//----

void setup_timer4(uint32_t freq_)
{
uint16_t clk_div=get_clk_div(freq_);
uint8_t clk_cnt=(48000000/clk_div)/freq_;
setup_timer4(clk_div, clk_cnt);
}
//---------------------------------------------------------------------------

void TC4_Handler()
{
if (TC4->COUNT16.INTFLAG.bit.OVF && TC4->COUNT16.INTENSET.bit.OVF)
{
float gx, gy, gz;
float ax, ay, az;
micro_neu = micros();
micro = (micro_neu - micro_alt);
micro_alt = micros();
counter++;
IMU.readGyroscope(gx, gy, gz);
IMU.readAcceleration(ax, ay, az);
Serial.print(micro);
Serial.print(’\t’);
Serial.println(counter);
Serial.print("Gyroskop: ");
Serial.print(gx);
Serial.print(’\t’);
Serial.print(gy);
Serial.print(’\t’);
Serial.println(gz);
Serial.print("Beschleunigung: ");
Serial.print(ax);
Serial.print(’\t’);
Serial.print(ay);
Serial.print(’\t’);
Serial.println(az);
REG_TC4_INTFLAG = TC_INTFLAG_OVF;
}
}

So who as any idea what I could do to solve the problem?

Here ist the Error Message:

Der Sketch verwendet 23412 Bytes (8%) des Programmspeicherplatzes. Das Maximum sind 262144 Bytes.
Erzwinge Reset durch öffnen/schließen mit 1200 bps auf dem Port COM21
PORTS {COM21, } / {COM21, } => {}
PORTS {COM21, } / {COM21, } => {}
PORTS {COM21, } / {COM21, } => {}
PORTS {COM21, } / {COM21, } => {}
PORTS {COM21, } / {COM21, } => {}
PORTS {COM21, } / {COM21, } => {}
PORTS {COM21, } / {COM21, } => {}
PORTS {COM21, } / {COM21, } => {}
PORTS {COM21, } / {COM21, } => {}
PORTS {COM21, } / {COM21, } => {}
PORTS {COM21, } / {COM21, } => {}
PORTS {COM21, } / {COM21, } => {}
PORTS {COM21, } / {COM21, } => {}
PORTS {COM21, } / {COM21, } => {}
PORTS {COM21, } / {COM21, } => {}
PORTS {COM21, } / {COM21, } => {}
PORTS {COM21, } / {COM21, } => {}
PORTS {COM21, } / {COM21, } => {}
PORTS {COM21, } / {COM21, } => {}
PORTS {COM21, } / {COM21, } => {}
Uploading using selected port: COM21
C:\Users\Robert\AppData\Local\Arduino15\packages\arduino\tools\bossac\1.7.0-arduino3/bossac.exe -i -d --port=COM21 -U true -i -e -w -v C:\Users\Robert\AppData\Local\Temp\arduino_build_47570/190807_Inbetriebnahme.ino.bin -R
Beim Hochladen des Sketches ist ein Fehler aufgetreten
processing.app.SerialException: Fehler beim Öffnen des seriellen Ports “COM21”.
at processing.app.Serial.(Serial.java:147)
at processing.app.Serial.(Serial.java:82)
at processing.app.SerialMonitor$4.(SerialMonitor.java:101)
at processing.app.SerialMonitor.open(SerialMonitor.java:101)
at processing.app.AbstractMonitor.resume(AbstractMonitor.java:104)
at processing.app.Editor.resumeOrCloseSerialMonitor(Editor.java:2098)
at processing.app.Editor.access$1400(Editor.java:113)
at processing.app.Editor$UploadHandler.run(Editor.java:2076)
at java.lang.Thread.run(Thread.java:748)
Caused by: jssc.SerialPortException: Port name - COM21; Method name - openPort(); Exception type - Port busy.
at jssc.SerialPort.openPort(SerialPort.java:164)
at processing.app.Serial.(Serial.java:136)
… 8 more
Fehler beim Öffnen des seriellen Ports “COM21”.

P.S. I changed the Arduino LSM6DS3 library a little to change the sample rate but the worked always perfectly fine.

The way uploads work is:

  • The Arduino IDE (or the upload tool used by the Arduino IDE) sends a signal for the microcontroller to reset.
  • The microcontroller resets.
  • The bootloader runs and waits (normally only for a short time) for an upload to start.
  • The upload tool sends the program to the microcontroller, where the bootloader writes it to flash memory.

On the boards with native USB (like the one you're using), the way the IDE signals the microcontroller to reset is by opening a serial connection at 1200 baud. There is some special code running in the background on the microcontroller that does the reset when it detects that 1200 baud connection.

In some cases, the reset code that's supposed to be on the microcontroller could be missing or not working correctly, which will mean the bootloader never runs and the upload fails with the error you're seeing. The fix is to manually reset the board.

Try this:

  • Press the reset button on your board quickly twice. You should now see the LED on the board pulsing, which means the bootloader is running. The double press causes the bootloader to run indefinitely (until the board is reset, powered off, or an upload is done), which means you don't need to get the timing of the reset just right.
  • Select the port of your board from the Tools > Port menu. The port will be different when the bootloader is running so don't assume you already have the correct port selected.
  • Start an upload in the Arduino IDE.

The upload should now finish successfully. After this, you should be able to go back to doing normal uploads without needing to press the reset button. If you still need to do the reset trick to do uploads after this, the problem may be caused by your code. You can verify this by uploading a simple sketch like File > Examples > 01.Basics > BareMinimum.

I don't have a specific explanation of why your code might break USB. Maybe someone else here will be able to provide that information. My recommendation would be for you to simplify the code down as far as you can while still breaking USB as that will narrow down the source of the problem.

robpo:
Hello everybody,

I just got the new Arduino Nano 33 IOT and wanted to know the new board.
Everything worked fine until I uploaded an internal timer interrupt. I found the timer interrupt code in an arduino forum. The sketch works but I cannot upload any other sketch using the Arduino IDE 1.8.8.

Here is the sketch I uploaded:
So who as any idea what I could do to solve the problem?

Here ist the Error Message:

P.S. I changed the Arduino LSM6DS3 library a little to change the sample rate but the worked always perfectly fine.

Dear robpo,

May I know how did you modify the Arduino LSM6DS3 library?

Can you get accelerometer sample rate greater than 416Hz?

I modify value of below line in LSM6DS3.cpp
writeRegister(LSM6DS3_CTRL1_XL, 0x4A)
Tried from 0x1A to 0xAA, and expect to get sample rate from 12.5Hz to 6664Hz.

I can get the accelerometer sample rate correctly for 12.5Hz, 26Hz, 52Hz, 104Hz, 208Hz, 416Hz

But I cannot get a higher sample rate, the maximum sample rate is about 500Hz.

Thanks

Ambrose