diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index fe966efb..b02fe1b4 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -714,7 +714,7 @@ void canonical_machine_init() // If you can assume all memory has been zeroed by a hard reset you don't need this code: // memset(&cm, 0, sizeof(cm)); // do not reset canonicalMachineSingleton once it's been initialized memset(&cm, 0, sizeof(cmSingleton_t)); // do not reset canonicalMachineSingleton once it's been initialized - memset(&cm.gm, 0, sizeof(GCodeState_t)); // clear all values, pointers and status + cm.gm.reset(); // clear all values, pointers and status -- not ALL to zero, however canonical_machine_init_assertions(); // establish assertions ACTIVE_MODEL = MODEL; // setup initial Gcode model pointer diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index 9da71fc2..8ec1a5f1 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -387,8 +387,8 @@ typedef struct GCodeState { // Gcode model state - used by model, pl arc_distance_mode = ABSOLUTE_DISTANCE_MODE; absolute_override = ABSOLUTE_OVERRIDE_OFF; coord_system = ABSOLUTE_COORDS; - tool = 0; - tool_select = 0; + tool = 1; + tool_select = 1; }; } GCodeState_t; diff --git a/g2core/gcode_parser.cpp b/g2core/gcode_parser.cpp index 5ddb0496..427fe985 100644 --- a/g2core/gcode_parser.cpp +++ b/g2core/gcode_parser.cpp @@ -840,7 +840,10 @@ stat_t _execute_gcode_block(char *active_comment) #if MARLIN_COMPAT_ENABLED == true // adjust T real quick if (cm.gmx.marlin_flavor && gf.tool_select) { - cm_select_tool(gv.tool_select); // We need to go ahead and apply to tool select + gv.tool_select += 1; + cm.gm.tool_select = gv.tool_select; // We need to go ahead and apply to tool select, and in Marlin 0 is valid, so add 1 + cm.gm.tool = cm.gm.tool_select; // Also, in Marlin, tool changes are effective immediately :facepalm: + gf.tool_select = false; // prevent a tool_select command from being buffered (planning to zero) } // Handle Marlin specifics @@ -850,12 +853,12 @@ stat_t _execute_gcode_block(char *active_comment) cm.gmx.marlin_flavor = true; // E should ONLY be seen in marlin flavor // Ennn T0 -> Annn - if (cm.gm.tool_select == 0) { + if (cm.gm.tool_select == 1) { gf.target[AXIS_A] = true; gv.target[AXIS_A] = gv.E_word; } // Ennn T1 -> Bnnn - else if (cm.gm.tool_select == 1) { + else if (cm.gm.tool_select == 2) { gf.target[AXIS_B] = true; gv.target[AXIS_B] = gv.E_word; } diff --git a/g2core/marlin_compatibility.cpp b/g2core/marlin_compatibility.cpp index 58d77270..f8b4a409 100644 --- a/g2core/marlin_compatibility.cpp +++ b/g2core/marlin_compatibility.cpp @@ -28,6 +28,7 @@ #include "canonical_machine.h" #include "util.h" #include "xio.h" // for char definitions +#include "temperature.h" // for temperature controls #include "json_parser.h" #include "planner.h" #include "MotateTimers.h" // for char definitions @@ -98,63 +99,40 @@ nvObj_t *_get_spcific_nv(const char *key) { */ void _report_temperatures(char *(&str)) { // Tool 0 is extruder 1 - uint8_t tool = cm.gm.tool_select; + uint8_t tool = cm.gm.tool; - nvObj_t *nv = nullptr; + str_concat(str, " T:"); + str += floattoa(str, cm_get_temperature(tool), 2); + str_concat(str, " /"); + str += floattoa(str, cm_get_set_temperature(tool), 2); - if (tool == 0) { - nv = _get_spcific_nv("he1t"); - } else if (tool == 1) { - nv = _get_spcific_nv("he2t"); - } else { - return; // we have no way of reporting errors here, ATM - } - if (!nv) { return; } - str += sprintf(str, " T:%.2f", (float)nv->value); + str_concat(str, " B:"); + str += floattoa(str, cm_get_temperature(3), 2); + str_concat(str, " /"); + str += floattoa(str, cm_get_set_temperature(3), 2); - if (tool == 0) { - nv = _get_spcific_nv("he1st"); - } else if (tool == 1) { - nv = _get_spcific_nv("he2st"); - } else { - return; // we have no way of reporting errors here, ATM - } - if (!nv) { return; } - str += sprintf(str, " /%.2f", (float)nv->value); + str_concat(str, " @:"); + str += floattoa(str, cm_get_heater_output(tool), 0); - nv = _get_spcific_nv("he3t"); - if (!nv) { return; } - str += sprintf(str, " B:%.2f", (float)nv->value); - - nv = _get_spcific_nv("he3st"); - if (!nv) { return; } - str += sprintf(str, " /%.2f", (float)nv->value); - - if (tool == 0) { - nv = _get_spcific_nv("he1op"); - } else if (tool == 1) { - nv = _get_spcific_nv("he2op"); - } if (!nv) { return; } - str += sprintf(str, " @:%.0f", (float)nv->value * 255.0); - - nv = _get_spcific_nv("he3op"); - if (!nv) { return; } - str += sprintf(str, " B@:%.0f", (float)nv->value * 255.0); + str_concat(str, " B@:"); + str += floattoa(str, cm_get_heater_output(3), 0); } /* * _report_position() - convenience function called from marlin_response() */ void _report_position(char *(&str)) { - str += sprintf(str, " X:%.2f", cm_get_work_position(ACTIVE_MODEL, 0)); - str += sprintf(str, " Y:%.2f", cm_get_work_position(ACTIVE_MODEL, 1)); - str += sprintf(str, " Z:%.2f", cm_get_work_position(ACTIVE_MODEL, 2)); + str_concat(str, " X:"); + str += floattoa(str, cm_get_work_position(ACTIVE_MODEL, 0), 2); + str_concat(str, " Y:"); + str += floattoa(str, cm_get_work_position(ACTIVE_MODEL, 1), 2); + str_concat(str, " Z:"); + str += floattoa(str, cm_get_work_position(ACTIVE_MODEL, 2), 2); - uint8_t tool = cm.gm.tool_select; - if (tool == 0) { - str += sprintf(str, " E:%.2f", cm_get_work_position(ACTIVE_MODEL, 3)); - } else if (tool == 1) { - str += sprintf(str, " E:%.2f", cm_get_work_position(ACTIVE_MODEL, 4)); + uint8_t tool = cm.gm.tool; + if ((tool > 0) && (tool < 3)) { + str_concat(str, " E:"); + str += floattoa(str, cm_get_work_position(ACTIVE_MODEL, 2), tool + 2); // A or B, depending on tool } } @@ -253,8 +231,8 @@ bool marlin_handle_fake_stk500(char *str) */ stat_t marlin_request_temperature_report() // M105 { - uint8_t tool = cm.gm.tool_select; - if ((tool < 0) || (tool > 1)) { + uint8_t tool = cm.gm.tool; + if ((tool < 1) || (tool > 2)) { return STAT_INPUT_VALUE_RANGE_ERROR; } @@ -282,8 +260,7 @@ void marlin_response(const stat_t status, char *buf) char *str = buffer; if ((status == STAT_OK) || (status == STAT_EAGAIN) || (status == STAT_NOOP)) { - strncpy(str, "ok", 2); - str += 2; + str_concat(str, "ok"); if (temperature_requested) { _report_temperatures(str); @@ -302,7 +279,7 @@ void marlin_response(const stat_t status, char *buf) } else { // str += sprintf(p, "echo:M%d %s", (int)status, get_status_message(status), buf); - str += sprintf(str, "Error:[%d] %s", (int)status, get_status_message(status)); + str += sprintf(str, "Error:%d %s", (int)status, get_status_message(status)); } *str++ = '\n'; @@ -345,7 +322,11 @@ bool _queue_next_temperature_commands() if ((MarlinSetTempState::SettingTemperature == set_temp_state) || (MarlinSetTempState::SettingTemperatureNoWait == set_temp_state)) { - str += sprintf(str, "{he%dst:%.2f}", next_temperature_tool+1, next_temperature); + str_concat(str, "{he"); + str += inttoa(str, next_temperature_tool); + str_concat(str, "st:"); + str += floattoa(str, next_temperature, 2); + str_concat(str, "}"); cm_json_command(buffer); if (MarlinSetTempState::SettingTemperatureNoWait == set_temp_state) { @@ -370,7 +351,9 @@ bool _queue_next_temperature_commands() if (MarlinSetTempState::StartingWait == set_temp_state) { str = buffer; - str += sprintf(str, "{he%dat:t}", next_temperature_tool+1); + str_concat(str, "{he"); + str += inttoa(str, next_temperature_tool); + str_concat(str, "at:t}"); cm_json_wait(buffer); set_temp_state = MarlinSetTempState::StoppingUpdates; @@ -424,7 +407,7 @@ stat_t marlin_set_temperature(uint8_t tool, float temperature, bool wait) { if (MarlinSetTempState::Idle != set_temp_state) { return (STAT_BUFFER_FULL_FATAL); // we shouldn't be here } - if ((tool < 0) || (tool > 2)) { + if ((tool < 1) || (tool > 2)) { return STAT_INPUT_VALUE_RANGE_ERROR; } @@ -485,7 +468,10 @@ stat_t marlin_set_fan_speed(const uint8_t fan, float speed) } // TODO: support other fans, or remapping output - str += sprintf(str, "{out4:%.2f}", (speed < 1.0) ? speed : (speed / 255.0)); + str_concat(str, "{out4:"); + str += floattoa(str, (speed < 1.0) ? speed : (speed / 255.0), 4); + str_concat(str, "}"); + cm_json_command(buffer); return (STAT_OK); @@ -503,7 +489,7 @@ stat_t marlin_disable_motors() char *str = buffer; // TODO: support other parameters - strncpy(str, "{md:0}", 6); + str_concat(str, "{md:0}"); cm_json_command(buffer); return (STAT_OK); diff --git a/g2core/temperature.cpp b/g2core/temperature.cpp index 864c5642..7d29ff10 100755 --- a/g2core/temperature.cpp +++ b/g2core/temperature.cpp @@ -666,7 +666,6 @@ stat_t cm_set_heater_p(nvObj_t *nv) case '2': { pid2._p_factor = nv->value / 100.0; break; } case '3': { pid3._p_factor = nv->value / 100.0; break; } - // Failsafe. We can only get here if we set it up in config_app, but not here. default: { break; } } @@ -684,7 +683,6 @@ stat_t cm_get_heater_i(nvObj_t *nv) case '2': { nv->value = pid2._i_factor * 100.0; break; } case '3': { nv->value = pid3._i_factor * 100.0; break; } - // Failsafe. We can only get here if we set it up in config_app, but not here. default: { nv->value = 0.0; break; } } @@ -700,7 +698,6 @@ stat_t cm_set_heater_i(nvObj_t *nv) case '2': { pid2._i_factor = nv->value / 100.0; break; } case '3': { pid3._i_factor = nv->value / 100.0; break; } - // Failsafe. We can only get here if we set it up in config_app, but not here. default: { break; } } @@ -717,7 +714,6 @@ stat_t cm_get_heater_d(nvObj_t *nv) case '2': { nv->value = pid2._d_factor * 100.0; break; } case '3': { nv->value = pid3._d_factor * 100.0; break; } - // Failsafe. We can only get here if we set it up in config_app, but not here. default: { nv->value = 0.0; break; } } nv->precision = GET_TABLE_WORD(precision); @@ -732,7 +728,6 @@ stat_t cm_set_heater_d(nvObj_t *nv) case '2': { pid2._d_factor = nv->value / 100.0; break; } case '3': { pid3._d_factor = nv->value / 100.0; break; } - // Failsafe. We can only get here if we set it up in config_app, but not here. default: { break; } } return (STAT_OK); @@ -740,67 +735,81 @@ stat_t cm_set_heater_d(nvObj_t *nv) /* * cm_get_set_temperature()/cm_set_set_temperature() - get/set the set value of the PID + * + * There are both the file-to-file use version, and the NV-pair form (which uses the other). */ -stat_t cm_get_set_temperature(nvObj_t *nv) +float cm_get_set_temperature(const uint8_t heater) { - switch(_get_heater_number(nv)) { - case '1': { nv->value = pid1._set_point; break; } - case '2': { nv->value = pid2._set_point; break; } - case '3': { nv->value = pid3._set_point; break; } - - // Failsafe. We can only get here if we set it up in config_app, but not here. - default: { nv->value = 0.0; break; } + switch(heater) { + case 1: { return pid1._set_point; break; } + case 2: { return pid2._set_point; break; } + case 3: { return pid3._set_point; break; } + default: { break; } } + return 0.0; +} +stat_t cm_get_set_temperature(nvObj_t *nv) +{ + nv->value = cm_get_set_temperature(_get_heater_number(nv) - '0'); nv->precision = GET_TABLE_WORD(precision); nv->valuetype = TYPE_FLOAT; return (STAT_OK); } -stat_t cm_set_set_temperature(nvObj_t *nv) +void cm_set_set_temperature(const uint8_t heater, const float value) { - switch(_get_heater_number(nv)) { - case '1': { pid1._set_point = min(TEMP_MAX_SETPOINT, nv->value); break; } - case '2': { pid2._set_point = min(TEMP_MAX_SETPOINT, nv->value); break; } - case '3': { pid3._set_point = min(TEMP_MAX_SETPOINT, nv->value); break; } + switch(heater) { + case 1: { pid1._set_point = min(TEMP_MAX_SETPOINT, value); break; } + case 2: { pid2._set_point = min(TEMP_MAX_SETPOINT, value); break; } + case 3: { pid3._set_point = min(TEMP_MAX_SETPOINT, value); break; } - // Failsafe. We can only get here if we set it up in config_app, but not here. + // default to quiet the compiler default: { break; } } - +} +stat_t cm_set_set_temperature(nvObj_t *nv) +{ + cm_set_set_temperature(_get_heater_number(nv) - '0', nv->value); return (STAT_OK); } /* * cm_get_fan_power()/cm_set_fan_power() - get/set the set high-value setting of the heater fan */ -stat_t cm_get_fan_power(nvObj_t *nv) +float cm_get_fan_power(const uint8_t heater) { - switch(_get_heater_number(nv)) { - case '1': { nv->value = min(1.0f, heater_fan1.max_value); break; } -// case '2': { nv->value = min(1.0f, heater_fan2.max_value); break; } -// case '3': { nv->value = min(1.0f, heater_fan3.max_value); break; } + switch(heater) { + case 1: { return min(1.0f, heater_fan1.max_value); } +// case 2: { return min(1.0f, heater_fan2.max_value); } +// case 3: { return min(1.0f, heater_fan3.max_value); } - // Failsafe. We can only get here if we set it up in config_app, but not here. - default: { nv->value = 0.0; break; } + default: { break; } } + return 0.0; +} +stat_t cm_get_fan_power(nvObj_t *nv) +{ + nv->value = cm_get_fan_power(_get_heater_number(nv) - '0'); nv->precision = GET_TABLE_WORD(precision); nv->valuetype = TYPE_FLOAT; return (STAT_OK); } -stat_t cm_set_fan_power(nvObj_t *nv) -{ - switch(_get_heater_number(nv)) { - case '1': { heater_fan1.max_value = max(0.0f, nv->value); break; } -// case '2': { heater_fan2.max_value = max(0.0, nv->value); break; } -// case '3': { heater_fan3.max_value = max(0.0, nv->value); break; } - // Failsafe. We can only get here if we set it up in config_app, but not here. +void cm_set_fan_power(const uint8_t heater, const float value) +{ + switch(heater) { + case 1: { heater_fan1.max_value = max(0.0f, value); break; } +// case 2: { heater_fan2.max_value = max(0.0, value); break; } +// case 3: { heater_fan3.max_value = max(0.0, value); break; } default: { break; } } - +} +stat_t cm_set_fan_power(nvObj_t *nv) +{ + cm_set_fan_power(_get_heater_number(nv) - '0', nv->value); return (STAT_OK); } @@ -814,7 +823,6 @@ stat_t cm_get_fan_min_power(nvObj_t *nv) // case '2': { nv->value = heater_fan2.min_value; break; } // case '3': { nv->value = heater_fan3.min_value; break; } - // Failsafe. We can only get here if we set it up in config_app, but not here. default: { nv->value = 0.0; break; } } @@ -830,10 +838,9 @@ stat_t cm_set_fan_min_power(nvObj_t *nv) // case '2': { heater_fan2.min_value = min(0.0, nv->value); break; } // case '3': { heater_fan3.min_value = min(0.0, nv->value); break; } - // Failsafe. We can only get here if we set it up in config_app, but not here. default: { break; } } - + return (STAT_OK); } @@ -847,7 +854,6 @@ stat_t cm_get_fan_low_temp(nvObj_t *nv) // case '2': { nv->value = heater_fan2.low_temp; break; } // case '3': { nv->value = heater_fan3.low_temp; break; } - // Failsafe. We can only get here if we set it up in config_app, but not here. default: { nv->value = 0.0; break; } } @@ -863,10 +869,9 @@ stat_t cm_set_fan_low_temp(nvObj_t *nv) // case '2': { heater_fan2.low_temp = min(0.0f, nv->value); break; } // case '3': { heater_fan3.low_temp = min(0.0f, nv->value); break; } - // Failsafe. We can only get here if we set it up in config_app, but not here. default: { break; } } - + return (STAT_OK); } @@ -880,7 +885,6 @@ stat_t cm_get_fan_high_temp(nvObj_t *nv) // case '2': { nv->value = heater_fan2.high_temp; break; } // case '3': { nv->value = heater_fan3.high_temp; break; } - // Failsafe. We can only get here if we set it up in config_app, but not here. default: { nv->value = 0.0; break; } } @@ -896,27 +900,30 @@ stat_t cm_set_fan_high_temp(nvObj_t *nv) // case '2': { heater_fan2.high_temp = min(0.0f, nv->value); break; } // case '3': { heater_fan3.high_temp = min(0.0f, nv->value); break; } - // Failsafe. We can only get here if we set it up in config_app, but not here. default: { break; } } - + return (STAT_OK); } /* * cm_get_at_temperature() - get a boolean if the heater has reaced the set value of the PID */ -stat_t cm_get_at_temperature(nvObj_t *nv) +bool cm_get_at_temperature(const uint8_t heater) { - switch(_get_heater_number(nv)) { - case '1': { nv->value = pid1._at_set_point; break; } - case '2': { nv->value = pid2._at_set_point; break; } - case '3': { nv->value = pid3._at_set_point; break; } + switch(heater) { + case 1: { return pid1._at_set_point; } + case 2: { return pid2._at_set_point; } + case 3: { return pid3._at_set_point; } - // Failsafe. We can only get here if we set it up in config_app, but not here. - default: { nv->value = 0.0; break; } + default: { break; } } + return false; +} +stat_t cm_get_at_temperature(nvObj_t *nv) +{ + nv->value = cm_get_at_temperature(_get_heater_number(nv) - '0'); nv->precision = GET_TABLE_WORD(precision); nv->valuetype = TYPE_BOOL; @@ -927,16 +934,20 @@ stat_t cm_get_at_temperature(nvObj_t *nv) /* * cm_get_heater_output() - get the output value (PWM duty cycle) of the PID */ +float cm_get_heater_output(const uint8_t heater) +{ + switch(heater) { + case 1: { return (float)fet_pin1; } + case 2: { return (float)fet_pin2; } + case 3: { return (float)fet_pin3; } + + default: { break; } + } + return 0.0; +} stat_t cm_get_heater_output(nvObj_t *nv) { - switch(_get_heater_number(nv)) { - case '1': { nv->value = (float)fet_pin1; break; } - case '2': { nv->value = (float)fet_pin2; break; } - case '3': { nv->value = (float)fet_pin3; break; } - - // Failsafe. We can only get here if we set it up in config_app, but not here. - default: { nv->value = 0.0; break; } - } + nv->value = cm_get_heater_output(_get_heater_number(nv) - '0'); nv->precision = GET_TABLE_WORD(precision); nv->valuetype = TYPE_FLOAT; @@ -953,7 +964,6 @@ stat_t cm_get_heater_adc(nvObj_t *nv) case '2': { nv->value = (float)thermistor2.raw_adc_value; break; } case '3': { nv->value = (float)thermistor3.raw_adc_value; break; } - // Failsafe. We can only get here if we set it up in config_app, but not here. default: { nv->value = 0.0; break; } } nv->precision = GET_TABLE_WORD(precision); @@ -965,17 +975,21 @@ stat_t cm_get_heater_adc(nvObj_t *nv) /* * cm_get_temperature() - get the current temperature */ + float cm_get_temperature(const uint8_t heater) + { + switch(heater) { + case 1: { return (last_reported_temp1 = thermistor1.temperature_exact()); } + case 2: { return (last_reported_temp2 = thermistor2.temperature_exact()); } + case 3: { return (last_reported_temp3 = thermistor3.temperature_exact()); } + + default: { break; } + } + + return 0.0; + } stat_t cm_get_temperature(nvObj_t *nv) { - switch(_get_heater_number(nv)) { - case '1': { nv->value = last_reported_temp1 = thermistor1.temperature_exact(); break; } - case '2': { nv->value = last_reported_temp2 = thermistor2.temperature_exact(); break; } - case '3': { nv->value = last_reported_temp3 = thermistor3.temperature_exact(); break; } - - // Failsafe. We can only get here if we set it up in config_app, but not here. - default: { nv->value = 0.0; break; } - } - + nv->value = cm_get_temperature(_get_heater_number(nv) - '0'); nv->precision = GET_TABLE_WORD(precision); nv->valuetype = TYPE_FLOAT; @@ -992,7 +1006,6 @@ stat_t cm_get_thermistor_resistance(nvObj_t *nv) case '2': { nv->value = thermistor2.get_resistance(); break; } case '3': { nv->value = thermistor3.get_resistance(); break; } - // Failsafe. We can only get here if we set it up in config_app, but not here. default: { nv->value = 0.0; break; } } nv->precision = GET_TABLE_WORD(precision); @@ -1022,7 +1035,6 @@ stat_t cm_get_pid_p(nvObj_t *nv) case '2': { nv->value = pid2._proportional; break; } case '3': { nv->value = pid3._proportional; break; } - // Failsafe. We can only get here if we set it up in config_app, but not here. default: { nv->value = 0.0; break; } } nv->precision = GET_TABLE_WORD(precision); @@ -1041,7 +1053,6 @@ stat_t cm_get_pid_i(nvObj_t *nv) case '2': { nv->value = pid2._integral; break; } case '3': { nv->value = pid3._integral; break; } - // Failsafe. We can only get here if we set it up in config_app, but not here. default: { nv->value = 0.0; break; } } nv->precision = GET_TABLE_WORD(precision); @@ -1060,12 +1071,11 @@ stat_t cm_get_pid_d(nvObj_t *nv) case '2': { nv->value = pid2._derivative; break; } case '3': { nv->value = pid3._derivative; break; } - // Failsafe. We can only get here if we set it up in config_app, but not here. default: { nv->value = 0.0; break; } } nv->precision = GET_TABLE_WORD(precision); nv->valuetype = TYPE_FLOAT; - + return (STAT_OK); } diff --git a/g2core/temperature.h b/g2core/temperature.h index 0163ce11..efa47165 100755 --- a/g2core/temperature.h +++ b/g2core/temperature.h @@ -49,20 +49,37 @@ stat_t cm_set_heater_d(nvObj_t* nv); stat_t cm_get_pid_p(nvObj_t* nv); stat_t cm_get_pid_i(nvObj_t* nv); stat_t cm_get_pid_d(nvObj_t* nv); + +float cm_get_set_temperature(const uint8_t heater); stat_t cm_get_set_temperature(nvObj_t* nv); + +void cm_set_set_temperature(const uint8_t heater, const float valoue); stat_t cm_set_set_temperature(nvObj_t* nv); + +float cm_get_fan_power(const uint8_t heater); stat_t cm_get_fan_power(nvObj_t* nv); + +void cm_set_fan_power(const uint8_t heater, const float value); stat_t cm_set_fan_power(nvObj_t* nv); + stat_t cm_get_fan_min_power(nvObj_t* nv); stat_t cm_set_fan_min_power(nvObj_t* nv); stat_t cm_get_fan_low_temp(nvObj_t* nv); stat_t cm_set_fan_low_temp(nvObj_t* nv); stat_t cm_get_fan_high_temp(nvObj_t* nv); stat_t cm_set_fan_high_temp(nvObj_t* nv); + +bool cm_get_at_temperature(const uint8_t heater); stat_t cm_get_at_temperature(nvObj_t* nv); + +float cm_get_heater_output(const uint8_t heater); stat_t cm_get_heater_output(nvObj_t* nv); + stat_t cm_get_heater_adc(nvObj_t* nv); + +float cm_get_temperature(const uint8_t heater); stat_t cm_get_temperature(nvObj_t* nv); + stat_t cm_get_thermistor_resistance(nvObj_t* nv); diff --git a/g2core/util.h b/g2core/util.h index af2dbcb6..7e6745f0 100644 --- a/g2core/util.h +++ b/g2core/util.h @@ -189,10 +189,15 @@ constexpr float c_atof_int_(char *&p_, int_type v_) { // Start portion constexpr float c_atof(char *&p_) { return (*p_ == '-') ? (c_atof_int_(++p_, 0) * -1.0) : ( (*p_ == '+') ? c_atof_int_(++p_, 0) : (c_atof_int_(p_, 0))); } - // It's assumed that the string buffer contains at lest count_ non-\0 chars //constexpr int c_strreverse(char * const t, const int count_, char hold = 0) { // return count_>1 ? (hold=*t, *t=*(t+(count_-1)), *(t+(count_-1))=hold), c_strreverse(t+1, count_-2), count_ : count_; //} +template +void str_concat(char *&dest, const char (&data)[length]) { + // length includes the \0 + strncpy(dest, data, length); dest += length-1; +}; + #endif // End of include guard: UTIL_H_ONCE