Board Keeps loosing Com port after upload

I have had my MKR 1010 Wifi for about 2 years and its been great, displaying and controlling the temperature of my water thermal store and transferring the heat to our swimming pool on demand locally and via web interface.

However; last week I wanted to upload a small script to check some sensors before returning it to its “day job”. I connected up the usb in the usual way and pressed “upload and save”; things have never worked very well since; connectivity to a com port is almost 100% unreliable - never seen this situation before.

If i double click the reset button, putting the board into bootloader mode windows (10) reliably detects the coms port (often port 5) and I can upload “blink”, the board then resets and windows sees it on port 3 and the sketch runs. If re upload “blink” when connected to port 3, the upload works just fine.

If i set the board into bootloader mode and try to upload my original sketch that has been running all last year the process starts - lots of compiling - the upload starts and then nothing the board disappears from the com port and the compiler just sits @ busy…

I then have to reset the board and restart the editor to connect to the board which at this point can only be seen on bootloader mode; upload “blink” again to get the board working.

With Blink running and windows seeing the board on com 3, i try to upload my original sketch - the editor suggests the upload is successful, but the board does not function and windows cannot see any connected com ports.

I have trawled the forums and google for guidance. I found many articles suggesting the MKR 1010 is known for com port problems and one even suggested my script could be affecting the com port code…?

I would really appreciate some help here - is the board knackered, although it appear fine with a simple sketch?

this topic forum link discusses this problem, but does not suggest how to identify what may be wrong in the sketch, or how to fix it.

So, your board is fine, and it is almost certainly an issue with your code.

As the post says, the USB communication is handled by the processor that handles your sketch as well. If you keep the processor busy it has no time to handle USB communication. Since you and I do not know exactly how the USB stack works here are a few general things that might help.

  • do not use delay() it just wastes processor cycles an stops other parts of your software from running

  • make sure loop runs as often as possible, when you leave loop other parts of the software could run before loop is called again

  • some libraries have functions that cost a lot of time because they need to communicate with external hardware, try to identify these and limit how often you call them if possible.

If you post your code, I might be able to find something more specific.

Klaus_K
I use delay twice - once after initialising the serial communication (as normally recommended in examples) and once at the end of the loop to slow the process down.

code below for your consideration; and just to recall; when in development this code was uploaded multiple times (without having to set bootloader first) and never lost the com port in the past. It, all last year, ran on the board 24/7 good as gold - but this year as described is now problematic.
Thanks in advance, skodauk

/*
  Sketch generated by the Arduino IoT Cloud Thing "Pool-Controller"
  https://create.arduino.cc/cloud/things/58fe1b9b-d2fb-4afa-9a06-9539ab4f6581

  Arduino IoT Cloud Properties description

  The following variables are automatically generated and updated when changes are made to the Thing

  float TankTopTemp;
  float SolarTemp;
  float PoolTemp;
  float TankBottomTemp;
  String SystemData;

  Properties which are marked as READ/WRITE in the Cloud Thing will also have functions
  which are called when their values are changed from the Dashboard.
  These functions are generated with the Thing and added at the end of this sketch.
*/

// Dallas temperature comntroller
// Include the libraries we need
// web connection
#include "thingProperties.h"

#include <OneWire.h>
#include <DallasTemperature.h>
/********************************************************************/
// Data wire is plugged into pin 2 on the Arduino
#define ONE_WIRE_BUS 2
/********************************************************************/
// Setup a oneWire instance to communicate with any OneWire devices
// (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
/********************************************************************/
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
/********************************************************************/

// Include Wire Library for I2C
#include <Wire.h>
// Include NewLiquidCrystal Library for I2C
#include <LiquidCrystal_I2C.h>

// Define LCD pinout
const int  en = 2, rw = 1, rs = 0, d4 = 4, d5 = 5, d6 = 6, d7 = 7, bl = 3;

// Define I2C Address - change if reqiuired
const int i2c_addr = 0x27;

LiquidCrystal_I2C lcd(i2c_addr, en, rw, rs, d4, d5, d6, d7, bl, POSITIVE);

#include <Adafruit_SleepyDog.h>

// set initial values
// Addresses of 3 DS18B20s
uint8_t sensorPoolTemp[8] = { 0x28, 0xAA, 0x6F, 0x3F, 0x48, 0x14, 0x01, 0xBC }; //0x0
uint8_t sensorTankBottomTemp[8] = { 0x28, 0xFF, 0xC1, 0x54, 0x90, 0x16, 0x05, 0x20 }; //0xx
uint8_t sensorTankTopTemp[8] = { 0x28, 0xFF, 0xD7, 0x29, 0xA4, 0x15, 0x03, 0x3D }; //xxO
uint8_t sensorSolarTemp[8] = { 0x28, 0xFF, 0x61, 0xCC, 0x6D, 0x18, 0x01, 0xCE }; //x00

// starting points for differential values
int SETSolarONDiff = 9;
int SETSolarOFFDiff = 6;
int SETPoolONDiff = 10;
int SETPoolOFFDiff = 6;

String Status_HeatTank = "";
String Status_HeatPool = "";
String Condition = "";
String Setup = "";

float Actual_Solar_Diff = 0.0; // SolarTemp - TankBottomTemp
float Actual_Pool_Diff = 0.0;  // TankTopTemp - PoolTemp

bool SolarPump = false;
bool PoolPump = false;
bool HeatPool = false;

//bool SolarWarning = false;
//bool PoolWarning = false;

int reading;           // the current reading from the input pin

String DataPars = "";
String Data = "";

//board pin conditions
const int PoolPumpPin = 6; // pool pump relay connected to pin 6
const int SolarPumpPin = 7; // solar pump relay connected to pin 7
const int inPin = 3;         // the number of the input pin

void setup() {
  // Initialize serial and wait for port to open:
  Serial.begin(9600);
  // This delay gives the chance to wait for a Serial Monitor without blocking if none is found
  delay(2000);

  // Set display type as 16 char, 2 rows
  lcd.begin(20, 4);

  // Defined in thingProperties.h
  initProperties();

  // Connect to Arduino IoT Cloud
  ArduinoCloud.begin(ArduinoIoTPreferredConnection);

  /*
     The following function allows you to obtain more information
     related to the state of network and IoT Cloud connection and errors
     the higher number the more granular information you’ll get.
     The default is 0 (only errors).
     Maximum is 4
  */
  setDebugMessageLevel(2);
  ArduinoCloud.printDebugInfo();

  // Start up the temperature sensors library
  sensors.begin();

  // Pin for relay module set as output
  pinMode(PoolPumpPin, OUTPUT);
  pinMode(SolarPumpPin, OUTPUT);
  pinMode(inPin, INPUT);

  sensors.setResolution(sensorSolarTemp, 11);
  sensors.setResolution(sensorTankBottomTemp, 11);
  sensors.setResolution(sensorTankTopTemp, 11);
  sensors.setResolution(sensorPoolTemp, 11);

  SystemData = "HPF";

  // set the watchdog timer to approx 10sec
  Watchdog.enable(20000);

}


void loop() {
  Watchdog.reset();

  if (WiFi.status() != WL_CONNECTED) {
    Serial.println("wifi not connected");
  }
  ArduinoCloud.update();
  Watchdog.reset();

  // Get temperatures from all sensors
  gettemperatures();

  // Calculate the Temperarture Differentials
  calculateTempDiffs();

  // check switch
  checkswitch();
  //Serial.println("reading");
  //Serial.println(reading);

  // Set Solar Pump
  setpumps();

  // Output System Condition
  updatelcd();

  Serial.println("System Data");
  Serial.println(SystemData);

  delay(2000);

}

void checkswitch() {
  // read the state of the pushbutton value:
  reading = digitalRead(inPin);

  // check if the switch in on, the pin state will be HIGH when on
  if (reading == HIGH) {
    HeatPool = true;
  } else {
    HeatPool = false;
  }
}

void gettemperatures() {
  sensors.requestTemperatures();

  SolarTemp = sensors.getTempC(sensorSolarTemp);
  if (SolarTemp == -127.0) {
    SolarTemp = -50.0;
  }
  TankBottomTemp = sensors.getTempC(sensorTankBottomTemp);
  if (TankBottomTemp == -127.0) {
    TankBottomTemp = -50.0;
  }
  TankTopTemp = sensors.getTempC(sensorTankTopTemp);
  if (TankTopTemp == -127.0) {
    TankTopTemp = -50.0;
  }
  PoolTemp = sensors.getTempC(sensorPoolTemp);
  if (PoolTemp == -127.0) {
    PoolTemp = -50.0;
  }
}

void setpumps() {

  // while the HeatPool Status is set to ON perform the following:
  if (HeatPool == true) {
    if (Actual_Pool_Diff > SETPoolONDiff) {
      PoolPump = true;
      digitalWrite(PoolPumpPin, HIGH);
    }
    if (Actual_Pool_Diff < SETPoolOFFDiff) {
      PoolPump = false;
      digitalWrite(PoolPumpPin, LOW);
    }
  } else {
    PoolPump = false;
    digitalWrite(PoolPumpPin, LOW);
  }

  // switch solar pump based on temperatures and user settings
  if (Actual_Solar_Diff > SETSolarONDiff) {
    SolarPump = true;
    digitalWrite(SolarPumpPin, HIGH);
  }
  if (Actual_Solar_Diff < SETSolarOFFDiff) {
    SolarPump = false;
    digitalWrite(SolarPumpPin, LOW);
  }
}

void updatelcd() {
  lcd.clear();
  // first line...................................
  lcd.setCursor(0, 0);
  lcd.print("S:");
  lcd.setCursor(2, 0);
  lcd.print(SolarTemp, 1);
  lcd.setCursor(7, 0);
  lcd.print("T:");
  lcd.setCursor(9, 0);
  lcd.print(TankBottomTemp, 1);
  lcd.setCursor(14, 0);
  lcd.print("D");
  lcd.setCursor(15, 0);
  lcd.print(Actual_Solar_Diff, 1);

  // third line...................................
  lcd.setCursor(0, 2);
  lcd.print("T:");
  lcd.setCursor(2, 2);
  lcd.print(TankTopTemp, 1);
  lcd.setCursor(7, 2);
  lcd.print("P:");
  lcd.setCursor(9, 2);
  lcd.print(PoolTemp, 1);
  lcd.setCursor(14, 2);
  lcd.print("D");
  lcd.setCursor(15, 2);
  lcd.print(Actual_Pool_Diff, 1);

  // second line..................................
  lcd.setCursor(0, 1);
  if (SolarPump == true) {
    lcd.print("SPump:ON");
  } else {
    lcd.print("SPump:OFF");
  }
  lcd.setCursor(10, 1);
  lcd.print(">");
  lcd.setCursor(11, 1);
  lcd.print(SETSolarONDiff);
  lcd.setCursor(14, 1);
  lcd.print("<");
  lcd.setCursor(15, 1);
  lcd.print(SETSolarOFFDiff);
  lcd.setCursor(19, 1);

  if (WiFi.status() != WL_CONNECTED) {
    lcd.print("0");
  } else {
    lcd.print("Y");
  }

  // forth line ..................................
  lcd.setCursor(0, 3);
  if (PoolPump == true) {
    lcd.print("PPump:ON");
  } else {
    lcd.print("PPump:OFF");
  }
  lcd.setCursor(10, 3);
  lcd.print(">");
  lcd.setCursor(11, 3);
  lcd.print(SETPoolONDiff, 1);
  lcd.setCursor(14, 3);
  lcd.print("<");
  lcd.setCursor(15, 3);
  lcd.print(SETPoolOFFDiff, 1);
  lcd.setCursor(18, 3);
  if (HeatPool == true) {
    lcd.print(">>");
  } else {
    lcd.print("XX");
  }
}

void calculateTempDiffs() {
  Actual_Solar_Diff = SolarTemp - TankBottomTemp;
  Actual_Pool_Diff = TankTopTemp - PoolTemp;
}

void onSystemDataChange() {
  DataPars = SystemData.substring(0, 3);

  if (DataPars == "SDO") {
    SETSolarONDiff = SystemData.substring(3, 5).toInt();
  }
  if (DataPars == "SDF") {
    SETSolarOFFDiff = SystemData.substring(3, 5).toInt();
  }
  if (DataPars == "PDO") {
    SETPoolONDiff = SystemData.substring(3, 5).toInt();
  }
  if (DataPars == "PDF") {
    SETPoolOFFDiff = SystemData.substring(3, 5).toInt();
  }
  if (DataPars == "HPO") {
    HeatPool = true;
  }
  if (DataPars == "HPF") {
    HeatPool = false;
  }
  if (DataPars == "WDF") {
    Watchdog.disable();
  }

  // clear Data
  Data = "";

  //build return string
  if (SolarPump == true) {
    Data = "Solar Pump:On";
  } else {
    Data = "Solar Pump:Off";
    " Pool Pump:" + PoolPump;
  }

  if (PoolPump == true) {
    Data = Data + " Pool Pump:On";
  } else {
    Data = Data + " Pool Pump:Off";
  }

  if (HeatPool == true) {
    Data = Data + " Heat Pool = Yes";
  } else {
    Data = Data + " Heat Pool = No";
  }

  Data = Data + " Solar On Diff:" + SETSolarONDiff;
  Data = Data + " Solar Off Diff:" + SETSolarOFFDiff;
  Data = Data + " Pool On Diff:" + SETPoolONDiff;
  Data = Data + " Pool Off Diff:" + SETSolarOFFDiff;
  SystemData = Data;
}

I’ve had similar com-port problems with MKR WiFi 1010 when uploading from Windows in a virtual machine in VMware. Could it be the case in your setup?

What should I be looking for that may be wrong in the setup?

  • Bootloader mode always displays the com port.
  • The Board connects (Bootloader or run time) and works with simple sketches like blink.
  • The Board looses com port connectivity with anything more complicated.
  • The board does not run the complicated sketch, assumedly as the upload did not complete?

The above code has been running successfully for about 12 months just fine, until now.

Update
I have found another post Com port issues that describes the very same problem and explains how the bootloader can be used.

What I cant find is any post that details how I can work out which part of my code may have started to inhibit the correct function or have broken the USB code.

Hello,

I had the same COM port problem. OneWire.h on Nano IoT using the Web IDE.

Code ran fine for the past few weeks/months, but suddenly decided not to work abouts 2 weeks ago (using the web IDE).

Problem was in the sketch, specifically the OneWire.h library that was causing the upload issues regarding the COM ports.

My solution:

  • Instead of using the built-in onewire.h available on the web IDE, I’d downloaded the library and reuploaded it to the web IDE as a zipped file instead.
  • Since the web IDE prioritizes uploaded libraries by the user, it will select the one you’d uploaded instead of the built in ones.

Once that’s done, the code should compile and upload with no problemo!

good luck man

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