Dear All,
I put together a controller for a stepper motor with Arduino Due. I have two buttons to move the table back and forward at a speed set with a pot. All works fine.
Now, connecting an I2C display, it's tempting to display the position of the table, that can be easily calculated. All good.
Now the troubles: if I try to have a live update of the data on the display the stream of pulses that drives the motor is interrupted and the movement is very slow and not fluid. Basically useless.
I can see this in practice and also looking at the pulses with a scope.
The question is: is there a smarter way to code the thing so that the pulse are continuous while the display is updated ?
The attached code has provision for three axes, but I am presently working only on X. I tried both to update the display with a function or with a direct command in the loop, the results are the same.
Here is the code:
/*
Stepper Motor Control
20180508
First version:
Display
Acceleration
Speed Selection
Only one axe
*/
#include <Stepper.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// Set the LCD address to 0x27 for a 16 chars and 2 line display
LiquidCrystal_I2C lcd(0x27, 20, 4);
#define RIGHT 51
#define LEFT 50
#define X_PULSE 22
#define X_DIR 23
#define X_ENA 24
#define Y_PULSE 26
#define Y_DIR 27
#define Y_ENA 28
#define Z_PULSE 30
#define Z_DIR 31
#define Z_ENA 32
#define AXE_SELECT 48
#define ZERO_PIN 49
#define START_SPEED 100 //50 mm/min
#define MAX_SPEED 2750 // 1400 mm/min
#define SPEED_INCREMENT 5
#define STEPS_PER_REVOLUTION 400
#define POSITION_INCREMENT 0.00125
#define MIN_STEPS 1
#define SET_SPEED_TOLERANCE 5
double Xpos = 0.0 ;
double Ypos = 0.0 ;
double Zpos = 0.0 ;
int axe = 0 ;
bool Xchange = true ;
bool Ychange = true ;
bool Zchange = true ;
bool Axechange = true ;
bool Speedchange = true ;
int SetSpeed = START_SPEED;
int tempSpeed = START_SPEED ;
Stepper myStepper(STEPS_PER_REVOLUTION, X_PULSE,X_DIR);
void read_Speed()
{
int temp = map(analogRead(A0), 0, 1023, START_SPEED, MAX_SPEED);
if (abs(temp-SetSpeed) > SET_SPEED_TOLERANCE )
{
SetSpeed = temp;
update_display();
Speedchange = true ;
}
}
void selectAxe()
{
if (digitalRead(AXE_SELECT)==false) axe++;
if (axe > 1) axe = 0 ;
}
void print_label()
{
lcd.clear();
lcd.setCursor(0,0);
lcd.print("X:");
lcd.setCursor(0,1);
lcd.print("Y:");
lcd.setCursor(0,2);
lcd.print("Speed:");
/*
lcd.setCursor(0,3);
lcd.print("Moving Speed:");
*/
}
void update_display()
{
if (Xchange)
{
lcd.setCursor(2,0);
if (Xpos>0) lcd.print("+");
else lcd.print("-");
if (abs(Xpos) < 100 ) lcd.print(" ");
if (abs(Xpos) < 10 ) lcd.print(" ");
lcd.print(abs(Xpos),3);
lcd.print(" ");
bool Xchange = false ;
}
if (Ychange)
{
lcd.setCursor(2,1);
if (Ypos>0) lcd.print("+");
else lcd.print("-");
if (abs(Ypos) < 100 ) lcd.print(" ");
if (abs(Ypos) < 10 ) lcd.print(" ");
lcd.print(abs(Ypos),3);
lcd.print(" ");
bool Ychange = false ;
}
if (Axechange)
{
lcd.setCursor(19,0);
switch (axe) {
case 0:
lcd.print("X");
break;
case 1:
lcd.print("Y");
break;
case 2:
lcd.print("Z");
break;
}
bool Axechange = false ;
}
if (Speedchange)
{
lcd.setCursor(6,2);
//lcd.rightToLeft();
if (SetSpeed < 1000 ) lcd.print(" ") ;
if (SetSpeed < 100 ) lcd.print(" ") ;
lcd.print(SetSpeed / 2 );
lcd.print("mm/min ");
bool Speedchange = false ;
}/*
lcd.setCursor(13,3);
if (tempSpeed < 1000 ) lcd.print(" ") ;
if (tempSpeed < 100 ) lcd.print(" ") ;
lcd.print(tempSpeed);
*/
}
void setup() {
myStepper.setSpeed(START_SPEED);
pinMode(RIGHT,INPUT_PULLUP);
pinMode(LEFT,INPUT_PULLUP);
pinMode(X_ENA,OUTPUT);
pinMode(Y_ENA,OUTPUT);
pinMode(AXE_SELECT,INPUT_PULLUP);
digitalWrite(X_ENA,HIGH); //HIGH is lose
digitalWrite(Y_ENA,HIGH); //HIGH is lose
// initialize the LCD
lcd.begin();
lcd.clear();
// Turn on the blacklight and print a message.
//lcd.backlight();
lcd.setCursor(3,0);
lcd.print("CNC Controller");
lcd.setCursor(6,2);
lcd.print("20180524");
delay(2000);
print_label();
read_Speed();
update_display();
// initialize the serial port:
//Serial.begin(9600);
}//end setup
void loop() {
// step one revolution in one direction:
while (digitalRead(RIGHT)==true && digitalRead(LEFT)==false) //clockwise
{
digitalWrite(X_ENA,LOW);
myStepper.step(MIN_STEPS);
Xpos += POSITION_INCREMENT;
Xchange = true ;
if (tempSpeed < SetSpeed)
{
tempSpeed +=SPEED_INCREMENT;
myStepper.setSpeed(tempSpeed);
}
//update_display();
}
while (digitalRead(LEFT)==true && digitalRead(RIGHT)==false)//counter-clockwise
{
digitalWrite(X_ENA,LOW);
myStepper.step(-MIN_STEPS);
Xpos -= POSITION_INCREMENT;
Xchange = true ;
if (tempSpeed < SetSpeed)
{
tempSpeed +=SPEED_INCREMENT;
myStepper.setSpeed(tempSpeed);
}
// update_display();
}
digitalWrite(X_ENA,HIGH);
digitalWrite(Y_ENA,HIGH);
selectAxe();
tempSpeed = START_SPEED ;
myStepper.setSpeed(tempSpeed);
read_Speed();
update_display();
} //end loop
Thanks,
Davide