The program design is divided into two parts:
For the transmitter part, the touching of doorknob is sensed by the following, as mentioned before. We check the digital signal for a few times long enough to make sure that the digital voltage level remains the same for a certain period so as to distinguish this touching signal (60Hz - low frequency) from the 433MHz high frequency RF signal. An interrupt is set up for every 0.2ms, and we use this timer interrupt to count the time and thus to detect the touching of a doorknob. For the opening of a door, we compare the voltage value from the accelerometer when the door is opened to the initial output voltage that we obtain from the accelerometer when we first initialize the MCU. The initial value is obtained when the program runs the initialize function during start-up. We set a value of 0.02V for the voltage offset to better detect the door movements and to counter all the small voltage fluctuations that would occur. Special variables for doorknob touching and door opening are set to indicate if any of them has been sensed. Conversions from analog voltage to digital values are done using the ADC channels of the MCU.
The transmitting scheme is as follow: when there is a data to be sent, we always start by sending six nibbles of alternating 1s and 0s, something like 10101010...... and then we have a data header with 0110 that signifies that the four bits after this data header are real data and should be interpreted at the receiver. The four bits can be 1010, 1001, 0110, 0101. The first two bits are for doorknob touching and the last two bits are for door opening. If the doorknob is touched, it would be 10; otherwise it would be 01. The same is true for door opening, if door is opened, it is 10, otherwise it is 01. Data transmission is done in the interrupt function when the bits in the transmit buffer are fed one at a time into pin C.0, which is connected to the data pin in the RF transmitter.
For the receiver part of the code, we use the same scheme described above to decode the received messages. For the PIR sensing, we also use a similar way as the accelerometer, but this time with an offset of 0.015V.
For the keypad at the receiver MCU, the code for detecting a press has the same format as the ones previously done in labs, namely with states Release, Debounce, DetectTerminator, StillPressed and DebounceRelease. The state transitions are the same. When a terminator is detected, the button that is pressed is converted to ASCII and stored in an array. This is also being displayed to the computer terminal at the same time, so we can also tell which key from the keypad is pressed on the screen. The keypad is used to stop the alarm that is triggered by any of the sensors. This can be done by pressing the correct 4 digits code in the keypad.
For the hyperterminal, it is able to perform several tasks. When the system is first initialized in start-up, it shows the following menu:
"Set Code - set oooo nnnn\n\r", "Set time and date - tim [month] [day] [hour] [minut]\n\r" "Activate - act y/n[stream] y/n[save]\n\r" "Log - log y/n[touch] y/n[open] y/n[motion]\n\r" "Retrieve log - ret\n\r" "Disable serial - dis\n\r" "Erase (clear screen) - era\n\r"
Basically the MCU will handle the 8 operations above as well as the one from the keypad. For the hyperterm, the first three alphabetical letters that are pressed will indicate which function to perform. The hyperterminal is able to change the 4 digits security code that is used to stop the alarm at the PC if the alarm is triggered by the any of our sensors. This is done by hitting 'set' and then entering 4 digits of old code followed by another 4 digits of the new security code. Time and date can also be set as shown above, and it keeps on running automatically once it is set. It can also activate the two operating modes: whether or not to activate streaming onto the screen and also whether or not to save the sensors triggerings into a log. The 'log' command at the hyperterm is used to enable the appropriate sensor to be logged. This information kept in the log can be retrieved anytime by pressing 'ret'. The record of a log is done using FIFO data structure, where the first element (oldest) in an array will be replaced once the array runs out of space. When data is retrieved using 'ret', the information in the array are all displayed out and then cleared. Serial connection to the computer can be disabled by pressing 'dis'. This will result in the computer having no ability to stop the alarm, and therefore only the keypad can be used to stop the alarm if serial is disabed. Last but not least, the hyperterm has a clear screen function that can clear up all the previous operations performed previously so that the computer screen show up clean when the user wants so.
The most tricky part of the program is the part at the receiver that deals with UART serial connection to the computer and all the functions that we implement. One of the important factors in ensuring that the keypad and serial connection function correctly lies in the appropriate use of a timer interrupt. Because in our case, we integrated the serial receive operation into the timer interrupt, which makes it important for the serial transmit/receive purpose. Another important note about our software design is that we make it such that if power is unplugged and restored, all the previous operating conditions of the system stay the same, for example the security code and the activated mode. This is to prevent someone from resetting the system simply by taking out the power source. It acts as a security measure here.