Exercise 4 Solution: Sensor Application Code

Bend Sensor Code:
  1 /*
  2 * Copyright (c) 2007 Sun Microsystems, Inc.
  3 *
  4 * Permission is hereby granted, free of charge, to any person
  5 * obtaining a copy of this software and associated documentation
  6 * files (the "Software"), to deal in the Software without
  7 * restriction, including without limitation the rights to use, copy,
  8 * modify, merge, publish, distribute, sublicense, and/or sell copies
  9 * of the Software, and to permit persons to whom the Software is
 10 * furnished to do so, subject to the following conditions:
 11 *
 12 * The above copyright notice and this permission notice shall be
 13 * included in all copies or substantial portions of the Software.
 14 *
 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 22 * SOFTWARE.
 23 */
 24 
 25 
 26 package org.sunspotworld;
 27 
 28 import com.sun.spot.sensorboard.EDemoBoard;
 29 import com.sun.spot.sensorboard.peripheral.ISwitch;
 30 import com.sun.spot.sensorboard.peripheral.ITriColorLED;
 31 import com.sun.spot.io.j2me.radiostream.*;
 32 import com.sun.spot.io.j2me.radiogram.*;
 33 import com.sun.spot.sensorboard.io.IScalarInput;
 34 import com.sun.spot.sensorboard.peripheral.ISwitchListener;
 35 import com.sun.spot.util.*;
 36 
 37 import java.io.*;
 38 import javax.microedition.io.*;
 39 import javax.microedition.midlet.MIDlet;
 40 import javax.microedition.midlet.MIDletStateChangeException;
 41 
 42 /**
 43  * The startApp method of this class is called by the VM to start the
 44  * application.
 45  * 
 46  * The manifest specifies this class as MIDlet-1, which means it will
 47  * be selected for execution.
 48  * 
 49  * This is the main class for the Bend Sensor application and 'controls'
 50  * the reading of sensor data and sending of sensor data to the remote
 51  * Sun SPOT.
 52  */
 53 public class Bendy extends MIDlet implements ISwitchListener {
 54 
 55     private ITriColorLED[] leds = EDemoBoard.getInstance().getLEDs();
 56     private static final int SAMPLE_SIZE = 150;
 57     private int bendMin = 1000; // any high value will do.
 58     private int bendCenter = 0; // any low value will do
 59     private int bendMax = 0; // any low value will do
 60     private IScalarInput bend = EDemoBoard.getInstance().getScalarInputs()[EDemoBoard.A0]; // the bend sensor is
» connected to pin A0
 61     private ISwitch sw1 = EDemoBoard.getInstance().getSwitches()[EDemoBoard.SW1];
 62     private ISwitch sw2 = EDemoBoard.getInstance().getSwitches()[EDemoBoard.SW2];
 63     private BendySender nw;
 64 
 65 
 66   /**
 67    * This is the main method called to start the Sun SPOT Application
 68    * @throws javax.microedition.midlet.MIDletStateChangeException Thrown when the state of the MIDlet is changed
 69    */
 70     protected void startApp() throws MIDletStateChangeException {
 71         new BootloaderListener().start();   // monitor the USB (if connected) and recognize commands from host
 72         nw = new BendySender();
 73         calibrate();
 74         sw2.addISwitchListener(this);
 75         readSensor(); // this never returns.
 76     }
 77     
 78   /**
 79    * Reads the data from the Sensor itself.
 80    * 
 81    * This method never returns.
 82    */
 83     private void readSensor(){
 84         int lastVal = 0;
 85         int bendInt = 0;
 86         leds[7].setRGB(0, 250, 0);
 87         while (true) {
 88             try {
 89                 bendInt = bend.getValue();
 90             } catch (IOException ex) {
 91                 ex.printStackTrace();
 92             }
 93             if ((bendInt > lastVal + 15) || (bendInt < lastVal - 15)) {
 94                 lastVal = bendInt;
 95                 String msg = String.valueOf(bendInt);
 96                 try {
 97                     nw.send(msg);
 98                 } catch (IOException ex) {
 99                     ex.printStackTrace();
100                 }
101             }
102             leds[7].setOn(!leds[7].isOn());
103             Utils.sleep(50);
104         }
105     }
106 
107     
108     
109   /**
110    * Calibrate (or re-calibrate) the sensor based on 
111    * user input.
112    */
113     protected void calibrate() {
114         leds[7].setOff();
115         setBendMin(1000);
116         setBendCenter(0);
117         setBendMax(0);
118         System.out.println("Do not touch bend sensor while red light is flashing ...");
119         Utils.sleep(1000);
120         leds[0].setRGB(250, 0, 0); // set color to moderate red
121         int z = 0;
122         /* 
123          * Collect a large sample size and average it to find the 'neutral' position
124          */
125         while (z < SAMPLE_SIZE) {
126             try {
127                 setBendCenter(getBendCenter() + bend.getValue());
128                 z++; // only collect successful reads
129             } catch (IOException ex) {
130                 ex.printStackTrace();
131             }
132             leds[0].setOn(!leds[0].isOn()); // Blink LED
133             Utils.sleep(50);
134         }
135         setBendCenter(getBendCenter() / SAMPLE_SIZE); // average over the sample size
136         System.out.println("Center Average: " + getBendCenter() + "(over " + SAMPLE_SIZE + " readings)");
137         System.out.println("Calibrate bend Sensor. Bend in both directions several times. Click Switch one when done.");
138         leds[0].setRGB(0, 0, 250); // set to blue
139         while (sw1.isOpen()) {                  // done when switch is pressed
140             try {
141                 int bendVal = bend.getValue();
142                 if (bendVal < getBendMin()) {
143                     setBendMin(bendVal);
144                 }
145                 if (bendVal > getBendMax()) {
146                     setBendMax(bendVal);
147                 }
148                 System.out.println("Bend: " + bendVal + "    Min: " + getBendMin() + "    Max: " + getBendMax());
149                 leds[0].setOn(!leds[0].isOn()); // Blink LED
150                 Utils.sleep(50);
151             } catch (IOException ex) {
152                 ex.printStackTrace();
153             }
154         }
155         System.out.println(" Setting Min: " + getBendMin() + "    Center: " + getBendCenter() + "     Max: " +
» getBendMax());
156         leds[0].setOff();
157         nw.connect();
158 
159     }
160 
161     protected void pauseApp() {
162     // This is not currently called by the Squawk VM
163     }
164 
165     /**
166    * Called if the MIDlet is terminated by the system.
167    * I.e. if startApp throws any exception other than MIDletStateChangeException,
168    * if the isolate running the MIDlet is killed with Isolate.exit(), or
169    * if VM.stopVM() is called.
170    * 
171    * It is not called if MIDlet.notifyDestroyed() was called.
172    * @param unconditional If true when this method is called, the MIDlet must
173    *    cleanup and release all resources. If false the MIDlet may throw
174    *    MIDletStateChangeException  to indicate it does not want to be destroyed
175    *    at this time.
176    * @throws javax.microedition.midlet.MIDletStateChangeException 
177    */
178     protected void destroyApp(boolean unconditional) throws MIDletStateChangeException {
179         for (int i = 0; i < 8; i++) {
180             leds[i].setOff();
181         }
182     }
183 
184   /**
185    * Return the currently-set minimum value for the bend sensor
186    * @return Sensor minimum value
187    */
188     public int getBendMin() {
189         return bendMin;
190     }
191 
192   /**
193    * Set the minimum value read from the Bend Sensor during configuration
194    * @param bendMin The minimum value read from the sensor
195    */
196     public void setBendMin(int bendMin) {
197         this.bendMin = bendMin;
198     }
199 
200   /**
201    * Return the currently stored 'center' point of the bend sensor
202    * as calculated
203    * @return The stored center-point of the sensor
204    */
205     public int getBendCenter() {
206         return bendCenter;
207     }
208 
209   /**
210    * Store the current 'center' point of the bend sensor
211    * as calculated
212    * @param bendCenter The calculated center point
213    */
214     public void setBendCenter(int bendCenter) {
215         this.bendCenter = bendCenter;
216     }
217 
218   /**
219    * Return the currently stored 'max' point of the bend sensor
220    * as calculated
221    * @return maximum possible sensor value
222    */
223     public int getBendMax() {
224         return bendMax;
225     }
226 
227   /**
228    * set the current  'maximum' point of the bend sensor
229    * as calculated
230    * @param bendMax calculated maximum sensor value
231    */
232     public void setBendMax(int bendMax) {
233         this.bendMax = bendMax;
234     }
235 
236     /* 
237      * We watch Switch 2 for a press, and if pressed, recalibrate the bend sensor
238      * and send the new calibration data to the servo.
239      */
240   /**
241    * Monitor Switch for a press. 
242    * When pressed, re-calibrate the bend sensor and
243    * send recalibration message to the remote
244    * Sun SPOT.
245    * @param sw The switch to watch
246    */
247     public void switchPressed(ISwitch sw) {
248         int switchNum = (sw == sw1) ? 1 : 2;
249         System.out.println("Switch " + switchNum + " closed.");
250         calibrate();
251     }
252 
253     public void switchReleased(ISwitch arg0) {
254     }
255 }

Go on to Exercise 5