Exercise 4: Developing the Source Code for the Bend Sensor

Expected duration: 45 minutes

Introduction:

In this exercise we'll develop the basic code to read data from the bend sensor. The bend sensor is an analog sensor, so we have (in the previous exercise) connected the bend sensor's data line to one of the Analog Pins on the Sun SPOT (Pin A0)

If you choose to use NetBeans for this lab (and I recommend it), then issue the following command in a shell, or use the NetBeans icon found on your desktop

$ netbeans
$

Once you have opened NetBeans, you should see a window that look similar to this:

If not, choose 'Open Project' and find the source code for the J1HOL-Bend and J1HOL-Servo projects and open them. These projects should be located in the <lab_root> directory.

For this exercise, right-click on the Bend Sensor Application and choose 'Set as Main Project' as this will make the exercise much easier.

For this portion of the Lab, we will look at the calibration of the sensor. The bend sensor is what is called a thin-film resistor, and it electrically resists depending on how far, and in which direction, it is bent. Each sensor may react slightly differently -- giving slightly different values -- depending on many factors including temperature, current, etc.

So the first thing we need to do is calibrate the sensor. The first thing we need to determine is where the sensor believes the 'mid point' to be in its range. To determin that value, we will take a large sampling from the sensor while it is at rest, then average those results. This will give us a relatively accurate 'center' value. After that we willl take some samples while the sensor is being bent to its maximum extent and use these as the minimum and maximum values for the sensor.

We will use the LEDs to give the user some feedback on what is being done, and when their input is required. The following is the 'calibrate' method in which all of this takes place.

109     
110   /**
111    * Calibrate (or re-calibrate) the sensor based on 
112    * user input.
113    */
114     protected void calibrate() {
115         leds[7].setOff();
116         setBendMin(1000);
117         setBendCenter(0);
118         setBendMax(0);
119         System.out.println("Do not touch bend sensor while red light is flashing ...");
120         Utils.sleep(1000);
121         leds[0].setRGB(250, 0, 0); // set color to moderate red
122         int z = 0;
123         /* 
124          * Collect a large sample size and average it to find the 'neutral' position
125          */
126         while (z < SAMPLE_SIZE) {
127             try {
128                 setBendCenter(getBendCenter() + bend.getValue());
129                 z++; // only collect successful reads
130             } catch (IOException ex) {
131                 ex.printStackTrace();
132             }
133             leds[0].setOn(!leds[0].isOn()); // Blink LED
134             Utils.sleep(50);
135         }
136         setBendCenter(getBendCenter() / SAMPLE_SIZE); // average over the sample size
137         System.out.println("Center Average: " + getBendCenter() + "(over " + SAMPLE_SIZE + " readings)");
138         System.out.println("Calibrate bend Sensor. Bend in both directions several times. Click Switch one when done.");
139         leds[0].setRGB(0, 0, 250); // set to blue
140         while (sw1.isOpen()) {                  // done when switch is pressed
141             try {
142                 int bendVal = bend.getValue();
143                 if (bendVal < getBendMin()) {
144                     setBendMin(bendVal);
145                 }
146                 if (bendVal > getBendMax()) {
147                     setBendMax(bendVal);
148                 }
149                 System.out.println("Bend: " + bendVal + "    Min: " + getBendMin() + "    Max: " + getBendMax());
150                 leds[0].setOn(!leds[0].isOn()); // Blink LED
151                 Utils.sleep(50);
152             } catch (IOException ex) {
153                 ex.printStackTrace();
154             }
155         }
156         System.out.println(" Setting Min: " + getBendMin() + "    Center: " + getBendCenter() + "     Max: " +
ยป getBendMax());
157         leds[0].setOff();
158         nw.connect();
159 
160     }
            

To test the effect of calibration, you can edit the definition of SAMPLE_SIZE by changing its value in the line:

           56     private static final int SAMPLE_SIZE = 150;
          

It likely will not change the final value significantly, but you can see that sampling a sensor to gather a large amount of data can be done in a short amount of time.

By giving the user information both via the console and the LEDs a user can know what is being done, and what might be required of them. For instance, while the red light is flashing, don't touch the sensor. And once the blue light begins to flash, it is time for them to calibrate the sensor by bending it back and forth.

You can also change to color of the lights by changing the RGB values (RGB stands for Red, Green, Blue, so by altering each value you can change the color of the lights in this line:

           86         leds[7].setRGB(0, 250, 0);
          
You can also alter which LED is lit by changing the value of the LED array item referenced in the same line.

Building and deploying your code:

The simplest way to build and deploy your code is via the NetBeans context-menus. Simply right-click on the project node

Choosing "Build Project + Deploy to Sun SPOT" will do just that for you. You can also choose "Run" which will build, deploy and run your application allowing you to see the output in NetBeans' output window.

If you have more than one Sun SPOT connected, you will be asked to select which Sun SPOT to deploy your code to. For now, I suggest having just the Bend Sensor Sun SPOT plugged in.

Alternatively, if you are using a command-line approach, you can simply type:
          $ ant deploy run
          
You will then see a vast amount of output from the ant command, which should look like the following, roughly:
[dhcp-069-184:~/NetBeansProjects/HandsOnLab08/J1HOL-Bend] davidgs% ant deploy
Buildfile: build.xml

-pre-init:

-do-init:

-post-init:

init:

-set-selector-for-nonbasestation:

-find-manifest:

-check-for-manifest:

-set-jar-name:
     [echo] No jar.file specified.
     [echo] Using "suite/Bendy_1.0.0.jar"

-pre-clean:

-do-clean:
   [delete] Deleting directory /Users/davidgs/NetBeansProjects/HandsOnLab08/J1HOL-Bend/build
   [delete] Deleting directory /Users/davidgs/NetBeansProjects/HandsOnLab08/J1HOL-Bend/suite
   [delete] Deleting directory /Users/davidgs/NetBeansProjects/HandsOnLab08/J1HOL-Bend/j2meclasses

-post-clean:

clean:

-pre-compile:

-do-compile:
    [mkdir] Created dir: /Users/davidgs/NetBeansProjects/HandsOnLab08/J1HOL-Bend/build
    [javac] Compiling 2 source files to /Users/davidgs/NetBeansProjects/HandsOnLab08/J1HOL-Bend/build

-post-compile:

compile:

-pre-preverify:

-make-preverify-directory:
    [mkdir] Created dir: /Users/davidgs/NetBeansProjects/HandsOnLab08/J1HOL-Bend/j2meclasses

-unjar-utility-jars:

-do-preverify:

-post-preverify:

preverify:

-pre-jar-app:

-do-jar-app:
    [mkdir] Created dir: /Users/davidgs/NetBeansProjects/HandsOnLab08/J1HOL-Bend/suite
      [jar] Building jar: /Users/davidgs/NetBeansProjects/HandsOnLab08/J1HOL-Bend/suite/Bendy_1.0.0.jar

-post-jar-app:

jar-app:

-check-for-jar:

-override-warning-find-spots:

-prepare-conditions-for-find-spots:

-find-shared-basestation:

-run-spotfinder:

-pre-suite:

-do-suite-new:
     [java] [loaded object memory from 'file://squawk.suite']
     [java] [loaded object memory from 'file://squawk.suite.metadata']
     [java] [loaded object memory from 'file://transducerlib.suite']
     [java] [loaded object memory from 'file://transducerlib.suite.metadata']
     [java] [translating suite image ...]
     [java] Translator properties and current values:
     [java]     translator.help=false
     [java]     translator.verbose=true
     [java]     translator.optimizeConstantObjects=true
     [java]     translator.deadMethodElimination=true
     [java] [Translator: computing closure.....167ms.]
     [java] [Translator: whole-suite optimizing and inlining...3ms.]
     [java] [Translator: phase2...[Loaded org.sunspotworld.Bendy]
     [java] [Loaded org.sunspotworld.BendySender]
     [java] 45ms.]
     [java] [Including resource: META-INF/MANIFEST.MF]
     [java] [Adding property key: |Manifest-Version| value: |1.0|]
     [java] [Adding property key: |Ant-Version| value: |Apache Ant 1.7.0|]
     [java] [Adding property key: |Created-By| value: |1.5.0_13-119 (Apple Inc.)|]
     [java] [Adding property key: |MIDlet-Name| value: |Bendy|]
     [java] [Adding property key: |MIDlet-Version| value: |1.0.0|]
     [java] [Adding property key: |MIDlet-Vendor| value: |Sun Microsystems Inc|]
     [java] [Adding property key: |MIDlet-1| value: |Bendy, , org.sunspotworld.Bendy|]
     [java] [Adding property key: |MicroEdition-Profile| value: |IMP-1.0|]
     [java] [Adding property key: |MicroEdition-Configuration| value: |CLDC-1.1|]
     [java] [Adding property key: |#ServoSPOT| value: |0014.4F01.0000.033A|]
     [java] [Adding property key: |#BendySPOT| value: |0014.4F01.0000.0575|]
     [java] [Adding property key: |BendySPOT| value: |9846.45b8.0000.1001|]
     [java] [Adding property key: |ServoSPOT| value: |9846.45b8.0000.1002|]
     [java] [loaded object memory from 'file://image.suite']
     [java] Romizer processed 2 classes and generated these files:
     [java]   /Users/davidgs/NetBeansProjects/HandsOnLab08/J1HOL-Bend/image.sym
     [java]   /Users/davidgs/NetBeansProjects/HandsOnLab08/J1HOL-Bend/image.suite
     [java]   /Users/davidgs/NetBeansProjects/HandsOnLab08/J1HOL-Bend/image.suite.metadata
     [java]   /Users/davidgs/NetBeansProjects/HandsOnLab08/J1HOL-Bend/image.suite.api
     [move] Moving 1 file to /Users/davidgs/NetBeansProjects/HandsOnLab08/J1HOL-Bend/suite
     [move] Moving 1 file to /Users/davidgs/NetBeansProjects/HandsOnLab08/J1HOL-Bend/suite
     [move] Moving 1 file to /Users/davidgs/NetBeansProjects/HandsOnLab08/J1HOL-Bend/suite
   [delete] Deleting: /Users/davidgs/NetBeansProjects/HandsOnLab08/J1HOL-Bend/image.suite.api

-do-suite-old:

-do-suite:

-post-suite:

-pre-deploy:

-do-deploy:

-check-run-spotclient-parameters:

-run-spotclient-once-with-remote-id:

-run-spotclient-multiple-times-with-remote-id:

-run-spotclient-once-locally:

-echo-progress-for-remote-runs:

-echo-progress-for-local-runs:

-run-spotclient-once:
     [java] SPOT Client starting...
     [java] RXTX Warning:  Removing stale lock file. /var/lock/LK.003.009.131
     [java] [waiting for reset] Exiting - detected bootloader command
     [java] [waiting for reset] 
     [java] [waiting for reset] 
     [java] [waiting for reset] ** VM stopped: exit code = 0 ** 
     [java] [waiting for reset] 
     [java] 
     [java] Sun SPOT bootloader (purple-071018) 
     [java] SPOT serial number = 0014.4F01.0000.033A
     [java] About to flash to /Users/davidgs/NetBeansProjects/HandsOnLab08/J1HOL-Bend/suite/image
     [java] Writing imageapp57273.bintemp(6476 bytes) to local SPOT on port /dev/cu.usbmodemfd351
     [java] |===                                                         | 7%
     [java] |======                                                      | 10%
     [java] |=========                                                   | 15%
     [java] |============                                                | 21%
     [java] |===============                                             | 25%
     [java] |==================                                          | 31%
     [java] |=====================                                       | 35%
     [java] |========================                                    | 40%
     [java] |===========================                                 | 45%
     [java] |==============================                              | 50%
     [java] |=================================                           | 57%
     [java] |====================================                        | 60%
     [java] |=======================================                     | 65%
     [java] |==========================================                  | 71%
     [java] |=============================================               | 75%
     [java] |================================================            | 81%
     [java] |===================================================         | 85%
     [java] |======================================================      | 90%
     [java] |=========================================================   | 95%
     [java] |============================================================| 100%
     [java] 
     [java] 
     [java] 
     [java] Exiting
     [java] Experimental:  JNI_OnLoad called.

-run-spotclient-multiple-times-locally:

-run-spotclient:

-post-deploy:

jar-deploy:

deploy:

BUILD SUCCESSFUL
Total time: 16 seconds
          

The Bend Sensor Application is designed to give you visual feedback, via the on-board LEDs, about what the application is doing. While the Sun SPOT is finding the center-point (through averaging), an LED blinks red to indicate that you should not touch the Sensor.

Once the center-point calibration ic completed, the LED then blinks blue to indicate that it is awaiting further calibration.

Finally, you should press Switch 1 to complete the calibration sequence, after which an LED will blink green to indicate that the sensor application is running.

Summary:

You should have successfully calibrated your Bend Sensor at the end of this exercise.

View the Solution

Go on to next exercise