Arduino GIGA stop executing code after few seconds

Hello everyone,

I’m working on a project with an Arduino GIGA to control a stepper motor using the AccelStepper library. I took inspiration from Overvolt. The stepper motor operates an elevator mechanism as part of an automated drink dispenser. The system is integrated with Arduino IoT Cloud, and I trigger the process via Alexa (the functions appear as lights in Alexa).

The Problem
While the system initially works as expected, the stepper motor moves briefly before stopping abruptly. Here’s what happens:

The Serial Monitor disconnects, and the program appears to freeze.
If I don’t turn off the corresponding “light” in Alexa, the board restarts the code from the beginning after a few seconds.
This issue occurs consistently.

I suspect the problem might be related to the use of runToPosition(), which blocks the execution of the code until the motor reaches its destination. Alternatively, it could be related to the dual-core architecture of the GIGA, but I’m not sure.

What I’ve Tried So Far

  • Debugging with Serial Prints:
    the code consistently stops after this:
Controllo fattibilità drink
Blocco ascensore: OFF
Spostamento ascensore verso: 215000
  • Switching to Non-Blocking Execution:
    I replaced runToPosition() with run(), but had no success

Here's the full code:

#include <AccelStepper.h>
#include <MultiStepper.h>

#include "thingProperties.h"

#include <Servo.h>

#define unml 34  // moltiplicatore per associare ml a ms di funzionamento di una pompa

//   ORDINE DRINK
#define quantiDrink 5


//   CONFIGURAZIONE DRINK
int richiesto[quantiDrink][6] = {
  /*                       acqua   vodka   rum   gin   aperol tonica prosecco aaaa
  /*  cuba_libre       */  {    0  ,    0 ,    0 ,   0   ,   0  ,    0},
  /*  mocktail_trop    */  {    0  ,    0 ,    0 ,   0   ,   0  ,    0},
  /*  arancia_triplo   */  {    0  ,    0 ,    0 ,   0   ,  100 ,   25},
  /*  triple_sec_fizz  */  {    20 ,    0 ,   50 ,   0   ,   0  ,    0},
  /*  coca_lime        */  {    0  ,    0 ,    0 ,  50   ,   0  ,   50 },
};

#define RELE_BLOCCO 17
#define EN_PIN 2 

#define su 1
#define giu 215000

int livello[8] = { 0, 0, 0, 0, 0, 0, 0, 0};  // da sostituire con la eeprom/flash

AccelStepper ascensore(1, 4, 3); // driver di tipo 1 (a 2 pin) , pin 4 per gli step, pin 3 per la direzione
Servo rubinetto;

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

  initProperties(); // Defined in thingProperties.h
  ArduinoCloud.begin(ArduinoIoTPreferredConnection); // Connect to Arduino IoT Cloud

  setDebugMessageLevel(2);
  ArduinoCloud.printDebugInfo();

  pinMode(RELE_BLOCCO, OUTPUT);
  pinMode(EN_PIN, OUTPUT);

  bloccaAscensore(0);
  ascensore.setMaxSpeed(3000); 
  ascensore.setAcceleration(1100);
  ascensore.setCurrentPosition(0);
  delay(500);
  bloccaAscensore(1);

  rubinetto.attach(A7);
  rubinetto.write(0); //posizione iniziale föra di ball

  for(int i=6;i<=13;i++) pinMode(i,OUTPUT);  //cicla tutti i pin delle pompe mettendoli a output

  arancia_triplo = false;
  coca_lime = false;
  cuba_libre = false;
  mocktail_trop = false;
  triple_sec_fizz = false;

  Serial.println("Setup completato");
}

void loop() {
  ArduinoCloud.update();
  Serial.println("Loop in esecuzione");
}

void onAranciaTriploChange()  {
  Serial.println("Cambio stato: arancia_triplo");
  if(arancia_triplo == true) {
      resetDrinkFlags();
      nuovoDrink(2);
  }
}

void onCocaLimeChange()  {
  Serial.println("Cambio stato: coca_lime");
  if(coca_lime == true) {
      resetDrinkFlags();
      nuovoDrink(4);
  }
}

void onCubaLibreChange()  {
  Serial.println("Cambio stato: cuba_libre");
  if(cuba_libre == true) {
      resetDrinkFlags();
      nuovoDrink(0);
  }
}

void onMocktailTropChange()  {
  Serial.println("Cambio stato: mocktail_trop");
  if(mocktail_trop == true) {
      resetDrinkFlags();
      nuovoDrink(1);
  }
}

void onTripleSecFizzChange()  {
  Serial.println("Cambio stato: triple_sec_fizz");
  if( triple_sec_fizz == true) {
      resetDrinkFlags();
      nuovoDrink(3);
  }
}

void resetDrinkFlags() {
  Serial.println("Reset dei flag dei drink");
  arancia_triplo = false;
  coca_lime = false;
  cuba_libre = false;
  mocktail_trop = false;
  triple_sec_fizz = false;
}

void nuovoDrink(int drink) {
  Serial.print("Preparazione nuovo drink: ");
  Serial.println(drink);

  if(!controllaFattibile(drink)) {
    Serial.println("Drink non fattibile, uscita.");
    return;
  }

  spostaAscensore(giu);
  rubinetto.write(50);
  Serial.println("Rubinetto aperto");

  // eroga(drink);
  sgrulla();

  rubinetto.write(0);
  Serial.println("Rubinetto chiuso");

  spostaAscensore(su);
}

void spostaAscensore(int dove) {
  Serial.print("Spostamento ascensore verso: ");
  Serial.println(dove);

  bloccaAscensore(0);
  delay(1500); // Attendi per sicurezza
  ascensore.moveTo(-dove);
  ascensore.runToPosition();
  bloccaAscensore(1);

  Serial.println("Spostamento ascensore completato");
  delay(1500); // Attendi per sicurezza
}

void bloccaAscensore(bool stato) {
  Serial.print("Blocco ascensore: ");
  Serial.println(stato ? "ON" : "OFF");

  if(stato) {
    digitalWrite(EN_PIN, HIGH);
    digitalWrite(RELE_BLOCCO, LOW);
  } else {
    digitalWrite(RELE_BLOCCO, HIGH);
    digitalWrite(EN_PIN, LOW);
  }
}

bool controllaFattibile(int drink) {
  Serial.println("Controllo fattibilità drink");
  return true; // Simulato come sempre fattibile

  for(int bottiglia=0; bottiglia<8; bottiglia++) {
    if(richiesto[bottiglia][drink] == 0)
      continue;

    if(livello[bottiglia] < (richiesto[bottiglia][drink] + 50)) {
      Serial.print("Livello insufficiente per bottiglia: ");
      Serial.println(bottiglia);
      return false;
    }
  }
  return true;
}

void eroga(int drink) {
  Serial.println("Erogazione del drink");
  for(int bottiglia=0; bottiglia<8; bottiglia++) {
    if(richiesto[bottiglia][drink] == 0)
      continue;

    versa(richiesto[bottiglia][drink], bottiglia);
    livello[bottiglia] -= richiesto[bottiglia][drink];
  }
}

void versa(int quanto, int cosa) {
  Serial.print("Versamento da bottiglia: ");
  Serial.print(cosa);
  Serial.print(", Quantità: ");
  Serial.println(quanto);

  digitalWrite(cosa+6, HIGH);
  delay(quanto * unml);
  digitalWrite(cosa+6, LOW);

  Serial.println("Versamento completato");
}

void sgrulla() {
  Serial.println("Sgrullamento rubinetto");
  rubinetto.write(30);
  delay(200);
  rubinetto.write(44);
  delay(200);
  rubinetto.write(28);
  delay(200);
  Serial.println("Sgrullamento completato");
}

Let me know if you need additional information

Hi @jackyll

It is a good hypothesis. If a problem in the sketch code caused the program to go into a state where ArduinoCloud.update() is not called at all, all Cloud Variables would cease to be synced altogether. For this reason, Thing sketches have a "watchdog timer":

https://docs.arduino.cc/arduino-cloud/cloud-interface/sketches/#watchdog-timer-wdt

This feature will automatically reset the Arduino board if a long interval passes since the last time ArduinoCloud.update() was called.

As an experiment, you can disable the watchdog feature in the sketch code, then upload the modified sketch to your GIGA R1 WiFi board, and check to see if the problem still occurs. If it doesn't, then you will know that the blocking code in your sketch is the cause of the problem. You can disable the watchdog feature by changing this line in your sketch:

to this:

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

You can learn a useful technique for writing sketches that perform actions at defined intervals, while allowing the loop function to run freely and continue calling ArduinoCloud.update() frequently, from this tutorial:

https://docs.arduino.cc/built-in-examples/digital/BlinkWithoutDelay

Thanks, with that flag being false the code runs smoothly

You are welcome. I'm glad we were able to identify the cause of the misbehavior!

Regards, Per