Skip to content

Commit

Permalink
Implement M119 (#72). Note that endstops have no label yet.
Browse files Browse the repository at this point in the history
  • Loading branch information
Wallacoloo committed Jan 11, 2015
1 parent f1c8839 commit 81a2d81
Show file tree
Hide file tree
Showing 9 changed files with 77 additions and 26 deletions.
4 changes: 3 additions & 1 deletion src/common/tupleutil.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,9 +124,11 @@ template <typename TupleT, typename Func, typename ...Args> bool tupleReduceLogi
//Return @f(@t[@idx], args...)
//Note: if @idx > the size of the tuple, behavior is undefined.
// Most likely, that would result in applying @f to the last item in the tuple (but no guarantee)
template <typename TupleT, typename Func, typename ...Args> auto tupleCallOnIndex(TupleT &t, Func f, std::size_t idx, Args... args) -> decltype(__callOnIndex<TupleT, std::tuple_size<TupleT>::value, Func, Args...>()(t, f, idx, args...)) {
template <typename TupleT, typename Func, typename ...Args> auto tupleCallOnIndex(TupleT &t, Func f, std::size_t idx, Args... args)
-> decltype(__callOnIndex<TupleT, std::tuple_size<TupleT>::value, Func, Args...>()(t, f, idx, args...)) {
return __callOnIndex<TupleT, std::tuple_size<TupleT>::value, Func, Args...>()(t, f, idx, args...);
}

}

using namespace tupleutil;
Expand Down
5 changes: 4 additions & 1 deletion src/iodrivers/endstop.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,13 @@ class Endstop : public IODriver {
this->pin.setDefaultState(IO_DEFAULT_HIGH_IMPEDANCE);
this->pin.makeDigitalInput();
}
inline bool isEndstop() const {
return true;
}
inline bool isNull() const {
return pin.isNull();
}
inline bool isTriggered() const {
inline bool isEndstopTriggered() const {
//if the endstop is NULL, then always return triggered.
bool t = isNull() ? true : pin.digitalRead();
LOGV("LeverEndstop is %i\n", t);
Expand Down
23 changes: 13 additions & 10 deletions src/iodrivers/iodriver.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ class IODriver {
//OVERRIDE THIS (beds only: return true. No need to define a bed if it isn't heated).
inline bool isHeatedBed() const { return false; }
inline bool isServo() const { return false; }
inline bool isEndstop() const { return false; }
//endstops only:
inline bool isEndstopTriggered() const { return false; }
//OVERRIDE THIS (hotends / beds only)
inline void setTargetTemperature(CelciusType) { assert(false && "IoDriver::setTargetTemperature() must be overriden by subclass."); }
//OVERRIDE THIS (hotends / beds only)
Expand Down Expand Up @@ -91,8 +94,8 @@ class IODriver {
(void)dutyCycle;
assert(false && "IoDriver::setFanDutyCycle() must be overriden by subclass");
}
template <typename TupleT> static void lockAllAxis(TupleT &drivers);
template <typename TupleT> static void unlockAllAxis(TupleT &drivers);
template <typename TupleT> static void lockAllAxes(TupleT &drivers);
template <typename TupleT> static void unlockAllAxes(TupleT &drivers);
template <typename TupleT> static void setHotendTemp(TupleT &drivers, CelciusType temp);
template <typename TupleT> static void setBedTemp(TupleT &drivers, CelciusType temp);
template <typename TupleT> static CelciusType getHotendTemp(TupleT &drivers);
Expand All @@ -106,16 +109,16 @@ class IODriver {
namespace {
//place helper functions in an unnamed namespace to limit visibility and hint the documentation generator

//IODriver::lockAllAxis helper
struct IODriver__lockAllAxis {
//IODriver::lockAllAxes helper
struct IODriver__lockAllAxes {
template <typename T> void operator()(std::size_t index, T &driver) {
(void)index; //unused;
driver.lockAxis();
}
};

//IODriver::unlockAllAxis helper
struct IODriver__unlockAllAxis {
//IODriver::unlockAllAxes helper
struct IODriver__unlockAllAxes {
template <typename T> void operator()(std::size_t index, T &driver) {
(void)index; //unused;
driver.unlockAxis();
Expand Down Expand Up @@ -221,11 +224,11 @@ namespace {



template <typename TupleT> void IODriver::lockAllAxis(TupleT &drivers) {
callOnAll(drivers, IODriver__lockAllAxis());
template <typename TupleT> void IODriver::lockAllAxes(TupleT &drivers) {
callOnAll(drivers, IODriver__lockAllAxes());
}
template <typename TupleT> void IODriver::unlockAllAxis(TupleT &drivers) {
callOnAll(drivers, IODriver__unlockAllAxis());
template <typename TupleT> void IODriver::unlockAllAxes(TupleT &drivers) {
callOnAll(drivers, IODriver__unlockAllAxes());
}
template <typename TupleT> void IODriver::setHotendTemp(TupleT &drivers, CelciusType temp) {
callOnAll(drivers, IODriver__setHotendTemp(), temp);
Expand Down
4 changes: 2 additions & 2 deletions src/iodrivers/tempcontrol.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ template <typename Thermistor, typename PID=PID, typename Filter=NoFilter> class
static const std::chrono::microseconds _intervalThresh;
static const std::chrono::microseconds _readInterval;
static const std::chrono::microseconds _maxRead;
TempControlType _hotType;
const TempControlType _hotType;
IntervalTimer _intervalTimer;
IoPin _heater;
Thermistor _therm;
Expand All @@ -67,7 +67,7 @@ template <typename Thermistor, typename PID=PID, typename Filter=NoFilter> class
bool _isReading;
EventClockT::time_point _nextReadTime;
public:
inline TempControl(TempControlType hotType, IoPin &&heater, Thermistor &&therm, const PID &pid, const Filter &filter, float pwmPeriod=1./25000)
inline TempControl(const TempControlType hotType, IoPin &&heater, Thermistor &&therm, const PID &pid, const Filter &filter, float pwmPeriod=1./25000)
: IODriver(), _hotType(hotType), _heater(std::move(heater)), _therm(std::move(therm)), _pid(pid), _filter(filter), _pwmPeriod(pwmPeriod), _destTemp(-300), _lastTemp(-300), _isReading(false),
_nextReadTime(EventClockT::now()) {
_heater.setDefaultState(IO_DEFAULT_LOW);
Expand Down
8 changes: 6 additions & 2 deletions src/motion/linearcoordmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,16 @@ template <typename Stepper1, typename Stepper2, typename Stepper3, typename Step
bedLevel(t),
endstops({{std::move(endstopX), std::move(endstopY), std::move(endstopZ), std::move(iodrv::Endstop())}}),
stepperDrivers(std::move(stepper1), std::move(stepper2), std::move(stepper3), std::move(stepper4)) {}
inline std::tuple<Stepper1&, Stepper2&, Stepper3&, Stepper4&> getDependentIoDrivers() {
inline std::tuple<Stepper1&, Stepper2&, Stepper3&, Stepper4&,
iodrv::Endstop&, iodrv::Endstop&, iodrv::Endstop&> getDependentIoDrivers() {
return std::tie(
std::get<0>(stepperDrivers),
std::get<1>(stepperDrivers),
std::get<2>(stepperDrivers),
std::get<3>(stepperDrivers));
std::get<3>(stepperDrivers),
endstops[0],
endstops[1],
endstops[2]);
}
inline _AxisStepperTypes getAxisSteppers() const {
return _AxisStepperTypes();
Expand Down
8 changes: 6 additions & 2 deletions src/motion/lineardeltacoordmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,12 +93,16 @@ template <typename Stepper1, typename Stepper2, typename Stepper3, typename Step
bedLevel(t),
endstops({{std::move(endstopA), std::move(endstopB), std::move(endstopC), std::move(iodrv::Endstop())}}),
stepperDrivers(std::move(stepper1), std::move(stepper2), std::move(stepper3), std::move(stepper4)) {}
inline std::tuple<Stepper1&, Stepper2&, Stepper3&, Stepper4&> getDependentIoDrivers() {
inline std::tuple<Stepper1&, Stepper2&, Stepper3&, Stepper4&,
iodrv::Endstop&, iodrv::Endstop&, iodrv::Endstop&> getDependentIoDrivers() {
return std::tie(
std::get<0>(stepperDrivers),
std::get<1>(stepperDrivers),
std::get<2>(stepperDrivers),
std::get<3>(stepperDrivers));
std::get<3>(stepperDrivers),
endstops[0],
endstops[1],
endstops[2]);
}
inline _AxisStepperTypes getAxisSteppers() const {
return _AxisStepperTypes();
Expand Down
4 changes: 2 additions & 2 deletions src/motion/lineardeltastepper.h
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ template <typename StepperDriverT, DeltaAxis AxisIdx> class LinearDeltaArcSteppe
//Then we test that time for a backward step (sTotal - 1).
//We choose the nearest resulting time as our next step.
//This is necessary because axis velocity can actually reverse direction during a circular cartesian movement.
if (useEndstops && endstop->isTriggered()) {
if (useEndstops && endstop->isEndstopTriggered()) {
this->time = NAN; //at endstop; no more steps.
} else {
float negTime = testDir((this->sTotal-1)*MM_STEPS()); //get the time at which next steps would occur.
Expand Down Expand Up @@ -403,7 +403,7 @@ template <typename StepperDriverT, DeltaAxis AxisIdx> class LinearDeltaStepper :
//Then we test that time for a backward step (sTotal - 1).
//We choose the nearest resulting time as our next step.
//This is necessary because axis velocity can actually reverse direction during a linear cartesian movement.
if (useEndstops && endstop->isTriggered()) {
if (useEndstops && endstop->isEndstopTriggered()) {
this->time = NAN; //at endstop; no more steps.
} else {
float negTime = testDir((this->sTotal-1)*MM_STEPS()); //get the time at which next steps would occur.
Expand Down
2 changes: 1 addition & 1 deletion src/motion/linearstepper.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ template <typename StepperDriverT, CartesianAxis CoordType> class LinearStepper
}
//protected:
inline void _nextStep(bool useEndstops) {
if (useEndstops && endstop->isTriggered()) {
if (useEndstops && endstop->isEndstopTriggered()) {
this->time = NAN; //at endstop; no more steps.
} else {
this->time += timePerStep;
Expand Down
45 changes: 40 additions & 5 deletions src/state.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ template <typename Drv> class State {
}
};
struct State__setFanRate; //forward declare a type used internally in setFanRate() function
class State__getEndstopStatusString; //forware declare a type used internally in getEndstopStatusString() function
struct State__onIdleCpu; //forward declare a type used internally in onIdleCpu() function
typedef Scheduler<SchedInterface> SchedType;
//The ioDrivers are a combination of the ones used by the coordmap and the miscellaneous ones from the machine
Expand Down Expand Up @@ -265,6 +266,7 @@ template <typename Drv> class State {
bool isHotendReady();
/* Set the hotend (and bed) fan to a duty cycle between 0.0 and 1.0 (if value > 1, it will assume a scale from 0-255) */
void setFanRate(float rate);
std::string getEndstopStatusString() const;
};


Expand Down Expand Up @@ -505,7 +507,7 @@ template <typename Drv> template <typename ReplyFunc> void State<Drv>::execute(g
if (!_isHomed && _motionPlanner.doHomeBeforeFirstMovement()) {
this->homeEndstops();
}
LOGW("Warning: G3 is experimental\n");
LOGW("Warning: G2/G3 is experimental\n");
//first, get the end coordinate and optional feed-rate:
bool hasX, hasY, hasZ, hasE;
bool hasF;
Expand Down Expand Up @@ -571,14 +573,14 @@ template <typename Drv> template <typename ReplyFunc> void State<Drv>::execute(g
setHostZeroPos(actualX, actualY, actualZ, actualE);
reply(gparse::Response::Ok);
} else if (cmd.isM0()) { //Stop; empty move buffer & exit cleanly
LOG("recieved M0 command: finishing moves, then exiting\n");
LOGD("recieved M0 command: finishing moves, then exiting\n");
_doShutdownAfterMoveCompletes = true;
reply(gparse::Response::Ok);
} else if (cmd.isM17()) { //enable all stepper motors
iodrv::IODriver::lockAllAxis(this->ioDrivers);
iodrv::IODriver::lockAllAxes(this->ioDrivers);
reply(gparse::Response::Ok);
} else if (cmd.isM18()) { //allow stepper motors to move 'freely'
iodrv::IODriver::unlockAllAxis(this->ioDrivers);
iodrv::IODriver::unlockAllAxes(this->ioDrivers);
reply(gparse::Response::Ok);
} else if (cmd.isM21()) { //initialize SD card (nothing to do).
reply(gparse::Response::Ok);
Expand All @@ -597,7 +599,7 @@ template <typename Drv> template <typename ReplyFunc> void State<Drv>::execute(g
setExtruderPosMode(POS_RELATIVE);
reply(gparse::Response::Ok);
} else if (cmd.isM84()) { //stop idle hold: relax all motors (same as M18)
iodrv::IODriver::unlockAllAxis(this->ioDrivers);
iodrv::IODriver::unlockAllAxes(this->ioDrivers);
reply(gparse::Response::Ok);
} else if (cmd.isM99()) { //return from macro/subprogram
//note: can't simply pop the top file, because then that causes memory access errors when trying to send it areply.
Expand Down Expand Up @@ -634,6 +636,7 @@ template <typename Drv> template <typename ReplyFunc> void State<Drv>::execute(g
setFanRate(s);
reply(gparse::Response::Ok);
} else if (cmd.isM107()) { //set fan = off.
LOGW("M107 is deprecated. Use M106 with S=0 instead.\n");
setFanRate(0);
reply(gparse::Response::Ok);
} else if (cmd.isM109()) { //set extruder temperature to S param and wait.
Expand Down Expand Up @@ -671,6 +674,11 @@ template <typename Drv> template <typename ReplyFunc> void State<Drv>::execute(g
} else if (cmd.isM117()) { //print message
LOG("M117 message: '%s'\n", cmd.getSpecialStringParam().c_str());
reply(gparse::Response::Ok);
} else if (cmd.isM119()) {
//get endstop status
LOGW("M119 not tested\n");
//reply(gparse::Response(gparse::ResponseOk, iodrv::IODriver::getEndstopNameStatusPairs(ioDrivers)));
reply(gparse::Response(gparse::ResponseOk, getEndstopStatusString()));
} else if (cmd.isM140()) { //set BED temp and return immediately.
LOGW("(gparse/state.h): OP_M140 (set bed temp) is untested\n");
bool hasS;
Expand Down Expand Up @@ -756,4 +764,31 @@ template <typename Drv> void State<Drv>::setFanRate(float rate) {
callOnAll(ioDrivers, State__setFanRate(), this, rate);
}

template <typename Drv> class State<Drv>::State__getEndstopStatusString {
std::ostringstream imploded;
bool first;
public:
State__getEndstopStatusString() : first(true) {}
template <typename T> void operator()(std::size_t index, T &driver) {
(void)index; //unused
if (driver.isEndstop()) {
if (first) {
first = false;
} else {
imploded << ' ';
}
imploded << (driver.isEndstopTriggered() ? "triggered" : "open");
}
}
std::string str() const {
return imploded.str();
}
};

template <typename Drv> std::string State<Drv>::getEndstopStatusString() const {
State__getEndstopStatusString statusObj;
callOnAll(this->ioDrivers, &statusObj);
return statusObj.str();
}

#endif

0 comments on commit 81a2d81

Please sign in to comment.