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.