In this post I want to introduce a new way to use an android phone and explain how we can use it to control a Sphero ball. If you don’t know about this incredible ball take a look at Sphero site.
Plan: Control Sphero using temperature sensorIn this Android project, I want to describe how we can integrate the temperature sensor inside the smart phone to control the color of the Sphero ball. In other words, I want to change the color of the ball according to the temperature measured by the smart phone even if it's in stand by. This is an interesting project because it can be used to demonstrate some important concepts:
And finally, but not least, how to connect and use Sphero ball with its SDK. What we want to design is an app like the one shown below:
Now that we know what we want to obtain, we can mix Android features and components to get it. We need a component that monitors the temperature sensor and another one that connects to the Sphero. As said before, we want to make this work even if the app is not in the foreground or the smart phone is in standby. So we need a Service, because this Android component can fulfill our requirements. The components we will use to control the Sphero are:
- An Activity that is the app UI
- A Service that monitors the temperature sensor
- A Service that connects to the ball and controls its color
The UI activity starts two services and listens for events coming from them. The activity sets up an alarm that is used to start the temperature sensor service so that we won’t drain the battery. The alarm can be configured to start at fixed intervals. Every time the temperature sensor starts it measure the environment temperature and broadcasts the value. The UI activity listens to these events and shows the value in the UI. At the same time, the ball connection service listens for the same event and calculates the color components (R,G,B) and sets the ball's color.
Create Temperature Sensor Service: codeNow that we have an overview of the main components in our app, we can start coding it. The first element we want to code is the temperature sensor service.
Create Ball Connection Service: codeThe other service we have to implement is to handle the Sphero connection via Bluetooth. You can refer to Sphero SDK for more information. We want to handle the connection in an android service:
public class BallConnectionService extends Service {
..
}
Now in the onStartCommand
we start connecting to the Sphero and at the same time we start listening for incoming temperature events (line 8).
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (mySphero == null)
doConnection();
IntentFilter rec = new IntentFilter();
rec.addAction(SensorService.TEMP_BALL_SENSOR);
registerReceiver(receiver, rec);
return Service.START_STICKY;
}
In doConnection
we make the actual connection:
private void doConnection() {
sendStatus(CONNECTING);
createNotification("Connecting...");
RobotProvider.getDefaultProvider().addConnectionListener(new ConnectionListener() {
@Override
public void onConnected(Robot robot) {
Log.d("Temp", "Connected");
mySphero = (Sphero) robot;
sendStatus(CONNECTED);
createNotification("Connected");
}
@Override
public void onConnectionFailed(Robot robot) {
Log.d("Temp", "Conection failed");
sendStatus(FAILED);
}
@Override
public void onDisconnected(Robot robot) {
Log.d("Temp", "Disconnected");
mySphero = null;
createNotification("Disconnected!");
}
});
RobotProvider.getDefaultProvider().addDiscoveryListener(new DiscoveryListener() {
@Override
public void onBluetoothDisabled() {
Log.d("Temp", "BT Disabled");
}
@Override
public void discoveryComplete(List<Sphero> spheros) {
Log.d("Temp", "Found ["+spheros.size()+"]");
}
@Override
public void onFound(List<Sphero> spheros) {
// Do connection
Log.d("Temp", "Found ball");
RobotProvider.getDefaultProvider().connect(spheros.get(0));
}
});
boolean success = RobotProvider.getDefaultProvider().startDiscovery(this);
}
The code seems complex but it is really simple if you look at it carefully. We start broadcasting the event that we are trying to connect to the Sphero (line 3), then, using Sphere API, we register a listener to know when the connection is established and broadcast a new event that the connection is active, at the end of this method we start discovering if a new Sphero is around and ready to connect.
The last part of the service is used for listening to the temperature event and set the ball color:
private BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
float val = intent.getFloatExtra("value", 0);
Log.d("Temp", "Received value ["+val+"]");
if (mySphero != null) {
// send color to sphero
int red = (int) (255 * val / RANGE) * (val > 10 ? 1 : 0);
int green = (int) ( (255 * (RANGE - Math.abs(val)) / RANGE) * (val < 10 ? 0.2 : 1) );
int blue = (int) (255 * (10 - val) / 10) * (val < 10 ? 1 : 0);
mySphero.setColor(red, green, blue);
}
}
;
Now it is time to create the app and control Sphero using Android temperature sensor.
Comments