415 lines
9.3 KiB
C++
415 lines
9.3 KiB
C++
#include <Vector.h>
|
|
#include <Streaming.h>
|
|
#include <Arduino.h>
|
|
#include "app.h"
|
|
#include "features.h"
|
|
|
|
// #define HAS_SHRED_DEBUG
|
|
|
|
#ifdef HAS_SHRED_DEBUG
|
|
#define SHRED_DEBUG(A) Serial.println(A);
|
|
#else
|
|
#define SHRED_DEBUG(A)
|
|
#endif
|
|
|
|
#define MANUAL_ABORT \
|
|
if (app->opModeSwitch->value() == OP_MANUAL) \
|
|
{ \
|
|
return; \
|
|
}
|
|
|
|
short App::plungerCB(short val)
|
|
{
|
|
mLoad->loop();
|
|
if (mLoad->jammed() || overloaded || isAutoReversing())
|
|
{
|
|
return false;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
ushort App::loop_auto_reverse()
|
|
{
|
|
switch (shredState)
|
|
{
|
|
case JAMMED:
|
|
{
|
|
this->shredState = FORWARDING;
|
|
this->vfd->rev(true);
|
|
jamCounter++;
|
|
timer.in(
|
|
AR_REVERSE_TIME, [](App *app) -> void
|
|
{
|
|
app->vfd->stop();
|
|
app->shredState = REVERSED;
|
|
},
|
|
this);
|
|
break;
|
|
}
|
|
case STOPPING:
|
|
{
|
|
this->shredState = FORWARDING;
|
|
timer.in(
|
|
AR_FORWARD_WAIT_TIME, [](App *app) -> void
|
|
{ app->shredState = REVERSED; },
|
|
this);
|
|
break;
|
|
}
|
|
case REVERSED:
|
|
{
|
|
if (this->mLoad->jammed())
|
|
{
|
|
shredState = STUCK;
|
|
break;
|
|
}
|
|
this->vfd->fwd(true);
|
|
this->plunger->reset();
|
|
this->shredState = FORWARDING;
|
|
timer.in(
|
|
AR_FORWARDING_TIME, [](App *app) -> void
|
|
{
|
|
// MANUAL_ABORT;
|
|
if (app->mLoad->jammed())
|
|
{
|
|
app->shredState = JAMMED;
|
|
SHRED_DEBUG("Stll jammed");
|
|
}
|
|
else
|
|
{
|
|
SHRED_DEBUG(app->shredStateLast);
|
|
app->shredState = app->shredStateLast;
|
|
}
|
|
},
|
|
this);
|
|
break;
|
|
}
|
|
}
|
|
return E_OK;
|
|
}
|
|
short App::shred(short value)
|
|
{
|
|
shredState = INIT;
|
|
shredStateLast = 0;
|
|
_state = SHREDDING;
|
|
shredStart = millis();
|
|
statusLightError.status_blink(true);
|
|
}
|
|
bool App::isAutoReversing()
|
|
{
|
|
return (shredState == App::SHRED_STATE::JAMMED ||
|
|
shredState == App::SHRED_STATE::REVERSING ||
|
|
shredState == App::SHRED_STATE::REVERSED ||
|
|
shredState == App::SHRED_STATE::STOPPING ||
|
|
shredState == App::SHRED_STATE::FORWARDING) ||
|
|
_state == JAMMED;
|
|
}
|
|
short App::setShredState(short newState)
|
|
{
|
|
|
|
if (shredState == App::SHRED_STATE::CANCELLING)
|
|
{
|
|
return App::SHRED_STATE::CANCELLING;
|
|
}
|
|
|
|
if (isAutoReversing())
|
|
{
|
|
return App::SHRED_STATE::JAMMED;
|
|
}
|
|
|
|
if (shredState != App::SHRED_STATE::WAITING && shredState != App::SHRED_STATE::FORWARDING)
|
|
{
|
|
shredStateLast = shredState;
|
|
}
|
|
shredState = newState;
|
|
|
|
return shredState;
|
|
}
|
|
|
|
void App::loopShredCancel()
|
|
{
|
|
|
|
switch (shredCancelState)
|
|
{
|
|
case INIT:
|
|
{
|
|
plunger->reset();
|
|
if (vfd->direction != VFD::DIRECTION::STOP)
|
|
{
|
|
vfd->stop();
|
|
timer.in(
|
|
SWT_UNPOWERED, [](App *app) -> void
|
|
{ app->shredCancelState = SHREDDED; },
|
|
this);
|
|
}
|
|
else
|
|
{
|
|
shredCancelState = SHREDDED;
|
|
}
|
|
break;
|
|
}
|
|
|
|
case SHREDDED:
|
|
{
|
|
shredCancelState = WAITING;
|
|
plunger->home();
|
|
timer.in(
|
|
SWT_SHREDDED, [](App *app) -> void
|
|
{
|
|
if (app->plunger->home())
|
|
{
|
|
app->shredCancelState = DONE;
|
|
}
|
|
else
|
|
{
|
|
if (app->shredCancelState != DONE)
|
|
{
|
|
app->shredCancelState = SHREDDED;
|
|
}
|
|
}
|
|
},
|
|
this);
|
|
break;
|
|
}
|
|
case DONE:
|
|
{
|
|
SHRED_DEBUG("CANCELLED SHREDDING ----------------------------------------------------");
|
|
shredCancelState = DONE;
|
|
shredState = CANCELLED;
|
|
plunger->reset();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
ushort App::loopShred()
|
|
{
|
|
if (shredState == STUCK)
|
|
{
|
|
SHRED_DEBUG("stuck");
|
|
return;
|
|
}
|
|
|
|
if (shredState == CANCELLING)
|
|
{
|
|
loopShredCancel();
|
|
return E_OK;
|
|
}
|
|
|
|
if (this->isAutoReversing())
|
|
{
|
|
return this->loop_auto_reverse();
|
|
}
|
|
|
|
if (this->mLoad->jammed())
|
|
{
|
|
if (!this->isAutoReversing())
|
|
{
|
|
SHRED_DEBUG("jammed");
|
|
this->plunger->pause();
|
|
this->setShredState(JAMMED);
|
|
this->loop_auto_reverse();
|
|
}
|
|
return E_OK;
|
|
}
|
|
|
|
short mLoadError = this->mLoad->ok();
|
|
/*
|
|
if (mLoadError != E_OK)
|
|
{
|
|
shredState == CANCELLING;
|
|
vfd->stop();
|
|
Serial.println("cancel!");
|
|
}*/
|
|
|
|
if (_state != App::APP_STATE::SHREDDING && analogRead(SHRED_START_PIN) > 700)
|
|
{
|
|
shred();
|
|
return;
|
|
}
|
|
|
|
switch (shredState)
|
|
{
|
|
case CANCELLING:
|
|
{
|
|
loopShredCancel();
|
|
break;
|
|
}
|
|
case INIT:
|
|
{
|
|
this->setShredState(WAITING);
|
|
this->plunger->reset();
|
|
timer.in(
|
|
SWT_INIT, [](App *app) -> void
|
|
{
|
|
MANUAL_ABORT;
|
|
app->setShredState(POWERED);
|
|
},
|
|
this);
|
|
|
|
break;
|
|
}
|
|
case POWERED:
|
|
{
|
|
this->setShredState(WAITING);
|
|
this->plunger->home(false);
|
|
timer.in(
|
|
SWT_POWERED, [](App *app) -> void
|
|
{
|
|
MANUAL_ABORT;
|
|
if (app->plunger->home(false))
|
|
{
|
|
app->setShredState(HOMED);
|
|
}
|
|
else
|
|
{
|
|
app->setShredState(POWERED);
|
|
}
|
|
},
|
|
this);
|
|
break;
|
|
}
|
|
case HOMED:
|
|
{
|
|
this->setShredState(WAITING);
|
|
this->vfd->fwd(true);
|
|
timer.in(
|
|
SWT_STARTED, [](App *app) -> void
|
|
{
|
|
MANUAL_ABORT;
|
|
app->setShredState(STARTED);
|
|
},
|
|
this);
|
|
break;
|
|
}
|
|
case PLUNGED_SHREDDING:
|
|
{
|
|
this->setShredState(WAITING);
|
|
if (this->mLoad->shredding())
|
|
{
|
|
timer.in(
|
|
1000, [](App *app) -> void
|
|
{
|
|
MANUAL_ABORT;
|
|
app->setShredState(PLUNGED_SHREDDING);
|
|
},
|
|
this);
|
|
}
|
|
else
|
|
{
|
|
if (this->opModeSwitch->value() == OP_MANUAL)
|
|
{
|
|
return;
|
|
}
|
|
if (now - this->mLoad->lastLoad > 2000)
|
|
{
|
|
this->setShredState(UNPOWERED);
|
|
}
|
|
else
|
|
{
|
|
this->setShredState(PLUNGED_SHREDDING);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case STARTED:
|
|
{
|
|
this->setShredState(WAITING);
|
|
this->plunger->plunge();
|
|
this->mLoad->lastLoad = millis();
|
|
timer.in(
|
|
SWT_PLUNGED, [](App *app) -> void
|
|
{
|
|
MANUAL_ABORT;
|
|
if (app->isAutoReversing())
|
|
{
|
|
return;
|
|
}
|
|
if (app->plunger->plunge())
|
|
{
|
|
app->setShredState(PLUNGED_SHREDDING);
|
|
}
|
|
else
|
|
{
|
|
app->setShredState(STARTED);
|
|
}
|
|
},
|
|
this);
|
|
break;
|
|
}
|
|
|
|
case PLUNGED:
|
|
{
|
|
this->setShredState(WAITING);
|
|
timer.in(
|
|
SWT_PLUNGED, [](App *app) -> void
|
|
{
|
|
MANUAL_ABORT;
|
|
if (app->mLoad->shredding())
|
|
{
|
|
app->setShredState(PLUNGED);
|
|
}
|
|
else
|
|
{
|
|
app->setShredState(UNPOWERED);
|
|
}
|
|
},
|
|
this);
|
|
break;
|
|
}
|
|
case UNPOWERED:
|
|
{
|
|
this->setShredState(WAITING);
|
|
this->vfd->stop();
|
|
timer.in(
|
|
SWT_UNPOWERED, [](App *app) -> void
|
|
{
|
|
MANUAL_ABORT;
|
|
app->setShredState(SHREDDED);
|
|
},
|
|
this);
|
|
break;
|
|
}
|
|
case SHREDDED:
|
|
{
|
|
this->setShredState(WAITING);
|
|
this->plunger->home();
|
|
timer.in(
|
|
SWT_SHREDDED, [](App *app) -> void
|
|
{
|
|
MANUAL_ABORT;
|
|
if (app->plunger->home())
|
|
{
|
|
app->setShredState(DONE);
|
|
}
|
|
else
|
|
{
|
|
|
|
if (app->shredState == DONE || app->shredState == RESET)
|
|
{
|
|
SHRED_DEBUG(app->shredState);
|
|
}
|
|
app->setShredState(SHREDDED);
|
|
}
|
|
},
|
|
this);
|
|
break;
|
|
}
|
|
case DONE:
|
|
{
|
|
timer.in(
|
|
SWT_SHREDDED_POWER_OFF, [](App *app) -> void
|
|
{ MANUAL_ABORT; },
|
|
this);
|
|
this->plunger->reset();
|
|
this->_state = App::APP_STATE::RESET;
|
|
this->shredStateLast = 0;
|
|
this->shredCancelState = 0;
|
|
this->shredState = WAITING;
|
|
this->statusLightError.status_blink(false);
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
}
|