/*----------------------------------------------------------------------------- * Ausgang für Rollladen einschalten * Schaltet sich nach 30 s automatisch ab */ void DigOutShade(TDigOutShadeNumber number, TDigOutShadeAction action) { TDigOutNumber onSwitch; TDigOutNumber dirSwitch; onSwitch = sShade[number].onSwitch; dirSwitch = sShade[number].dirSwitch; if ((onSwitch == eDigOutInvalid) || (dirSwitch == eDigOutInvalid)) { return; } switch (action) { case eDigOutShadeOpen: /* Richtungsrelais soll sich ebenfalls ausschalten */ /* mit größerer Verzögerung, damit sichergestellt ist, dass */ /* nicht bei abschalten kurz in die andere Richtung gefahren */ /* wird */ /* 1. Strom (on) AUS */ /* 2. Richtung (dir) EIN mit Verzögerung */ /* 3. Strom (on) EIN mit Verzögerung kurz nach Richtung EIN */ /* 4. Warten (30 s) */ /* 5. Strom (on) AUS */ /* 6. Richtung (dir) AUS kurz nach Strom AUS */ DigOutOff(onSwitch); DigOutDelayedOnDelayedOff(dirSwitch, SHADE_DELAY_DIFF, SHADE_DELAY + SHADE_DELAY_DIFF * 2); DigOutDelayedOnDelayedOff(onSwitch, SHADE_DELAY_DIFF * 2, SHADE_DELAY); break; case eDigOutShadeClose: /* 1, Strom (on) AUS */ /* 2. Richtung (dir) AUS mit Verzögerung falls vorher EIN) */ /* 3. Strom (on) EIN mit Verzögerung kurz nach Richtung AUS */ /* 4. Warten (30 s) */ /* 5. Strom (on) AUS */ DigOutOff(onSwitch); if (DigOutState(dirSwitch) == TRUE) { DigOutDelayedOff(dirSwitch, SHADE_DELAY_DIFF); } DigOutDelayedOnDelayedOff(onSwitch, SHADE_DELAY_DIFF * 2, SHADE_DELAY); break; case eDigOutShadeStop: /* 1. Strom (on) AUS */ /* 2. Richtung (dir) AUS mit Verzögerung falls vorher EIN */ /* Ausschaltverzögerung deaktivieren und sofort abschalten */ DigOutOff(onSwitch); sState[onSwitch].state = eDigOutNoDelay; /* dirSwitch verzögert abschalten */ if (DigOutState(dirSwitch) == TRUE) { DigOutDelayedOff(dirSwitch, SHADE_DELAY_DIFF); } break; default: break; } }
/*----------------------------------------------------------------------------- * alle Ausgänge ausschalten */ void DigOutOffAll(void) { UINT8 i; for (i = 0; i < NUM_DIGOUT; i++) { DigOutOff(i); } }
/*----------------------------------------------------------------------------- * alle Ausgänge ausschalten */ void DigOutOffAll(void) { uint8_t i; for (i = 0; i < NUM_DIGOUT; i++) { DigOutOff(i); } }
/*----------------------------------------------------------------------------- * Statemachine für zeitgesteuerung Aktionen * mit jedem Aufruf wird ein Ausgang bearbeitet */ void DigOutStateCheck(void) { static UINT8 sDigoutNum = 0; TDigoutDesc *pState; TDelayState delayState; UINT32 actualTime; GET_TIME_MS32(actualTime); pState = &sState[sDigoutNum]; delayState = pState->state; if (delayState == eDigOutNoDelay) { /* nichts zu tun */ } else if (delayState == eDigOutDelayOn) { if (((UINT32)(actualTime - pState->startTimeMs)) >= pState->onDelayMs) { DigOutOn(sDigoutNum); delayState = eDigOutNoDelay; } } else if (delayState == eDigOutDelayOff) { if (((UINT32)(actualTime - pState->startTimeMs)) >= pState->offDelayMs) { DigOutOff(sDigoutNum); delayState = eDigOutNoDelay; } } else if (delayState == eDigOutDelayOnOff) { if (DigOutState(sDigoutNum) == FALSE) { /* einschaltverzögerung aktiv*/ if (((UINT32)(actualTime - pState->startTimeMs)) >= pState->onDelayMs) { DigOutOn(sDigoutNum); /* ab jetzt beginnt die Ausschaltverzögerung */ pState->startTimeMs = actualTime; } } else { if (((UINT32)(actualTime - pState->startTimeMs)) >= pState->offDelayMs) { DigOutOff(sDigoutNum); delayState = eDigOutNoDelay; } } } sDigoutNum++; if (sDigoutNum >= NUM_DIGOUT) { sDigoutNum = 0; } pState->state = delayState; }
/*----------------------------------------------------------------------------- * Ausgang wechseln */ void DigOutToggle(TDigOutNumber number) { uint32_t bitMask; bitMask = 1UL << (uint32_t)number; if ((sDigOutShadow & bitMask) == 0) { DigOutOn(number); } else { DigOutOff(number); } }
/*----------------------------------------------------------------------------- * alle Ausgangszustände setzen (mit zeitverzögerung zwischen eingeschalteten * Ausgängen zur Verringerung von Einschaltstromspitzen) */ void DigOutAll(UINT8 *pBuf, UINT8 bufLen) { UINT8 i; UINT8 maxIdx; maxIdx = min(bufLen * 8, NUM_DIGOUT); for (i = 0; i < maxIdx; i++) { if ((*(pBuf + i / 8) & (1 << (i % 8))) != 0) { DigOutOn(i); /* Verzögerung nur bei eingeschalteten Ausgängen */ DELAY_MS(200); } else { DigOutOff(i); } } }
void ShaderCheck(void) { static uint8_t sShaderNum = 0; TShaderDesc *pShader; TShaderCmd cmd; TShaderCmd nextCmd; TShaderInternalState nextState; uint16_t currentTime; uint32_t actionPeriod; sShaderNum++; sShaderNum %= eShaderNum; pShader = &sShader[sShaderNum]; if ((pShader->onSwitch == eDigOutInvalid) || (pShader->dirSwitch == eDigOutInvalid)) { return; } cmd = pShader->cmd; nextState = pShader->state; // default: the next state is the current one nextCmd = cmd; GET_TIME_10MS16(currentTime); actionPeriod = currentTime - pShader->actionTimestamp; switch (pShader->state) { case eStateStopped: switch (cmd) { case eCmdSetPosition: if (pShader->setPosition < pShader->actualPosition) { DigOutOff(pShader->dirSwitch); nextState = eStateCloseInit; } else if (pShader->setPosition > pShader->actualPosition) { DigOutOn(pShader->dirSwitch); nextState = eStateOpenInit; } GET_TIME_10MS16(pShader->actionTimestamp); break; default: break; } // eCmdStop and eCmdNone are ignored nextCmd = eCmdNone; break; case eStateExit: if (actionPeriod >= SHADER_DELAY_RELAY) { DigOutOff(pShader->dirSwitch); nextState = eStateStopped; GET_TIME_10MS16(pShader->actionTimestamp); } break; case eStateOpenInit: if (actionPeriod >= SHADER_DELAY_RELAY) { DigOutOn(pShader->onSwitch); nextState = eStateOpening; pShader->startingPosition = pShader->actualPosition; GET_TIME_10MS16(pShader->actionTimestamp); } break; case eStateOpening: if ((actionPeriod * 100 / pShader->openDuration) > (100 - pShader->startingPosition)) { pShader->actualPosition = 100; } else { pShader->actualPosition = pShader->startingPosition + actionPeriod * 100 / pShader->openDuration; } switch (cmd) { case eCmdNone: if (pShader->setPosition == SHADER_OPEN_COMPLETELY) { if (actionPeriod >= ((uint32_t)pShader->openDuration * 110 / 100 /* duration + 10% */)) { DigOutOff(pShader->onSwitch); nextState = eStateExit; GET_TIME_10MS16(pShader->actionTimestamp); } } else if (pShader->actualPosition >= pShader->setPosition) { DigOutOff(pShader->onSwitch); nextState = eStateExit; GET_TIME_10MS16(pShader->actionTimestamp); } break; case eCmdStop: DigOutOff(pShader->onSwitch); nextState = eStateExit; GET_TIME_10MS16(pShader->actionTimestamp); break; case eCmdSetPosition: if (pShader->setPosition < pShader->actualPosition) { DigOutOff(pShader->onSwitch); nextState = eStateDirectionChangeCloseInit; GET_TIME_10MS16(pShader->actionTimestamp); } break; default: break; } nextCmd = eCmdNone; break; case eStateCloseInit: if (actionPeriod >= SHADER_DELAY_RELAY) { DigOutOn(pShader->onSwitch); nextState = eStateClosing; pShader->startingPosition = pShader->actualPosition; GET_TIME_10MS16(pShader->actionTimestamp); } break; case eStateClosing: if ((actionPeriod * 100 / pShader->closeDuration) > (pShader->startingPosition)) { pShader->actualPosition = 0; } else { pShader->actualPosition = pShader->startingPosition - actionPeriod * 100 / pShader->closeDuration; } switch (cmd) { case eCmdNone: if (pShader->setPosition == SHADER_CLOSE_COMPLETELY) { if (actionPeriod >= ((uint32_t)pShader->closeDuration * 110 / 100 /* duration + 10% */)) { DigOutOff(pShader->onSwitch); nextState = eStateExit; GET_TIME_10MS16(pShader->actionTimestamp); } } else if (pShader->actualPosition <= pShader->setPosition) { DigOutOff(pShader->onSwitch); nextState = eStateExit; GET_TIME_10MS16(pShader->actionTimestamp); } break; case eCmdStop: DigOutOff(pShader->onSwitch); nextState = eStateExit; GET_TIME_10MS16(pShader->actionTimestamp); break; case eCmdSetPosition: if (pShader->setPosition > pShader->actualPosition) { DigOutOff(pShader->onSwitch); nextState = eStateDirectionChangeOpenInit; GET_TIME_10MS16(pShader->actionTimestamp); } break; default: break; } nextCmd = eCmdNone; break; case eStateDirectionChangeCloseInit: switch (cmd) { case eCmdNone: if (actionPeriod >= SHADER_DELAY_DIRCHANGE) { DigOutOff(pShader->dirSwitch); nextState = eStateCloseInit; GET_TIME_10MS16(pShader->actionTimestamp); } break; case eCmdStop: DigOutOff(pShader->onSwitch); nextState = eStateExit; GET_TIME_10MS16(pShader->actionTimestamp); break; case eCmdSetPosition: if (pShader->setPosition > pShader->actualPosition) { // no direction change, continue in same direction DigOutOn(pShader->dirSwitch); nextState = eStateOpenInit; GET_TIME_10MS16(pShader->actionTimestamp); } break; default: break; } nextCmd = eCmdNone; break; case eStateDirectionChangeOpenInit: switch (cmd) { case eCmdNone: if (actionPeriod >= SHADER_DELAY_DIRCHANGE) { DigOutOn(pShader->dirSwitch); nextState = eStateOpenInit; GET_TIME_10MS16(pShader->actionTimestamp); } break; case eCmdStop: DigOutOff(pShader->onSwitch); nextState = eStateExit; GET_TIME_10MS16(pShader->actionTimestamp); break; case eCmdSetPosition: if (pShader->setPosition < pShader->actualPosition) { // no direction change, continue in same direction DigOutOff(pShader->dirSwitch); nextState = eStateCloseInit; GET_TIME_10MS16(pShader->actionTimestamp); } break; default: break; } nextCmd = eCmdNone; break; default: break; } pShader->cmd = nextCmd; pShader->state = nextState; }