Wireless tilt sensor & shake-detection program

Amit Pitaru
March 6 2006


1. Create a wireless device that sends data from a simple tilt switch.
2. Use a PC to capture, analyze, and detect shaking mosion..


1. Place a simple tilt switch on a wireless RF board (PIC12F675).
2. Receive the RF data onto a USB PIC (PIC18F2550).
3. Transmit the data to a laptop using USB serial port emulation (PBP code).
4. Analyze the data using Processing, identify and visualize shake-motion.


1. I'm currently using an unknown tilt-sensor brand donated by Doria (Thanks!). It uses a ball to close a switch when tilted over 15deg. Therefore the device is more sensitive in some angles than others. This could be fixed with a multi-directional tilt sensor (see other sensor reports for more details).

2. I'm trying to conserve battery power on the RF transmitter. Therefore the device only transmits data when a tilt has been detected (via interrupt), and otherwise sleeps.


1. RF Transmitter
The circuit and code is based on this 'Simple-RF' project:

The tilt sensor is

Code: Click here for full TX code

Main sensor algorithm within the PIC12F675 code:

  • All variables in the code below are Bytes, except for 'tilt' - which is a pin.
  • Notice how the PIC sends an RF transmission (vie serout2 command) every time that a tilt has been detected on the 'tilt' pin.
  • Each transmission is repeated 20 times ('blast') to ensure that it has been received by the USB receiver.
  • The blast can take a few ms, in which time the device may be tilted some more. So during every 'blast', we check if the 'tilt' pin has changed and update the serout2 transmission accordingly.
  • Each blast has a unique ID (transmitID), so the receiver will know if a transmission is new or part of a previous blast.

    ' set pin 3 on the pic to an input and name it 'tilt' 
    tilt var gpio.3 : TrisIO.3=1
    ' if the 'tilt' pin has changed since last checked..
    IF tilt <> tiltPrev THEN
        tiltcount = tiltcount + 1    ' increase tilt count..
        sleepCounter = 0    ' make sure pic doesn't fall asleep (sleep code not shown here)
              ' 'blast' the same RF 20 times to ensure the receiver captures the transmission.
              FOR i = 0 TO 20
                ' protocol:
                ' "B" -> special wait character on receiver's end.
                ' transmitID -> unique ID for this transmition, so reciever
                ' can identify if a tranmission belowns to the same 'blast'.
                ' tiltcount -> sends this twice so receiver can compare the data for error-checking.
                SEROUT2 tx, n_2400, ["B", transmitID, tiltcount,tiltcount]
                       ' during the 'blast', if the tilt has changed, increase tiltCount during the blast
                       ' note to self - a litte bug here..
                       ' the TX will receive an accumilated value instead of a count.
                        IF tilt <> tiltPrev THEN
                            tiltcount = tiltcount + 1  
                            transmitID = transmitID + 1
                            transmitID = transmitID//100
                        tiltPrev = tilt
              ' set a new ID for the next transmission.
              transmitID = transmitID + 1
              transmitID = transmitID//100
              tiltcount = 0         
    tiltPrev = tilt

2. USB-Serial emulation is based on this project:
Circuit is based on this project (I'll upadet with my own circuit soon): http://pic18fusb.online.fr/wiki/wikka.php?wakka=UsbBootload

Code: Click here for full code

Main sensor algorithm within the code:

  • The receiver sums up (accumulates) the number of tilts until it is requested to send it to processing. Upon Processing's request, the data is sent and the accumulation buffer resets. So if processing asks for data every 1 second, than each time it will receive the number of tilts that have occurred during that second.
  • Each transmission is sent 20 times (to increase the chances of a successful wireless transmission). We don't want to add up the same tilt data 20 times, so we make sure that the data is fresh by looking at is transmitID (see transmitter code for more details).
  • To ensure that the received data is correct, the tilt value is sent twice on each transmission. We check these two values against each other and only update the buffer if they match.

buffer  	Var	    Byte[5]
temp 	    Var 	Byte[5]
transmitID	Var 	Byte
transmitID = 101

' wait for the "B" character. ' If not received within 1ms: return to main code (not shown here) ' If received: place 3 remaining data bytes in 'temp' string. SERIN2 rx, n_2400, 1, waitForInput, [WAIT("B"),STR temp\3] ' error-check if both data bytes are similar IF temp[1] = temp[2] THEN ' check in new data is part of a previous 'blast' or a new transmission ' (the tranmiter sends 20 transmissions for each new value). IF transmitID <> temp[0] THEN ' accumilate the tilt data into a buffer by incrementing its value. ' this buffer is sent to Processing upon request. ' Processing will receive the number of tilts since its last request. buffer[0] = buffer[0] + temp[1] transmitID = temp[0] ' save this transmission's ID to check agains new transmissions. GOTO waitForInput ' goto main routine (not shown here). ENDIF ENDIF

3. Processing/Java applet
Using the Serial library to communicate with the PIC, the program graphs out the sensor input, and provides a user interface to analyze the input and detect a shake motion.

The Processing app on the right simulates the original program.

  • Hover with the mouse on top of the applet in order to simulate the tilt motion.
  • Drag the mouse to create various buffer windows for analysis.
  • The buffer-window will automatically snap to the scan-line. Data inside the window will be analyzed towards moving the circle on the screen.
  • The window's width determines the length of the buffer.
  • The window's height determines the threshold for the shake detection (it is triggered when the lines exceed the window's height)

Click here to download the Processing Sketch.

To view this content, you need to install Java from java.com