Sfondo
Sto scrivendo firmware C ++ con freertos su penplottingrobot. È un XYplotter di sblocco e il firmware si sta collegando al software mDraw per le istruzioni di comando tramite i driver USB. Il programma MDraw invia comandi Gcode. Se devi sapere, c'è una matita controllata da un servo di modulazione di larghezza d'onda e il plotter viene azionato con motori passo-passo a due assi.
Ai nostri intenti e quegli input mDraw sono ottenuti come std::string s e inviati a Gcodeparser::parseCommand(std::string) .
Problema
Esiste una soluzione più elegante di quanto segue ???
// quindi il codice funziona sin d'ora, ma non ha una buona interfaccia o usabilità
Sto utilizzando un parser_task , con un oggetto Gcodeparser per analizzare quei Gcodecommands . .ParseCommand() memberfunction richiede std::string come parametro e restituisce un CommandStruct in base al valore. CommandStruct contiene solo tipi di dati semplici-vecchi come int , enum e bool . Dopo che un comando legale è stato analizzato, viene quindi inviato a una coda freeRTOS per valore ( CommandStruct viene inviato alla coda). La coda è necessaria per comunicare con l'altra attività, chiamata execute_commands_task , che ovviamente sta leggendo questa coda.
Ho diverse possibilità di legale Gcode s, ma condividono solo due datamembers in comune: enum {M4, G1, G28 ... }baseType e bool isLegalCommand .
Altrimenti tutti quei "diversi tipi di basi" Gcode s possono avere una quantità differente di datamembers, di tipi diversi (in genere bool o int datamembers, ma ci sono coordinatevalue s, pencilservo valori, clockwisemotordirectionvalue s ecc ...).
Quindi, la mia soluzione corrente che era stupida (ma funziona), era quella di mettere tutti i datamembers disponibili in quel CommandStruct . In questo modo puoi utilizzare quella struttura per passare qualsiasi tipo di comando Gcode nella coda freeRTOS e ottenere comunque dati validi.
Il codice è fastidiosamente brutto perché ci sono datamembers non utilizzati per ogni comando Gcode ...
Ma devo ancora essere in grado di passare qualcosa nella coda freeRTOS che è in grado di trasmettere tutti i dati richiesti.
#pragma once
struct CommandStruct {
enum {
M1,
M4,
M10,
G1,
G28,
M5,
M11,
M28,
M2,
uninitialized
} commandWord; //any Gcode command has commandWord (essentially a basetype)
int commandNumber; //pencilServoParameter, or laserParameter [0,255]
int penUp; //parameter for M2 command
int penDown; //parameter for M2 command
int height; //parameter for M5 command
int width; //parameter for M5 command
int speed; //parameter for M5 command
bool xMotorClockwise; //parameter for M5 command
bool yMotorClockwise; //parameter for M5 command
bool isLegal; //any Gcode command has legality
int xCoord; //coords for G1command HUNDREDTHS of mm
int yCoord; //coords for G1command HUNDREDTHS of mm
CommandStruct() {
commandWord = uninitialized;
commandNumber = -1;
penUp = -1;
penDown = -1;
height = -1;
width = -1;
speed = -1;
xMotorClockwise = true;
yMotorClockwise = true;
isLegal = false;
xCoord = -1;
yCoord = -1;
}
};