/*
* The Sphinx -- A Device for Asking Riddles at the Entrance to the Garage
*
- * (c) 2017 Martin Mares <mj@ucw.cz>
+ * (c) 2017--2019 Martin Mares <mj@ucw.cz>
*/
/*
*
* +-------------------+
* | RESET* VCC |
- * button* | PB3 PB2=SCK |
- * output | PB4 PB1=MISO |
+ * button* | PB3 PB2=SCK | signal "closed" from drive*
+ * output to drive | PB4 PB1=MISO | corridor LED
* | GND PB0=MOSI | diagnostic LED*
* +-------------------+
*
- * Note that MOSI is used for programming, so the LED is connected
- * via jumper, which must be open during programming.
+ * Note that MISO, MOSI, and SCK are used for programming, so our signals
+ * are connected via jumpers, which must be kept open during programming.
+ *
+ * Connections to door control unit:
+ *
+ * 3 = +24V
+ * 1 = GND
+ * 2 = output
+ *
+ * Connections to EP 161 module:
+ *
+ * H1 = signal +
+ * 92 = signal -
*/
#define F_CPU 1200000UL
static byte pressed;
static u16 press_timer;
#define LONG_PRESS 150
-static byte second_timer;
-static byte unlocked;
-#define UNLOCK_SECONDS 60
+static u16 unlock_timer;
+#define UNLOCK_SECONDS 30
+static byte blink_timer;
ISR(TIM0_COMPA_vect)
{
+ // Generate output pulse
if (out_pulse) {
if (!--out_pulse)
PORTB &= ~B(PB4);
}
- if (!second_timer) {
- second_timer = 100;
- if (unlocked)
- unlocked--;
- }
- second_timer--;
-
+ // Debounce the button
if (PINB & B(PB3)) {
// Switch open
if (debounce)
pressed = 1;
}
- if (unlocked) {
- if (!(second_timer & 7))
- PORTB ^= B(PB0);
+ // PB2 is 0 if the door is fully closed,
+ // we need to set door_open if it is at least partially open.
+ byte door_open;
+ if (PINB & B(PB2)) {
+ door_open = 1;
+ PORTB |= B(PB1);
+ unlock_timer = UNLOCK_SECONDS * 60;
+ } else {
+ door_open = 0;
+ PORTB &= ~B(PB1);
+ }
+
+ // Locking
+ if (unlock_timer) {
if (pressed) {
+ PORTB &= ~B(PB0);
if (out_pulse < 2)
out_pulse = 2;
PORTB |= B(PB4);
- unlocked = UNLOCK_SECONDS;
+ unlock_timer = UNLOCK_SECONDS * 100;
+ } else if (door_open) {
+ if (!(blink_timer & 63))
+ PORTB ^= B(PB0);
+ } else {
+ if (!(blink_timer & 15))
+ PORTB ^= B(PB0);
+ unlock_timer--;
}
} else {
if (!pressed) {
PORTB &= ~B(PB0);
if (press_timer < LONG_PRESS) {
press_timer++;
- if (press_timer == LONG_PRESS) {
- out_pulse = OUT_PULSE_WIDTH;
- PORTB |= B(PB4);
- unlocked = UNLOCK_SECONDS;
- }
+ if (press_timer == LONG_PRESS)
+ unlock_timer = UNLOCK_SECONDS * 100;
}
}
}
+
+ blink_timer++;
}
int main(void)
// PB0: output for diagnostic LED
DDRB |= B(PB0);
+ // PB1: output for corridor LED
+ PORTB &= ~B(PB1);
+ DDRB |= B(PB1);
+
+ // PB2: signal "door closed" from the drive, needs pull up
+ PORTB |= B(PB2);
+
// PB3: button input, needs pull up
PORTB |= B(PB3);
// Copy mode
for (;;) {
sleep(10);
- if (PINB & B(PB3)) {
+ if (PINB & B(PB2)) {
PORTB |= B(PB0);
+ PORTB &= ~B(PB1);
PORTB &= ~B(PB4);
} else {
PORTB &= ~B(PB0);
+ PORTB |= B(PB1);
PORTB |= B(PB4);
}
}