/* * Movement detector and logger v1.0 * Written by Daniel Smith, 2011.11.20 * www.pagemac.com * * This program will detect motion and log the timestamp in the EEPROM * When the program is first run, it will blink an LED, waiting for a timestamp to be sent * At this time, the serial interface is active. You can press p to print the log, c to clear, * and t to print the time. These commands need to be followed by pressing enter. * The program will wait until it receives the 10 byte + \r\n unix time in ASCII. * The system will then wait for a switch and arm and monitor the ADXL335 accelerometer. * When any axis is outside the tolerance, it will log the time to EEPROM. * * Connections: * ADXL335 on Analog 0, 1, 2 * LED's on 11 and 13 * Switch on 8 */ #include #include // RX serial buffer size #define IN_BUFFER_SIZE 11 // threshold for motion on any axis #define TOLERANCE 20 int addr = 0; int x, y, z; int BASELINE_X, BASELINE_Y, BASELINE_Z; unsigned long cur_time; // unix time for setting the real world time boolean bTimeSet = false; int ledState=1; int incomingByte = 0; // for incoming serial data char inBytes[IN_BUFFER_SIZE]; int bufPos=0; int EEPROM_Next_Addr=0; void setup() { pinMode(11, OUTPUT); // red pinMode(13, OUTPUT); // blue pinMode(10, OUTPUT); // blue gnd digitalWrite(14, 0); pinMode(8, INPUT); // switch input Serial.begin(9600); //clearEEPROM(); findLogEnd(); printLog(); Serial.println("Waiting for time stamp..."); } void loop() { // SERIAL CONTROL while (Serial.available() > 0) { inBytes[bufPos] = Serial.read(); bufPos++; if (inBytes[bufPos-1] == '\n' || inBytes[bufPos-1] == '\r') { if (bufPos == IN_BUFFER_SIZE) { // ARMING SYSTEM! cur_time = atol(inBytes); Serial.print("Time set: "); Serial.println(cur_time); digitalClockDisplay(cur_time); setTime(cur_time); bTimeSet = true; digitalWrite(13, 0); // turn off red led Serial.println("Waiting for switch..."); ledState = 1; while (!digitalRead(8)) { digitalWrite(11, ledState); // toggle blue led ledState = !ledState; delay(1000); } digitalWrite(11, 1); // turn on blue led delay(3000); // wait 3 seconds digitalWrite(11, 0); // turn off blue led // set the baseline for the accelerometer BASELINE_X = analogRead(0); // read analog input pin 0 BASELINE_Y = analogRead(1); // read analog input pin 1 BASELINE_Z = analogRead(2); // read analog input pin 1 Serial.println("System now armed!"); } else if (bufPos == 2 || bufPos == 3) { switch (inBytes[0]) { case 'c': clearEEPROM(); break; case 't': digitalClockDisplay(now()); break; case 'p': printLog(); break; } } else { Serial.print("Error: Expected 10 characters (got "); Serial.print(bufPos); Serial.println(")."); } bufPos = 0; } if (bufPos >= IN_BUFFER_SIZE) { Serial.println("Error: too many characters (max 10)."); bufPos = 0; } } // END SERIAL CONTROL if (!bTimeSet) { digitalWrite(13, ledState); ledState = !ledState; //printAccelo(); delay(1000); } else { //digitalClockDisplay(now()); x = analogRead(0); // read analog input pin 0 y = analogRead(1); // read analog input pin 1 z = analogRead(2); // read analog input pin 1 if (x > BASELINE_X + TOLERANCE || x < BASELINE_X - TOLERANCE || y > BASELINE_Y + TOLERANCE || y < BASELINE_Y - TOLERANCE || z > BASELINE_Z + TOLERANCE || z < BASELINE_Z - TOLERANCE ) { digitalWrite(13, 1); // turn on LED writeTime(); Serial.print("Movement detected: "); digitalClockDisplay(now()); delay(2000); // pause 2 seconds digitalWrite(13, 0); // turn off LED BASELINE_X = analogRead(0); // read analog input pin 0 BASELINE_Y = analogRead(1); // read analog input pin 1 BASELINE_Z = analogRead(2); // read analog input pin 1 } delay(100); } // wait a second so as not to send massive amounts of data //delay(1000); } void digitalClockDisplay(time_t t) { // digital clock display of the time Serial.print(hour(t)); printDigits(minute(t)); printDigits(second(t)); Serial.print(" "); Serial.print(month(t)); Serial.print("/"); Serial.print(day(t)); Serial.print("/"); Serial.print(year(t)); Serial.println(); } void printDigits(int digits){ // utility function for digital clock display: prints preceding colon and leading 0 Serial.print(":"); if(digits < 10) Serial.print('0'); Serial.print(digits); } void writeTime() { // write the 4 byte unix time to the EEPROM int addr = EEPROM_Next_Addr; cur_time = now(); EEPROM.write(addr , (cur_time & 0xFF000000) >> 24); EEPROM.write(addr+1, (cur_time & 0x00FF0000) >> 16); EEPROM.write(addr+2, (cur_time & 0x0000FF00) >> 8); EEPROM.write(addr+3, (cur_time & 0x000000FF)); EEPROM_Next_Addr += 4; } // find the end of the log by looking for 0xFF (unprogrammed) bytes. void findLogEnd() { int addr=0; while (EEPROM.read(addr) != 0xFF) { addr += 4; if (addr >= 512) { Serial.println("EEPROM Full!!"); break; } } EEPROM_Next_Addr = addr; Serial.print("Found end of log: "); Serial.println(addr); } // print the log from EEPROM void printLog() { int addr=0, logCount=0; byte byte1, byte2, byte3, byte4; Serial.println("Reading log entries:"); while (EEPROM.read(addr) != 0xFF) { byte1 = EEPROM.read(addr); byte2 = EEPROM.read(addr+1); byte3 = EEPROM.read(addr+2); byte4 = EEPROM.read(addr+3); cur_time = ((unsigned long)byte1 << 24) + ((unsigned long)byte2 << 16) + ((unsigned long)byte3 << 8) + (unsigned long)byte4; logCount++; Serial.print("Log entry "); Serial.print(logCount); Serial.print(": "); digitalClockDisplay(cur_time); //Serial.println(cur_time); addr += 4; if (addr >= 512) { break; } } Serial.println("Reached end of log!"); } void clearEEPROM() { digitalWrite(11, 1); // turn on blue led digitalWrite(13, 1); // turn on red led Serial.print("Erasing EEPROM... "); for (int i = 0; i < 512; i++) EEPROM.write(i, 0xFF); Serial.println("done!"); digitalWrite(11, 0); // turn off blue led digitalWrite(13, 0); // turn off red led } void printAccelo() { x = analogRead(0); // read analog input pin 0 y = analogRead(1); // read analog input pin 1 z = analogRead(2); // read analog input pin 1 Serial.print("accelerations are x, y, z: "); Serial.print(x, DEC); // print the acceleration in the X axis Serial.print(" "); // prints a space between the numbers Serial.print(y, DEC); // print the acceleration in the Y axis Serial.print(" "); // prints a space between the numbers Serial.println(z, DEC); // print the acceleration in the Z axis }