AI2 Component  (Version nb184)
NxtSoundSensor.java
Go to the documentation of this file.
1 // -*- mode: java; c-basic-offset: 2; -*-
2 // Copyright 2009-2011 Google, All Rights reserved
3 // Copyright 2011-2012 MIT, All rights reserved
4 // Released under the Apache License, Version 2.0
5 // http://www.apache.org/licenses/LICENSE-2.0
6 
7 package com.google.appinventor.components.runtime;
8 
19 
20 import android.os.Handler;
21 
29 @DesignerComponent(version = YaVersion.NXT_SOUNDSENSOR_COMPONENT_VERSION,
30  description = "A component that provides a high-level interface to a sound sensor on a " +
31  "LEGO MINDSTORMS NXT robot.",
32  category = ComponentCategory.LEGOMINDSTORMS,
33  nonVisible = true,
34  iconName = "images/legoMindstormsNxt.png")
35 @SimpleObject
36 public class NxtSoundSensor extends LegoMindstormsNxtSensor implements Deleteable {
37 
38  private enum State { UNKNOWN, BELOW_RANGE, WITHIN_RANGE, ABOVE_RANGE }
39  private static final String DEFAULT_SENSOR_PORT = "2";
40  private static final int DEFAULT_BOTTOM_OF_RANGE = 256;
41  private static final int DEFAULT_TOP_OF_RANGE = 767;
42 
43  private Handler handler;
44  private final Runnable sensorReader;
45  private State previousState;
46  private int bottomOfRange;
47  private int topOfRange;
48  private boolean belowRangeEventEnabled;
49  private boolean withinRangeEventEnabled;
50  private boolean aboveRangeEventEnabled;
51 
55  public NxtSoundSensor(ComponentContainer container) {
56  super(container, "NxtSoundSensor");
57  handler = new Handler();
58  previousState = State.UNKNOWN;
59  sensorReader = new Runnable() {
60  public void run() {
61  if (bluetooth != null && bluetooth.IsConnected()) {
62  SensorValue<Integer> sensorValue = getSoundValue("");
63  if (sensorValue.valid) {
64  State currentState;
65  if (sensorValue.value < bottomOfRange) {
66  currentState = State.BELOW_RANGE;
67  } else if (sensorValue.value > topOfRange) {
68  currentState = State.ABOVE_RANGE;
69  } else {
70  currentState = State.WITHIN_RANGE;
71  }
72 
73  if (currentState != previousState) {
74  if (currentState == State.BELOW_RANGE && belowRangeEventEnabled) {
75  BelowRange();
76  }
77  if (currentState == State.WITHIN_RANGE && withinRangeEventEnabled) {
78  WithinRange();
79  }
80  if (currentState == State.ABOVE_RANGE && aboveRangeEventEnabled) {
81  AboveRange();
82  }
83  }
84 
85  previousState = currentState;
86  }
87  }
88  if (isHandlerNeeded()) {
89  handler.post(sensorReader);
90  }
91  }
92  };
93 
94  SensorPort(DEFAULT_SENSOR_PORT);
95  BottomOfRange(DEFAULT_BOTTOM_OF_RANGE);
96  TopOfRange(DEFAULT_TOP_OF_RANGE);
100  }
101 
102  @Override
103  protected void initializeSensor(String functionName) {
104  // TODO(user) - support SENSOR_TYPE_SOUND_DBA by adding a DesignerProperty.
105  setInputMode(functionName, port, SENSOR_TYPE_SOUND_DB, SENSOR_MODE_RAWMODE);
106  }
107 
113  defaultValue = DEFAULT_SENSOR_PORT)
114  @SimpleProperty(userVisible = false)
115  public void SensorPort(String sensorPortLetter) {
116  setSensorPort(sensorPortLetter);
117  }
118 
119  @SimpleFunction(description = "Returns the current sound level as a value between 0 and 1023, " +
120  "or -1 if the sound level can not be read.")
121  public int GetSoundLevel() {
122  String functionName = "GetSoundLevel";
123  if (!checkBluetooth(functionName)) {
124  return -1;
125  }
126 
127  SensorValue<Integer> sensorValue = getSoundValue(functionName);
128  if (sensorValue.valid) {
129  return sensorValue.value;
130  }
131 
132  // invalid response
133  return -1;
134  }
135 
136  private SensorValue<Integer> getSoundValue(String functionName) {
137  byte[] returnPackage = getInputValues(functionName, port);
138  if (returnPackage != null) {
139  boolean valid = getBooleanValueFromBytes(returnPackage, 4);
140  if (valid) {
141  int normalizedValue = getUWORDValueFromBytes(returnPackage, 10);
142  return new SensorValue<Integer>(true, normalizedValue);
143  }
144  }
145 
146  // invalid response
147  return new SensorValue<Integer>(false, null);
148  }
149 
154  @SimpleProperty(description = "The bottom of the range used for the BelowRange, WithinRange," +
155  " and AboveRange events.",
156  category = PropertyCategory.BEHAVIOR)
157  public int BottomOfRange() {
158  return bottomOfRange;
159  }
160 
166  defaultValue = "" + DEFAULT_BOTTOM_OF_RANGE)
168  public void BottomOfRange(int bottomOfRange) {
169  this.bottomOfRange = bottomOfRange;
170  previousState = State.UNKNOWN;
171  }
172 
177  @SimpleProperty(description = "The top of the range used for the BelowRange, WithinRange, and" +
178  " AboveRange events.",
179  category = PropertyCategory.BEHAVIOR)
180  public int TopOfRange() {
181  return topOfRange;
182  }
183 
189  defaultValue = "" + DEFAULT_TOP_OF_RANGE)
191  public void TopOfRange(int topOfRange) {
192  this.topOfRange = topOfRange;
193  previousState = State.UNKNOWN;
194  }
195 
200  @SimpleProperty(description = "Whether the BelowRange event should fire when the sound level" +
201  " goes below the BottomOfRange.",
202  category = PropertyCategory.BEHAVIOR)
203  public boolean BelowRangeEventEnabled() {
204  return belowRangeEventEnabled;
205  }
206 
211  @DesignerProperty(editorType = PropertyTypeConstants.PROPERTY_TYPE_BOOLEAN, defaultValue = "False")
213  public void BelowRangeEventEnabled(boolean enabled) {
214  boolean handlerWasNeeded = isHandlerNeeded();
215 
216  belowRangeEventEnabled = enabled;
217 
218  boolean handlerIsNeeded = isHandlerNeeded();
219  if (handlerWasNeeded && !handlerIsNeeded) {
220  handler.removeCallbacks(sensorReader);
221  }
222  if (!handlerWasNeeded && handlerIsNeeded) {
223  previousState = State.UNKNOWN;
224  handler.post(sensorReader);
225  }
226  }
227 
228  @SimpleEvent(description = "Sound level has gone below the range.")
229  public void BelowRange() {
230  EventDispatcher.dispatchEvent(this, "BelowRange");
231  }
232 
237  @SimpleProperty(description = "Whether the WithinRange event should fire when the sound level" +
238  " goes between the BottomOfRange and the TopOfRange.",
239  category = PropertyCategory.BEHAVIOR)
240  public boolean WithinRangeEventEnabled() {
241  return withinRangeEventEnabled;
242  }
243 
248  @DesignerProperty(editorType = PropertyTypeConstants.PROPERTY_TYPE_BOOLEAN, defaultValue = "False")
250  public void WithinRangeEventEnabled(boolean enabled) {
251  boolean handlerWasNeeded = isHandlerNeeded();
252 
253  withinRangeEventEnabled = enabled;
254 
255  boolean handlerIsNeeded = isHandlerNeeded();
256  if (handlerWasNeeded && !handlerIsNeeded) {
257  handler.removeCallbacks(sensorReader);
258  }
259  if (!handlerWasNeeded && handlerIsNeeded) {
260  previousState = State.UNKNOWN;
261  handler.post(sensorReader);
262  }
263  }
264 
265  @SimpleEvent(description = "Sound level has gone within the range.")
266  public void WithinRange() {
267  EventDispatcher.dispatchEvent(this, "WithinRange");
268  }
269 
274  @SimpleProperty(description = "Whether the AboveRange event should fire when the sound level" +
275  " goes above the TopOfRange.",
276  category = PropertyCategory.BEHAVIOR)
277  public boolean AboveRangeEventEnabled() {
278  return aboveRangeEventEnabled;
279  }
280 
285  @DesignerProperty(editorType = PropertyTypeConstants.PROPERTY_TYPE_BOOLEAN, defaultValue = "False")
287  public void AboveRangeEventEnabled(boolean enabled) {
288  boolean handlerWasNeeded = isHandlerNeeded();
289 
290  aboveRangeEventEnabled = enabled;
291 
292  boolean handlerIsNeeded = isHandlerNeeded();
293  if (handlerWasNeeded && !handlerIsNeeded) {
294  handler.removeCallbacks(sensorReader);
295  }
296  if (!handlerWasNeeded && handlerIsNeeded) {
297  previousState = State.UNKNOWN;
298  handler.post(sensorReader);
299  }
300  }
301 
302  @SimpleEvent(description = "Sound level has gone above the range.")
303  public void AboveRange() {
304  EventDispatcher.dispatchEvent(this, "AboveRange");
305  }
306 
307  private boolean isHandlerNeeded() {
308  return belowRangeEventEnabled || withinRangeEventEnabled || aboveRangeEventEnabled;
309  }
310 
311  // Deleteable implementation
312 
313  @Override
314  public void onDelete() {
315  handler.removeCallbacks(sensorReader);
316  super.onDelete();
317  }
318 }
com.google.appinventor.components.runtime.EventDispatcher
Definition: EventDispatcher.java:22
com.google.appinventor.components.runtime.NxtSoundSensor.WithinRangeEventEnabled
void WithinRangeEventEnabled(boolean enabled)
Definition: NxtSoundSensor.java:250
com.google.appinventor.components.runtime.NxtSoundSensor.WithinRange
void WithinRange()
Definition: NxtSoundSensor.java:266
com.google.appinventor.components.annotations.SimpleFunction
Definition: SimpleFunction.java:23
com.google.appinventor.components.runtime.NxtSoundSensor.BelowRangeEventEnabled
void BelowRangeEventEnabled(boolean enabled)
Definition: NxtSoundSensor.java:213
com.google.appinventor.components.runtime.NxtSoundSensor.initializeSensor
void initializeSensor(String functionName)
Definition: NxtSoundSensor.java:103
com.google.appinventor.components.common.YaVersion
Definition: YaVersion.java:14
com.google.appinventor.components.annotations.DesignerProperty
Definition: DesignerProperty.java:25
com.google.appinventor.components.runtime.LegoMindstormsNxtBase.bluetooth
BluetoothClient bluetooth
Definition: LegoMindstormsNxtBase.java:77
com.google.appinventor.components
com.google.appinventor.components.common.PropertyTypeConstants.PROPERTY_TYPE_NON_NEGATIVE_INTEGER
static final String PROPERTY_TYPE_NON_NEGATIVE_INTEGER
Definition: PropertyTypeConstants.java:206
com.google.appinventor.components.runtime.LegoMindstormsNxtSensor.setSensorPort
final void setSensorPort(String sensorPortLetter)
Definition: LegoMindstormsNxtSensor.java:78
com.google.appinventor.components.runtime.BluetoothConnectionBase.IsConnected
final boolean IsConnected()
Definition: BluetoothConnectionBase.java:204
com.google.appinventor.components.common.PropertyTypeConstants.PROPERTY_TYPE_BOOLEAN
static final String PROPERTY_TYPE_BOOLEAN
Definition: PropertyTypeConstants.java:35
com.google.appinventor.components.runtime.NxtSoundSensor.NxtSoundSensor
NxtSoundSensor(ComponentContainer container)
Definition: NxtSoundSensor.java:55
com.google.appinventor.components.annotations.DesignerComponent
Definition: DesignerComponent.java:22
com.google.appinventor.components.annotations.SimpleEvent
Definition: SimpleEvent.java:20
com.google.appinventor.components.annotations.PropertyCategory.BEHAVIOR
BEHAVIOR
Definition: PropertyCategory.java:15
com.google.appinventor.components.runtime.NxtSoundSensor.WithinRangeEventEnabled
boolean WithinRangeEventEnabled()
Definition: NxtSoundSensor.java:240
com.google.appinventor.components.runtime.LegoMindstormsNxtSensor.SensorPort
String SensorPort()
Definition: LegoMindstormsNxtSensor.java:70
com.google.appinventor.components.runtime.LegoMindstormsNxtBase.getInputValues
final byte[] getInputValues(String functionName, int port)
Definition: LegoMindstormsNxtBase.java:168
com.google.appinventor.components.runtime.EventDispatcher.dispatchEvent
static boolean dispatchEvent(Component component, String eventName, Object...args)
Definition: EventDispatcher.java:188
com.google.appinventor.components.runtime.NxtSoundSensor
Definition: NxtSoundSensor.java:36
com.google.appinventor.components.runtime.NxtSoundSensor.onDelete
void onDelete()
Definition: NxtSoundSensor.java:314
com.google.appinventor.components.runtime.LegoMindstormsNxtSensor
Definition: LegoMindstormsNxtSensor.java:21
com.google.appinventor.components.runtime.NxtSoundSensor.AboveRangeEventEnabled
void AboveRangeEventEnabled(boolean enabled)
Definition: NxtSoundSensor.java:287
com.google.appinventor.components.annotations.SimpleProperty
Definition: SimpleProperty.java:23
com.google.appinventor.components.runtime.NxtSoundSensor.TopOfRange
void TopOfRange(int topOfRange)
Definition: NxtSoundSensor.java:191
com.google.appinventor.components.runtime.NxtSoundSensor.GetSoundLevel
int GetSoundLevel()
Definition: NxtSoundSensor.java:121
com.google.appinventor.components.runtime.NxtSoundSensor.BottomOfRange
void BottomOfRange(int bottomOfRange)
Definition: NxtSoundSensor.java:168
com.google.appinventor.components.annotations.PropertyCategory
Definition: PropertyCategory.java:13
com.google.appinventor.components.runtime.ComponentContainer
Definition: ComponentContainer.java:16
com.google.appinventor.components.runtime.NxtSoundSensor.AboveRangeEventEnabled
boolean AboveRangeEventEnabled()
Definition: NxtSoundSensor.java:277
com.google.appinventor.components.runtime.Deleteable
Definition: Deleteable.java:15
com.google.appinventor.components.common
Definition: ComponentCategory.java:7
com.google.appinventor.components.common.ComponentCategory
Definition: ComponentCategory.java:48
com.google.appinventor.components.runtime.NxtSoundSensor.TopOfRange
int TopOfRange()
Definition: NxtSoundSensor.java:180
com.google.appinventor.components.runtime.LegoMindstormsNxtBase.checkBluetooth
final boolean checkBluetooth(String functionName)
Definition: LegoMindstormsNxtBase.java:250
com.google.appinventor.components.annotations.SimpleObject
Definition: SimpleObject.java:23
com.google.appinventor.components.runtime.LegoMindstormsNxtSensor.port
int port
Definition: LegoMindstormsNxtSensor.java:56
com.google.appinventor.components.runtime.LegoMindstormsNxtBase.getBooleanValueFromBytes
final boolean getBooleanValueFromBytes(byte[] bytes, int offset)
Definition: LegoMindstormsNxtBase.java:399
com.google.appinventor.components.runtime.LegoMindstormsNxtBase.getUWORDValueFromBytes
final int getUWORDValueFromBytes(byte[] bytes, int offset)
Definition: LegoMindstormsNxtBase.java:416
com.google
com
com.google.appinventor.components.common.PropertyTypeConstants.PROPERTY_TYPE_LEGO_NXT_SENSOR_PORT
static final String PROPERTY_TYPE_LEGO_NXT_SENSOR_PORT
Definition: PropertyTypeConstants.java:101
com.google.appinventor.components.runtime.NxtSoundSensor.AboveRange
void AboveRange()
Definition: NxtSoundSensor.java:303
com.google.appinventor.components.runtime.NxtSoundSensor.BelowRange
void BelowRange()
Definition: NxtSoundSensor.java:229
com.google.appinventor.components.runtime.NxtSoundSensor.BottomOfRange
int BottomOfRange()
Definition: NxtSoundSensor.java:157
com.google.appinventor.components.runtime.LegoMindstormsNxtBase.setInputMode
final void setInputMode(String functionName, int port, int sensorType, int sensorMode)
Definition: LegoMindstormsNxtBase.java:158
com.google.appinventor.components.runtime.NxtSoundSensor.BelowRangeEventEnabled
boolean BelowRangeEventEnabled()
Definition: NxtSoundSensor.java:203
com.google.appinventor.components.common.PropertyTypeConstants
Definition: PropertyTypeConstants.java:14
com.google.appinventor.components.annotations
com.google.appinventor