use atmega32 to control stepper motors

Signed-off-by: Stepan Usatyuk <usaatyuk@ustk.me>
This commit is contained in:
2019-05-16 14:36:40 +03:00
parent c7299e7916
commit a96a47f0f9
26 changed files with 513 additions and 200 deletions

View File

@@ -1,6 +0,0 @@
#define EGG_DIA 35.0
#define Y_DEGREES_PER_MM (360 / (PI * EGG_DIA))
#define X_LIMIT 70.0
#define EGG_LENGTH 50.0
#define X_DEGREES_PER_MM (X_LIMIT / EGG_LENGTH)

View File

@@ -1,21 +1,9 @@
#include <Arduino.h>
#include "common/Commands.h"
#ifndef PARSER_H
#define PARSER_H
enum command {
unk,
G00,
G01,
M99,
};
enum bcAxis {
X = 1,
Y = 2,
Z = 3,
};
float *parseGCode(String gcode);
#endif

View File

@@ -1,25 +0,0 @@
#include <Arduino.h>
#include "Stepper.h"
#include "Pen.h"
#include "EggConstants.h"
#include "StepperTimer.h"
#ifndef GLOBALS_H
#define GLOBALS_H
#define STEPS_PER_REVOLUTION 4076
#define DEF_RPM 2
Stepper eggStepper(D1, D2, D3, D4, STEPS_PER_REVOLUTION, 10, 0,
Y_DEGREES_PER_MM, typeBoth, false);
Stepper servoStepper(D5, D6, D7, D8, -STEPS_PER_REVOLUTION, 0, X_LIMIT,
X_DEGREES_PER_MM, typeClockwise, false);
StepperTimer eggStepperTimer(DEF_RPM, STEPS_PER_REVOLUTION);
StepperTimer servoStepperTimer(DEF_RPM, STEPS_PER_REVOLUTION);
Pen pen(D0, 100, 150);
String inString;
#endif

View File

@@ -1,24 +0,0 @@
#include <Servo.h>
#ifndef PEN_H
#define PEN_H
#define DELAY 15
class Pen {
private:
int posEngaged;
int posDisengaged;
bool engaged = true;
Servo servo;
public:
Pen(int pin, int posEngaged, int posDisengaged);
void engage();
void disengage();
void init();
bool getEngaged();
~Pen();
};
#endif

View File

@@ -1,46 +0,0 @@
#ifndef STEPPER_H
#define STEPPER_H
enum backlashCompType { typeClockwise, typeCounterClockwise, typeBoth };
class Stepper {
private:
int stepsPerRevolution;
int pin1;
int pin2;
int pin3;
int pin4;
int curStep = 1;
int remainingSteps;
int backlashSteps;
float degreesPerMM;
bool direction;
void clockwise();
void counterClockwise();
void step(int steps);
float pos = 0;
int limit;
bool compAlways;
backlashCompType backlashComp;
public:
Stepper(int pin1, int pin2, int pin3, int pin4, int stepsPerRevolution,
int backlashSteps, int limit, float degreesPerMM,
backlashCompType backlashComp, bool compAlways);
int getRemainingSteps();
void rotate(float degrees);
void rotateTo(float degrees);
void moveTo(float dist);
void setPos(float degrees);
float getDist(float degrees);
int degreesToSteps(float degrees);
int mmToSteps(float dist);
void doStep();
bool finished();
float getPos();
float getPosMm();
float getDistMm(float pos);
};
#endif

View File

@@ -1,19 +0,0 @@
#include <Ticker.h>
#include "Stepper.h"
#ifndef STEPPER_TIMER_H
#define STEPPER_TIMER_H
class StepperTimer {
private:
float speedDelay;
int stepsPerRevolution;
Ticker stepperTicker;
Stepper *stepper;
public:
StepperTimer(float rpm, int stepsPerRevolution);
void setStepper(Stepper *stepper);
void setRPM(float rpm);
void tick();
};
#endif

View File

@@ -0,0 +1 @@
../../common

View File

@@ -4,6 +4,10 @@
float bytecode[4] = {-1, -1, -1, -1};
float* parseGCode(String gcode) {
for (int i = 0; i < 4; i++) {
bytecode[i] = -1.0F;
}
char commandStringIn[50];
char commandString[50];

View File

@@ -1,36 +0,0 @@
#include "Pen.h"
#include <Servo.h>
Pen::Pen(int pin, int posEngaged, int posDisengaged)
: posEngaged(posEngaged), posDisengaged(posDisengaged) {
servo.attach(pin);
}
void Pen::engage() {
if (!engaged) {
for (int i = posDisengaged; i > posEngaged; i--) {
servo.write(i);
delay(DELAY);
}
}
engaged = true;
}
void Pen::disengage() {
if (engaged) {
for (int i = posEngaged; i < posDisengaged; i++) {
servo.write(i);
delay(DELAY);
}
}
engaged = false;
}
void Pen::init() {
servo.write(posDisengaged);
engaged = false;
}
bool Pen::getEngaged() { return engaged; }
Pen::~Pen() {}

View File

@@ -1,223 +0,0 @@
#include "Stepper.h"
#include <Arduino.h>
void Stepper::clockwise() {
switch (curStep) {
case 1:
digitalWrite(pin4, HIGH);
digitalWrite(pin3, LOW);
digitalWrite(pin2, LOW);
digitalWrite(pin1, LOW);
break;
case 2:
digitalWrite(pin4, HIGH);
digitalWrite(pin3, HIGH);
digitalWrite(pin2, LOW);
digitalWrite(pin1, LOW);
break;
case 3:
digitalWrite(pin4, LOW);
digitalWrite(pin3, HIGH);
digitalWrite(pin2, LOW);
digitalWrite(pin1, LOW);
break;
case 4:
digitalWrite(pin4, LOW);
digitalWrite(pin3, HIGH);
digitalWrite(pin2, HIGH);
digitalWrite(pin1, LOW);
break;
case 5:
digitalWrite(pin4, LOW);
digitalWrite(pin3, LOW);
digitalWrite(pin2, HIGH);
digitalWrite(pin1, LOW);
break;
case 6:
digitalWrite(pin4, LOW);
digitalWrite(pin3, LOW);
digitalWrite(pin2, HIGH);
digitalWrite(pin1, HIGH);
break;
case 7:
digitalWrite(pin4, LOW);
digitalWrite(pin3, LOW);
digitalWrite(pin2, LOW);
digitalWrite(pin1, HIGH);
break;
case 8:
digitalWrite(pin4, HIGH);
digitalWrite(pin3, LOW);
digitalWrite(pin2, LOW);
digitalWrite(pin1, HIGH);
}
if (curStep == 8) {
curStep = 1;
} else {
curStep++;
}
}
void Stepper::counterClockwise() {
switch (curStep) {
case 1:
digitalWrite(pin1, HIGH);
digitalWrite(pin2, LOW);
digitalWrite(pin3, LOW);
digitalWrite(pin4, LOW);
break;
case 2:
digitalWrite(pin1, HIGH);
digitalWrite(pin2, HIGH);
digitalWrite(pin3, LOW);
digitalWrite(pin4, LOW);
break;
case 3:
digitalWrite(pin1, LOW);
digitalWrite(pin2, HIGH);
digitalWrite(pin3, LOW);
digitalWrite(pin4, LOW);
break;
case 4:
digitalWrite(pin1, LOW);
digitalWrite(pin2, HIGH);
digitalWrite(pin3, HIGH);
digitalWrite(pin4, LOW);
break;
case 5:
digitalWrite(pin1, LOW);
digitalWrite(pin2, LOW);
digitalWrite(pin3, HIGH);
digitalWrite(pin4, LOW);
break;
case 6:
digitalWrite(pin1, LOW);
digitalWrite(pin2, LOW);
digitalWrite(pin3, HIGH);
digitalWrite(pin4, HIGH);
break;
case 7:
digitalWrite(pin1, LOW);
digitalWrite(pin2, LOW);
digitalWrite(pin3, LOW);
digitalWrite(pin4, HIGH);
break;
case 8:
digitalWrite(pin1, HIGH);
digitalWrite(pin2, LOW);
digitalWrite(pin3, LOW);
digitalWrite(pin4, HIGH);
}
if (curStep == 8) {
curStep = 1;
} else {
curStep++;
}
}
Stepper::Stepper(int pin1, int pin2, int pin3, int pin4, int stepsPerRevolution,
int backlashSteps, int limit, float degreesPerMM,
backlashCompType backlashComp, bool compAlways)
: pin1(pin1),
pin2(pin2),
pin3(pin3),
pin4(pin4),
stepsPerRevolution(stepsPerRevolution),
backlashSteps(backlashSteps),
limit(limit),
degreesPerMM(degreesPerMM),
backlashComp(backlashComp),
compAlways(compAlways) {
pinMode(pin1, OUTPUT);
pinMode(pin2, OUTPUT);
pinMode(pin3, OUTPUT);
pinMode(pin4, OUTPUT);
}
void Stepper::doStep() {
if (remainingSteps > 0) {
if (direction) {
clockwise();
} else {
counterClockwise();
}
remainingSteps--;
}
}
void Stepper::step(int steps) {
if (steps == 0) {
return;
}
if (steps > 0) {
if (!direction || compAlways) {
if (backlashComp == typeClockwise || backlashComp == typeBoth) {
remainingSteps += backlashSteps;
}
}
direction = true;
remainingSteps += steps;
} else {
if (direction || compAlways) {
if (backlashComp == typeCounterClockwise ||
backlashComp == typeBoth) {
remainingSteps += backlashSteps;
}
}
direction = false;
remainingSteps += abs(steps);
}
}
int Stepper::degreesToSteps(float degrees) {
return (degrees * stepsPerRevolution) / 360;
}
void Stepper::rotate(float degrees) {
int steps = degreesToSteps(degrees);
if (!limit) {
pos = fmod((pos + degrees), 360);
if (pos < 0) {
pos = 360 + pos;
}
step(steps);
} else {
if (degrees + pos > limit) {
step(degreesToSteps(limit - pos));
pos = limit;
} else if (degrees + pos < 0) {
step(degreesToSteps(-pos));
pos = 0;
} else {
step(steps);
pos += degrees;
}
}
}
float Stepper::getDist(float degrees) {
float mod = fmod(degrees, 360);
return abs(mod - pos);
}
void Stepper::rotateTo(float degrees) {
float mod = fmod(degrees, 360);
rotate(mod - pos);
}
void Stepper::moveTo(float dist) { rotateTo(dist * degreesPerMM); }
int Stepper::mmToSteps(float dist) {
return abs(degreesToSteps(dist * degreesPerMM));
}
float Stepper::getPosMm() { return pos / degreesPerMM; }
float Stepper::getDistMm(float pos) { return abs(getPosMm() - pos); }
void Stepper::setPos(float degrees) { pos = degrees; }
int Stepper::getRemainingSteps() { return remainingSteps; }
bool Stepper::finished() { return remainingSteps == 0; }
float Stepper::getPos() { return pos; }

View File

@@ -1,19 +0,0 @@
#include "StepperTimer.h"
#include "Stepper.h"
StepperTimer::StepperTimer(float rpm, int stepsPerRevolution)
: stepsPerRevolution(stepsPerRevolution) {
stepperTicker.detach();
speedDelay = 60 / (rpm * stepsPerRevolution);
stepperTicker.attach(speedDelay, std::bind(&StepperTimer::tick, this));
}
void StepperTimer::setStepper(Stepper *_stepper) { stepper = _stepper; }
void StepperTimer::tick() { stepper->doStep(); }
void StepperTimer::setRPM(float rpm) {
stepperTicker.detach();
speedDelay = 60 / (rpm * stepsPerRevolution);
stepperTicker.attach(speedDelay, std::bind(&StepperTimer::tick, this));
}

View File

@@ -0,0 +1 @@
../../commonSrc

View File

@@ -1,116 +1,87 @@
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <Ticker.h>
#include "EggConstants.h"
#include <Wire.h>
#include "GCodeParser.h"
#include "Globals.h"
#include "Pen.h"
#include "Stepper.h"
#include "StepperTimer.h"
#include "common/Commands.h"
int RPM = DEF_RPM;
String inString;
bool waitingForNext;
bool needAdjust = false;
void sendCommand(float *command) {
if (command[0] != unk) {
Wire.beginTransmission(8);
byte txBuffer[4];
for (int i = 0; i < 4; i++) {
floatToBytes(txBuffer, command[i]);
Wire.write(txBuffer, 4);
}
Wire.endTransmission();
} else {
Serial.println("UNK");
}
Ticker adjustTicker;
void execCommand(float *command) {
if (command[0] == G01 || command[0] == G00) {
if (command[0] == G01) {
needAdjust = true;
if (command[X] != -1 && command[Y] != -1) {
float distX = servoStepper.getDistMm(command[X]);
float distY = eggStepper.getDistMm(command[Y]);
int stepsX = servoStepper.mmToSteps(distX);
int stepsY = eggStepper.mmToSteps(distY);
if (stepsX != 0 && stepsY != 0) {
if (stepsX > stepsY) {
float rpm = (float)RPM * (float)stepsY / (float)stepsX;
eggStepperTimer.setRPM(rpm);
} else if (stepsY > stepsX) {
float rpm = (float)RPM * (float)stepsX / (float)stepsY;
servoStepperTimer.setRPM(rpm);
}
}
}
} else {
needAdjust = false;
}
if (command[X] != -1) {
servoStepper.moveTo(command[X]);
}
if (command[Y] != -1) {
eggStepper.moveTo(command[Y]);
}
if (command[Z] < 0) {
pen.engage();
}
if (command[Z] >= 0) {
pen.disengage();
}
Wire.requestFrom(8, 1);
waitingForNext = true;
return;
}
if (command[0] == M99) {
Wire.requestFrom(8, 5 * sizeof(float));
float resp[5];
byte buffer[4];
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 4; j++) {
while (!Wire.available()) {
}
char read = Wire.read();
buffer[j] = read;
}
bytesToFloat(&resp[i], buffer);
}
Serial.println("Status:");
Serial.println("X: " + String(servoStepper.getPos()));
Serial.println("Y: " + String(eggStepper.getPos()));
Serial.println("Xmm: " + String(servoStepper.getPosMm()));
Serial.println("Ymm: " + String(eggStepper.getPosMm()));
Serial.println("PEN: " + String(pen.getEngaged()));
Serial.println("X: " + String(resp[servoRot]));
Serial.println("Y: " + String(resp[eggRot]));
Serial.println("Xmm: " + String(resp[servoPos]));
Serial.println("Ymm: " + String(resp[eggPos]));
Serial.println("PEN: " + String(resp[penPos]));
return;
}
}
void adjustRPM() {
if (needAdjust) {
cli();
int stepsX = servoStepper.getRemainingSteps();
int stepsY = eggStepper.getRemainingSteps();
if (stepsX > stepsY) {
float rpm = (float)RPM * (float)stepsY / (float)stepsX;
eggStepperTimer.setRPM(rpm);
} else if (stepsY > stepsX) {
float rpm = (float)RPM * (float)stepsX / (float)stepsY;
servoStepperTimer.setRPM(rpm);
} else {
eggStepperTimer.setRPM(RPM);
servoStepperTimer.setRPM(RPM);
}
sei();
}
}
void setup() {
WiFi.mode(WIFI_OFF);
Serial.begin(115200);
eggStepperTimer.setStepper(&eggStepper);
servoStepperTimer.setStepper(&servoStepper);
pen.init();
servoStepper.setPos(70);
adjustTicker.attach_ms(50, adjustRPM);
Wire.begin(D1, D2);
}
void loop() {
while (Serial.available() > 0) {
char inChar = Serial.read();
inString += inChar;
Serial.write(inChar);
if (inChar == '\n') {
inString.trim();
execCommand(parseGCode(inString));
while (!eggStepper.finished() || !servoStepper.finished()) {
delay(50);
sendCommand(parseGCode(inString));
while (waitingForNext) {
while (!Wire.available()) {
}
int response = Wire.read();
if (response == WAIT) {
delay(1);
Wire.requestFrom(8, 1);
} else if (response == NEXT) {
Serial.println("OK");
waitingForNext = false;
} else {
Serial.println("Error");
}
}
eggStepperTimer.setRPM(RPM);
servoStepperTimer.setRPM(RPM);
Serial.println("OK");
inString = "";
}
}