Skip to content

Commit 429c27f

Browse files
committed
Plasma: added basic support for LinuxCNC style M190 and "magic" comments. Untested. Ref. issue #21.
1 parent a560035 commit 429c27f

File tree

1 file changed

+246
-3
lines changed

1 file changed

+246
-3
lines changed

thc.c

Lines changed: 246 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#if PLASMA_ENABLE
2727

2828
#include <math.h>
29+
#include <stdio.h>
2930
#include <stdint.h>
3031
#include <stdbool.h>
3132
#include <string.h>
@@ -54,6 +55,31 @@ typedef enum {
5455
Plasma_ModeArcOK
5556
} plasma_mode_t;
5657

58+
typedef struct material
59+
{
60+
uint32_t id; // nu
61+
char name[50]; // na
62+
bool thc_status; // th
63+
union {
64+
float params[12];
65+
struct {
66+
float pierce_height; // ph
67+
float pierce_delay; // pd
68+
float cut_height; // ch
69+
float feed_rate; // fr
70+
float kerf_width; // kw
71+
float cut_amps; // ca
72+
float cut_voltage; // cv
73+
float end_pause; // pe
74+
float gas_pressure; // gp
75+
float cut_mode; // cm
76+
float jump_height; // jh
77+
float jump_delay; // jd
78+
};
79+
};
80+
struct material *next;
81+
} material_t;
82+
5783
typedef union {
5884
uint8_t flags;
5985
struct {
@@ -137,6 +163,8 @@ static st2_motor_t *z_motor;
137163
static void (*volatile stateHandler)(void) = state_idle;
138164
static plasma_mode_t mode = Plasma_ModeOff;
139165
static xbar_t arc_ok, cutter_down, cutter_up, parc_voltage;
166+
static uint32_t mat_number = 1000000;
167+
static material_t *materials = NULL, *material = NULL, tmp_material;
140168

141169
static settings_changed_ptr settings_changed;
142170
static driver_reset_ptr driver_reset = NULL;
@@ -148,6 +176,47 @@ static on_report_options_ptr on_report_options;
148176
static on_spindle_selected_ptr on_spindle_selected;
149177
static on_execute_realtime_ptr on_execute_realtime = NULL;
150178
static on_realtime_report_ptr on_realtime_report = NULL;
179+
static on_gcode_message_ptr on_gcode_comment;
180+
static user_mcode_ptrs_t user_mcode;
181+
182+
static uint32_t strnumentries (const char *s, const char delimiter)
183+
{
184+
char *p = (char *)s;
185+
uint32_t entries = *s ? 1 : 0;
186+
187+
while(entries && (p = strchr(p, delimiter))) {
188+
p++;
189+
entries++;
190+
}
191+
192+
return entries;
193+
}
194+
195+
static int32_t strlookup (const char *s1, const char *s2, const char delimiter)
196+
{
197+
bool found = false;
198+
char *e, *p = (char *)s2;
199+
uint32_t idx = strnumentries(s2, delimiter), len = strlen(s1);
200+
int32_t entry = 0;
201+
202+
while(idx--) {
203+
204+
if((e = strchr(p, delimiter)))
205+
found = (e - p) == len && !strncmp(p, s1, e - p);
206+
else
207+
found = strlen(p) == len && !strcmp(p, s1);
208+
209+
if(found || e == NULL)
210+
break;
211+
else {
212+
p = e + 1;
213+
entry++;
214+
}
215+
}
216+
217+
return found ? entry : -1;
218+
}
219+
151220

152221
// --- Virtual ports start
153222

@@ -361,6 +430,168 @@ static void add_virtual_ports (void *data)
361430
}
362431
}
363432

433+
static material_t *find_material (uint32_t id)
434+
{
435+
material_t *material = materials, *found = NULL;
436+
437+
if(material) do {
438+
if(material->id == id)
439+
found = material;
440+
} while(found == NULL && (material = material->next));
441+
442+
return found;
443+
}
444+
445+
static user_mcode_type_t mcode_check (user_mcode_t mcode)
446+
{
447+
return mcode == Plasma_SelectMaterial
448+
? UserMCode_Normal
449+
: (user_mcode.check ? user_mcode.check(mcode) : UserMCode_Unsupported);
450+
}
451+
452+
static status_code_t mcode_validate (parser_block_t *gc_block)
453+
{
454+
status_code_t state = Status_OK;
455+
456+
if(gc_block->user_mcode == Plasma_SelectMaterial) {
457+
if(gc_block->words.p) {
458+
if(!isintf(gc_block->values.p))
459+
state = Status_BadNumberFormat;
460+
else if(gc_block->words.p && !(gc_block->values.p == -1.0f || find_material((uint32_t)gc_block->values.p)))
461+
state = Status_GcodeValueOutOfRange;
462+
else
463+
gc_block->words.p = Off;
464+
}
465+
} else
466+
state = Status_Unhandled;
467+
468+
return state == Status_Unhandled && user_mcode.validate ? user_mcode.validate(gc_block) : state;
469+
}
470+
471+
static void mcode_execute (uint_fast16_t state, parser_block_t *gc_block)
472+
{
473+
if(gc_block->user_mcode == Plasma_SelectMaterial) {
474+
if((material = gc_block->values.p == -1.0f ? NULL : find_material((uint32_t)gc_block->values.p))) {
475+
char command[30];
476+
sprintf(command, "G1Z%.3fF%.1f", material->pierce_height, material->feed_rate);
477+
// grbl.enqueue_gcode(command);
478+
}
479+
} else if(user_mcode.execute)
480+
user_mcode.execute(state, gc_block);
481+
}
482+
483+
static status_code_t onGcodeComment (char *comment)
484+
{
485+
static const char params[] = "ph,pd,ch,fr,kw,ca,cv,pe,gp,cm,jh,jd,nu,na,th"; // NOTE: must match layout of material_t
486+
487+
status_code_t status = Status_OK;
488+
489+
if(strlen(comment) > 5 && comment[0] == 'o' && comment[1] == '=') {
490+
491+
material_t new_material = {};
492+
char option = comment[2];
493+
494+
uint_fast8_t i;
495+
496+
if(option == '0')
497+
new_material.id = mat_number++;
498+
499+
for(i = 0; i < 12; i++)
500+
new_material.params[i] = NAN;
501+
502+
char *param = strtok(comment + 4, ","), *eq;
503+
504+
while(param && status == Status_OK) {
505+
506+
while(*param == ' ')
507+
param++;
508+
509+
if((eq = strchr(param, '='))) {
510+
511+
int32_t p;
512+
513+
*eq = '\0';
514+
515+
switch((p = strlookup(param, params, ','))) {
516+
517+
case -1:
518+
status = Status_GcodeUnsupportedCommand;
519+
break;
520+
521+
case 12:
522+
if(option != '0') {
523+
uint_fast8_t cc = 1;
524+
status = read_uint(eq, &cc, &new_material.id);
525+
}
526+
break;
527+
528+
case 13:
529+
strncpy(new_material.name, eq + 1, sizeof(new_material.name));
530+
new_material.name[sizeof(new_material.name) - 1] = '\0';
531+
break;
532+
533+
case 14:
534+
new_material.thc_status = eq[1] != '0';
535+
break;
536+
537+
default:
538+
{
539+
uint_fast8_t cc = 1;
540+
if(!read_float(eq, &cc, &new_material.params[p]))
541+
status = Status_BadNumberFormat;
542+
}
543+
break;
544+
}
545+
*eq = '=';
546+
}
547+
param = strtok(NULL, ",");
548+
}
549+
550+
if(isnanf(new_material.pierce_height) ||
551+
isnanf(new_material.pierce_delay) ||
552+
isnanf(new_material.cut_height) ||
553+
isnanf(new_material.feed_rate))
554+
status = Status_GcodeValueWordMissing;
555+
556+
if(status == Status_OK) switch(option) {
557+
558+
case '0':
559+
material = &tmp_material;
560+
memcpy(material, &new_material, sizeof(material_t));
561+
break;
562+
563+
case '1':
564+
case '2':
565+
material_t *m = find_material(new_material.id);
566+
bool add = m == NULL;
567+
if(option == '2' || m == NULL) {
568+
if(m == NULL)
569+
m = malloc(sizeof(material_t));
570+
if(m) {
571+
memcpy(m, &new_material, sizeof(material_t));
572+
if(materials == NULL)
573+
materials = m;
574+
else if(add) {
575+
material_t *last = materials;
576+
while(last->next)
577+
last = last->next;
578+
last->next = m;
579+
}
580+
} // else error....
581+
}
582+
break;
583+
584+
default:
585+
status = Status_GcodeUnsupportedCommand;
586+
break;
587+
}
588+
589+
} else if(on_gcode_comment)
590+
status = on_gcode_comment(comment);
591+
592+
return status;
593+
}
594+
364595
// --- Virtual ports end
365596

366597
static void set_target_voltage (float v)
@@ -412,7 +643,10 @@ static void state_thc_delay (void)
412643
} else {
413644
pidf_reset(&pid);
414645
st2_set_position(z_motor, 0LL);
415-
set_target_voltage(parc_voltage.get_value(&parc_voltage) * plasma.arc_voltage_scale - plasma.arc_voltage_offset);
646+
if(material && !isnanf(material->cut_voltage))
647+
set_target_voltage(material->cut_voltage);
648+
else
649+
set_target_voltage(parc_voltage.get_value(&parc_voltage) * plasma.arc_voltage_scale - plasma.arc_voltage_offset);
416650
stateHandler = state_vad_lock;
417651
stateHandler();
418652
}
@@ -567,7 +801,7 @@ static void arcSetState (spindle_ptrs_t *spindle, spindle_state_t state, float r
567801
if((thc.arc_ok = hal.port.wait_on_input(Port_Digital, port_arc_ok, WaitMode_High, plasma.arc_fail_timeout) != -1)) {
568802
report_message("arc ok", Message_Plain);
569803
retries = 0;
570-
thc_delay = hal.get_elapsed_ticks() + (uint32_t)ceilf(1000.0f * plasma.thc_delay); // handle overflow!
804+
thc_delay = hal.get_elapsed_ticks() + (uint32_t)ceilf(1000.0f * (material ? material->pierce_delay : plasma.thc_delay)); // handle overflow!
571805
stateHandler = state_thc_delay;
572806
} else if(!(--retries)) {
573807
thc.torch_on = Off;
@@ -984,7 +1218,7 @@ static void onReportOptions (bool newopt)
9841218
*s1++ = ')';
9851219
*s1 = '\0';
9861220

987-
report_plugin(buf, "0.18");
1221+
report_plugin(buf, "0.19");
9881222

9891223
} else if(mode != Plasma_ModeOff)
9901224
hal.stream.write(",THC");
@@ -1028,9 +1262,18 @@ void plasma_init (void)
10281262

10291263
settings_register(&setting_details);
10301264

1265+
memcpy(&user_mcode, &grbl.user_mcode, sizeof(user_mcode_ptrs_t));
1266+
1267+
grbl.user_mcode.check = mcode_check;
1268+
grbl.user_mcode.validate = mcode_validate;
1269+
grbl.user_mcode.execute = mcode_execute;
1270+
10311271
on_report_options = grbl.on_report_options;
10321272
grbl.on_report_options = onReportOptions;
10331273

1274+
on_gcode_comment = grbl.on_gcode_comment;
1275+
grbl.on_gcode_comment = onGcodeComment;
1276+
10341277
/*
10351278
control_interrupt_callback = hal.control_interrupt_callback;
10361279
hal.control_interrupt_callback = trap_control_interrupts;

0 commit comments

Comments
 (0)