Programma per controllare motore passo-passo

Salve a tutti, ho scritto un programma per controllare un motore passo-passo (a puro scopo didattico) ma sto riscontrando alcune difficoltà.

Sto simulando il tutto usando tinkercad, i componenti principali sono una scheda arduino uno, uno schermo lcd e un ricevitore ir.
Il programma è composto da un menù nella funzione loop che permette di scegliere che modalità usare.
Per il momento ho scritto 3 funzioni:
-una funzione fa ruotare il motore fino a che non raggiunge un finecorsa e poi riporta il motore in una posizione di partenza.
-una funzione che permette di far ruotare il motore in una direzione o nell'altra usando le frecce del telecomando.
-una funzione che fa andare avanti e indietro il motore in automatico. La velocità viene cambiata tramite i tasti numerici del telecomando.

#include <IRremote.h> // use the library
int receiver = 10; // pin 1 of IR receiver to Arduino digital pin 10
IRrecv irrecv(receiver); // create instance of 'irrecv'
decode_results results;

//define the arrows and the ok button
//navigate the menù and control the motor
#define  upArrow 0xFF807F
#define  downArrow 0xFD906F
#define  rightArrow 0xFD609F
#define  leftArrow 0xFD20DF
#define  okButton 0xFDA05F

//define the keypad
//change speed of the motor
#define oneButton 0xFD08F7
#define twoButton 0xFD8877
#define threeButton 0xFD48B7
#define fourButton 0xFD28D7
#define fiveButton 0xFDA857
////////////////////////////////////////////////////////////////////////////

// include the library code:
#include <LiquidCrystal.h>
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

////////////////////////////////////////////////////////////////////////////
#include <Stepper.h>
const int stepsPerRevolution = 100;  //number of steps per revolution
Stepper stepperMotor(stepsPerRevolution, 8, 9, 10, 11); // initialize the stepper library

///////////////////////////////////////////////////////////////////////////
bool manualModeEnable = 0; //if true the manual mode is enabled
bool autoModeEnable = 0;  //if true the auto mode is enabled
bool modeSelected; // while true you can select a mode
int modeNumber; //number of the mode

///////////////////////////////////////////////////////////////////////////

//brings the motor to its lowest position
//brings the motor to its starting position
void homePosition()
{
  stepperMotor.setSpeed(70); //speed of the motor during this mode
  while (digitalRead(6) == LOW) //the motor lowers until it reaches "zero" position

  {
    stepperMotor.step(1);
    delay(50);
  }
  stepperMotor.step(70); //starting position
}

//two buttons to raise or lower the motor manually
//ok button to exit this mode
void manualMode()
{
  irrecv.resume();
  stepperMotor.setSpeed(70);
  lcd.clear();
  lcd.print("Modalita manuale");
  while (manualModeEnable == 1)
  {
    if (irrecv.decode(&results))
    {
      unsigned int valueManual = results.value;

      switch (valueManual) {
        case upArrow: //the motor goes up
          stepperMotor.step(1);
          lcd.clear();
          delay(50);
          lcd.print("Su");
          irrecv.resume();
          break;

        case downArrow: //the motor lowers
          stepperMotor.step(-1);
          lcd.clear();
          delay(50);
          lcd.print("Giu");
          irrecv.resume();
          break;

        case okButton: //exit the mode
          manualModeEnable = 0;
          irrecv.resume();
          break;
      }
    }
  }
}

void autoMode()
{
  irrecv.resume();
  stepperMotor.setSpeed(70); //safe and standard speed to start
  lcd.clear();
  lcd.print("Scegliere Velocita");
  while (autoModeEnable == 1)
  {
    //if a number is pressed the speed changes
    if (irrecv.decode(&results))
    {
      unsigned int valueAuto = results.value;

      switch (valueAuto) {
        case oneButton:
          stepperMotor.setSpeed(70);
          lcd.clear();
          delay(50);
          lcd.print("Velocita 1");
          irrecv.resume();
          break;

        case twoButton:
          stepperMotor.setSpeed(70);
          lcd.clear();
          delay(50);
          lcd.print("Velocita 2");
          irrecv.resume();
          break;

        case threeButton:
          stepperMotor.setSpeed(70);
          lcd.clear();
          delay(50);
          lcd.print("Velocita 3");
          irrecv.resume();
          break;

        case fourButton:
          stepperMotor.setSpeed(70);
          lcd.clear();
          delay(50);
          lcd.print("Velocita 4");
          irrecv.resume();
          break;
      }
    }
    stepperMotor.step(200);
    stepperMotor.step(-200);
  }
}
void setup() {

  pinMode(6, INPUT); //limit switch
  irrecv.enableIRIn(); // Start the receiver
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.print("Setup OK");
  delay(500);
  //homePosition();

}

void loop() {
  modeSelected = 0;
  modeNumber = 1;
  irrecv.resume();
  delay(15);
  lcd.clear();
  lcd.print("Scegliere mod");
  while (modeSelected == 0)
  {
    if (irrecv.decode(&results))
    {
      unsigned int valueMenu = results.value;
      switch (valueMenu) {
        case rightArrow:
          if (modeNumber < 3)
          {
            modeNumber++;
            lcd.clear();
            lcd.print("Modalita Aum");
          }
          irrecv.resume();
          break;
        case leftArrow:
          if (modeNumber >= 1)
          {
            modeNumber--;
            lcd.clear();
            lcd.print("Modalita Dim");
          }
          irrecv.resume();
          break;

        case okButton:
          modeSelected = 1;
          lcd.clear();
          lcd.print("Modalita scelta: ");
          irrecv.resume();
          break;
      }
    }
  }

  switch (modeNumber) {
    case 1:
      manualModeEnable = 1; //manual mode
      manualMode();
      break;
    case 2:
      autoModeEnable = 1; //auto mode
      autoMode();
      //homePosition();
      break;

  }
}

Il problema più grosso ora è che il telecomando sembra aver smesso di funzionare: il programma si ferma nel ciclo while all'interno della funzione void perchè non riconosce nessun input dal telecomando. Anche forzando l'esecuzione delle altre funzioni il problema persiste, non viene riconosciuto nessun input.
Avevo provato il programma solo con le funzioni "manualMode" e "homePosition" ( la funzione "autoMode" era già pronta per essere chiamata ma senza codice all'interno) e il programma funzionava (quasi) bene. Dopo che ho aggiunto il codice dentro la funzione e ho definito i tasti numerici all'inizio del programma ha iniziato a comportarsi come detto in precedenza.

Quando il programma funzionava ancora avevo riscontrato altri problemi:
Nella funzione "manualMode" premendo più volte i tasti il testo precedente non veniva cancellato e ne risultavano scritte come "suu7" o qualcosa di più complicato. Ho notato anche che premendo i tasti velocemente il programma smetteva di rispondere, non ho potuto proseguire con il debug a causa del telecomando non funzionante.

Nella funzione "homePosition", oltre a un ritardo pazzesco dalla pressione del pulsante al termine del ciclo while, lo schermo si inizia a rimepire di caratteri, in questo caso delle "U".

Vorrei aggiungere che tutti i valori riguardanti il motore passo-passo sono a caso, verranno poi sistemati quando potrò provare il programma con il motore collegato.
Inoltre mi scuso se ho detto/fatto qualche stupidata, è la prima volta che lavoro con la maggior parte di queste cose. Detto questo, grazie in anticipo a tutti quelli che mi aiuteranno.

Essendo il tuo primo post nella sezione Italiana del Forum, nel rispetto del regolamento di detta sezione (… punto 13, primo capoverso), ti chiedo cortesemente di presentarti QUI (spiegando bene quali conoscenze hai di elettronica e di programmazione ... possibilmente evitando di scrivere solo una riga di saluto) e di leggere con MOLTA attenzione il su citato REGOLAMENTO ... Grazie.

Guglielmo

P.S.: Dato che hai già affrontato problemi di stepper-motor nella sezione Inglese, fai sempre attenzione a NON fare cross-posting o i thread debbono venir chiusi e cancellati ... :wink:

Katoz:
Sto simulando il tutto usando tinkercad, i componenti principali sono una scheda arduino uno, uno schermo lcd e un ricevitore ir.

Un simulatore ?

gpb01:
Essendo il tuo primo post nella sezione Italiana del Forum, nel rispetto del regolamento di detta sezione (… punto 13, primo capoverso), ti chiedo cortesemente di presentarti QUI (spiegando bene quali conoscenze hai di elettronica e di programmazione ... possibilmente evitando di scrivere solo una riga di saluto) e di leggere con MOLTA attenzione il su citato REGOLAMENTO ... Grazie.

Guglielmo

Mi scuso per l'errore, ho provveduto a presentarmi.

gpb01:
P.S.: Dato che hai già affrontato problemi di stepper-motor nella sezione Inglese, fai sempre attenzione a NON fare cross-posting o i thread debbono venir chiusi e cancellati ... :wink:

Ho scritto nella sezione inglese ma non mi sono reso conto di quanto tempo ci metto a scrivere in inglese, da ora in poi scrivo solo qui.

nid69ita:
Un simulatore ?

Su tinkercad.com è possibile simulare circuiti elettronici e nei componenti è presente anche arduino uno, ho deciso di simulare prima il mio programma perchè non sapevo se sarei stato in grado di fare quello che volevo e non volevo sprecare i soldi per il motore passo-passo, lo schermo, ecc.

Ho ridotto all'osso il codice, lasciando solo il menù nella funzione loop, e ho testato il codice direttamente su arduino invece che simularlo.

#include <IRremote.h> // use the library
int receiver = 10; // pin 1 of IR receiver to Arduino digital pin 10
IRrecv irrecv(receiver); // create instance of 'irrecv'
decode_results results;

//define the arrows and the ok button
//navigate the menù and control the motor
#define  upArrow 0xFD8877
#define  downArrow 0xFD9867
#define  rightArrow 0xFD6897
#define  leftArrow 0xFD28D7
#define  okButton 0xFDA857
////////////////////////////////////////////////////////////////////////////

bool manualModeEnable = 0; //if true the manual mode is enabled
bool autoModeEnable = 0;  //if true the auto mode is enabled
bool modeSelected; // while true you can select a mode
int modeNumber; //number of the mode

///////////////////////////////////////////////////////////////////////////

void setup() {
  Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver
  Serial.println("Setup OK");
  delay(500);

}

void loop() {
  modeSelected = 0;
  modeNumber = 1;
  irrecv.resume();
  Serial.println("Scegliere modalità");
  while (modeSelected == 0)
  {
 
    if (irrecv.decode(&results))
    {
      unsigned int valueMenu = results.value;
      switch (valueMenu) {
        case rightArrow:
          if (modeNumber < 3)
          {
            modeNumber++;
            Serial.println("Modalita Aum");
          }
          irrecv.resume();
          delay(50);
          break;
          
        case leftArrow:
          if (modeNumber >= 1)
          {
            modeNumber--;
            Serial.println("Modalita Dim");
            delay(50);
          }
          irrecv.resume();
          break;

        case okButton:
          modeSelected = 1;
          Serial.println("Modalita scelta: ");
          irrecv.resume();
          break;
      }
    }
 delay(50); }
}

Usando questo codice il programma si comporta in maniera, almeno per me, casuale: il pulsante "ok" sembra funzionare in maniera corretta a meno che non lo tengo premuto, in quel caso si blocca il programma. Le frecce direzionali invece possono far bloccare il programma in ogni momento, a volte basta una sola pressione del tasto per bloccare tutto e a volte posso premere i pulsanti anche decine di volte prima che si blocchi.

Il programma compila correttamente ma aumentando il livello di warning appare questo messaggio per ogni caso dello switch case:

 warning: large integer implicitly truncated to unsigned type [-Woverflow]