486 lines
12 KiB
C++
486 lines
12 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
|
|
|
|
short App::setOverload(short val)
|
|
{
|
|
return;
|
|
overloaded = val;
|
|
if (!overloaded)
|
|
{
|
|
shredState = shredStateLast;
|
|
}
|
|
return val;
|
|
}
|
|
|
|
short App::plungerCB(short val)
|
|
{
|
|
mLoad->loop();
|
|
hopperLoaded->loop();
|
|
loop_com();
|
|
if (mLoad->jammed() || overloaded || isAutoReversing())
|
|
{
|
|
return false;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
ushort App::loop_auto_reverse()
|
|
{
|
|
|
|
#ifdef HAS_POWER
|
|
if (!powerSwitch->isOn(POWER_PRIMARY))
|
|
{
|
|
return E_POWER;
|
|
}
|
|
#endif
|
|
|
|
switch (shredState)
|
|
{
|
|
case JAMMED:
|
|
{
|
|
shredState = FORWARDING;
|
|
vfd->rev(true);
|
|
jamCounter++;
|
|
SHRED_DEBUG("jammed: reversing");
|
|
timer.in(
|
|
AR_REVERSE_TIME, [](App *app) -> void {
|
|
app->vfd->stop();
|
|
app->shredState = STOPPING;
|
|
SHRED_DEBUG("jammed: stopped");
|
|
},
|
|
this);
|
|
break;
|
|
}
|
|
case STOPPING:
|
|
{
|
|
shredState = FORWARDING;
|
|
SHRED_DEBUG("jammed: stopping");
|
|
timer.in(
|
|
AR_FORWARD_WAIT_TIME, [](App *app) -> void {
|
|
app->shredState = REVERSED;
|
|
SHRED_DEBUG("jammed: stopped");
|
|
},
|
|
this);
|
|
break;
|
|
}
|
|
case REVERSED:
|
|
{
|
|
shredState = FORWARDING;
|
|
if (mLoad->jammed())
|
|
{
|
|
SHRED_DEBUG("reversed: stuck!");
|
|
shredState = STUCK;
|
|
break;
|
|
}
|
|
vfd->fwd(true);
|
|
plunger->reset();
|
|
SHRED_DEBUG("jammed: forward");
|
|
timer.in(
|
|
AR_FORWARDING_TIME, [](App *app) -> void {
|
|
if (app->mLoad->jammed())
|
|
{
|
|
SHRED_DEBUG("jammed: still jammed, redo autoreverse");
|
|
app->shredState = JAMMED;
|
|
}
|
|
else
|
|
{
|
|
SHRED_DEBUG("jammed: continue with");
|
|
SHRED_DEBUG(app->shredStateLast);
|
|
SHRED_DEBUG(app->shredState);
|
|
if (app->shredStateLast && app->shredStateLast != WAITING)
|
|
{
|
|
app->shredState = app->shredStateLast;
|
|
}
|
|
else
|
|
{
|
|
if ((millis() - app->shredStart) / 1000 > 60)
|
|
{
|
|
SHRED_DEBUG("jammed: invalid state abort");
|
|
app->shredState = CANCELLING;
|
|
return;
|
|
}
|
|
SHRED_DEBUG("jammed: invalid state continue with");
|
|
|
|
app->shredState = JAMMED;
|
|
SHRED_DEBUG(app->shredStateLast);
|
|
SHRED_DEBUG(app->shredState);
|
|
SHRED_DEBUG((millis() - app->shredStart) / 1000);
|
|
app->vfd->stop();
|
|
}
|
|
app->plunger->reset();
|
|
app->plunger->plunge();
|
|
}
|
|
},
|
|
this);
|
|
break;
|
|
}
|
|
}
|
|
return E_OK;
|
|
}
|
|
short App::shred(short value)
|
|
{
|
|
shredState = INIT;
|
|
shredStateLast = 0;
|
|
_state = SHREDDING;
|
|
// {"0":25,"1":1,"2":1,"3":0,"4":0,"5":3478}
|
|
SHRED_DEBUG("START SHREDDING --------------------------");
|
|
powerSwitch->on(POWER_PRIMARY);
|
|
shredStart = millis();
|
|
}
|
|
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 (newState != WAITING && newState != FORWARDING)
|
|
{
|
|
shredStateLast = shredState;
|
|
}
|
|
shredState = newState;
|
|
Serial.print("Did set new shred state : ");
|
|
Serial.println(shredState);
|
|
return shredState;
|
|
}
|
|
|
|
void App::loopShredCancel()
|
|
{
|
|
|
|
switch (shredCancelState)
|
|
{
|
|
case INIT:
|
|
{
|
|
SHRED_DEBUG("CANCEL STOP SHREDDER");
|
|
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:
|
|
{
|
|
SHRED_DEBUG("CANCEL : SHREDDED");
|
|
shredCancelState = WAITING;
|
|
plunger->home();
|
|
timer.in(
|
|
SWT_SHREDDED, [](App *app) -> void {
|
|
if (app->plunger->home())
|
|
{
|
|
SHRED_DEBUG("\t cancel back homed, done");
|
|
app->shredCancelState = DONE;
|
|
}
|
|
else
|
|
{
|
|
if (app->shredCancelState != DONE)
|
|
{
|
|
SHRED_DEBUG("\t cancel not back homed , try again");
|
|
app->shredCancelState = SHREDDED;
|
|
}
|
|
}
|
|
},
|
|
this);
|
|
break;
|
|
}
|
|
case DONE:
|
|
{
|
|
SHRED_DEBUG("CANCELLED SHREDDING ----------------------------------------------------");
|
|
powerSwitch->off(POWER_PRIMARY);
|
|
powerSwitch->off(POWER_SECONDARY);
|
|
shredCancelState = DONE;
|
|
shredState = CANCELLED;
|
|
plunger->reset();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
ushort App::loopShred()
|
|
{
|
|
#ifdef HAS_POWER
|
|
if (_state == SHREDDING)
|
|
{
|
|
if (!powerSwitch->isOn(POWER_PRIMARY))
|
|
{
|
|
Serial.println("got no power");
|
|
return E_POWER;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
if (shredState == STUCK)
|
|
{
|
|
Serial.println("stuck");
|
|
return;
|
|
}
|
|
|
|
if (shredState == CANCELLING)
|
|
{
|
|
loopShredCancel();
|
|
return E_OK;
|
|
}
|
|
|
|
if (isAutoReversing())
|
|
{
|
|
return loop_auto_reverse();
|
|
}
|
|
|
|
if (mLoad->jammed())
|
|
{
|
|
if (!isAutoReversing())
|
|
{
|
|
SHRED_DEBUG("SET JAMMED !!! ");
|
|
plunger->pause();
|
|
shredStateLast = shredState;
|
|
shredState = JAMMED;
|
|
loop_auto_reverse();
|
|
}
|
|
return E_OK;
|
|
}
|
|
|
|
short mLoadError = mLoad->ok();
|
|
|
|
if (mLoadError != E_OK)
|
|
{
|
|
shredState == CANCELLING;
|
|
vfd->stop();
|
|
Serial.println("cancel!");
|
|
}
|
|
|
|
if (_state != App::APP_STATE::SHREDDING && analogRead(CONTROLLINO_A15) < 500)
|
|
{
|
|
Serial.println("shred");
|
|
shred();
|
|
return;
|
|
}
|
|
|
|
if (_state != App::APP_STATE::SHREDDING)
|
|
{
|
|
// delay(10);
|
|
// Serial.println("abort, not shredding");
|
|
return;
|
|
}
|
|
|
|
switch (shredState)
|
|
{
|
|
case CANCELLING:
|
|
{
|
|
loopShredCancel();
|
|
break;
|
|
}
|
|
case INIT:
|
|
{
|
|
SHRED_DEBUG("POWERED : powering");
|
|
powerSwitch->on(POWER_PRIMARY);
|
|
setShredState(WAITING);
|
|
plunger->reset();
|
|
timer.in(
|
|
SWT_INIT, [](App *app) -> void {
|
|
app->setShredState(POWERED);
|
|
},
|
|
this);
|
|
|
|
break;
|
|
}
|
|
case POWERED:
|
|
{
|
|
setShredState(WAITING);
|
|
SHRED_DEBUG("POWERED : homing");
|
|
plunger->home(false);
|
|
timer.in(
|
|
SWT_POWERED, [](App *app) -> void {
|
|
if (app->plunger->home(false))
|
|
{
|
|
app->setShredState(HOMED);
|
|
SHRED_DEBUG("\t homed!");
|
|
}
|
|
else
|
|
{
|
|
SHRED_DEBUG("\t not homed, try again");
|
|
app->setShredState(POWERED);
|
|
}
|
|
},
|
|
this);
|
|
break;
|
|
}
|
|
case HOMED:
|
|
{
|
|
setShredState(WAITING);
|
|
SHRED_DEBUG("HOMED");
|
|
vfd->fwd(true);
|
|
timer.in(
|
|
SWT_STARTED, [](App *app) -> void {
|
|
app->setShredState(STARTED);
|
|
},
|
|
this);
|
|
break;
|
|
}
|
|
case PLUNGED_SHREDDING:
|
|
{
|
|
setShredState(WAITING);
|
|
if (mLoad->shredding())
|
|
{
|
|
timer.in(
|
|
1000, [](App *app) -> void {
|
|
SHRED_DEBUG("PLUNGED_SHREDDING : still shredding");
|
|
app->setShredState(PLUNGED_SHREDDING);
|
|
},
|
|
this);
|
|
}
|
|
else
|
|
{
|
|
if (millis() - mLoad->lastLoad > 2000)
|
|
{
|
|
SHRED_DEBUG("PLUNGED_SHREDDING : seems idle, move on to homing");
|
|
setShredState(UNPOWERED);
|
|
}
|
|
else
|
|
{
|
|
setShredState(PLUNGED_SHREDDING);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case STARTED:
|
|
{
|
|
setShredState(WAITING);
|
|
SHRED_DEBUG("STARTED");
|
|
plunger->plunge();
|
|
mLoad->lastLoad = millis();
|
|
SHRED_DEBUG("STARTED : plunging");
|
|
timer.in(
|
|
SWT_PLUNGED, [](App *app) -> void {
|
|
if (app->plunger->plunge())
|
|
{
|
|
SHRED_DEBUG("STARTED : plunged");
|
|
app->setShredState(PLUNGED_SHREDDING);
|
|
}
|
|
else
|
|
{
|
|
SHRED_DEBUG("STARTED : not plunged");
|
|
app->setShredState(STARTED);
|
|
}
|
|
},
|
|
this);
|
|
break;
|
|
}
|
|
|
|
case PLUNGED:
|
|
{
|
|
setShredState(WAITING);
|
|
SHRED_DEBUG("PLUNGED");
|
|
timer.in(
|
|
SWT_PLUNGED, [](App *app) -> void {
|
|
if (app->mLoad->shredding())
|
|
{
|
|
SHRED_DEBUG("STILL SHREDDING");
|
|
app->setShredState(PLUNGED);
|
|
}
|
|
else
|
|
{
|
|
SHRED_DEBUG("SEEMS DONE SHREDDING");
|
|
app->setShredState(UNPOWERED);
|
|
}
|
|
},
|
|
this);
|
|
break;
|
|
}
|
|
case UNPOWERED:
|
|
{
|
|
setShredState(WAITING);
|
|
SHRED_DEBUG("STOP SHREDDER");
|
|
vfd->stop();
|
|
timer.in(
|
|
SWT_UNPOWERED, [](App *app) -> void {
|
|
app->setShredState(SHREDDED);
|
|
},
|
|
this);
|
|
break;
|
|
}
|
|
case SHREDDED:
|
|
{
|
|
setShredState(WAITING);
|
|
SHRED_DEBUG("SHREDDED : homing");
|
|
plunger->home();
|
|
timer.in(
|
|
SWT_SHREDDED, [](App *app) -> void {
|
|
if (app->plunger->home())
|
|
{
|
|
SHRED_DEBUG("\t back homed, done");
|
|
app->setShredState(DONE);
|
|
}
|
|
else
|
|
{
|
|
|
|
if (app->shredState == DONE || app->shredState == RESET)
|
|
{
|
|
SHRED_DEBUG("\t weird, tried to home after DONE");
|
|
SHRED_DEBUG(app->shredState);
|
|
// return;
|
|
}
|
|
SHRED_DEBUG("\t not back homed , try again");
|
|
app->setShredState(SHREDDED);
|
|
}
|
|
},
|
|
this);
|
|
break;
|
|
}
|
|
case DONE:
|
|
{
|
|
SHRED_DEBUG("DONE SHREDDING ----------------------------------------------------");
|
|
|
|
timer.in(
|
|
SWT_SHREDDED_POWER_OFF, [](App *app) -> void {
|
|
if (app->_state == App::APP_STATE::RESET)
|
|
{
|
|
app->powerSwitch->off(POWER_PRIMARY);
|
|
}
|
|
},
|
|
this);
|
|
plunger->reset();
|
|
_state = App::APP_STATE::RESET;
|
|
shredStateLast = 0;
|
|
shredCancelState = 0;
|
|
shredState = WAITING;
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
}
|