mirror of
https://github.com/usatiuk/EggbotWireless.git
synced 2025-10-26 16:57:48 +01:00
basic gcode sender thing
This commit is contained in:
@@ -1,7 +1,8 @@
|
|||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
|
import { GcodeSender } from "~GcodeSender";
|
||||||
|
|
||||||
export function AppComponent() {
|
export function AppComponent() {
|
||||||
return <div>Hello</div>;
|
return <GcodeSender />;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const App = AppComponent;
|
export const App = AppComponent;
|
||||||
|
|||||||
106
App/src/GcodeSender.tsx
Normal file
106
App/src/GcodeSender.tsx
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
import * as React from "react";
|
||||||
|
import { IEggbotStatus, getStatus, putCommand } from "~api/eggbot";
|
||||||
|
|
||||||
|
interface IGcodeSenderComponentState {
|
||||||
|
eggbotStatus: IEggbotStatus | null;
|
||||||
|
gcodeSet: boolean;
|
||||||
|
gcodeInput: string;
|
||||||
|
|
||||||
|
gcodeLinesSent: string[];
|
||||||
|
gcodeLinesQueue: string[];
|
||||||
|
|
||||||
|
executing: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
const defaultState: IGcodeSenderComponentState = {
|
||||||
|
eggbotStatus: null,
|
||||||
|
gcodeSet: false,
|
||||||
|
gcodeInput: "",
|
||||||
|
executing: false,
|
||||||
|
gcodeLinesSent: [],
|
||||||
|
gcodeLinesQueue: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
export class GcodeSenderComponent extends React.PureComponent<
|
||||||
|
{},
|
||||||
|
IGcodeSenderComponentState
|
||||||
|
> {
|
||||||
|
constructor() {
|
||||||
|
super(null);
|
||||||
|
this.state = defaultState;
|
||||||
|
|
||||||
|
this.handleInputChange = this.handleInputChange.bind(this);
|
||||||
|
this.handleSend = this.handleSend.bind(this);
|
||||||
|
this.update = this.update.bind(this);
|
||||||
|
|
||||||
|
setInterval(this.update, 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
public handleInputChange(
|
||||||
|
event:
|
||||||
|
| React.FormEvent<HTMLInputElement>
|
||||||
|
| React.FormEvent<HTMLTextAreaElement>,
|
||||||
|
) {
|
||||||
|
const target = event.currentTarget;
|
||||||
|
const value = target.value;
|
||||||
|
const name = target.name;
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
[name]: value,
|
||||||
|
} as any);
|
||||||
|
}
|
||||||
|
|
||||||
|
public handleSend() {
|
||||||
|
const lines = this.state.gcodeInput.split("\n");
|
||||||
|
this.setState({ gcodeLinesQueue: lines, executing: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
public async update() {
|
||||||
|
const status = await getStatus();
|
||||||
|
console.log(status);
|
||||||
|
const gcodeLinesQueue = [...this.state.gcodeLinesQueue];
|
||||||
|
const gcodeLinesSent = [...this.state.gcodeLinesSent];
|
||||||
|
const { executing } = this.state;
|
||||||
|
if (executing && status.commandQueue < 5) {
|
||||||
|
if (gcodeLinesQueue && gcodeLinesQueue.length > 0) {
|
||||||
|
const command = gcodeLinesQueue.shift();
|
||||||
|
putCommand(command.substr(0, 50));
|
||||||
|
gcodeLinesSent.push(command);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState({ gcodeLinesQueue, gcodeLinesSent });
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const queuedCommands = this.state.gcodeLinesQueue.map(el => (
|
||||||
|
<div>{el}</div>
|
||||||
|
));
|
||||||
|
|
||||||
|
const executedCommands = this.state.gcodeLinesSent.map(el => (
|
||||||
|
<div>{el}</div>
|
||||||
|
));
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
{this.state.executing ? (
|
||||||
|
<div>
|
||||||
|
<div style={{ color: "green" }}>{executedCommands}</div>
|
||||||
|
<div>{queuedCommands}</div>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div>
|
||||||
|
<textarea
|
||||||
|
name="gcodeInput"
|
||||||
|
value={this.state.gcodeInput}
|
||||||
|
onChange={this.handleInputChange}
|
||||||
|
/>
|
||||||
|
<button onClick={this.handleSend}>send</button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const GcodeSender = GcodeSenderComponent;
|
||||||
20
App/src/api/eggbot/index.ts
Normal file
20
App/src/api/eggbot/index.ts
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
import { fetchJSON } from "../utils";
|
||||||
|
|
||||||
|
export interface IEggbotStatus {
|
||||||
|
commandQueue: number;
|
||||||
|
eggDia: number;
|
||||||
|
eggLen: number;
|
||||||
|
feedrate: number;
|
||||||
|
mmE: number;
|
||||||
|
mmS: number;
|
||||||
|
pEng: number;
|
||||||
|
xLim: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function putCommand(command: string) {
|
||||||
|
return fetchJSON("/putCommand", "POST", command);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getStatus() {
|
||||||
|
return fetchJSON("/getStatus", "GET");
|
||||||
|
}
|
||||||
22
App/src/api/utils.ts
Normal file
22
App/src/api/utils.ts
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
const root = "http://eggbot.local";
|
||||||
|
|
||||||
|
export async function fetchJSON(
|
||||||
|
path: string,
|
||||||
|
method: string,
|
||||||
|
body?: string | object,
|
||||||
|
headers?: Record<string, string>,
|
||||||
|
) {
|
||||||
|
if (typeof body === "object") {
|
||||||
|
body = JSON.stringify(body);
|
||||||
|
}
|
||||||
|
const response = await fetch(root + path, {
|
||||||
|
method,
|
||||||
|
body,
|
||||||
|
headers: {
|
||||||
|
...headers,
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const json = await response.json();
|
||||||
|
return json;
|
||||||
|
}
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||||
<title>Writer</title>
|
<title>Eggbot</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="body">
|
<div id="body">
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ class WebAPI {
|
|||||||
void handleNotFound();
|
void handleNotFound();
|
||||||
void handlePutCommand();
|
void handlePutCommand();
|
||||||
void handleGetStatus();
|
void handleGetStatus();
|
||||||
|
void sendCORS();
|
||||||
|
|
||||||
String getStatusJson();
|
String getStatusJson();
|
||||||
public:
|
public:
|
||||||
WebAPI();
|
WebAPI();
|
||||||
|
|||||||
@@ -37,16 +37,19 @@ void QueueManager::loopRoutine() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void QueueManager::putCommand(std::string cmd) {
|
void QueueManager::putCommand(std::string cmd) {
|
||||||
|
if (!std::isalnum(cmd[0])) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (toupper(cmd[0]) == 'L') {
|
if (toupper(cmd[0]) == 'L') {
|
||||||
lCommandQueue.emplace(cmd);
|
lCommandQueue.emplace(cmd);
|
||||||
} else {
|
} else {
|
||||||
commandQueue.push(parseGCode(cmd));
|
Command cmdp = parseGCode(cmd);
|
||||||
|
commandQueue.push(cmdp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t QueueManager::execQueueSize() {
|
uint8_t QueueManager::execQueueSize() { return commandQueue.size(); }
|
||||||
return commandQueue.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
void QueueManager::putCommand(char *cmd) { putCommand(std::string(cmd)); }
|
void QueueManager::putCommand(char *cmd) { putCommand(std::string(cmd)); }
|
||||||
|
|
||||||
|
|||||||
@@ -23,16 +23,33 @@ String WebAPI::getStatusJson() {
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WebAPI::sendCORS() {
|
||||||
|
server.sendHeader("Access-Control-Allow-Origin", "*");
|
||||||
|
server.sendHeader("Access-Control-Max-Age", "10000");
|
||||||
|
server.sendHeader("Access-Control-Allow-Methods", "PUT,POST,GET,OPTIONS");
|
||||||
|
server.sendHeader("Access-Control-Allow-Headers",
|
||||||
|
"X-Requested-With, X-HTTP-Method-Override, "
|
||||||
|
"Content-Type, Cache-Control, Accept");
|
||||||
|
}
|
||||||
|
|
||||||
void WebAPI::handleNotFound() {
|
void WebAPI::handleNotFound() {
|
||||||
server.send(404, "text/plain", "File Not Found\n\n");
|
if (server.method() == HTTP_OPTIONS) {
|
||||||
|
sendCORS();
|
||||||
|
server.send(204);
|
||||||
|
} else {
|
||||||
|
server.send(404, "text/plain", "");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebAPI::handlePutCommand() {
|
void WebAPI::handlePutCommand() {
|
||||||
queueManager.putCommand(server.arg("plain").c_str());
|
sendCORS();
|
||||||
|
String cmd = server.arg("plain");
|
||||||
|
queueManager.putCommand(cmd.c_str());
|
||||||
server.send(200, "application/json", getStatusJson());
|
server.send(200, "application/json", getStatusJson());
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebAPI::handleGetStatus() {
|
void WebAPI::handleGetStatus() {
|
||||||
|
sendCORS();
|
||||||
server.send(200, "application/json", getStatusJson());
|
server.send(200, "application/json", getStatusJson());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,19 +8,16 @@
|
|||||||
|
|
||||||
#define STEPS_PER_REVOLUTION (360/1.8) * 32
|
#define STEPS_PER_REVOLUTION (360/1.8) * 32
|
||||||
|
|
||||||
Stepper eggStepper(6, 5, STEPS_PER_REVOLUTION, 0, defYDegPerMM);
|
extern Stepper eggStepper;
|
||||||
Stepper servoStepper(4, 3, STEPS_PER_REVOLUTION, xLimit,
|
extern Stepper servoStepper;
|
||||||
defXDegPerMM);
|
|
||||||
|
|
||||||
Pen pen(7, 120, 180);
|
extern unsigned int eggStepperDelay;
|
||||||
|
extern unsigned int servoStepperDelay;
|
||||||
|
|
||||||
unsigned int eggStepperDelay;
|
extern unsigned int eggDia;
|
||||||
unsigned int servoStepperDelay;
|
extern unsigned int eggLength;
|
||||||
|
|
||||||
unsigned int eggDia;
|
extern float eggStepperRPM;
|
||||||
unsigned int eggLength;
|
extern float servoStepperRPM;
|
||||||
|
|
||||||
float eggStepperRPM;
|
|
||||||
float servoStepperRPM;
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -17,7 +17,8 @@ class Pen {
|
|||||||
void disengage();
|
void disengage();
|
||||||
void init();
|
void init();
|
||||||
bool getEngaged();
|
bool getEngaged();
|
||||||
~Pen();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern Pen pen;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
13
Firmware/MotorControl/src/Globals.cpp
Normal file
13
Firmware/MotorControl/src/Globals.cpp
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
#include "Globals.h"
|
||||||
|
|
||||||
|
Stepper eggStepper(6, 5, STEPS_PER_REVOLUTION, 0, defYDegPerMM);
|
||||||
|
Stepper servoStepper(4, 3, STEPS_PER_REVOLUTION, xLimit, defXDegPerMM);
|
||||||
|
|
||||||
|
unsigned int eggStepperDelay;
|
||||||
|
unsigned int servoStepperDelay;
|
||||||
|
|
||||||
|
unsigned int eggDia;
|
||||||
|
unsigned int eggLength;
|
||||||
|
|
||||||
|
float eggStepperRPM;
|
||||||
|
float servoStepperRPM;
|
||||||
@@ -3,27 +3,19 @@
|
|||||||
|
|
||||||
#include "Pen.h"
|
#include "Pen.h"
|
||||||
|
|
||||||
#define DELAY 15
|
|
||||||
|
|
||||||
Pen::Pen(int pin, int posEngaged, int posDisengaged)
|
Pen::Pen(int pin, int posEngaged, int posDisengaged)
|
||||||
: posEngaged(posEngaged), posDisengaged(posDisengaged), pin(pin) {}
|
: posEngaged(posEngaged), posDisengaged(posDisengaged), pin(pin) {}
|
||||||
|
|
||||||
void Pen::engage() {
|
void Pen::engage() {
|
||||||
if (!engaged) {
|
if (!engaged) {
|
||||||
for (int i = posDisengaged; i > posEngaged; i--) {
|
servo.write(posEngaged);
|
||||||
servo.write(i);
|
|
||||||
delay(DELAY);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
engaged = true;
|
engaged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Pen::disengage() {
|
void Pen::disengage() {
|
||||||
if (engaged) {
|
if (engaged) {
|
||||||
for (int i = posEngaged; i < posDisengaged; i++) {
|
servo.write(posDisengaged);
|
||||||
servo.write(i);
|
|
||||||
delay(DELAY);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
engaged = false;
|
engaged = false;
|
||||||
}
|
}
|
||||||
@@ -36,4 +28,4 @@ void Pen::init() {
|
|||||||
|
|
||||||
bool Pen::getEngaged() { return engaged; }
|
bool Pen::getEngaged() { return engaged; }
|
||||||
|
|
||||||
Pen::~Pen() {}
|
Pen pen(7, 120, 170);
|
||||||
|
|||||||
@@ -35,11 +35,9 @@ void adjustRPM() {
|
|||||||
calculateDelay(eggStepperRPM, STEPS_PER_REVOLUTION);
|
calculateDelay(eggStepperRPM, STEPS_PER_REVOLUTION);
|
||||||
int newServoStepperDelay =
|
int newServoStepperDelay =
|
||||||
calculateDelay(servoStepperRPM, STEPS_PER_REVOLUTION);
|
calculateDelay(servoStepperRPM, STEPS_PER_REVOLUTION);
|
||||||
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
|
|
||||||
eggStepperDelay = newEggStepperDelay;
|
eggStepperDelay = newEggStepperDelay;
|
||||||
servoStepperDelay = newServoStepperDelay;
|
servoStepperDelay = newServoStepperDelay;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Command command;
|
Command command;
|
||||||
|
|
||||||
@@ -67,36 +65,36 @@ byte txBuffer[i2cStsBytes];
|
|||||||
Status sts;
|
Status sts;
|
||||||
void requestEvent() { Wire.write(txBuffer, i2cStsBytes); }
|
void requestEvent() { Wire.write(txBuffer, i2cStsBytes); }
|
||||||
|
|
||||||
void execCommand() {
|
void execCommand(Command cmd) {
|
||||||
executing = true;
|
executing = true;
|
||||||
|
|
||||||
if (command.type == CommandType::G01 || command.type == CommandType::G00) {
|
|
||||||
newCommand = false;
|
newCommand = false;
|
||||||
if (command.type == CommandType::G01) {
|
|
||||||
|
if (cmd.type == CommandType::G01 || cmd.type == CommandType::G00) {
|
||||||
|
if (cmd.type == CommandType::G01) {
|
||||||
needAdjust = true;
|
needAdjust = true;
|
||||||
} else {
|
} else {
|
||||||
needAdjust = false;
|
needAdjust = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isnan(command.arg1)) {
|
if (!isnan(cmd.arg1)) {
|
||||||
servoStepper.moveTo(command.arg1);
|
servoStepper.moveTo(cmd.arg1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isnan(command.arg2)) {
|
if (!isnan(cmd.arg2)) {
|
||||||
eggStepper.moveTo(command.arg2);
|
eggStepper.moveTo(cmd.arg2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isnan(command.arg3)) {
|
if (!isnan(cmd.arg3)) {
|
||||||
if (command.arg3 < 0) {
|
if (cmd.arg3 < 0) {
|
||||||
pen.engage();
|
pen.engage();
|
||||||
}
|
}
|
||||||
if (command.arg3 >= 0) {
|
if (cmd.arg3 >= 0) {
|
||||||
pen.disengage();
|
pen.disengage();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isnan(command.arg4)) {
|
if (!isnan(cmd.arg4)) {
|
||||||
curRPM = command.arg4;
|
curRPM = cmd.arg4;
|
||||||
}
|
}
|
||||||
|
|
||||||
adjustRPM();
|
adjustRPM();
|
||||||
@@ -157,6 +155,8 @@ void steppersRoutine() {
|
|||||||
sts.mmS = servoStepper.getPosMm();
|
sts.mmS = servoStepper.getPosMm();
|
||||||
sts.mmE = eggStepper.getPosMm();
|
sts.mmE = eggStepper.getPosMm();
|
||||||
|
|
||||||
|
sts.feedrate = curRPM;
|
||||||
|
|
||||||
sts.pEng = (float)pen.getEngaged();
|
sts.pEng = (float)pen.getEngaged();
|
||||||
|
|
||||||
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { sts.toBytes(txBuffer); }
|
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { sts.toBytes(txBuffer); }
|
||||||
@@ -171,7 +171,7 @@ void steppersRoutine() {
|
|||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
if (newCommand) {
|
if (newCommand) {
|
||||||
execCommand();
|
execCommand(command);
|
||||||
}
|
}
|
||||||
steppersRoutine();
|
steppersRoutine();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user