basic gcode sender thing

This commit is contained in:
2019-08-03 14:27:13 +03:00
parent 73af651ac4
commit 17891a2a64
13 changed files with 223 additions and 49 deletions

View File

@@ -1,7 +1,8 @@
import * as React from "react";
import { GcodeSender } from "~GcodeSender";
export function AppComponent() {
return <div>Hello</div>;
return <GcodeSender />;
}
export const App = AppComponent;

106
App/src/GcodeSender.tsx Normal file
View 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;

View 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
View 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;
}

View File

@@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Writer</title>
<title>Eggbot</title>
</head>
<body>
<div id="body">

View File

@@ -10,6 +10,8 @@ class WebAPI {
void handleNotFound();
void handlePutCommand();
void handleGetStatus();
void sendCORS();
String getStatusJson();
public:
WebAPI();

View File

@@ -37,16 +37,19 @@ void QueueManager::loopRoutine() {
}
void QueueManager::putCommand(std::string cmd) {
if (!std::isalnum(cmd[0])) {
return;
}
if (toupper(cmd[0]) == 'L') {
lCommandQueue.emplace(cmd);
} else {
commandQueue.push(parseGCode(cmd));
Command cmdp = parseGCode(cmd);
commandQueue.push(cmdp);
}
}
uint8_t QueueManager::execQueueSize() {
return commandQueue.size();
}
uint8_t QueueManager::execQueueSize() { return commandQueue.size(); }
void QueueManager::putCommand(char *cmd) { putCommand(std::string(cmd)); }

View File

@@ -23,16 +23,33 @@ String WebAPI::getStatusJson() {
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() {
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() {
queueManager.putCommand(server.arg("plain").c_str());
sendCORS();
String cmd = server.arg("plain");
queueManager.putCommand(cmd.c_str());
server.send(200, "application/json", getStatusJson());
}
void WebAPI::handleGetStatus() {
sendCORS();
server.send(200, "application/json", getStatusJson());
}

View File

@@ -8,19 +8,16 @@
#define STEPS_PER_REVOLUTION (360/1.8) * 32
Stepper eggStepper(6, 5, STEPS_PER_REVOLUTION, 0, defYDegPerMM);
Stepper servoStepper(4, 3, STEPS_PER_REVOLUTION, xLimit,
defXDegPerMM);
extern Stepper eggStepper;
extern Stepper servoStepper;
Pen pen(7, 120, 180);
extern unsigned int eggStepperDelay;
extern unsigned int servoStepperDelay;
unsigned int eggStepperDelay;
unsigned int servoStepperDelay;
extern unsigned int eggDia;
extern unsigned int eggLength;
unsigned int eggDia;
unsigned int eggLength;
float eggStepperRPM;
float servoStepperRPM;
extern float eggStepperRPM;
extern float servoStepperRPM;
#endif

View File

@@ -17,7 +17,8 @@ class Pen {
void disengage();
void init();
bool getEngaged();
~Pen();
};
extern Pen pen;
#endif

View 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;

View File

@@ -3,27 +3,19 @@
#include "Pen.h"
#define DELAY 15
Pen::Pen(int pin, int posEngaged, int posDisengaged)
: posEngaged(posEngaged), posDisengaged(posDisengaged), pin(pin) {}
void Pen::engage() {
if (!engaged) {
for (int i = posDisengaged; i > posEngaged; i--) {
servo.write(i);
delay(DELAY);
}
servo.write(posEngaged);
}
engaged = true;
}
void Pen::disengage() {
if (engaged) {
for (int i = posEngaged; i < posDisengaged; i++) {
servo.write(i);
delay(DELAY);
}
servo.write(posDisengaged);
}
engaged = false;
}
@@ -36,4 +28,4 @@ void Pen::init() {
bool Pen::getEngaged() { return engaged; }
Pen::~Pen() {}
Pen pen(7, 120, 170);

View File

@@ -35,10 +35,8 @@ void adjustRPM() {
calculateDelay(eggStepperRPM, STEPS_PER_REVOLUTION);
int newServoStepperDelay =
calculateDelay(servoStepperRPM, STEPS_PER_REVOLUTION);
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
eggStepperDelay = newEggStepperDelay;
servoStepperDelay = newServoStepperDelay;
}
}
Command command;
@@ -67,36 +65,36 @@ byte txBuffer[i2cStsBytes];
Status sts;
void requestEvent() { Wire.write(txBuffer, i2cStsBytes); }
void execCommand() {
void execCommand(Command cmd) {
executing = true;
if (command.type == CommandType::G01 || command.type == CommandType::G00) {
newCommand = false;
if (command.type == CommandType::G01) {
if (cmd.type == CommandType::G01 || cmd.type == CommandType::G00) {
if (cmd.type == CommandType::G01) {
needAdjust = true;
} else {
needAdjust = false;
}
if (!isnan(command.arg1)) {
servoStepper.moveTo(command.arg1);
if (!isnan(cmd.arg1)) {
servoStepper.moveTo(cmd.arg1);
}
if (!isnan(command.arg2)) {
eggStepper.moveTo(command.arg2);
if (!isnan(cmd.arg2)) {
eggStepper.moveTo(cmd.arg2);
}
if (!isnan(command.arg3)) {
if (command.arg3 < 0) {
if (!isnan(cmd.arg3)) {
if (cmd.arg3 < 0) {
pen.engage();
}
if (command.arg3 >= 0) {
if (cmd.arg3 >= 0) {
pen.disengage();
}
}
if (!isnan(command.arg4)) {
curRPM = command.arg4;
if (!isnan(cmd.arg4)) {
curRPM = cmd.arg4;
}
adjustRPM();
@@ -157,6 +155,8 @@ void steppersRoutine() {
sts.mmS = servoStepper.getPosMm();
sts.mmE = eggStepper.getPosMm();
sts.feedrate = curRPM;
sts.pEng = (float)pen.getEngaged();
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { sts.toBytes(txBuffer); }
@@ -171,7 +171,7 @@ void steppersRoutine() {
void loop() {
if (newCommand) {
execCommand();
execCommand(command);
}
steppersRoutine();
}