AI2 Component  (Version nb184)
Ev3ColorSensor.java
Go to the documentation of this file.
1 // -*- mode: java; c-basic-offset: 2; -*-
2 // Copyright 2016 MIT, All rights reserved
3 // Released under the Apache License, Version 2.0
4 // http://www.apache.org/licenses/LICENSE-2.0
5 
6 package com.google.appinventor.components.runtime;
7 
19 import android.os.Handler;
20 
30 @DesignerComponent(version = YaVersion.EV3_COLORSENSOR_COMPONENT_VERSION,
31  description = "A component that provides a high-level interface to a color sensor on a " +
32  "LEGO MINDSTORMS EV3 robot.",
33  category = ComponentCategory.LEGOMINDSTORMS,
34  nonVisible = true,
35  iconName = "images/legoMindstormsEv3.png")
36 @SimpleObject
37 public class Ev3ColorSensor extends LegoMindstormsEv3Sensor implements Deleteable {
38  private static final int SENSOR_TYPE = 29;
39  private static final int SENSOR_MODE_REFLECTED = 0;
40  private static final int SENSOR_MODE_AMBIENT = 1;
41  private static final int SENSOR_MODE_COLOR = 2;
42  private static final String SENSOR_MODE_REFLECTED_STRING = "reflected";
43  private static final String SENSOR_MODE_AMBIENT_STRING = "ambient";
44  private static final String SENSOR_MODE_COLOR_STRING = "color";
45  private static final int DEFAULT_BOTTOM_OF_RANGE = 30;
46  private static final int DEFAULT_TOP_OF_RANGE = 60;
47  private static final String DEFAULT_SENSOR_MODE_STRING = SENSOR_MODE_REFLECTED_STRING;
48  private static final int DELAY_MILLISECONDS = 50;
49 
50  private int mode = 0;
51  private String modeString = SENSOR_MODE_REFLECTED_STRING;
52  private Handler eventHandler;
53  private final Runnable sensorValueChecker;
54  private int bottomOfRange;
55  private int topOfRange;
56  private int previousLightLevel = 0;
57 
58  private int previousColor = -1;
59  private boolean belowRangeEventEnabled;
60  private boolean withinRangeEventEnabled;
61  private boolean aboveRangeEventEnabled;
62  private boolean colorChangedEventEnabled;
63 
67  public Ev3ColorSensor(ComponentContainer container) {
68  super(container, "Ev3ColorSensor");
69 
70  eventHandler = new Handler();
71  sensorValueChecker = new Runnable() {
72  public void run() {
73  String functionName = "";
74 
75  if (bluetooth != null && bluetooth.IsConnected()) {
76  if (mode == SENSOR_MODE_COLOR) {
77  int currentColor = getSensorValue(functionName);
78 
79  if (previousColor < 0) {
80  previousColor = currentColor;
81  eventHandler.postDelayed(this, DELAY_MILLISECONDS);
82  return;
83  }
84 
85  if (currentColor != previousColor && colorChangedEventEnabled)
86  ColorChanged(currentColor, toColorName(functionName, currentColor));
87 
88  previousColor = currentColor;
89  } else { // mode == SENSOR_MODE_REFLECTED or mode == SENSOR_MODE_AMBIENT
90  int currentLightLevel = getSensorValue(functionName);
91  if (previousLightLevel < 0) {
92  previousLightLevel = currentLightLevel;
93  eventHandler.postDelayed(this, DELAY_MILLISECONDS);
94  return;
95  }
96 
97  // trigger events according to the conditions
98  if (currentLightLevel < bottomOfRange) {
99  if (belowRangeEventEnabled && previousLightLevel >= bottomOfRange)
100  BelowRange();
101  } else if (currentLightLevel > topOfRange) {
102  if (aboveRangeEventEnabled && previousLightLevel <= topOfRange)
103  AboveRange();
104  } else {
105  if (withinRangeEventEnabled && (previousLightLevel < bottomOfRange || previousLightLevel > topOfRange))
106  WithinRange();
107  }
108 
109  previousLightLevel = currentLightLevel;
110  }
111  }
112 
113  eventHandler.postDelayed(this, DELAY_MILLISECONDS);
114  }
115  };
116  eventHandler.post(sensorValueChecker);
117 
118  TopOfRange(DEFAULT_TOP_OF_RANGE);
119  BottomOfRange(DEFAULT_BOTTOM_OF_RANGE);
120  BelowRangeEventEnabled(false);
121  AboveRangeEventEnabled(false);
124  Mode(DEFAULT_SENSOR_MODE_STRING);
125  }
126 
130  @SimpleFunction(description = "It returns the light level in percentage, or " +
131  "-1 when the light level cannot be read.")
132  public int GetLightLevel() {
133  if (mode == SENSOR_MODE_COLOR)
134  return -1;
135 
136  String functionName = "GetLightLevel";
137  return getSensorValue(functionName);
138  }
139 
143  @SimpleFunction(description = "It returns the color code from 0 to 7 corresponding to no color, black, blue, green, yellow, red, white and brown.")
144  public int GetColorCode() {
145  if (mode != SENSOR_MODE_COLOR)
146  return 0;
147 
148  String functionName = "GetColorCode";
149  return getSensorValue(functionName);
150  }
151 
155  @SimpleFunction(description = "Return the color name in one of \"No Color\", \"Black\", \"Blue\", \"Green\", \"Yellow\", \"Red\", \"White\", \"Brown\".")
156  public String GetColorName() {
157  if (mode != SENSOR_MODE_COLOR)
158  return "No Color";
159 
160  String functionName = "GetColorName";
161  int colorCode = getSensorValue(functionName);
162  return toColorName(functionName, colorCode);
163  }
164 
169  @SimpleProperty(description = "The bottom of the range used for the BelowRange, WithinRange, " +
170  "and AboveRange events.",
171  category = PropertyCategory.BEHAVIOR)
172  public int BottomOfRange() {
173  return bottomOfRange;
174  }
175 
181  defaultValue = "" + DEFAULT_BOTTOM_OF_RANGE)
183  public void BottomOfRange(int bottomOfRange) {
184  this.bottomOfRange = bottomOfRange;
185  }
186 
191  @SimpleProperty(description = "The top of the range used for the BelowRange, WithinRange, and " +
192  "AboveRange events.",
193  category = PropertyCategory.BEHAVIOR)
194  public int TopOfRange() {
195  return topOfRange;
196  }
197 
203  defaultValue = "" + DEFAULT_TOP_OF_RANGE)
205  public void TopOfRange(int topOfRange) {
206  this.topOfRange = topOfRange;
207  }
208 
213  @SimpleProperty(description = "Whether the BelowRange event should fire when the light level" +
214  " goes below the BottomOfRange.",
215  category = PropertyCategory.BEHAVIOR)
216  public boolean BelowRangeEventEnabled() {
217  return belowRangeEventEnabled;
218  }
219 
225  defaultValue = "False")
227  public void BelowRangeEventEnabled(boolean enabled) {
228  belowRangeEventEnabled = enabled;
229  }
230 
231  @SimpleEvent(description = "Light level has gone below the range.")
232  public void BelowRange() {
233  EventDispatcher.dispatchEvent(this, "BelowRange");
234  }
235 
240  @SimpleProperty(description = "Whether the WithinRange event should fire when the light level " +
241  "goes between the BottomOfRange and the TopOfRange.",
242  category = PropertyCategory.BEHAVIOR)
243  public boolean WithinRangeEventEnabled() {
244  return withinRangeEventEnabled;
245  }
246 
252  defaultValue = "False")
254  public void WithinRangeEventEnabled(boolean enabled) {
255  withinRangeEventEnabled = enabled;
256  }
257 
258  @SimpleEvent(description = "Light level has gone within the range.")
259  public void WithinRange() {
260  EventDispatcher.dispatchEvent(this, "WithinRange");
261  }
262 
267  @SimpleProperty(description = "Whether the AboveRange event should fire when the light level " +
268  "goes above the TopOfRange.",
269  category = PropertyCategory.BEHAVIOR)
270  public boolean AboveRangeEventEnabled() {
271  return aboveRangeEventEnabled;
272  }
273 
279  defaultValue = "False")
281  public void AboveRangeEventEnabled(boolean enabled) {
282  aboveRangeEventEnabled = enabled;
283  }
284 
285  @SimpleEvent(description = "Light level has gone above the range.")
286  public void AboveRange() {
287  EventDispatcher.dispatchEvent(this, "AboveRange");
288  }
289 
294  @SimpleProperty(description = "Whether the ColorChanged event should fire when the Mode" +
295  " property is set to \"color\" and the detected color changes.",
296  category = PropertyCategory.BEHAVIOR)
297  public boolean ColorChangedEventEnabled() {
298  return colorChangedEventEnabled;
299  }
300 
306  defaultValue = "False")
308  public void ColorChangedEventEnabled(boolean enabled) {
309  colorChangedEventEnabled = enabled;
310  }
311 
315  @SimpleEvent(description = "Called when the detected color has changed. The ColorChanged event will occur " +
316  "if the Mode property is set to \"color\" and the ColorChangedEventEnabled property " +
317  "is set to True.")
318  public void ColorChanged(int colorCode, String colorName) {
319  EventDispatcher.dispatchEvent(this, "ColorChanged", colorCode, colorName);
320  }
321 
322  private int getSensorValue(String functionName) {
323  int level = readInputPercentage(functionName,
324  0, // assume layer = 0
326  SENSOR_TYPE,
327  mode);
328 
329  // map values according to LEGO's convention
330  if (mode == SENSOR_MODE_COLOR) {
331  switch (level) {
332  case 0:
333  return 0;
334  case 12:
335  return 1;
336  case 25:
337  return 2;
338  case 37:
339  return 3;
340  case 50:
341  return 4;
342  case 62:
343  return 5;
344  case 75:
345  return 6;
346  case 87:
347  return 7;
348  default:
349  return 0;
350  }
351  } else {
352  return level;
353  }
354  }
355 
356  private String toColorName(String functionName, int colorCode) {
357  if (mode != SENSOR_MODE_COLOR)
358  return "No Color";
359 
360  switch (colorCode) {
361  case 0:
362  return "No Color";
363  case 1:
364  return "Black";
365  case 2:
366  return "Blue";
367  case 3:
368  return "Green";
369  case 4:
370  return "Yellow";
371  case 5:
372  return "Red";
373  case 6:
374  return "White";
375  case 7:
376  return "Brown";
377  default:
378  return "No Color";
379  }
380  }
381 
385  @DesignerProperty(editorType = PropertyTypeConstants.PROPERTY_TYPE_LEGO_EV3_COLOR_SENSOR_MODE,
386  defaultValue = DEFAULT_SENSOR_MODE_STRING)
387  @SimpleProperty
388  public void Mode(String modeName) {
389  String functionName = "Mode";
390  try {
391  setMode(modeName);
392  } catch(IllegalArgumentException e) {
393  form.dispatchErrorOccurredEvent(this, functionName, ErrorMessages.ERROR_EV3_ILLEGAL_ARGUMENT, functionName);
394  }
395  }
396 
400  @SimpleProperty(description = "Get the current sensor mode.",
401  category = PropertyCategory.BEHAVIOR)
402  public String Mode() {
403  return modeString;
404  }
405 
409  @SimpleFunction(description = "Enter the color detection mode.")
410  public void SetColorMode() {
411  String functionName = "SetColorMode";
412  try {
413  setMode(SENSOR_MODE_COLOR_STRING);
414  } catch(IllegalArgumentException e) {
415  form.dispatchErrorOccurredEvent(this, functionName, ErrorMessages.ERROR_EV3_ILLEGAL_ARGUMENT, functionName);
416  }
417  }
418 
422  @SimpleFunction(description = "Make the sensor read the light level with reflected light.")
423  public void SetReflectedMode() {
424  String functionName = "SetReflectedMode";
425  try {
426  setMode(SENSOR_MODE_REFLECTED_STRING);
427  } catch(IllegalArgumentException e) {
428  form.dispatchErrorOccurredEvent(this, functionName, ErrorMessages.ERROR_EV3_ILLEGAL_ARGUMENT, functionName);
429  }
430  }
431 
435  @SimpleFunction(description = "Make the sensor read the light level without reflected light.")
436  public void SetAmbientMode() {
437  String functionName = "SetAmbientMode";
438  try{
439  setMode(SENSOR_MODE_AMBIENT_STRING);
440  } catch(IllegalArgumentException e) {
441  form.dispatchErrorOccurredEvent(this, functionName, ErrorMessages.ERROR_EV3_ILLEGAL_ARGUMENT, functionName);
442  }
443  }
444 
445  private void setMode(String newModeString) {
446  previousColor = -1;
447  previousLightLevel = -1;
448 
449  if (SENSOR_MODE_REFLECTED_STRING.equals(newModeString))
450  mode = SENSOR_MODE_REFLECTED;
451  else if (SENSOR_MODE_AMBIENT_STRING.equals(newModeString))
452  mode = SENSOR_MODE_AMBIENT;
453  else if (SENSOR_MODE_COLOR_STRING.equals(newModeString))
454  mode = SENSOR_MODE_COLOR;
455  else
456  throw new IllegalArgumentException();
457 
458  this.modeString = newModeString;
459  }
460 
461  // interface Deleteable implementation
462  @Override
463  public void onDelete() {
464  eventHandler.removeCallbacks(sensorValueChecker);
465  super.onDelete();
466  }
467 }
com.google.appinventor.components.runtime.EventDispatcher
Definition: EventDispatcher.java:22
com.google.appinventor.components.runtime.LegoMindstormsEv3Sensor.sensorPortNumber
int sensorPortNumber
Definition: LegoMindstormsEv3Sensor.java:26
com.google.appinventor.components.annotations.SimpleFunction
Definition: SimpleFunction.java:23
com.google.appinventor.components.runtime.Ev3ColorSensor.ColorChanged
void ColorChanged(int colorCode, String colorName)
Definition: Ev3ColorSensor.java:318
com.google.appinventor.components.runtime.util.ErrorMessages
Definition: ErrorMessages.java:17
com.google.appinventor.components.runtime.util
-*- mode: java; c-basic-offset: 2; -*-
Definition: AccountChooser.java:7
com.google.appinventor.components.runtime.LegoMindstormsEv3Base.bluetooth
BluetoothClient bluetooth
Definition: LegoMindstormsEv3Base.java:30
com.google.appinventor.components.runtime.Ev3ColorSensor.onDelete
void onDelete()
Definition: Ev3ColorSensor.java:463
com.google.appinventor.components.common.YaVersion
Definition: YaVersion.java:14
com.google.appinventor.components.annotations.DesignerProperty
Definition: DesignerProperty.java:25
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.Ev3ColorSensor.GetLightLevel
int GetLightLevel()
Definition: Ev3ColorSensor.java:132
com.google.appinventor.components.runtime.Ev3ColorSensor.SetColorMode
void SetColorMode()
Definition: Ev3ColorSensor.java:410
com.google.appinventor.components.runtime.Ev3ColorSensor.BelowRange
void BelowRange()
Definition: Ev3ColorSensor.java:232
com.google.appinventor.components.runtime.LegoMindstormsEv3Sensor.readInputPercentage
final int readInputPercentage(String functionName, int layer, int no, int type, int mode)
Definition: LegoMindstormsEv3Sensor.java:61
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.Ev3ColorSensor.WithinRangeEventEnabled
boolean WithinRangeEventEnabled()
Definition: Ev3ColorSensor.java:243
com.google.appinventor.components.runtime.Ev3ColorSensor.WithinRange
void WithinRange()
Definition: Ev3ColorSensor.java:259
com.google.appinventor.components.runtime.Ev3ColorSensor.BottomOfRange
int BottomOfRange()
Definition: Ev3ColorSensor.java:172
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.Ev3ColorSensor.TopOfRange
void TopOfRange(int topOfRange)
Definition: Ev3ColorSensor.java:205
com.google.appinventor.components.runtime.Ev3ColorSensor.AboveRangeEventEnabled
void AboveRangeEventEnabled(boolean enabled)
Definition: Ev3ColorSensor.java:281
com.google.appinventor.components.runtime.Ev3ColorSensor.SetAmbientMode
void SetAmbientMode()
Definition: Ev3ColorSensor.java:436
com.google.appinventor.components.runtime.Ev3ColorSensor.ColorChangedEventEnabled
boolean ColorChangedEventEnabled()
Definition: Ev3ColorSensor.java:297
com.google.appinventor.components.runtime.Ev3ColorSensor.BelowRangeEventEnabled
boolean BelowRangeEventEnabled()
Definition: Ev3ColorSensor.java:216
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.Ev3ColorSensor.GetColorName
String GetColorName()
Definition: Ev3ColorSensor.java:156
com.google.appinventor.components.annotations.SimpleProperty
Definition: SimpleProperty.java:23
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.Ev3ColorSensor.WithinRangeEventEnabled
void WithinRangeEventEnabled(boolean enabled)
Definition: Ev3ColorSensor.java:254
com.google.appinventor.components.runtime
Copyright 2009-2011 Google, All Rights reserved.
Definition: AccelerometerSensor.java:8
com.google.appinventor.components.runtime.Ev3ColorSensor.BelowRangeEventEnabled
void BelowRangeEventEnabled(boolean enabled)
Definition: Ev3ColorSensor.java:227
com.google.appinventor.components.runtime.LegoMindstormsEv3Sensor
Definition: LegoMindstormsEv3Sensor.java:24
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.Ev3ColorSensor.AboveRange
void AboveRange()
Definition: Ev3ColorSensor.java:286
com.google.appinventor.components.runtime.Ev3ColorSensor.SetReflectedMode
void SetReflectedMode()
Definition: Ev3ColorSensor.java:423
com.google.appinventor.components.runtime.Form.dispatchErrorOccurredEvent
void dispatchErrorOccurredEvent(final Component component, final String functionName, final int errorNumber, final Object... messageArgs)
Definition: Form.java:1011
com.google.appinventor.components.annotations.SimpleObject
Definition: SimpleObject.java:23
com.google.appinventor.components.runtime.Ev3ColorSensor
Definition: Ev3ColorSensor.java:37
com.google.appinventor.components.runtime.Ev3ColorSensor.Mode
String Mode()
Definition: Ev3ColorSensor.java:402
com.google.appinventor.components.runtime.Ev3ColorSensor.AboveRangeEventEnabled
boolean AboveRangeEventEnabled()
Definition: Ev3ColorSensor.java:270
com.google
com
com.google.appinventor.components.runtime.Ev3ColorSensor.GetColorCode
int GetColorCode()
Definition: Ev3ColorSensor.java:144
com.google.appinventor.components.runtime.util.ErrorMessages.ERROR_EV3_ILLEGAL_ARGUMENT
static final int ERROR_EV3_ILLEGAL_ARGUMENT
Definition: ErrorMessages.java:216
com.google.appinventor.components.runtime.AndroidNonvisibleComponent.form
final Form form
Definition: AndroidNonvisibleComponent.java:19
com.google.appinventor.components.runtime.Ev3ColorSensor.Mode
void Mode(String modeName)
Definition: Ev3ColorSensor.java:388
com.google.appinventor.components.runtime.Ev3ColorSensor.TopOfRange
int TopOfRange()
Definition: Ev3ColorSensor.java:194
com.google.appinventor.components.runtime.Ev3ColorSensor.Ev3ColorSensor
Ev3ColorSensor(ComponentContainer container)
Definition: Ev3ColorSensor.java:67
com.google.appinventor.components.runtime.Ev3ColorSensor.BottomOfRange
void BottomOfRange(int bottomOfRange)
Definition: Ev3ColorSensor.java:183
com.google.appinventor.components.common.PropertyTypeConstants
Definition: PropertyTypeConstants.java:14
com.google.appinventor.components.annotations
com.google.appinventor.components.runtime.Ev3ColorSensor.ColorChangedEventEnabled
void ColorChangedEventEnabled(boolean enabled)
Definition: Ev3ColorSensor.java:308
com.google.appinventor