diff --git a/Control/log.c b/Control/log.c
new file mode 100644
index 0000000000000000000000000000000000000000..e44668e13d0edfd13123d8fed590559689980a60
--- /dev/null
+++ b/Control/log.c
@@ -0,0 +1,95 @@
+#include <avr/eeprom.h>
+#include <avr/pgmspace.h>
+
+#include "log.h"
+#include "door.h"
+#include "power_monitor.h"
+
+char log_event_startup[]              PROGMEM = "== System Started ==";
+char log_event_alarm_raised[]         PROGMEM = "Alarm Raised";
+char log_event_alarm_changed[]        PROGMEM = "State change during Alarm";
+char log_event_alarm_login[]          PROGMEM = "Login during Alarm";
+char log_event_alarm_disabled[]       PROGMEM = "Alarm disabled";
+char log_event_ac_fail[]              PROGMEM = "AC Power Fail";
+char log_event_ac_return[]            PROGMEM = "AC Power Restored";
+char log_event_main_battery_low[]     PROGMEM = "Main Battery Low";
+char log_event_keymatic_battery_low[] PROGMEM = "Keymatic Battery Low";
+char log_event_door_command_timeout[] PROGMEM = "Door command Timeout";
+
+char* event_names[] PROGMEM = {log_event_startup,
+                               log_event_alarm_raised,
+                               log_event_alarm_changed,
+                               log_event_alarm_login,
+                               log_event_alarm_disabled,
+                               log_event_ac_fail,
+                               log_event_ac_return,
+                               log_event_main_battery_low,
+                               log_event_keymatic_battery_low,
+                               log_event_door_command_timeout};
+
+uint8_t log_get_first_entry_index(void){
+	uint8_t l = eeprom_read_byte(LOG_START_POINTER_LOCATION);
+	return l;
+}
+uint8_t log_get_last_entry_index(void){
+	uint8_t l = eeprom_read_byte(LOG_END_POINTER_LOCATION);
+	return l;
+}
+void log_set_entry_indices(uint8_t first, uint8_t last){
+	eeprom_update_byte(LOG_START_POINTER_LOCATION, first);
+	eeprom_write_byte(LOG_END_POINTER_LOCATION, last);
+}
+
+void log_read_entry(uint8_t index, log_entry_t* entry){
+	eeprom_read_block((void*)entry, (const void*)(LOG_DATA_OFFSET + index*sizeof(log_entry_t)), sizeof(log_entry_t));
+}
+
+void log_write_entry(uint8_t index, log_entry_t* entry){
+	eeprom_write_block((const void*)entry, (void*)(LOG_DATA_OFFSET + index*sizeof(log_entry_t)), sizeof(log_entry_t));
+}
+
+void log_append(uint8_t event, uint16_t param){
+	log_entry_t entry;
+	
+	ds1307_get_date(&entry.date);
+	entry.event        = event;
+	entry.param        = param;
+	entry.door_status  = door_get_status();
+	entry.power_status = power_get_status();
+	
+	uint8_t last  = log_get_last_entry_index();
+	uint8_t first = log_get_first_entry_index();
+	if (last >= (LOG_MAX_COUNT-1)) {last = 0;} else {last++;}
+	if (last == first) first++;
+	if (first >= (LOG_MAX_COUNT-1)) first = 0;
+	log_write_entry(last, &entry);
+	log_set_entry_indices(first,last);
+	
+	printf_P(PSTR("-- Event Logged %i %i --\n"), first,last);
+}
+
+void log_dump(void){
+	uint8_t current = log_get_first_entry_index();
+	uint8_t last = log_get_last_entry_index();
+	log_entry_t entry;
+	while(1){
+		log_read_entry(current, &entry);
+		if (entry.event == LOG_EVENT_NONE) break;
+		
+		ds1307_write_date(&(entry.date));
+		printf_P(PSTR(": "));
+		
+		PGM_P name_p = pgm_read_word(&(event_names[entry.event])); //Flash pointer to name string
+ 		if (name_p){
+			printf_P((PGM_P)name_p);
+ 		} else {
+ 			printf_P(PSTR("Event ?%i"), entry.event);
+ 		}
+		printf_P(PSTR(" (%i), State: %02x, Power: %02x\n"), entry.param,
+		                                                      entry.door_status,
+		                                                      entry.power_status);
+		if (current == last) break;
+		current++;
+		if (current >= LOG_MAX_COUNT) current = 0;
+	}
+}
diff --git a/Control/log.h b/Control/log.h
new file mode 100644
index 0000000000000000000000000000000000000000..111d446ee20b1c978ef4fdb04d17f6019ee3b9a9
--- /dev/null
+++ b/Control/log.h
@@ -0,0 +1,38 @@
+#pragma once
+
+#include "ds1307.h"
+#include "shell/shell.h"
+
+#define EEPROM_SIZE 2048
+
+struct log_entry_t{
+	uint8_t event;         // 1
+	
+	date_t date;           // 7
+	uint8_t door_status;   // 1
+	uint8_t power_status;  // 1
+	
+	uint16_t param;        // 2
+} typedef log_entry_t;     //12byte
+
+#define LOG_DATA_OFFSET 1024
+#define LOG_MAX_COUNT ((EEPROM_SIZE-2-LOG_DATA_OFFSET)/sizeof(log_entry_t)) 
+#define LOG_START_POINTER_LOCATION ((void*)(EEPROM_SIZE-1))
+#define LOG_END_POINTER_LOCATION   ((void*)(EEPROM_SIZE-2))
+
+#define LOG_EVENT_STARTUP              0x00
+#define LOG_EVENT_ALARM_RAISED         0x01
+#define LOG_EVENT_ALARM_CHANGED        0x02
+#define LOG_EVENT_ALARM_LOGIN          0x03
+#define LOG_EVENT_ALARM_DISABLED       0x04
+#define LOG_EVENT_AC_FAIL              0x05
+#define LOG_EVENT_AC_RETURN            0x06
+#define LOG_EVENT_MAIN_BATTERY_LOW     0x07
+#define LOG_EVENT_KEYMATIC_BATTERY_LOW 0x08
+#define LOG_EVENT_DOOR_COMMAND_TIMEOUT 0x09
+
+#define LOG_EVENT_NONE                 0xFF
+
+
+void log_dump(void);
+void log_append(uint8_t event, uint16_t param);
\ No newline at end of file