Hier werden die Unterschiede zwischen zwei Versionen gezeigt.
Beide Seiten der vorigen Revision Vorhergehende Überarbeitung Nächste Überarbeitung | Vorhergehende Überarbeitung | ||
mechatronik:sose24:remote-plotter:code [2024/07/31 10:26] TPfoch [Arduino] |
mechatronik:sose24:remote-plotter:code [2024/07/31 10:29] (aktuell) TPfoch [Backend] |
||
---|---|---|---|
Zeile 44: | Zeile 44: | ||
} | } | ||
</file> | </file> | ||
- | =====Motor===== | + | ====Axies==== |
- | <file C++ motor_mtrobo.cpp> | + | <file C++ Axies.hpp> |
#pragma once | #pragma once | ||
- | #include <math.h> | + | #include "AccelStepper.h" |
+ | #include "MultiStepper.h" | ||
#ifndef PI | #ifndef PI | ||
#define PI 3.14159265358979 | #define PI 3.14159265358979 | ||
#endif | #endif | ||
- | class Motor{ | + | |
+ | struct Point {double x,y;}; | ||
+ | struct Angles {double root, ext;}; | ||
+ | |||
+ | class Axies | ||
+ | { | ||
public: | public: | ||
- | // return inaccuarrcy | + | virtual void moveTo(Point p)=0; |
- | virtual double setAngle(double angle)=0; | + | |
- | virtual double update(int steps)=0; | + | |
}; | }; | ||
- | class StepperMotor : public Motor | + | struct Motor |
{ | { | ||
- | double partial=0; | + | AccelStepper stepper; |
- | int speed, | + | int stepsPerRev=-1; |
- | stepsPerRev; | + | Motor(AccelStepper stepper, int stepsPerRev, int speed=4000): |
- | double target=0; | + | stepper(stepper), stepsPerRev(stepsPerRev) |
- | int current=0; | + | { |
- | public: | + | this->stepper.setAcceleration(1000); |
- | StepperMotor(int stepsPerRev, int speed=5) | + | this->stepper.setMaxSpeed(speed); |
- | : speed(speed), stepsPerRev(stepsPerRev) | + | this->stepper.setSpeed(speed); |
- | {} | + | } |
- | // return inaccuarrcy | + | |
- | double setAngle(double angle) override | + | long getSteps(double deg) |
- | { | + | { |
- | target = angle*stepsPerRev/360.0; | + | return deg/360.0*stepsPerRev; |
- | } | + | } |
- | double update(int steps) override | + | |
- | { | + | |
- | double delta = target/steps+partial; | + | |
- | partial = delta-(int)delta; | + | |
- | current+=delta; | + | |
- | stepBy(delta); | + | |
- | return 0; | + | |
- | } | + | |
- | private: | + | |
- | virtual void stepBy(int delta) =0; | + | |
}; | }; | ||
- | #include "Stepper.h" | ||
- | class SmallMotor : public StepperMotor { | ||
- | Stepper s; | ||
+ | class Arm | ||
+ | { | ||
+ | double rootLen, extLen; | ||
+ | Motor root, ext; | ||
+ | MultiStepper ms; | ||
public: | public: | ||
- | SmallMotor(int in1, int in2, int in3, int in4, int stepsPerRev, int speed=5) | + | Arm(double rootLen, double extLen, Motor root, Motor ext); |
- | : s(stepsPerRev, in1, in2, in3, in4), StepperMotor(stepsPerRev, speed) | + | void moveTo(Point p); |
- | { | + | |
- | s.setSpeed(speed); | + | |
- | } | + | |
private: | private: | ||
- | void stepBy(int delta) override | + | //calculates the angles of the two sections so the end of the second is at point p |
- | { | + | Angles pointToAngles(Point p); |
- | Serial.println(delta); | + | |
- | s.step(delta); | + | |
- | } | + | |
}; | }; | ||
+ | </file> | ||
+ | <file C++ Axies.cpp> | ||
+ | #include "Axies.hpp" | ||
- | #include "AccelStepper.h" | + | Arm::Arm(double rootLen, double extLen, Motor root, Motor ext) : |
+ | rootLen(rootLen), extLen(extLen), ms(), root(root), ext(ext) | ||
+ | { | ||
+ | ms.addStepper(root.stepper); | ||
+ | ms.addStepper(ext.stepper); | ||
+ | } | ||
+ | |||
+ | |||
+ | void Arm::moveTo(Point p) | ||
+ | { | ||
+ | Angles angle = pointToAngles(p); // 0-360 | ||
+ | Serial.println("Root: " + String(angle.root) + "°->" + String(root.getSteps(angle.root))); | ||
+ | Serial.println("Ext: " + String(angle.ext) + "°->" + String(ext.getSteps(angle.root))); | ||
+ | long pos[2] = {root.getSteps(angle.root), ext.getSteps(angle.ext)}; | ||
+ | ms.moveTo(pos); | ||
+ | ms.runSpeedToPosition(); | ||
+ | } | ||
+ | |||
+ | Angles Arm::pointToAngles(Point p) | ||
+ | { | ||
+ | double ph2= acos( | ||
+ | (p.x*p.x+p.y*p.y-rootLen*rootLen-extLen*extLen)/ | ||
+ | (2*rootLen*extLen)); | ||
+ | |||
+ | double phi1 = atan2(p.y,p.x) | ||
+ | -atan2(extLen*sin(ph2), | ||
+ | (rootLen+extLen*cos(ph2))); | ||
+ | |||
+ | return {phi1/PI*180, ph2/PI*180}; | ||
+ | } | ||
+ | </file> | ||
+ | ====Gantry==== | ||
+ | <file C++ Gantry.hpp> | ||
+ | #pragma once | ||
+ | #include <Servo.h> | ||
+ | |||
+ | class Gantry | ||
+ | { | ||
+ | Servo use, // servo for lowering tool | ||
+ | select;// Servo to switch between tools | ||
+ | // ^ currently unused | ||
- | class AccelMotor : public StepperMotor { | ||
- | AccelStepper stepper; | ||
public: | public: | ||
- | AccelMotor(int stepPin, int dirPin, int stepsPerRev, int speed=1000) | + | Gantry(int usePin, int selectPin) |
- | : stepper(1, stepPin, dirPin), StepperMotor(stepsPerRev, speed) | + | |
{ | { | ||
- | stepper.setCurrentPosition(0); | + | use.attach(usePin); |
- | stepper.setMaxSpeed(10000); | + | select.attach(selectPin); |
- | stepper.setAcceleration(500); | + | |
- | stepper.setSpeed(500); | + | |
} | } | ||
+ | enum Tool { | ||
+ | NONE, | ||
+ | PEN | ||
+ | }; | ||
+ | void setTool(Tool tool); | ||
- | // double update() override | ||
- | // { | ||
- | // if(stepper.currentPosition() < target) | ||
- | // { | ||
- | // stepper.setSpeed(speed); | ||
- | // stepper.runSpeed(); | ||
- | // } | ||
- | // else if(stepper.currentPosition() > target) | ||
- | // { | ||
- | // stepper.setSpeed(-speed); | ||
- | // stepper.runSpeed(); | ||
- | // } else { | ||
- | // stepper.setSpeed(0); | ||
- | // stepper.runSpeed(); | ||
- | // } | ||
- | // } | ||
- | private: | ||
- | void stepBy(int delta) override | ||
- | { | ||
- | stepper.moveTo(stepper.currentPosition()+delta); | ||
- | stepper.runToPosition(); | ||
- | } | ||
}; | }; | ||
+ | </file> | ||
+ | <file C++ Gantry.cpp> | ||
+ | #include "Gantry.hpp" | ||
- | #include <Servo.h> | + | void Gantry::setTool(Tool tool) |
+ | { | ||
+ | // maybe second servo for tool switch | ||
- | class MotorServo : public Motor { | + | // dummy implementation |
- | Servo s; | + | use.write(180*(tool==PEN)); |
- | uint8_t pin; | + | } |
- | double currentAngle=0, | + | |
- | speed; | + | |
- | public: | + | |
- | MotorServo(uint8_t pin, double speed=100) : pin(pin), speed(speed) | + | |
- | { | + | |
- | s.attach(pin); | + | |
- | } | + | |
- | double setAngle(double angle) override | + | |
- | { | + | |
- | double dAngle = angle - currentAngle; | + | |
- | Serial.println(dAngle); | + | |
- | s.write(angle); | + | |
- | delay(1000/speed*dAngle); | + | |
- | currentAngle=angle; | + | |
- | return 0; | + | |
- | } | + | |
- | double update() {}; | + | |
- | }; | + | |
</file> | </file> | ||
+ | |||
+ | |||
=====Frontend===== | =====Frontend===== | ||
Dieses Programm ist mithilfe des Tkinter-Moduls geschrieben. Hiermt hat man eine Zeichenoberfläche, welche die aktuelle Zeichnung speichern kann als auch die Koordinaten der Zeichnung während Laufzeit ausgibt und an den Arduino schicken kann.(?) | Dieses Programm ist mithilfe des Tkinter-Moduls geschrieben. Hiermt hat man eine Zeichenoberfläche, welche die aktuelle Zeichnung speichern kann als auch die Koordinaten der Zeichnung während Laufzeit ausgibt und an den Arduino schicken kann.(?) |