machines/shredder/asterix-pp/firmware/app_shredding.cpp
2023-11-12 21:43:05 +01:00

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;
}
}