CURRENT ISSUE
Contests
Feature Article
|
|
Issue #203 June 2007
Video-Based Motion Sensor
Third Prize Atmel AVR Design Contest 2006
by Naubert Aparicio
Start | System Overview | System Design | Hardware Design | Software Design | Sources & PDF
SOFTWARE DESIGN
The motion sensor’s software was designed in functional sections to minimize its complexity. When the software starts, motion sensing begins immediately. The algorithm first enables the interrupt service routines (ISRs), where the video sampling and averaging process is performed. Once the required frames are captured, the motion-detection algorithm processes them. This cycle repeats until it is interrupted by the user. When the motion algorithm is stopped, the user interface code is enabled.
The most important part of the code is the video sampling and averaging process, which produces the 12 × 15 frame matrices (see Figure 5). The process runs in real time through interrupts generated by the video-synchronization signals that come from U2. The ISRs change the state of the finite state machine (FSM) that is used to determine which step of the video-capture process the system is in. The possible states are waiting for frame (ST_WAIT_FRAME), waiting for video line data start, (ST_SEEK_DATA) and integration start/capture (ST_INTEGRATE). Three ISRs are defined in the interrupt vector table: frame_start ISR for the INT0 signal, line_start ISR for the INT1 signal, and capture_task for the timer 0 compare A ISR.
![]() |
| Figure 5—This flowchart shows the logic of the sampling process. Only the even fields are processed to leave time to run the motion algorithm during the odd frames. |
When the system starts, the FSM is initialized to the waiting-for-frame state. In this state, only the INT0 interrupt is enabled. When a new frame arrives, the LM1881 senses the odd/even field change and asserts the INT0 signal, which starts the frame_start interrupt handler. This ISR checks if the frame has to be averaged. If it has to (i.e., it is even), the accumulators are initialized. These will store the 16 horizontal segments luminance sums. The line and step counters are also initialized and the FSM is set to count lines (change state to ST_SEEK_DATA). The INT1 is enabled so that the next horizontal-synchronization signal will call the line_start ISR. The X pointer is set to the current frame storage (FRAME0 or FRAME1) where the captured data is going to be stored.
Next comes the INT1 interrupt service handler. Every time a horizontal synchronization signal is detected, the line_start ISR is called. The routine is responsible for skipping the first nonvisible video lines (until line 15) and starting the capture process by changing the FSM state to ST_INTEGRATE. The ISR also counts the lines until the end of the visible frame, where the end of the frame capture is signaled. When the state is ST_INTEGRATE, the line counter is reset to count from 0 to 239, or 240 valid video lines. This offset to zero is useful to simplify the vertical grouping. By dividing the LINE counter by 16, the result will give the vertical group number from 0 to 14 directly. When counting lines in the valid range, the line_start ISR also enables the TMR0 interrupt, which is set to interrupt at T_START cycles from the beginning of the line_start interrupt. This happens to be exactly the start of the video line data (see Photo 3). After line 240, a couple of additional lines are sampled to fill the missing values in the circular buffer, due to the ADC pipeline. After line 241 is processed, the routine stops the sampling process and disables the INT1 interrupt. The resulting captured and compressed frame is stored in the FRAME0 or FRAME1 buffer, which is indicated by the F_FRAME1 flag.
![]() |
| Photo 3—This is an oscilloscope capture of an NTSC video line. Line luminance data starts 4.7 µs after the end of the horizontal synchronization signal. |
The TMR0 interrupt runs the capture_task, the most important segment of code. This ISR is responsible for sampling the video signal, its vertical averaging, and the video-output highlighting. This task runs 13 times for each line. This ISR is first called at the beginning of the video line. At this point, it starts the integrator and then sets the TMR0 to interrupt about every 4 µs to sample the resulting integrated values from the ADC. In the second to thirteenth interrupts, the previous started integration is sampled by toggling the capture output. It is then averaged into the accumulators (pointed by Y). In the last line of the 16-line group, the accumulator is moved into the frame buffer pointed by the X register. Using this schema, a circular buffer as the accumulator array, and ignoring the first four ADC samples, the four-level pipeline of the ADC is effectively handled and the samples are synchronized with the frame buffers. This part of the code is very time-sensitive, and its length is limited by the horizontal-average resolution of the sensor to 12 segments. A large number of optimizations were performed here, like using dedicated registers as variables and moving some calculations to the line_start ISR.
The motion-detection algorithm roughly follows the logic in Figure 6. The algorithm is performed in the motion_detect subroutine. This subroutine captures a base frame first and then compares it to the following frames. The comparison is just a matrix subtraction. If the absolute value of any element in the resulting matrix exceeds your defined threshold, the corresponding block is flagged to indicate motion at its position in the frame. Only the nonignored blocks are flagged. Once the number of flagged blocks repeatedly exceeds a minimum value for a number of consecutive frames, an alarm is generated and the output signal is asserted. You can define both of those parameters through the serial command interface (SCI). Other parameters can be modified to make the system ignore frames when the number of flagged blocks exceeds a certain threshold. This is useful to avoid false alarms when the illumination changes abruptly. The user can also set a number of frames to be ignored after these events so that automatic exposure cameras have time to stabilize.
![]() |
| Figure 6—This flowchart shows the logic of the motion-detection algorithm. A base frame is captured and then compared with the following frame as a matrix subtraction. Motion is detected if any element in the resulting matrix exceeds a threshold. |
The serial port is configured for data with 19,200 bps, 8 data bits, no parity bits, and 1 stop bit. When you send a character through the port, the motion-sensor function is interrupted and the sensor enters Command mode. This part of the source code interprets and executes the available commands sent to the interface. Backspace support was implemented for user interaction, although the interface can also be used by a controlling computer. Output messages begin with codes that facilitate its interpretation for this effect. A special Movement Detection-mode command (M1) that will detect motion until a movement is detected was implemented. After it stops, frame dump commands can be used to let higher-level systems further analyze the data. The code for this part is very simple. After a line is read, a command comparison is performed and the corresponding segment of code is run. During the execution of the user interface, the motion-detection algorithm is stopped. It will resume after an M or an M1 command.
The project was difficult. Fitting everything in such a relatively low-processing microcontroller was challenging. A good software design was key, but the fast ATmega88, with its versatile instruction set, made this project a reality. I am very proud of the end result. It is robust, it has a lot of functionality, and it has a lot of room for improvement. Of the ATmega88’s 8 KB of the flash memory capacity, only about 40% was used. Just 56% of the RAM was used.
After developing the video motion sensor, I am now more open to considering mixed-signal designs for future applications. By creatively using analog components in the design, I significantly reduced the system’s complexity and built an interesting application that couldn’t have been built digitally at such a low cost. So, thinking outside the “digital box” may reward your design and your wallet.
|


