summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSadeep Madurange <sadeep@asciimx.com>2025-05-01 14:18:31 +0800
committerSadeep Madurange <sadeep@asciimx.com>2025-05-01 14:18:31 +0800
commita1de6ebc054c84e1f27b21998cb017ae38151a2e (patch)
treee59592281e8f81fe4e5e6aa4586fe1e796b14176
parent57e9d1a5c00dc7dc5cf3149c35a8004b5f7aab7f (diff)
downloadsmart-home-a1de6ebc054c84e1f27b21998cb017ae38151a2e.tar.gz
Check vcc and add LEDs for lock/unlock.
-rw-r--r--lock/bend.c43
-rw-r--r--lock/util.c23
-rw-r--r--lock/util.h2
3 files changed, 64 insertions, 4 deletions
diff --git a/lock/bend.c b/lock/bend.c
index 2eff858..2c18996 100644
--- a/lock/bend.c
+++ b/lock/bend.c
@@ -29,6 +29,14 @@
#define RX_PCMSK PCMSK2
#define RX_PCINTVEC PCINT2_vect
+#define VCC_MIN 4810 /* servo min voltage. */
+
+#define LOCK_LED PC3
+#define UNLOCK_LED PC4
+#define BATLOW_LED PC5
+#define LED_DDR DDRC
+#define LED_PORT PORTC
+
static char tab[] = {
'0', '8', '3', '6', 'a', 'Z', '$', '4', 'v', 'R', '@',
'E', '1', 'o', '#', ')', '2', '5', 'q', ';', '.', 'I',
@@ -91,6 +99,16 @@ static inline void init_btns(void)
EIMSK = (1 << INT0) | (1 << INT1);
}
+static inline void init_leds(void)
+{
+ LED_DDR |= (1 << LOCK_LED) | (1 << UNLOCK_LED);
+ LED_DDR |= (1 << BATLOW_LED);
+
+ LED_PORT &= ~(1 << LOCK_LED);
+ LED_PORT &= ~(1 << UNLOCK_LED);
+ LED_PORT &= ~(1 << BATLOW_LED);
+}
+
static inline void init_servo(void)
{
ICR1 = PWM_TOP;
@@ -105,7 +123,6 @@ static inline void lock(void)
OCR1A = PWM_MID;
_delay_ms(100);
OCR1A = PWM_TOP;
- uart_write_line("locked");
}
static inline void unlock(void)
@@ -113,7 +130,6 @@ static inline void unlock(void)
OCR1A = PWM_MAX - 50;
_delay_ms(100);
OCR1A = PWM_TOP;
- uart_write_line("unlocked");
}
int main(void)
@@ -125,6 +141,7 @@ int main(void)
init_wdt();
init_rx();
+ init_leds();
init_btns();
init_servo();
@@ -176,16 +193,34 @@ ISR(RX_PCINTVEC)
ISR(INT0_vect)
{
- if (is_btn_pressed(PIND, LOCK_PIN))
+ if (is_btn_pressed(PIND, LOCK_PIN)) {
lock();
+ LED_PORT |= (1 << LOCK_LED);
+ _delay_ms(70);
+ LED_PORT &= ~(1 << LOCK_LED);
+ _delay_ms(70);
+ LED_PORT |= (1 << LOCK_LED);
+ _delay_ms(70);
+ LED_PORT &= ~(1 << LOCK_LED);
+ }
}
ISR(INT1_vect)
{
- if (is_btn_pressed(PIND, UNLOCK_PIN))
+ if (is_btn_pressed(PIND, UNLOCK_PIN)) {
unlock();
+ LED_PORT |= (1 << UNLOCK_LED);
+ _delay_ms(70);
+ LED_PORT &= ~(1 << UNLOCK_LED);
+ _delay_ms(70);
+ LED_PORT |= (1 << UNLOCK_LED);
+ _delay_ms(70);
+ LED_PORT &= ~(1 << UNLOCK_LED);
+ }
}
ISR(WDT_vect)
{
+ if (getvcc() < VCC_MIN)
+ LED_PORT ^= (1 << BATLOW_LED);
}
diff --git a/lock/util.c b/lock/util.c
index 4f63625..ebcf9fe 100644
--- a/lock/util.c
+++ b/lock/util.c
@@ -21,3 +21,26 @@ void xor(const char *k, const char *s, char *d, uint8_t n)
d[i] = s[i] ^ k[i];
}
+/* Measure vcc by measuring known internal 1.1v bandgap
+ * reference voltage against AVCC.
+ * Place a 100nF bypass capacitor on AREF.
+ */
+uint16_t getvcc(void)
+{
+ uint16_t vcc;
+
+ ADMUX |= (1 << REFS0);
+ ADMUX |= (1 << MUX3) | (1 << MUX2) | (1 << MUX1);
+ ADCSRA |= (1 << ADEN) | (1 << ADPS2) | (1 << ADPS0);
+
+ // https://www.sciencetronics.com/greenphotons/?p=1521
+ _delay_us(500);
+
+ ADCSRA |= (1 << ADSC);
+ while (ADCSRA & (1 << ADSC))
+ ;
+ vcc = (1100UL * 1023 / ADC);
+
+ ADCSRA &= ~(1 << ADEN);
+ return vcc;
+}
diff --git a/lock/util.h b/lock/util.h
index 51a990c..730beae 100644
--- a/lock/util.h
+++ b/lock/util.h
@@ -14,4 +14,6 @@ int is_btn_pressed(uint8_t pin, uint8_t btn);
void xor(const char *k, const char *s, char *d, uint8_t n);
+uint16_t getvcc(void);
+
#endif /* MY_UTIL_H */