Bootloader/com issue?

Hello!

I am currently dealing with some type of USB issue on my Nano 33 IoT . My PC does not recognize my Arduino when I plug it in, It was working earlier today and I don't understand why it would suddenly stop. It started when I was uploading some test code and I got this error.

"Couldn't find a Board on the selected port. Check that you have the correct port selected. If it is correct, try pressing the board's reset button after initiating the upload."

I was confused as I had not changed the com port or unplugged anything. When I tried to change/fix the selected port it appeared grayed out. I was able to get the Arduino to recognize on my pc by putting it into bootloader mode ( double-clicking the reset button) ,when I do this the port selection becomes usable and code can be uploaded but when the serial monitior is used the arduino disconnects and windows dosent identify the arduino(all it does is make window able to identify it).

to summarize The arduino is not recognized by windows unless I double tap the reset button as discribed by this artical although I am using a nano not an Arduino Edge https://support.arduino.cc/hc/en-us/articles/360021532700-How-to-set-the-Edge-Control-to-bootloader-mode, as using the bootloader mode does not allow normal operations I need to be able to select a port when not in bootloader mode.(atleast I think thats the root of the problem)

Thanks for any help.

Does the problem also happen after you upload a simple sketch like blink?

I can upload simple example sketches like the blink. although it uploads via a com4 even though its plugged in via com3

The tricky thing about the boards with native USB capability like your Nano 33 IoT is that the USB code that creates the CDC serial port is running on the same microcontroller as your sketch. This means your sketch code can break the USB code, or stop it from running. When that happens, it no longer presents a port.

This can be unexpected to those who previously mainly worked with the boards like Uno and Mega with a dedicated USB chip that can never be affected by the sketch code.

As you discovered, the board can easily be recovered from this state by putting it in bootloader mode, but if you then upload the problematic sketch once again, you will get the same result.

So the next step is to study your code to find the cause. In some cases, that might even be the expected result. For example, it is normal and expected for the board to not have a port if your code puts the microcontroller to sleep to save power. In other cases, it might be a bug in the code that causes the problem.

The first thing I would do is to start to remove parts of the sketch, uploading each time to check whether the problem still occurs. When you reach the state where the problem no longer occurs, you will know that the last code you removed was the cause. That should allow you to produce a minimal demonstration sketch that will make the problem clear.

You can post the code here on the forum and it is likely the helpers will be able to explain the reason why it breaks the USB.

@in0, I did consider that but it's my understanding that the problem persists after loading blink.

You are right to question that assumption I made @sterretje. I see now that I read too much into this comment:

@fred_d please tell us whether the "My PC does not recognize my Arduino" problem still occurs while the Arduino board is running the "Blink" sketch.

No, actually after I upload the blink sketch It functions normally until I uploaded the test program.

here is the test and the functions are included

#include "Wire.h"
#include <MPU6050_tockn.h>
#include <Servo.h>
#include "DFRobot_BMP280.h"
#include <SPI.h>
#include <SD.h>
#include <PID_v2.h>


#define SEA_LEVEL_PRESSURE    1015.0f
void Pad_State_SetupF();
void MPU_dataF();
void Loop_PIDX_F();
void Loop_PIDY_F();
void PID_setup_xF();
void PID_setup_yF();
void BMP_setup_F();
void BMP_loop_F();
String angX_SD;
String angY_SD;
String SD_alt;
float mpuY=0.0;
float mpuX=0.0;
typedef DFRobot_BMP280_IIC    BMP;
const int chipSelect = 10;
BMP   bmp(&Wire, BMP::eSdoLow);
Servo Xserv;
Servo Yserv;
Servo Pserv;
unsigned long timer = 0;
MPU6050 mpu6050(Wire);
double XKp = .2, XKi = .5, XKd = 1;
PID_v2 XPID(XKp, XKi, XKd, PID::Direct);
double YKp = .2, YKi = .5, YKd = 1;
PID_v2 YPID(YKp, YKi, YKd, PID::Direct);



float   temp = bmp.getTemperature();
uint32_t    press = bmp.getPressure();
float   alti = bmp.calAltitude(SEA_LEVEL_PRESSURE, press);


void printLastOperateStatus(BMP::eStatus_t eStatus)
{
  switch(eStatus) {
  case BMP::eStatusOK:    Serial.println("everything ok"); break;
  case BMP::eStatusErr:   Serial.println("unknow error"); break;
  case BMP::eStatusErrDeviceNotDetected:    Serial.println("device not detected"); break;
  case BMP::eStatusErrParameter:    Serial.println("parameter error"); break;
  default: Serial.println("unknow status"); break;
  }
}

void setup() {
  PID_setup_xF();
  PID_setup_yF();
  Pad_State_SetupF();
  BMP_setup_F();
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }


  Serial.print("Initializing SD card...");

  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    while (1);
  }
  Serial.println("card initialized.");
 }


void loop() {
  Loop_PIDX_F();
  Loop_PIDY_F();
  BMP_loop_F();
  MPU_dataF();
 


  if(timer>=30000){
  Pserv.write(90);
  }
  
  Serial.println(timer);

  String dataString = "";

  File dataFile2 = SD.open("datalog2.txt", FILE_WRITE);

    //if the file is available, write to it:
  if (dataFile2) {
    dataFile2.println(" angX");
    dataFile2.print(angX_SD);
    dataFile2.println(" angY");
    dataFile2.print(angY_SD);
    dataFile2.print(alti);
    dataFile2.close();
    //print to the serial port too:
    Serial.println(dataString);
  }
  //if the file isn't open, pop up an error:
  else {
    Serial.println("error opening datalog.txt");
  }
}

void BMP_loop_F () {
   {
   float   temp = bmp.getTemperature();
   uint32_t    press = bmp.getPressure();
   float   alti = bmp.calAltitude(SEA_LEVEL_PRESSURE, press);

   Serial.println();
   Serial.println("======== start print ========");
   Serial.print("temperature (unit Celsius): "); Serial.println(temp);
   Serial.print("pressure (unit pa):         "); Serial.println(press);
   Serial.print("altitude (unit meter):      "); Serial.println(alti);
   Serial.println("========  end print  ========");

   SD_alt = alti;

 }
}

void BMP_setup_F() {
 {
   Serial.begin(115200);
   bmp.reset();
   Serial.println("bmp read data test");
   while(bmp.begin() != BMP::eStatusOK) {
     Serial.println("bmp begin faild");
     printLastOperateStatus(bmp.lastOperateStatus);
     delay(2000);
   }
   Serial.println("bmp begin success");
   delay(100);
 }
}

void Loop_PIDX_F() {
  const double Xinput = mpu6050.getAngleX();
  const double Xoutput = XPID.Run(Xinput);        
  Xserv.write(Xoutput); 

  angX_SD = mpu6050.getAngleX();
  String(angX_SD);
}

void Loop_PIDY_F() {
  const double Yinput = mpu6050.getAngleY();
  const double Youtput = YPID.Run(Yinput);       
  Yserv.write(Youtput); 

  angY_SD = mpu6050.getAngleY();
  String(angY_SD);
}

  void MPU_dataF() {
  mpu6050.update();
  Serial.print("angleX : ");
  Serial.print(mpu6050.getAngleX());
  Serial.print("\tangleY : ");
  Serial.print(mpu6050.getAngleY());
  Serial.print("\tangleZ : ");
  Serial.println(mpu6050.getAngleZ());
}

void PID_setup_xF() {
Xserv.attach(8);
Xserv.write (90);
  XPID.Start(mpu6050.getAngleX(),  // input
              90,                      // current output
              2.8);                   // setpoint     
}

void PID_setup_yF() {
Yserv.attach(7);
Yserv.write (90);
  YPID.Start(mpu6050.getAngleY(),  // input
              90,                      // current output
              0);                   // setpoint   
}

void Pad_State_SetupF() {
  Pserv.attach(6);
  Pserv.write(0);
  
  Serial.begin(9600);
  Wire.begin();
  mpu6050.begin();
  mpu6050.calcGyroOffsets(true);

  angY_SD = mpu6050.getAngleY();
  
}

OK, so my explanation in post #4 is applicable.

Please tell us where you got the libraries for these files:

  • MPU6050_tockn.h
  • DFRobot_BMP280.h
  • PID_v2.h

(I'm assuming Servo.h and SD.h are from the official Arduino libraries).

If you installed it using the Arduino Library Manager (Sketch > Include Library > Manage Libraries in the Arduino IDE or Libraries > Library Manager in the Arduino Web Editor) then say so and state the full name of the library.

If you downloaded it from a website, then please post a link to that website.

They are all from the manage libraries drop down in the IDE.

all the GitHub links are listed below

1.) GitHub - tockn/MPU6050_tockn: Arduino library for easy communication with MPU6050
2.) GitHub - DFRobot/DFRobot_BMP280
3.) ttps://github.com/imax9000/Arduino-PID-Library

Here is the problem:

Minimal sketch that demonstrates the bug:

#include <DFRobot_BMP280.h>
DFRobot_BMP280_IIC bmp(&Wire, DFRobot_BMP280_IIC::eSdoLow);
float temp = bmp.getTemperature();
void setup() {}
void loop() {}

You should not make these calls from outside of a function. I see that you are not even using these variables at all (you have local variables shadowing them). So you can simply delete the lines I quoted above to fix the bug.