// Constant Vars for homing and limits values in ms
const int w_max_limit =200 ;
const int w_min_limit =0 ;
const int W_Job_Select_speed =1 ;
const int W_On_Homing_Speed =1 ;
const int W_Off_Homing_Speed =1 ;
const int W_Move_Speed =1 ;
const int W_Steps_off_limit =50 ;
// IO MAPPING change as required per board GPIO
//DIGITAL IN pin assignment
const int ix_Up_manual = 2; // the number of the UP dir input
const int ix_Down_manual = 3; // the number of the Down dir input
const int ix_Go_To_Job1 = 4; // the number of the go to job 1 input
const int ix_Go_To_Job2 = 5; // the number of the go to job 2 input
const int ix_Save_position = 6; // the number of the Save Job Hight Input
const int ix_Lower_limit = 7; // Limit Switch
// Digital Out
const int Qx_pul_out = 8;
const int Qx_dir_out = 9;
//ANALOG IN
const int iW_Speed_in = 10; // the number of the Analog Input for speed ref
// GVL
int W_Scaled_speed_ref;
int w_machine_state ;
int w_Job1_position ;
int w_Job2_position ;
int x_Save_position ;
int Machine_state ;
int w_current_position;
#include <EEPROM.h>
void setup() {
pinMode(ix_Up_manual, INPUT_PULLUP);
pinMode(ix_Down_manual, INPUT_PULLUP);
pinMode(ix_Go_To_Job1, INPUT_PULLUP);
pinMode(ix_Go_To_Job2, INPUT_PULLUP);
pinMode(ix_Save_position, INPUT_PULLUP);
pinMode(ix_Lower_limit, INPUT_PULLUP) ;
pinMode(Qx_pul_out, OUTPUT) ;
pinMode(Qx_dir_out , OUTPUT) ;
Serial.begin (9600) ;
Machine_state=0 ;
}
void loop() {
// Homing input, home axis before entering tun mode.
bool x_Lower_limit =digitalRead(ix_Lower_limit);
// Test output Serial data
//delay(1000);
//Serial.print ("Machine state is: ");
//Serial.println (Machine_state);
switch (Machine_state) {
case 0:
// Machine Homing state 0 on startup
Homing (x_Lower_limit);
break;
case 10:
// Run mode once homing complete
RunMode();
break;
}
}
void RunMode(){
// process input and execute functions accordingly
//Serial.println("im in run mode after homing ");
Serial.println(w_current_position);
bool x_Up_manual = digitalRead(ix_Up_manual) ;
bool x_Down_manual = digitalRead(ix_Down_manual) ;
bool x_Go_To_Job1 = digitalRead(ix_Go_To_Job1) ;
bool x_Go_To_Job2 = digitalRead(ix_Go_To_Job2) ;
bool x_Save_position = digitalRead(ix_Save_position);
// read analog input and scale as required
//Test Serial Data
/* Serial.print("x_Up_manual level : ");
Serial.println(x_Up_manual) ;
Serial.print("x_Down_manual level : ");
Serial.println(x_Down_manual) ;
Serial.print("x_Go_To_Job1 level : ");
Serial.println(x_Go_To_Job1) ;
Serial.print("x_Go_To_Job2 level : ");
Serial.println(x_Go_To_Job2) ;
Serial.print("x_Save_position level: ");
Serial.println(x_Save_position);
*/
/*Serial.print("Current pos: ");
//Serial.println(w_current_position);
// Serial.print("Job 1 pos: ");
//Serial.println(w_Job1_position );
// Serial.print("Job 2 pos: ");
//Serial.println(w_Job2_position );
*/
// Go to states based on input Logic
if (x_Up_manual == 0){
MoveUpwards(x_Up_manual);
}
else if (x_Down_manual == 0){
// Move Downwards State
MoveDownwards(x_Down_manual);
}
else if ((x_Go_To_Job1 == 0 && x_Save_position == 1)){
// Go to job 1 state
Go_to_job_1();
}
else if ((x_Go_To_Job2 == 0 && x_Save_position == 1)){
// Go to job 2 state
Go_to_job_2();
}
else if ((x_Go_To_Job1==0 && x_Save_position == 0 ) || (x_Go_To_Job2 ==0 && x_Save_position == 0)){
// Go to save job state.
SaveJobPosition(x_Go_To_Job1,x_Go_To_Job2);
}
}
//Functions
void Homing(bool x_Limit_Switch){
// Home the axis if the limit switch is not closed.
if (x_Limit_Switch== 1){
RunMotor(W_On_Homing_Speed ,0,1);
w_current_position=0;
}
// if home switch, back off by step count if limit is off change to run mode state.
else if (x_Limit_Switch== 0){
RunMotor(W_Off_Homing_Speed ,1,W_Steps_off_limit);
HandleMemory(0,0,1,1);
w_current_position=0;
Machine_state =10;
}
}
void MoveUpwards(bool Input){
RunMotor(W_Move_Speed,1,1);
}
void MoveDownwards(bool Input){
RunMotor(W_Move_Speed,0,1);
}
void Go_to_job_1(){
bool Direction_required;
int Steps_needed;
if (w_current_position>w_Job1_position){
Direction_required=0;
Steps_needed=w_current_position-w_Job1_position;
RunMotor(W_Job_Select_speed ,Direction_required,Steps_needed);
}
if (w_current_position<w_Job1_position){
Direction_required=1;
Steps_needed=w_Job1_position-w_current_position;
RunMotor(W_Job_Select_speed ,Direction_required,Steps_needed);
}
}
void Go_to_job_2(){
bool Direction_required;
int Steps_needed;
if (w_current_position>w_Job2_position){
Direction_required=0;
Steps_needed=w_current_position-w_Job2_position;
RunMotor(W_Job_Select_speed ,Direction_required,Steps_needed);
}
if (w_current_position<w_Job2_position){
Direction_required=1;
Steps_needed=w_Job2_position-w_current_position;
RunMotor(W_Job_Select_speed ,Direction_required,Steps_needed);
}
}
void SaveJobPosition(bool SaveJob1,bool SaveJob2){
if (SaveJob1==0) {
w_Job1_position=w_current_position;
HandleMemory(1,0,0,0);
}
if (SaveJob2==0) {
w_Job2_position=w_current_position;
HandleMemory(0,1,0,0);
}
}
void RunMotor(int Speed, bool Direction, int Steps){
// Take in commands from program to request movements to the motor at speed defined in ms 1ms= 500hz(ish) Direction is positive 1 , steps is amount of steps required.
// Limits will be checked as defined by upped and lower limits in COnstant variables for homing.
if ((w_current_position<=w_max_limit) && (w_current_position>=w_min_limit)){
// step up control
if (Direction==1){
digitalWrite(Qx_dir_out,HIGH);
for (int x = 0; x < Steps; x ++) {
digitalWrite(Qx_pul_out, HIGH);
delay(Speed);
digitalWrite(Qx_pul_out, LOW);
delay(Speed);
w_current_position = w_current_position+1;
}
}
// step down control
if (Direction==0){
digitalWrite(Qx_dir_out,LOW);
for (int x = 0; x < Steps; x ++) {
digitalWrite(Qx_pul_out, HIGH);
delay(Speed);
digitalWrite(Qx_pul_out, LOW);
delay(Speed);
w_current_position = w_current_position-1;
}
}
}
// control the out of bounds limits and only allow direction in the opposite travel from the specified limit
if ((w_current_position>w_max_limit) && (Direction==0)) {
for (int x = 0; x < Steps; x ++) {
digitalWrite(Qx_pul_out, HIGH);
delay(Speed);
digitalWrite(Qx_pul_out, LOW);
delay(Speed);
w_current_position = w_current_position-1;
}
}
// control the out of bounds limits and only allow direction in the opposite travel from the specified limit
if ((w_current_position<w_min_limit) && (Direction==1)){
for (int x = 0; x < Steps; x ++) {
digitalWrite(Qx_dir_out, HIGH);
delay(Speed);
digitalWrite(Qx_dir_out, LOW);
delay(Speed);
w_current_position = w_current_position+1;
}
}
}
void HandleMemory(bool Save1, bool Save2, bool Read1, bool Read2){
if (Save1){
EEPROM.put(0,w_current_position);
}
if (Save2){
EEPROM.put(2,w_current_position );
}
if (Read1){
w_Job1_position=EEPROM.get(0,w_Job1_position );
}
if (Read2){
w_Job2_position = EEPROM.get(2,w_Job2_position );
}
}
//Code written by Ryan Caffery of RC Coding Ltd