Imagine | Develop | Create

#include "config.h"
#include <SPI.h>
#include <SD.h>
//http://marlinfw.org/meta/gcode/
#include <Arduino.h>
#include <gcode.h>
#include <AccelStepper.h>
#include <Plex.h>
#define XMultiplier 80
#define YMultiplier 80
#define CircleRatio 1
#define Speed 1000 //200
#define Acceleration 50000000.0
#define XUpperLimitSelect 2
#define XLowerLimitSelect 3
#define YUpperLimitSelect 4
#define YLowerLimitSelect 5
#define scrollButton 6
#define selectButton 7
#define ASelect 1
#define BSelect 7
//#define machineInputPin A7
//#define UserInputPin A4
#define StepPin A2
#define DirPin A5
#define enablePin A4
#define PlasmaPin 3
#define SDchipSelectPin 10
const float pi = 3.14159265359;
double X;
double Y;
int encoder0Pos = 0;
int encoder0PinALast = LOW;
unsigned long currentPosInFile = 0;
bool Running = false;
long inPos = 0;
void homeMachine();
void PlasmaOn();
void PlasmaOff();
void Enabled();
void Disabled();
commandscallback commands[6] = {{"G28",homeMachine},
{"M3",PlasmaOn},
{"M4",PlasmaOn},
{"M5",PlasmaOff},
{"M17",Enabled},
{"M18",Disabled}};
gcode Commands(6,commands);
AccelStepper stepperA;
AccelStepper stepperB;
Plex PLEX;
File dir;
File Files;
int FileNumber = 0;
bool displayed = false;
void setup()
{
pinMode(enablePin, OUTPUT);
pinMode(PlasmaPin, OUTPUT);
digitalWrite(enablePin,HIGH);
digitalWrite(PlasmaPin,LOW);
Commands.begin("OK");
stepperA = AccelStepper(1,StepPin,DirPin);
stepperA.setMaxSpeed(Speed);
stepperA.setCurrentPosition(0);
stepperA.setAcceleration(Acceleration);
stepperB = AccelStepper(1,StepPin,DirPin);
stepperB.setMaxSpeed(Speed);
stepperB.setCurrentPosition(0);
stepperB.setAcceleration(Acceleration);
PLEX.lcd.setCursor(0, 0);
PLEX.lcd.print("Start");
}
void loop()
{
if (!SD.begin(SDchipSelectPin))
{
PLEX.lcd.setCursor(0,0);
PLEX.lcd.print("can not read SD!");
PLEX.lcd.setCursor(0,1);
PLEX.lcd.print(" ");
displayed = false;
FileNumber=0;
}
else
{
if (PLEX.digitalReadC(scrollButton) == HIGH)
{
Serial.println("scrollButton");
while(PLEX.digitalReadC(scrollButton) == HIGH);
FileNumber++;
displayed = false;
}
if(displayed)
{
if(FileNumber<0)
FileNumber=0;
Files = getFile(FileNumber);
if(Files)
{
PrintFileName(Files);
displayed = true;
}
else if(FileNumber == 0)
{
PLEX.lcd.clear();
PLEX.lcd.print("can not read SD!");
displayed = true;
}
else
{
FileNumber--;
}
}
if (PLEX.digitalReadC(selectButton) == HIGH)
{
Serial.println("selectButton");
File dataFile = getFile(FileNumber);
if(dataFile)
{
Enabled();
while (dataFile.available())
{
char SDinput = dataFile.read();
Serial.print(SDinput);
if(Commands.available(SDinput))
{
if(Commands.GetValue('G') == 0 || Commands.GetValue('G') == 1)
{
Serial.println("gotoLocation");
gotoLocation();
}
else if(Commands.GetValue('G') == 2)
arc(1);
else if(Commands.GetValue('G') == 3)
arc(0);
else if(Commands.GetValue('G') == 4)
{
if(Commands.availableValue('S'))
delay(Commands.GetValue('S')*1000);
else if(Commands.availableValue('P'))
delay(Commands.GetValue('P'));
}
Commands.clearBuffer();
}
}
Disabled();
}
dataFile.close();
PLEX.lcd.clear();
PLEX.lcd.print(" Finished ");
displayed = false;
while(PLEX.digitalReadC(selectButton) == LOW);
while(PLEX.digitalReadC(selectButton) == HIGH);
}
}
}
File getFile(int number)
{
int count = 0;
dir = SD.open("/");
while (true)
{
File entry = dir.openNextFile();
if (!entry.available())
{
return entry;
break;
}
if (!entry.isDirectory())
{
if(number == count)return entry;
count++;
}
entry.close();
}
return;
}
void PrintFileName(File entry)
{
PLEX.lcd.clear();
PLEX.lcd.setCursor(0,0);
PLEX.lcd.print(entry.name());
PLEX.lcd.setCursor(0,1);
PLEX.lcd.print(entry.size(), DEC);
}
/****************************** MACHINE CONTROL ******************************/
void PlasmaOn()
{
digitalWrite(PlasmaPin,HIGH);
PLEX.lcd.clear();
PLEX.lcd.print("Plasma on");
}
void PlasmaOff()
{
digitalWrite(PlasmaPin,LOW);
PLEX.lcd.clear();
PLEX.lcd.print("Plasma off");
}
void Enabled()
{
digitalWrite(enablePin,LOW);
PLEX.lcd.setCursor(0, 0);
PLEX.lcd.print("Enabled");
}
void Disabled()
{
digitalWrite(enablePin,HIGH);
PLEX.lcd.setCursor(0, 0);
PLEX.lcd.print("Disabled");
}
/****************************** MOTOR CONTROL ******************************/
void gotoLocation()
{
if(Commands.availableValue('X'))
X = Commands.GetValue('X');
if(Commands.availableValue('Y'))
Y = Commands.GetValue('Y');
setMotorLocation(X,Y);
runStepperMotors();
}
void arc(boolean clockwise)
{
/*
http://marlinfw.org/docs/gcode/G002-G003.html
****** I,J Form ******
- I specifies an X offset. J specifies a Y offset.
- At least one of the I J parameters is required.
- X and Y can be omitted to do a complete circle.
- The given X Y is not error-checked. The arc ends based on the angle of the destination.
- Mixing I or J with R will throw an error.
****** R Form ******
- R specifies the radius. X or Y is required.
- Omitting both X and Y will throw an error.
- X or Y must differ from the current XY position.
- Mixing R with I or J will throw an error.
*/
/*
double startX = X;
double startY = Y;
double finishedX = X;
double finishedY = Y;
double XCenter = X;
double YCenter = Y;
double radius = 0;
//I,J Form
if((Commands.availableValue('I') || Commands.availableValue('J')) && !Commands.availableValue('R'))
{
double J = 0;
double I = 0;
if(Commands.availableValue('I'))
I = Commands.GetValue('I');
if(Commands.availableValue('J'))
J = Commands.GetValue('J');
if(Commands.availableValue('X'))
{
finishedX = Commands.GetValue('X');
}
if(Commands.availableValue('Y'))
{
finishedY = Commands.GetValue('Y');
}
XCenter = startX + I;
YCenter = startY + J;
radius = sqrt(J*J+I*I);
}
// R Form
else if (!Commands.availableValue('I') && !Commands.availableValue('J') && Commands.availableValue('R') && (Commands.availableValue('X') || Commands.availableValue('Y')))
{
if(Commands.availableValue('R'))
radius = Commands.GetValue('R');
if(Commands.availableValue('X'))
{
finishedX = Commands.GetValue('X');
}
if(Commands.availableValue('Y'))
{
finishedY = Commands.GetValue('Y');
}
/*
double q = sqrt((finishedX-startX)*(finishedX-startX) + (finishedY-startY)*(finishedY-startY));
double x1 = x3 + sqrt(r^2-(q/2)*(q/2))*(startY-finishedY)/q
double y1 = y3 + sqrt(r^2-(q/2)*(q/2))*(finishedX-startX)/q
double x2 = x3 - sqrt(r^2-(q/2)*(q/2))*(startY-finishedY)/q
double y2 = y3 - sqrt(r^2-(q/2)*(q/2))*(finishedX-startX)/q
XCenter = x1;
YCenter = x2;* /
}
float startAngle = atan2((startY-YCenter), (startX-XCenter));
float finishedAngle = atan2((finishedY-YCenter), (finishedX-XCenter));
float Curcunfrence = atan2((finishedY-YCenter), (finishedX-XCenter));
double AngleBetween = startAngle - finishedAngle;
if(startAngle == finishedAngle)
AngleBetween = 2*pi;
/* if(clockwise)
AngleBetween = 2*pi - AngleBetween;
* /
double NewfinishedAngle = startAngle - finishedAngle;
/*
if(clockwise)
{
if(finishedAngle > startAngle)
finishedAngle = finishedAngle-2*pi;
for(double i = startAngle; i<finishedAngle)
{
setMotorLocation(X,Y);
runStepperMotors();
}
}
else
{
if(finishedAngle < startAngle)
finishedAngle = finishedAngle+2*pi;
for(double i = startAngle; i)
{
setMotorLocation(X,Y);
runStepperMotors();
}
}
setMotorLocation(finishedX,finishedY);
runStepperMotors();
Serial.println();
Serial.println(startX);
Serial.println(startY);
Serial.println(finishedX);
Serial.println(finishedY);
Serial.println(J);
Serial.println(I);
Serial.println(YCenter);
Serial.println(radius);
Serial.println(startAngle);
Serial.println(finishedAngle);
Serial.println(AngleBetween);* /
*/
}
void homeMachine()
{
/*setMotorLocation(-100000,-100000);
while((PLEX.digitalReadC(XUpperLimitSelect) == LOW && PLEX.digitalReadC(XLowerLimitSelect) == LOW) || (PLEX.digitalReadC(YUpperLimitSelect) == LOW && PLEX.digitalReadC(YLowerLimitSelect) == LOW))
{
PLEX.selectD(BSelect);
stepperA.run();
PLEX.selectD(ASelect);
stepperB.run();
}
X = 0;
Y = 0;
stepperA.setCurrentPosition(0);
stepperB.setCurrentPosition(0);*/
}
void setMotorLocation(double NewX,double NewY)
{
X = NewX;
Y = NewY;
double x = NewX*XMultiplier;
double y = NewY*YMultiplier;
double XCurrent = 0.5*(stepperA.currentPosition() + stepperB.currentPosition());
double YCurrent = 0.5*(stepperA.currentPosition() - stepperB.currentPosition());
double R = sqrt((y-YCurrent)*(y-YCurrent)+(x-XCurrent)*(x-XCurrent));
double t = R/Speed;
double a = x+y;
double b = x-y;
double Speeda = abs(a - stepperA.currentPosition())/t;
double Speedb = abs(b - stepperB.currentPosition())/t;
stepperA.setMaxSpeed(Speeda);
stepperB.setMaxSpeed(Speedb);
stepperA.setSpeed(Speeda);
stepperB.setSpeed(Speedb);
stepperA.moveTo(a);
stepperB.moveTo(b);
PLEX.lcd.setCursor(0, 1);
PLEX.lcd.print(NewX);
PLEX.lcd.print(",");
PLEX.lcd.print(NewY);
PLEX.lcd.print(" ");
}
double currentX()
{
return (int)(0.5*(stepperA.currentPosition() + stepperB.currentPosition()));
}
double currentY()
{
return (int)(0.5*(stepperA.currentPosition() - stepperB.currentPosition()));
}
void runStepperMotors()
{
//if(testLimit(XUpperLimitSelect) == HIGH && currentX()<X){ setMotorLocation(currentX(),Y);}
//if(testLimit(XLowerLimitSelect) == HIGH && currentX()>X){ setMotorLocation(currentX(),Y);}
//if(testLimit(YUpperLimitSelect) == HIGH && currentY()<Y){ setMotorLocation(X,currentY());}
//if(testLimit(YLowerLimitSelect) == HIGH && currentY()>Y){ setMotorLocation(X,currentY());}
while(stepperA.distanceToGo() != 0 || stepperB.distanceToGo() != 0)
{
PLEX.selectD(BSelect);
stepperA.run();
PLEX.selectD(ASelect);
stepperB.run();
}
}