Skip to content

Commit

Permalink
Handle recovery blanking as separate state, update docs, format code
Browse files Browse the repository at this point in the history
  • Loading branch information
Dragos GALALAE committed Dec 5, 2024
1 parent fc80cd0 commit 3a35dbb
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 54 deletions.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,18 @@ To flash MCU:
7) wait for program to flash, check messages in terminal for errors

Current features:
- response time: 100ms - changes in conditions faster than this won't be detected
- response time: 100ms - changes in conditions faster than this won't be detected, limit to max 500ms
- startup delay: 60s - the relay will not trip is PS_ON is disconnected (or 0) and power has just been applied
- power off delay: 20s - time to allow the board/PC to shutdown cleanly
- recovery delay: 5s - recover with PS_ON after power off, blanking time to avoid fast power off/on cycle
- recovery delay: 30s - blanking time to avoid fast power off/on cycle, after which relay can recover with PS_ON (self-reset)

Leds show state:
- green off and red off - no power to the relay
- green on and red on - MCU is reset or in programming mode
- green on and red blinking - startup delay, power to system, only SC is available
- green on and red off - power to the system
- green blinking and red off - PS_ON triggered, power off delay
- green and red blinking - no power to the system, wait for recovery delay
- green off and red on - no power to the system, relay is in power off state
- green alternate red blinking - SC triggered

Expand Down
129 changes: 77 additions & 52 deletions src/main.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include <stdio.h>
#include <STC15Fxx.h>
#include <delay.h>
#include <reset.h>

#define LED_OFF P30 /* Power off led (red) */
#define LED_ON P31 /* Power on led (green) */
Expand All @@ -11,13 +12,9 @@
#define RESPONSE_DELAY 100 /* how fast the sofware responds to input changes */
#define START_DELAY_S 60 /* time at startup to ignore PS_DLY state */
#define STOP_DELAY_S 20 /* time to wait before power off after trigger by PS_DLY */
#define RECOVER_DELAY_S 5 /* time to wait before power recovery after PS_DLY gets restored */
#define RECOVER_DELAY_S 30 /* time to wait before power recovery after PS_DLY gets restored */
#define BLINKER_MUL 3 /* used for blinking LEDs, multiple of RESPONSE_DELAY */

#if (RECOVER_DELAY_S > (STOP_DELAY_S-1))
#error "RECOVER_DELAY_S must be at least 1 second smaller than STOP_DELAY_S"
#endif

#if (RESPONSE_DELAY > 500)
#error "RESPONSE_DELAY must be lower than 500ms"
#endif
Expand All @@ -30,18 +27,38 @@
#define PWDN_DLY_TICKS (STOP_DELAY_S*1000UL/RESPONSE_DELAY*1UL)
#define PWRE_DLY_TICKS (STOP_DELAY_S*1000UL/RESPONSE_DELAY*1UL)

/* stated of the device */
typedef enum
{
/* states of the device */
typedef enum {
powerup, /* first startup/reset will ignore PS_DLY state */
running, /* normal running state */
psdelay, /* PS_DLY was triggered, but we wait for power off delay */
blanking, /* PS_DLY was triggered, power was cut, we wait recovery delay*/
tripped, /* PS_DLY trigger occurred */
tripped_sc, /* SCP trigger occurred */
}states_t;

void main(void)
{
/* vars */
states_t state = powerup;
uint32_t updelay = 0;
uint8_t blink = 0;

/* things to always do when switching to new state */
void goto_state(states_t new) {
/* reset leds */
LED_ON = 0;
LED_OFF = 0;
/* if short, start with red led on */
if (new == tripped_sc)
LED_OFF = 1;
/* reset timers */
updelay = 0;
blink = 0;
/* set new state */
state = new;
}

/* setup and init i/o */
void init_io(void) {
/* setup i/o */
P3M1 = 0xB4;
P3M0 = 0xB4;
Expand All @@ -50,10 +67,11 @@ void main(void)
RELAY = 0;
LED_OFF = 0;
LED_ON = 0;
/* vars */
states_t state = powerup;
uint32_t updelay = 0;
uint8_t blink = 0;
}

void main(void) {
/* setup i/o */
init_io();
/* program loop */
while(1) {
/* wait response time */
Expand All @@ -62,103 +80,110 @@ void main(void)
if (SCP)
state = tripped_sc;
/* check states */
switch (state)
{
switch (state) {
case powerup:
/* powering state */
RELAY = 0;
/* led state */
LED_ON = 1;
/* increase delay timers */
updelay += 1;
blink += 1;
/* blink led */
if (blink > BLINKER_MUL) {
/* leds */
LED_OFF = (!LED_OFF);
LED_ON = 1;
blink = 0;
}
/* check power up delay */
if (updelay > PWUP_DLY_TICKS) {
updelay = 0;
/* check PS_DLY */
if (PS_DLY)
state = running;
else
state = tripped;
goto_state(running);
/* PS_ON must have signal to continue ! */
goto_state(blanking);
}
break;
case running:
/* powering state */
RELAY = 0;
/* leds */
/* led state */
LED_OFF = 0;
LED_ON = 1;
/* reset timers */
updelay = 0;
blink = 0;
/* check PS_DLY */
if (PS_DLY)
state = psdelay;
goto_state(psdelay);
break;
case psdelay:
/* powering state */
RELAY = 0;
/* led state */
LED_OFF = 0;
/* increase delay timers */
updelay += 1;
blink += 1;
/* blink led */
if (blink > BLINKER_MUL) {
/* leds */
LED_OFF = 0;
LED_ON = (!LED_ON);
blink = 0;
}
/* check power down delay */
if (updelay > PWDN_DLY_TICKS) {
/* reset timers */
if (updelay > PWDN_DLY_TICKS)
goto_state(blanking);
break;
case blanking:
/* tripped state */
RELAY = 1;
/* increase delay timers */
updelay += 1;
blink += 1;
/* blink both leds */
if (blink > BLINKER_MUL) {
/* leds */
LED_OFF = (!LED_OFF);
LED_ON = (!LED_ON);
blink = 0;
updelay = 0;
state = tripped;
}
/* check power down delay */
if (updelay > PWRE_DLY_TICKS)
goto_state(tripped);
break;
case tripped:
/* tripped state */
RELAY = 1;
/* leds */
LED_OFF = 1;
LED_ON = 0;
/* increase delay timers */
updelay += 1;
/* power recovery */
if (updelay > PWRE_DLY_TICKS) {
/* check PS_DLY pin */
if (!PS_DLY) {
/* reset timers */
blink = 0;
updelay = 0;
state = running;
}
updelay = PWRE_DLY_TICKS;
}
/* power recovery (self-reset) */
if (!PS_DLY)
//goto_state(powerup);
reset();
break;
default:
/* tripped state */
RELAY = 1;
/* increase delay timers */
blink += 1;
/* blinking leds alternatively, one it BLINKER_MUL on, then the other is BLINKER_MUL on */
if (blink > (2*BLINKER_MUL))
blink=0;
/* blinking leds alternating them */
if (blink > BLINKER_MUL) {
/* leds */
LED_OFF = 1;
LED_ON = 0;
} else {
/* leds */
LED_OFF = 0;
LED_ON = 1;
if(LED_ON) {
LED_OFF = 1;
LED_ON = 0;
} else {
LED_OFF = 0;
LED_ON = 1;
}
/* reset blink timer */
blink = 0;
}
/* reset timers */
/* reset other timers */
updelay = 0;
break;
}
}
}
}

0 comments on commit 3a35dbb

Please sign in to comment.