MKR 1500 NB crashing when not connected to the USB Port of my PC

I am having an issue where - When my MKR 1500 NB is connected to my PC the code runs perfectly, when disconnected from my PC the code runs for a small while then crashes.

The controller controls lights via DMX using the Arduinodmx library.

I have seen many posts with people that have had similar issues and the advice is often to check the power supply.

I don't believe this to be my problem for a few reasons.

But mainly because if I sever the two data lines of the USB and leave the USB connected to the PC the issue remains, so I would think that supplying the MKR with the additional power supply is not helping, but the actual connection to the Serial is stopping the issue from revealing itself.

I don't think the schematic is relevant as the issue is still present even when nothing is connected to the MKR except the USB cable with the two data lines severed.

I have had many many iterations of this code trying to solve what I originally thought was a memory overflow issue, but here is my current code below...

Can I give tips to whoever solves this? I am at my wits end!!

#include "arduino_secrets.h"
/* 
  Sketch generated by the Arduino IoT Cloud Thing "Untitled"
  https://create.arduino.cc/cloud/things/8ea158c5-d0be-4d41-9050-66ef8f808e54 

  Arduino IoT Cloud Variables description

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

  float current;
  int colour;
  CloudSchedule hbSched;
  CloudSchedule onTime;
  bool heartbeat;
  bool power;

  Variables 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.
*/
// ArduinoRS485 - Version: Latest
#include <ArduinoRS485.h>

// ArduinoDMX - Version: Latest
#include <ArduinoDMX.h>

#include "thingProperties.h"

#include <MemoryFree.h>;
#include <pgmStrToRAM.h>;  // not needed for new way. but good to have for reference.



#define ch1 1
#define ch2 2
#define ch3 3
#define ch4 4

const int hbPin = 8;
const int statusB = 3;
const int currentPin = A0;
const int testPin = 6;

const int universeSize = 4;

unsigned long lastToggleTime = 0;
bool statusBState = false;

int counter = 0;
int resetCounter = 0;
unsigned long totalCurrent = 0;


void setup() {

  //Serial.begin(9600);
  //delay(1500);
  initProperties();

  ArduinoCloud.begin(ArduinoIoTPreferredConnection);

  pinMode(hbPin, OUTPUT);
  pinMode(statusB, OUTPUT);
  pinMode(currentPin, INPUT);

  DMX.begin(universeSize);
}

void loop() {
  ArduinoCloud.update();
  //Serial.println(freeMemory());
  dmxLoop();
  checkHeartbeat();
  toggleStatusB();
  currentLoop();
  //Serial.println(colour);
  //Serial.println(heartbeat);
  //Serial.println(current);
  //Serial.println(counter);
  //Serial.println(totalCurrent);
}

void dmxLoop() {

  ArduinoCloud.update();

  DMX.beginTransmission();

  if (onTime.isActive()) {

    power = true;

    switch (colour) {

      case 1:  //Static Red

        DMX.write(ch1, 255);
        DMX.write(ch2, 255);
        DMX.write(ch3, 255);
        DMX.write(ch4, 108);

        break;

      case 2:  //Static Green

        DMX.write(ch1, 255);
        DMX.write(ch2, 255);
        DMX.write(ch3, 255);
        DMX.write(ch4, 0);

        break;

      case 3:  //Static Yellow

        DMX.write(ch1, 255);
        DMX.write(ch2, 255);
        DMX.write(ch3, 108);
        DMX.write(ch4, 255);

        break;

      case 4:  //Static Blue

        DMX.write(ch1, 255);
        DMX.write(ch2, 255);
        DMX.write(ch3, 108);
        DMX.write(ch4, 108);

        break;

      case 5:  //Static Magenta

        DMX.write(ch1, 255);
        DMX.write(ch2, 255);
        DMX.write(ch3, 108);
        DMX.write(ch4, 0);

        break;

      case 6:  //Static Cyan

        DMX.write(ch1, 255);
        DMX.write(ch2, 255);
        DMX.write(ch3, 0);
        DMX.write(ch4, 255);

        break;

      case 7:  //Static White

        DMX.write(ch1, 255);
        DMX.write(ch2, 255);
        DMX.write(ch3, 0);
        DMX.write(ch4, 108);

        break;

      case 8:  //Static Multicoloured

        DMX.write(ch1, 255);
        DMX.write(ch2, 255);
        DMX.write(ch3, 0);
        DMX.write(ch4, 0);

        break;

      case 9:  //2 second fade up and down in RED

        DMX.write(ch1, 0);
        DMX.write(ch2, 255);
        DMX.write(ch3, 0);
        DMX.write(ch4, 108);

        break;

      case 10:  //2 second fade up and down in GREEN

        DMX.write(ch1, 0);
        DMX.write(ch2, 255);
        DMX.write(ch3, 0);
        DMX.write(ch4, 0);

        break;

      case 11:  //2 second fade up and down in YELLOW

        DMX.write(ch1, 255);
        DMX.write(ch2, 108);
        DMX.write(ch3, 255);
        DMX.write(ch4, 255);

        break;

      case 12:  //2 second fade up and down in BLUE

        DMX.write(ch1, 255);
        DMX.write(ch2, 108);
        DMX.write(ch3, 255);
        DMX.write(ch4, 108);

        break;

      case 13:  //2 second fade up and down in MAGENTA

        DMX.write(ch1, 255);
        DMX.write(ch2, 108);
        DMX.write(ch3, 255);
        DMX.write(ch4, 0);

        break;

      case 14:  //2 second fade up and down in CYAN

        DMX.write(ch1, 255);
        DMX.write(ch2, 108);
        DMX.write(ch3, 108);
        DMX.write(ch4, 255);

        break;

      case 15:  //2 second fade up and down in WHITE

        DMX.write(ch1, 255);
        DMX.write(ch2, 108);
        DMX.write(ch3, 108);
        DMX.write(ch4, 108);

        break;

      case 16:  //2 second fade up and down in MULTICOLOUR

        DMX.write(ch1, 255);
        DMX.write(ch2, 108);
        DMX.write(ch3, 108);
        DMX.write(ch4, 0);

        break;

      case 17:  //Fast white twinkle in RED

        DMX.write(ch1, 108);
        DMX.write(ch2, 108);
        DMX.write(ch3, 255);
        DMX.write(ch4, 108);

        break;

      case 18:  //Fast white twinkle in GREEN

        DMX.write(ch1, 108);
        DMX.write(ch2, 108);
        DMX.write(ch3, 255);
        DMX.write(ch4, 0);

        break;

      case 19:  //Fast white twinkle in YELLOW

        DMX.write(ch1, 108);
        DMX.write(ch2, 108);
        DMX.write(ch3, 108);
        DMX.write(ch4, 255);

        break;

      case 20:  //Fast white twinkle in BLUE

        DMX.write(ch1, 108);
        DMX.write(ch2, 108);
        DMX.write(ch3, 108);
        DMX.write(ch4, 108);

        break;

      case 21:  //Fast white twinkle in MAGENTA

        DMX.write(ch1, 108);
        DMX.write(ch2, 108);
        DMX.write(ch3, 108);
        DMX.write(ch4, 0);

        break;

      case 22:  //Fast white twinkle in CYAN

        DMX.write(ch1, 108);
        DMX.write(ch2, 108);
        DMX.write(ch3, 0);
        DMX.write(ch4, 255);

        break;

      case 23:  //Fast white twinkle in WHITE

        DMX.write(ch1, 108);
        DMX.write(ch2, 108);
        DMX.write(ch3, 0);
        DMX.write(ch4, 108);

        break;

      case 24:  //Fast white twinkle in MULTICOLOUR

        DMX.write(ch1, 108);
        DMX.write(ch2, 108);
        DMX.write(ch3, 0);
        DMX.write(ch4, 0);

        break;

      case 25:  //All off with fast twinkle in RED

        DMX.write(ch1, 0);
        DMX.write(ch2, 108);
        DMX.write(ch3, 108);
        DMX.write(ch4, 108);

        break;

      case 26:  //All off with fast twinkle in GREEN

        DMX.write(ch1, 0);
        DMX.write(ch2, 108);
        DMX.write(ch3, 108);
        DMX.write(ch4, 0);

        break;

      case 27:  //All off with fast twinkle in YELLOW

        DMX.write(ch1, 0);
        DMX.write(ch2, 108);
        DMX.write(ch3, 0);
        DMX.write(ch4, 255);

        break;

      case 28:  //All off with fast twinkle in BLUE

        DMX.write(ch1, 0);
        DMX.write(ch2, 108);
        DMX.write(ch3, 0);
        DMX.write(ch4, 108);

        break;

      case 29:  //All off with fast twinkle in MAGENTA

        DMX.write(ch1, 0);
        DMX.write(ch2, 108);
        DMX.write(ch3, 0);
        DMX.write(ch4, 0);

        break;

      case 30:  //All off with fast twinkle in CYAN

        DMX.write(ch1, 255);
        DMX.write(ch2, 0);
        DMX.write(ch3, 255);
        DMX.write(ch4, 255);


        break;

      case 31:  //All off with fast twinkle in WHITE

        DMX.write(ch1, 255);
        DMX.write(ch2, 0);
        DMX.write(ch3, 255);
        DMX.write(ch4, 108);

        break;

      case 32:  //All off with fast twinkle in MULTICOLOUR

        DMX.write(ch1, 255);
        DMX.write(ch2, 0);
        DMX.write(ch3, 255);
        DMX.write(ch4, 0);

        break;

      case 33:  //Slow white twinkle on RED

        DMX.write(ch1, 255);
        DMX.write(ch2, 0);
        DMX.write(ch3, 0);
        DMX.write(ch4, 108);

        break;

      case 34:  //Slow white twinkle on GREEN

        DMX.write(ch1, 255);
        DMX.write(ch2, 0);
        DMX.write(ch3, 0);
        DMX.write(ch4, 0);

        break;

      case 35:  //Slow white twinkle on YELLOW

        DMX.write(ch1, 108);
        DMX.write(ch2, 0);
        DMX.write(ch3, 255);
        DMX.write(ch4, 255);

        break;

      case 36:  //Slow white twinkle on BLUE

        DMX.write(ch1, 108);
        DMX.write(ch2, 0);
        DMX.write(ch3, 255);
        DMX.write(ch4, 108);

        break;

      case 37:  //Slow white twinkle on MAGENTA

        DMX.write(ch1, 108);
        DMX.write(ch2, 0);
        DMX.write(ch3, 255);
        DMX.write(ch4, 0);

        break;

      case 38:  //Slow white twinkle on CYAN

        DMX.write(ch1, 108);
        DMX.write(ch2, 0);
        DMX.write(ch3, 108);
        DMX.write(ch4, 255);

        break;

      case 39:  //Slow white twinkle on WHITE

        DMX.write(ch1, 108);
        DMX.write(ch2, 0);
        DMX.write(ch3, 108);
        DMX.write(ch4, 108);

        break;

      case 40:  //Slow white twinkle on MULTICOLOUR

        DMX.write(ch1, 0);
        DMX.write(ch2, 0);
        DMX.write(ch3, 108);
        DMX.write(ch4, 0);

        break;

      case 41:  //Twinkling slowly to off in RED

        DMX.write(ch1, 108);
        DMX.write(ch2, 0);
        DMX.write(ch3, 0);
        DMX.write(ch4, 255);

        break;

      case 42:  //Twinkling slowly to off in GREEN

        DMX.write(ch1, 108);
        DMX.write(ch2, 0);
        DMX.write(ch3, 0);
        DMX.write(ch4, 108);

        break;

      case 43:  //Twinkling slowly to off in YELLOW

        DMX.write(ch1, 108);
        DMX.write(ch2, 0);
        DMX.write(ch3, 0);
        DMX.write(ch4, 0);

        break;

      case 44:  //Twinkling slowly to off in BLUE

        DMX.write(ch1, 0);
        DMX.write(ch2, 0);
        DMX.write(ch3, 255);
        DMX.write(ch4, 255);

        break;

      case 45:  //Twinkling slowly to off in MAGENTA

        DMX.write(ch1, 0);
        DMX.write(ch2, 0);
        DMX.write(ch3, 255);
        DMX.write(ch4, 108);

        break;

      case 46:  //Twinkling slowly to off in CYAN

        DMX.write(ch1, 0);
        DMX.write(ch2, 0);
        DMX.write(ch3, 255);
        DMX.write(ch4, 0);

        break;

      case 47:  //Twinkling slowly to off in WHITE

        DMX.write(ch1, 0);
        DMX.write(ch2, 0);
        DMX.write(ch3, 108);
        DMX.write(ch4, 255);

        break;

      case 48:  //Twinkling slowly to off in MULTICOLOUR

        DMX.write(ch1, 0);
        DMX.write(ch2, 0);
        DMX.write(ch3, 0);
        DMX.write(ch4, 255);

        break;

      case 49:  //Off with slow twinkle in RED

        DMX.write(ch1, 108);
        DMX.write(ch2, 255);
        DMX.write(ch3, 255);
        DMX.write(ch4, 108);

        break;

      case 50:  //Off with slow twinkle in GREEN

        DMX.write(ch1, 108);
        DMX.write(ch2, 255);
        DMX.write(ch3, 255);
        DMX.write(ch4, 0);

        break;

      case 51:  //Off with slow twinkle in YELLOW

        DMX.write(ch1, 0);
        DMX.write(ch2, 255);
        DMX.write(ch3, 108);
        DMX.write(ch4, 255);

        break;

      case 52:  //Off with slow twinkle in BLUE

        DMX.write(ch1, 0);
        DMX.write(ch2, 255);
        DMX.write(ch3, 108);
        DMX.write(ch4, 108);

        break;

      case 53:  //Off with slow twinkle in MAGENTA

        DMX.write(ch1, 0);
        DMX.write(ch2, 255);
        DMX.write(ch3, 108);
        DMX.write(ch4, 0);

        break;

      case 54:  //Off with slow twinkle in CYAN

        DMX.write(ch1, 255);
        DMX.write(ch2, 108);
        DMX.write(ch3, 0);
        DMX.write(ch4, 255);

        break;

      case 55:  //Off with slow twinkle in WHITE

        DMX.write(ch1, 255);
        DMX.write(ch2, 108);
        DMX.write(ch3, 0);
        DMX.write(ch4, 108);

        break;

      case 56:  //Off with slow twinkle in MULTICOLOUR

        DMX.write(ch1, 255);
        DMX.write(ch2, 108);
        DMX.write(ch3, 0);
        DMX.write(ch4, 0);

        break;
    }  // Close switch

  }  // if (onTime.isActive())

  else {  //Set DMX output to OFF


    DMX.write(ch1, 255);
    DMX.write(ch2, 255);
    DMX.write(ch3, 255);
    DMX.write(ch4, 255);


    power = false;

  }  // Close else

  DMX.endTransmission();
}

void checkHeartbeat() {
  if (hbSched.isActive()) {
    heartbeat = true;
    digitalWrite(hbPin, HIGH);
  } else {
    heartbeat = false;
    digitalWrite(hbPin, LOW);
  }
}

void toggleStatusB() {
  if (millis() - lastToggleTime >= 500) {
    lastToggleTime = millis();
    statusBState = !statusBState;
    digitalWrite(statusB, statusBState);
    digitalWrite(testPin, statusBState);
  }
}

void currentLoop() {

  static unsigned long lastExecutionTime = 0;  // initialize the last execution time variable

  // check if 9ms have passed since the last execution
  if (millis() - lastExecutionTime >= 9) {
    lastExecutionTime = millis();  // update the last execution time variable

    int currentValue = analogRead(A0);
    if (currentValue > 512) {
      totalCurrent += currentValue;
    }



    counter++;
    if (counter >= 1479) {
      current = totalCurrent / 1480;

      counter = 0;
      totalCurrent = 0;
    }
  }
}
/*
  Since Power is READ_WRITE variable, onPowerChange() is
  executed every time a new value is received from IoT Cloud.
*/
void onPowerChange() {
  // Add your code here to act upon Power change
}

/*
  Since Colour is READ_WRITE variable, onColourChange() is
  executed every time a new value is received from IoT Cloud.
*/
void onColourChange() {
  // Add your code here to act upon Colour change
}

/*
  Since Current is READ_WRITE variable, onCurrentChange() is
  executed every time a new value is received from IoT Cloud.
*/
void onCurrentChange() {
  // Add your code here to act upon Current change
}

/*
  Since HbSched is READ_WRITE variable, onHbSchedChange() is
  executed every time a new value is received from IoT Cloud.
*/
void onHbSchedChange() {
  // Add your code here to act upon HbSched change
}

/*
  Since Heartbeat is READ_WRITE variable, onHeartbeatChange() is
  executed every time a new value is received from IoT Cloud.
*/
void onHeartbeatChange() {
  // Add your code here to act upon Heartbeat change
}

/*
  Since OnTime is READ_WRITE variable, onOnTimeChange() is
  executed every time a new value is received from IoT Cloud.
*/
void onOnTimeChange() {
  // Add your code here to act upon OnTime change
}

Why do you say the code is "crashing"? What are the symptoms of that?

I noticed that all your Serial.print() are commented out. If you run the Arduino connected to pc with serial monitor open, do you see any characters printed?

I have a suggestion that will dramatically reduce the length of your code, if you are interested.

Hi @PaulRB, Thank you so much for your reply.

Why do you say the code is "crashing"? What are the symptoms of that?

I have in the code a snippet that toggles the L LED every 500ms, when the board 'crashes' this led stops flashing, after a while and after it has reconnected to the cloud the LED starts flashing again.

Additionally, my LED lights flash randomly when the Arduino is resetting, this also happens when the MKR 'crashes'. It is pretty recognisable.

I noticed that all your Serial.print() are commented out. If you run the Arduino connected to pc with serial monitor open, do you see any characters printed?

Yes, there are a number of lines printed by the IoT cloud library, as the Arduino connects, I can see these.. Sim Card OK, Connected to IoT cloud etc. Interestingly, when I comment out serial.begin, I can still see this text, and any other Serial.prints that aren't commented out also.

I have a suggestion that will dramatically reduce the length of your code, if you are interested.

My goodness yes!!!

Ty Paul,

Best,

M

I wonder if, when not connected to the pc, because the Arduino knows that the serial port is not connected, the serial buffer is becoming full, stalling the code at one of the Serial.print() lines.

But if the IoT cloud library always uses Serial.print(), no sketch would ever work on the MKR NB 1500 unless it was connected to a pc. If that were true it would make the board pointless, it's supposed to run standalone, so it can't be that.

It's that huge switch-case statement that could be completely removed. Whenever you see code, that is almost the same, being repeated multiple times (56 times in your code) that's a sign that you could/should have written it another way.

Symbols or variables with numbers in their names is another clue.

Arrays are your friends in these situations.

const byte channels = 4;
const byte ch[channels] = {1, 2, 3, 4};

const byte colours = 57;
const byte pattern[colours][channels] = {
  {255, 255, 255, 255}, //Set DMX output to OFF
  {255, 255, 255, 108}, //1: Static Red
  {255, 255, 255,   0}, //2: Static Green
  ...
  {255, 108,   0, 108}, //55: Off with slow twinkle in WHITE
  {255, 108,   0,   0} //56: Off with slow twinkle in MULTICOLOUR
};

Then you can replace the entire switch-case statement with this single line:

for (byte c=0; c<channels; c++) DMX.write(ch[c], pattern[colour][c]);

Hi @PaulRB,

Thank you for your time writing this out.

Some follow up questions if I may...

Do arrays not use more memory? I wrote the switch statement out this way with 'never forgo clarity for brevity' in mind (Or however the saying goes?).

#define ch1 1
#define ch2 2

As for these, this makes it easy for me to change the start DMX address as this code, if it were working would be uploaded to different locations where the start address would be different.

Very keen to hear your thoughts, you aren't suggesting that this is causing my issue btw?

Best,
M

More dynamic memory (ram), yes. That can probably be prevented if necessary, but that array will use around 200 bytes, and your arduino has 32K bytes. Your code would be shorter, so less program memory (flash) used.

It's a good principle to always keep in mind. But avoiding repetition in code is also a good principle and your code is repeating the same thing 50+ times over. If you need to change that piece of code, you have to do that change 50+ times over.

Can you give an example? I don't see how my suggestion would make changing the start address more difficult.

Not sure what you mean by "this", but, no, pretty sure my suggestions won't fix your stalling problem, sorry.

Hi @PaulRB

More dynamic memory (ram), yes. That can probably be prevented if necessary, but that array will use around 200 bytes, and your arduino has 32K bytes. Your code would be shorter, so less program memory (flash) used.

The arduino generated IoT memory uses a huge amount of this 32K, like over 90%, so I am being quite careful about RAM used, I will definitely load your code though and if it doesn't tip the scales, I very much prefer it to my method.

Can you give an example? I don't see how my suggestion would make changing the start address more difficult.

I was really just explaining why I was using variable names with numbers, but your way is far better.

I believe I have fixed my stalling problem thank you for your help. The reason why I was confused (I think) is that when I severed the data lines on my USB cable, my computer was turning off the power, I am guessing this is because of some sort of PD negotiation or similar. I am unsure, but when I connected the Arduino to a power bank it starting working correctly. The issue I was having is that I was powering the Arduino through a SSR, I did this so that the Arduino would be power cycled if it ever lost comms with the cloud. (Long Story). Anyway, I have changed this to a mechanical relay and my rebooting woes seem to have subsided.

Best,

M

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