// lines between /* and */ are one large comment block
// anything after // is a comment, either commenting on what the line does or to comment out debug lines like
// print (print but no new line abd println which adds cr
// all comments are removed during compile so do not affect speed or memory so after running comment out the dep=but lines, but leave in in case needed
// so several ways to comment things it can be added at the end of a line to help explain things
// there is a difference between '' and "" '' is used for one charecter as in mode "" is used for a string as in the print statements
// to compile and upload this you need an "arduino ide" you can down load it and install it.
//I will include the IDE version is used on the memory stick with this program
/*
There are 2 limit switches. When it hits the back one it reverses direction and goes to the 0 position , if it it hits the front it shuts off
There is a one pole 3 position switch (on off on ) that controls the direction. If in cut direction the speed is cut, if return direction the speed is jog.
If the switch is off the motor stops.
There are 2 pots to control speed one if cut speed the other is jog speed
There is a jog button that only works only in the cut direction this increases the speed from cut speed to jog speed while pressed
if you jog it resets the position to 0 when done jogging. if yo use hte return to back it up it also resets the position to 0.
if you refese to far and hit front switch or the counter goes off and front switch is hit it stops
putting the 3 way switch to center stops and resets variables like tripped that is set when rear limit is hit
There are two solid staterelays, and a master power switch.
The master power supplies 12 v power to the "feed switch"
When it is on it powers the arduino and stepper motor controller.
5 v is applied to the pos side of the scr. the neg side goes to the lid switch, then t the saw switch.
The other side of the switch foes to the red led pin.
so saw can if the led light is off, it is grounded and the solid state switch is grounded.
If it is on the led is outting 5 v to power the led, and it stops the ground of the scr.
so.
Basic operation :
1) Move carrage to start position either feed and jog or return (start position)
2) Load rRock, lock the cross feed
3) start cut by pressing switch to feed. If needed press jog to move quicker. (start position updated)
4) continue cutting until rear limit switch is hit then reverse direction to start position then stop
note to keep track that rear switch has been set update a called tripped you set it to 0 if the rear is hit,
then you setp back until you are home.
at home, tripped is set to 1, and parked by return is set to 0.
all pins are assigned high, and the switches are connected to ground. so if the switch is off it 1 and on if 0. a litle backward but easiest to wire.
There are two buss bars one positive 5 v one ground
basic wiring, is switches have one side to ground the other to assigned pin.
pots are wired so "left" side is ground and "right side is 5 v. the read pot routine does the reading and sets speed in pulses per second.
as a ref the motor is 400 steps per rev so 3 pulser per sec is .45 rpm 1.5 rpm is 10 pulses per second.
with a 20 thread per inch feed screw .05 feed per rev
shoot for 9-13 inches per hour
9 inches per hour divide by .05 inch per rev gives 180 revs per hour
180 rev per hour divide by 60 is 3 rpm
3 rpm times 400 pulses per rev is 1200 pulses per minute
1200 pulses per minute divide by 60 sec per min is 20 pulses per second.
pulse reate is in pulses per second
as a ref highland park 20 inch saw with 1 hp motor is 9 - 13.5 inches per hour
9 inches per hour / .05 advance per feed is 180 turns per hour or 3 rpm at 400 pulses per rev is 12000 pulses per min or 20 oylses per second
13 is 260 turns per hour or 4.33 rpm is 1733 pulses per min or 29 pulses per second
make cut go from 15 to 33
the controller is wired so dir + and pulse + are wired to 5 v
dir - and pul - are wired to arduino pins
Leds are powered by the LED pn with 5 volts, then a resistor, then the led. which hs the neg side to ground.
So setting pin high iturns on the led, low turns it off.
the speed range can be adjusted in the read pot routine
this is a c++ program so a lot of {} this is used to tell the program what is included in a section of code
() is most ofter input to a statement often followed by a set of {}
all statements end with a ;
I have defined debugprint, debugprintln, and debug speed. to the the serial statements.
there is a debug = 0 or 1.
If it is 1, then the debugprint statements are set to Serial.Pring commands
if 0 then they are set to null.
or learn debugger and set some stop points, i have not learned it yet i just got ide 2 and the debugger is new to it
without uploading the program you go to tools and open the serial monitor
one of the comment out sections is a pause waiting for a switch on outout
digital read 10 is the command. 10 defaults to hi, so to run ground d10 WHICH IS THIRD PIN ON THE RIGHT
touch the wire to the ground bar for a second, then take it off, enlarge the serial monitor screen to see what is going on
pin assignment
Ao is jog pot
A1 is cut pot
A2 cut switch
A3 return switch
A4 jog switch
12 rear limit
11 Front limit
3 direction
2 pulse
4 cut led (green)
5 ret led (yellow)
6 off led (red) and solid state saw relay
added pause to help debug
added all of the print statements to help debug, before switched to ide ver 2 that has a debug mode
remove all of them when it is working
note on modes
O is off
C is cut
J is Jog
H is return from cut (home)
R is return mode from front switch setting
i do switch reading this way
the switch is assigned a pin number on the computer
then the state of that is stored in a variable to be used for comparison
I added a debounce routine to try and cleanup problems with saw returning early
will debounce all switches
Description
*/
// setting up global variables is next they are global if declaired before setup in not global their scope is limited to the function they are created in
// i tried to make all global so they could be changed as needed and work in aby area of the code
// global variables
//I use
#define to set static parameters.
// define is a substitute during compile, saves memory for static items
#define driverdir 3
#define driverpul 2
#define cutpot A1
#define jogpot A0
#define cutswitch A2
#define returnswitch A3
#define jogswitch A4
#define rearswitch 12
#define frontswitch 11
#define runled 4
#define retled 5
#define offled 6
// this is to make debugging easier
#define debug 1
#if debug == 1
#define debugprint(x) Serial.print(x)
#define debugprintln(X) Serial.println(X)
#define debugspeed(X) Serial.begin(9600)
#else
#define debugprint(x)
#define debugprintln(X)
#define debugspeed(X)
#endif
char mode = 'O'; // mode will be cut jog return or off this is one character field o is off
int cut = 1; // variable for the cutswitch state there may be a better way but this make the code easier to read (i think)
int ret = 1; // global used to store the state of the return switch
int tripped = 1; //variable to say that the rear switch was tripped, need to use it untill back at 0 position
int jog = 1; //global for state of jog switch
int rear = 1; //global for state of rear switch
int front = 1; //global for state of front
int cutspeed = 5; //global for cut speed set to five untill pots working
int jogspeed = 300; //global variable for jog speed change to non integer
int parkedbyreturn = 1; // a new variable to say parked by returning This goes to 0 when we have returned to start position and want to be parked.
// global variables called but still need to do some house keeping for the accellstepper library which declares a bunch of new functions
#
#include <AccelStepper.h> // this is a library that helps with stepper motors
int stepsPerRevolution = 400; // change this to fit the number of steps per revolution
// initialize the stepper library driver mode pins 2 and 3
AccelStepper mystepper(1, driverpul, driverdir); // this sets up the controller with direction and pulse pins.
#include <Bounce2.h>
// instanciate the buttons
Bounce2::Button cutbutton = Bounce2::Button();
Bounce2::Button returnbutton = Bounce2::Button();
Bounce2::Button jogbutton = Bounce2::Button();
Bounce2::Button rearbutton = Bounce2::Button();
Bounce2::Button frontbutton = Bounce2::Button();
void setup() { //this is run once
debugspeed(9600); // open the serial port at 9600 bps needed to print lines for debug.
debugprintln("test");
// set up switches
cutbutton.attach(cutswitch,INPUT_PULLUP);
returnbutton.attach(returnswitch, INPUT_PULLUP);
jogbutton.attach(jogswitch, INPUT_PULLUP);
rearbutton.attach(rearswitch, INPUT_PULLUP);
frontbutton.attach(frontswitch, INPUT_PULLUP);
// set dechounce time
cutbutton.interval(50);
returnbutton.interval(50);
jogbutton.interval(50);
rearbutton.interval(50);
frontbutton.interval(50);
// set pressed button state
cutbutton.setPressedState(HIGH);
returnbutton.setPressedState(HIGH);
jogbutton.setPressedState(HIGH);
rearbutton.setPressedState(HIGH);
frontbutton.setPressedState(HIGH);
pinMode(jogpot, INPUT); // this sets the jog pot as input
pinMode(cutpot, INPUT); //this sets the cut pot as input
pinMode(driverpul, OUTPUT); // this sets the drive pin as outpout
pinMode(driverdir, OUTPUT); // sets direction pin as output on
pinMode(runled, OUTPUT); // same for the run led run led
pinMode(retled, OUTPUT); // return led
pinMode(offled, OUTPUT); // off led
// pinMode(10, INPUT_PULLUP); // a pin assigned to help debug. it allows exution to pause so i can read the debug screen
mystepper.setMaxSpeed(4000); // sets max speed
} // end of setup
void loop() { // this is the loop that runs over and over again
// while (digitalRead(10) == HIGH) { }//here to debug comment out when debuged it does nothing but wait untill the pin goes high so grounding the pin pauses
readpots(); //reads pots this is a function defined below
readswitches(); //reads switches same
setmode(); //determines the mode
switch (mode) { // this executes code based on what is stored in mode global
case 'O': //off
digitalWrite(offled, HIGH ); // set the off led (red) on turn others off
digitalWrite(runled, LOW);
digitalWrite(retled, LOW);
debugprintln("in case O "); // debugin cas to tell me what mode i am in
mystepper.disableOutputs(); // if off this disables output to the controller
mystepper.setCurrentPosition(0); // set position to 0
break;
case 'C': //cut
digitalWrite(offled, LOW);
digitalWrite(runled, HIGH);
digitalWrite(retled, LOW);
debugprint("CASE Cut position ");
debugprintln(mystepper.currentPosition());
mystepper.enableOutputs(); // enables outout in case it was set off by the off state
mystepper.setSpeed(cutspeed); // sets the cut speed determined during read pots
mystepper.runSpeed(); // this tells it to take a step at the set speed
debugprint("in cut for loop ");
debugprint("my position is ");
debugprintln(mystepper.currentPosition());
break; // the end of this case
case 'J': // jog mode
digitalWrite(offled, LOW); // turn off led off
digitalWrite(runled, HIGH); // turn run led on
digitalWrite(retled, LOW); // turn return led off
debugprint("CASE jog mode speed "); // in jog mode
mystepper.setSpeed(jogspeed);
mystepper.runSpeed(); // take a step
mystepper.setCurrentPosition(0); // set cuttent position to 0 so we can return here after the cut
break; // end of jog
case 'H': //this is return during a cut
digitalWrite(offled, LOW);
digitalWrite(runled, LOW);
digitalWrite(retled, HIGH);
debugprint("CASE HOME mode position ");
mystepper.setSpeed(jogspeed * -1);
mystepper.runSpeed();
debugprint("position is ");
debugprintln(mystepper.currentPosition());
break; // end of return mode
case 'R': // in this case we were in a cut but hit rear so we are returning home
digitalWrite(offled, LOW);
digitalWrite(runled, LOW);
digitalWrite(retled, HIGH);
debugprint(" in return case R return mode");
mystepper.setSpeed(jogspeed * -1); // the *-1 makes speed negative or backward
mystepper.runSpeed();
mystepper.setCurrentPosition(0); // set cuttent position to 0 so we can return here after the cut
break; // end of R case
default: // default we are in unknown state shut things down it is what happens if the mode is not one of the set cases it should never happen
mystepper.disableOutputs(); // disable the controller
tripped = 1; // motor is off set rtipped highc // reset tripped
parkedbyreturn =1;
digitalWrite(offled, HIGH);
digitalWrite(runled, HIGH);
digitalWrite(retled, HIGH);
break; // end of default mode
} //end of switch mode
} // end of loop()
void readpots() { // this starts defining a functIon to read the pots
cutspeed = map((analogRead(cutpot)), 0, 1025, 33, 15); // analoRead reads the pot and converts it to digital o to 1025 bits
// Serial.print ("cut ");
debugprint ("cut speed");
debugprintln (cutspeed);
jogspeed = map((analogRead(jogpot)), 0, 1025, 3500, 700); //set jog speed same logic as cut b
debugprint("jog ");
debugprintln(jogspeed);
}
void readswitches() { // start of reading the switches
// get the button states
// THIS IS NEEDED TO UPDATE THE BUTTON STATE
cutbutton.update();
returnbutton.update();
jogbutton.update();
rearbutton.update();
frontbutton.update();
debugprint("cut button pressed is ");
debugprintln(cutbutton.isPressed());
debugprint("returnbutton pressed is ");
debugprintln(returnbutton.isPressed());
debugprint("jogbutton pressed is ");
debugprintln(jogbutton.isPressed());
debugprint("front button pressed is ");
debugprintln(frontbutton.isPressed());
debugprint("rearbitton is pressed is ");
debugprintln(rearbutton.isPressed());
//THIS SETS CONDITIONS TO SET BUTTON VARIABLES
cut=cutbutton.isPressed();
ret=returnbutton.isPressed();
jog=jogbutton.isPressed();
front=frontbutton.isPressed();
rear=rearbutton.isPressed();
debugprintln ("cut ret jog frt rear ");
debugprint(cut);
debugprint(" , ");
debugprint(ret);
debugprint(" , ");
debugprint(front);
debugprint(" , ");
debugprint(rear);
}
void setmode() { // logic o set the mode
// note pins are high by default same for tripped and parked so 0 is on 1 is off
// tripped and parked by return 1 is not set 0 is set
debugprint ("tripped is ");
debugprintln(tripped);
debugprint("parked by return is ");
debugprintln (parkedbyreturn);
debugprint("cut is ");
debugprintln(cut);
debugprint("return switch is ");
debugprintln(ret);
debugprint("jog is ");
debugprintln(jog);
debugprint("front switch is ");
debugprintln(front);
debugprint("rear switch is ");
debugprintln(rear);
debugprint("position is ");
debugprintln(mystepper.currentPosition());
debugprint("mode is ");
debugprintln(mode);
if (cut == 1 && ret == 1 ) { //mode 1 cut and return switches are off defaulted high clear settings v if #2
mode = 'O'; // set mode to off
parkedbyreturn = 1; // reset parked by return
tripped = 1; //remember default to high do this even if tripped or parked
debugprintln(" mode if 1 mode O cut and return are off");
}
if (cut == 0 && tripped == 0 && front == 0) { // mode 2 was in return mode but hit front switch
mode = 'O';
tripped = 1;
parkedbyreturn = 0;
debugprintln("mode if 2 mode is O special case ");
// this is a special case that we went past 0 and hit front switch
} // end
if (cut == 0 && tripped == 0 && mystepper.currentPosition() <= 0) { // mode 3 in return mode from tripped but position is at 0 or less if 3
mode = 'O';
tripped = 1; // reset tripped
parkedbyreturn = 0; // set parked
debugprintln("mode if 3 cut and return tripped with position home");
}
if (cut == 0 && parkedbyreturn == 0) { //mode 4 cut switch is on but have been parked so stop if this happens untill we set cut switch to off position
mode = 'O';
tripped = 1; // reset tripped sonce now home
debugprintln("mode if 4 cut is on but parkedbyreturn");
}
if (ret == 0 && front == 0) { // mode 5 the return switch is held but but hit front limit
mode = 'O';
debugprintln("mode if 5 was returning but hit front switch");
}
if (cut == 0 && tripped == 1 && parkedbyreturn == 1) { //mode 6 in cut mode but not tripped yet and parked has been reset so cut the thing if 5
mode = 'C';
debugprintln("mode if 6 cut on but not tripped or parked");
}
if (cut == 0 && rear == 0 && tripped ==1) { // mode 7 in cut mode but hit rear stop aet up for returning to home
mode = 'H';
tripped = 0; //set tripped so we can return
parkedbyreturn = 1; // unset parked by return to 1 that is not set
// this says we hit the return swwitch so in return mode untill at home
debugprintln("mode if 7 cut and just hit rear limit");
}
if(cut == 0 && tripped == 0 && mystepper.currentPosition() >0){ // mode 8 we are in return form cut but not there yet
mode = 'H';
parkedbyreturn = 1; // just setting it to be sure
debugprintln("mode if 8 home ");
}
if (cut == 0 && jog == 0 && tripped == 1 && parkedbyreturn == 1) { // mode 9 in cut mode, and jogg pressed but not tripped, not parkedif 6
mode = 'J';
debugprintln("mode if 9 cut and jog npot tripped not parked");
}
if (cut == 0 && tripped == 0 && mystepper.currentPosition() <= 0) { // mode 10 was cutting hit return switch and have returned to a home
// Serial.println(" home from return");
mode = 'O';
parkedbyreturn = 0; // we are home so set parked by home
tripped = 1; // reset the tripped variable
debugprintln(" mode if 10 was returning but hit home count");
}
if (ret == 0 && front == 1) { // mode 11
mode = 'R'; // ret switch set and front not hit
}
}