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