Hardware components | ||||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 2 | ||||
| × | 2 | ||||
| × | 1 | ||||
| × | 2 | ||||
| × | 22 |
Flip Intro
There is something kind of magical about swimming when you are a child. Do you remember growing up and watching your shadow as you swam in the pool, trying to mimic a perfect dolphin kick and imagining you were a mermaid rather than human? We all shared these sorts of memories and a few of us decided to create something that enhanced the sense of wonder kids’ get when they play and swim under water.
Video
Value Proposition
1. Swimming is a great form of exercise. One of the core objectives of Flip is to help kids to become healthy and competent swimmers.
2. However, another goal of this design is to make kids learn and care about water animals. Traditionally, aquariums have been a way of bringing people, and especially children, closer to sea life. By triggering a sense of wonder and appreciation in visitors, aquariums are an effective way of teaching people about sea-life preservation, and it’s also just really fun to learn about these animals and their habitats.
Ideation
We saw an opportunity to create a device that not only encouraged children to swim more, but also generated their interest in preserving sea creatures and their habitats through a fun interaction. We eventually imagined designing a pair of webbed aquatic gloves that would track acceleration. It would then sync with an educational mobile app in order to generate animal profiles real-time. Our desire is to promote learning through animal-metrics.
In our works-alike glove (see images below), we used simple material like fabric, Velcro and a pre-made fin to mock-up a simple casing that would be easy to work with.
Aqua Glove Demonstration Prototype
But for our actual prototype, we imagined using materials like silicone, which composes the glove and fin, and an elastomer material for the wristband.
The wristband houses all the hardware that stimulates the child's magical experience. It hides everything that doesn't want to be seen. The screen is the only component that is exposed, which would be waterproofed so children can, of course, swim with the glove.
Hardware/Sensors
Aqua Glove Prototype
Target Users
Our target users are children ages 4-9. On average in the United States, children learn to swim at age 4. We felt that this product would be best suited for kids who feel comfortable in the water but will be engaged with this simple interface.
Aquariums and books are great educational tools, but our product exposes kids to sea-life in a new way. By making them “feel” like they themselves ARE different animals while understanding the different marine life found in different geographies, Flip creates an experience that is highly engaging. Best of all, this product is fun and encourages kids to swim and care about sea creatures in a way that will hopefully encourage them to connect and care about their endangered habitats as they grow older.
Android & Mock ups
Arduino
Next Steps
We believe this product can be developed even further to include more opportunities for education, play, and fitness. Including additional sensors to detect water ion concentration and temperature would allow for even more advanced animals profiles. We’ve also brainstormed ways we could create interaction between multiple Flip users, allowing for a new spin on age-old favorite like sharks and minows.
#include <SPI.h>
// For Bluetooth
#include <Adafruit_BLE_UART.h>
// For Accelerometer
#include <Wire.h>
#include <Adafruit_MMA8451.h>
#include <Adafruit_Sensor.h>
// For OLED Screen
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1331.h>
// Accelerometer
Adafruit_MMA8451 accelerometer = Adafruit_MMA8451();
// Bluetooth LE
#define ADAFRUITBLE_REQ 10
#define ADAFRUITBLE_RDY 1
#define ADAFRUITBLE_RST 9
Adafruit_BLE_UART BLEserial = Adafruit_BLE_UART(ADAFRUITBLE_REQ, ADAFRUITBLE_RDY, ADAFRUITBLE_RST);
// OLED Screen
#define OLED_SCLK A0
#define OLED_MOSI A1
#define OLED_CS 8
#define OLED_RST 7
#define OLED_DC 6
// Color definitions
#define BLACK 0x0000
#define RED 0xF800
#define CYAN 0x07FF
#define YELLOW 0xFFE0
#define WHITE 0xFFFF
Adafruit_SSD1331 display = Adafruit_SSD1331(OLED_CS, OLED_DC, OLED_MOSI, OLED_SCLK, OLED_RST);
void setup(void)
{
Serial.begin(9600);
// Setup OLED
display.begin();
drawFlip();
// Setup BLE
BLEserial.setDeviceName("Flip"); // 7 Characters Max
BLEserial.begin();
// Setup Accelerometer
if (!accelerometer.begin()) {
Serial.println("Couldn't Start");
while (1);
}
Serial.println("Accelerometer Found");
accelerometer.setRange(MMA8451_RANGE_2_G);
Serial.print("Range = "); Serial.print(2 << accelerometer.getRange());
}
aci_evt_opcode_t laststatus = ACI_EVT_DISCONNECTED;
int counter = 0;
String lastMovement = "";
uint16_t time = millis();
String accel_buffer[10];
boolean sent = false;
void loop()
{
// Tell the nRF8001 to do whatever it should be working on.
BLEserial.pollACI();
// Ask what is our current status
aci_evt_opcode_t status = BLEserial.getState();
// If the status changed.
if (status != laststatus) {
if (status == ACI_EVT_DEVICE_STARTED) {
Serial.println(F("* Advertising started"));
}
if (status == ACI_EVT_CONNECTED) {
Serial.println(F("* Connected!"));
}
if (status == ACI_EVT_DISCONNECTED) {
Serial.println(F("* Disconnected or advertising timed out"));
}
laststatus = status;
}
if (status == ACI_EVT_CONNECTED) {
// Check for data
if (BLEserial.available()) {
Serial.print("* ");
Serial.print(BLEserial.available());
Serial.println(F(" bytes available from BTLE"));
}
// While there is something to read, read the next char
while (BLEserial.available()) {
char c = BLEserial.read();
Serial.print(c);
}
Serial.setTimeout(100);
if (!sent) {
bleSend();
}
// Print for Debugging
// Serial.print(F("\n* Sending -> \""));
// Serial.print((char *)sendbuffer);
// Serial.println("\"");
} else {
int index = counter % 10;
accel_buffer[index] = getAcceleration();
counter += 1;
if (counter == 10) {
counter = 0;
}
if (isMoving()) {
if (lastMovement != "m") {
drawFish();
lastMovement = "m";
time = millis();
}
} else {
if (lastMovement != "s" && (millis() - time > 2500)) {
drawStarfish();
lastMovement = "s";
}
}
}
delay(1000);
}
void bleSend()
{
int k;
for (k = 0; k < 10; k += 1) {
// Get buffer length
uint8_t sendbuffer[20];
accel_buffer[k].getBytes(sendbuffer, 20);
char sendbuffersize = min(20, accel_buffer[k].length());
// Write to BLE buffer
BLEserial.write(sendbuffer, sendbuffersize);
delay(200);
}
sent = true;
}
// Get Accelerometer Acceleration
String getAcceleration()
{
// Read the 'raw' data in 14-bit counts
accelerometer.read();
// Get a new sensor event
sensors_event_t event;
accelerometer.getEvent(&event);
// Get acceleration in m/(s^2)
float accel_x = event.acceleration.x;
float accel_y = event.acceleration.y;
float accel_z = event.acceleration.z;
String x = String(accel_x, 2);
String y = String(accel_y, 2);
String data = x + "," + y + "," + z + "\n";
return data;
}
boolean isMoving()
{
accelerometer.read();
// Get a new sensor event
sensors_event_t event;
accelerometer.getEvent(&event);
float accel_x = event.acceleration.x;
float accel_y = event.acceleration.y;
if (abs(accel_x) > 0.15 || abs(accel_y) > 0.15) {
return true;
} else {
return false;
}
}
void drawFlip(void) {
display.fillScreen(BLACK);
display.drawFastVLine(21, 17, 4, CYAN);
display.drawFastVLine(21, 40, 3, CYAN);
display.drawFastVLine(22, 17, 4, CYAN);
display.drawFastVLine(22, 40, 3, CYAN);
display.drawFastVLine(23, 18, 5, CYAN);
display.drawFastVLine(23, 36, 6, CYAN);
display.drawFastVLine(24, 20, 8, CYAN);
display.drawFastVLine(24, 31, 9, CYAN);
display.drawFastVLine(25, 20, 20, CYAN);
display.drawFastVLine(26, 21, 17, CYAN);
display.drawFastVLine(27, 25, 8, CYAN);
display.fillRect(28, 28, 14, 4, CYAN);
display.fillRect(32, 20, 5, 22, CYAN);
display.fillRect(34, 18, 9, 2, CYAN);
display.drawFastHLine(35, 17, 8, CYAN);
display.drawFastHLine(37, 16, 5, CYAN);
display.fillRect(46, 17, 4, 25, CYAN);
display.fillRect(53, 17, 4, 5, CYAN);
display.fillRect(53, 25, 4, 17, CYAN);
display.fillRect(61, 27, 4, 26, CYAN);
display.fillRect(65, 28, 2, 14, CYAN);
display.fillRect(67, 27, 2, 14, CYAN);
display.fillRect(67, 27, 7, 4, CYAN);
display.fillRect(67, 39, 7, 4, CYAN);
display.fillRect(73, 30, 3, 10, CYAN);
display.fillRect(72, 28, 3, 4, CYAN);
display.drawFastVLine(76, 32, 6, CYAN);
delay(2000);
}
void drawFish(void) {
display.fillScreen(BLACK);
display.fillRect(22, 31, 67, 5, YELLOW);
display.fillRect(23, 28, 65, 3, YELLOW);
display.fillRect(23, 36, 65, 3, YELLOW);
display.fillRect(24, 26, 63, 2, YELLOW);
display.fillRect(24, 39, 63, 2, YELLOW);
display.fillRect(25, 24, 60, 2, YELLOW);
display.fillRect(25, 41, 60, 2, YELLOW);
display.fillRect(27, 22, 56, 2, YELLOW);
display.fillRect(27, 43, 56, 2, YELLOW);
display.fillRect(30, 20, 51, 2, YELLOW);
display.fillRect(30, 45, 51, 2, YELLOW);
display.drawFastHLine(33, 19, 45, YELLOW);
display.drawFastHLine(33, 47, 45, YELLOW);
display.drawFastHLine(35, 18, 41, YELLOW);
display.drawFastHLine(35, 48, 41, YELLOW);
display.drawFastHLine(38, 17, 35, YELLOW);
display.drawFastHLine(38, 49, 35, YELLOW);
display.drawFastHLine(43, 16, 25, YELLOW);
display.drawFastHLine(43, 50, 25, YELLOW);
display.drawFastHLine(50, 15, 11, YELLOW);
display.drawFastHLine(50, 51, 11, YELLOW);
display.fillTriangle(10, 16, 28, 33, 10, 50, YELLOW);
delay(500);
}
void drawStarfish(void) {
display.fillScreen(BLACK);
display.fillRect(40, 24, 21, 20, RED);
display.fillRect(45, 9, 4, 15, RED);
display.drawPixel(41, 23, RED);
display.drawFastVLine(42, 19, 5, RED);
display.drawFastVLine(43, 15, 9, RED);
display.drawFastVLine(44, 13, 11, RED);
display.fillRect(46, 7, 2, 2, RED);
display.drawFastVLine(49, 11, 13, RED);
display.drawFastVLine(50, 15, 9, RED);
display.drawFastVLine(51, 18, 6, RED);
display.drawFastVLine(52, 22, 2, RED);
display.drawPixel(60, 23, RED);
display.fillRect(61, 23, 3, 10, RED);
display.fillRect(64, 22, 3, 9, RED);
display.drawFastVLine(67, 21, 9, RED);
display.fillRect(68, 20, 2, 9, RED);
display.drawFastVLine(70, 19, 9, RED);
display.drawFastVLine(71, 19, 7, RED);
display.drawPixel(66, 21, RED);
display.drawFastVLine(61, 33, 2, RED);
display.fillRect(72, 18, 2, 5, RED);
display.drawFastVLine(74, 18, 3, RED);
display.fillRect(56, 44, 14, 4, RED);
display.drawFastVLine(61, 38, 6, RED);
display.fillRect(62, 41, 3, 3, RED);
display.drawFastHLine(65, 43, 3, RED);
display.fillRect(70, 45, 2, 3, RED);
display.drawFastVLine(72, 46, 3, RED);
display.fillRect(60, 48, 12, 2, RED);
display.drawFastHLine(53, 44, 3, RED);
display.drawFastHLine(54, 45, 2, RED);
display.drawFastHLine(57, 48, 3, RED);
display.drawFastHLine(64, 50, 4, RED);
display.fillRect(39, 44, 9, 7, RED);
display.fillRect(37, 51, 8, 4, RED);
display.drawFastVLine(39, 41, 3, RED);
display.drawFastVLine(38, 45, 6, RED);
display.drawFastVLine(48, 44, 4, RED);
display.drawFastHLine(45, 51, 2, RED);
display.drawFastHLine(36, 55, 8, RED);
display.drawFastHLine(36, 56, 5, RED);
display.drawFastHLine(37, 57, 2, RED);
display.fillRect(34, 27, 6, 8, RED);
display.fillRect(29, 26, 5, 6, RED);
display.fillRect(25, 25, 4, 4, RED);
display.drawFastHLine(37, 35, 3, RED);
display.drawFastHLine(31, 32, 3, RED);
display.drawFastHLine(26, 29, 3, RED);
display.drawFastVLine(24, 26, 3, RED);
display.drawPixel(39, 36, RED);
display.drawPixel(33, 33, RED);
display.drawPixel(28, 30, RED);
display.drawPixel(29, 25, RED);
display.drawPixel(39, 26, RED);
delay(500);
}
package prov2.flip;
import android.app.Service;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothProfile;
import android.content.Context;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import java.util.List;
import java.util.UUID;
public class BLEService extends Service {
private final static String TAG = BLEService.class.getSimpleName();
private BluetoothManager mBluetoothManager;
private BluetoothAdapter mBluetoothAdapter;
private String mBluetoothDeviceAddress;
private BluetoothGatt mBluetoothGatt;
private int mConnectionState = STATE_DISCONNECTED;
private static final int STATE_DISCONNECTED = 0;
private static final int STATE_CONNECTING = 1;
private static final int STATE_CONNECTED = 2;
public final static String ACTION_GATT_CONNECTED =
"prov2.flip.ACTION_GATT_CONNECTED";
public final static String ACTION_GATT_DISCONNECTED =
"prov2.flip.ACTION_GATT_DISCONNECTED";
public final static String ACTION_GATT_SERVICES_DISCOVERED =
"prov2.flip.ACTION_GATT_SERVICES_DISCOVERED";
public final static String ACTION_DATA_AVAILABLE =
"prov2.flip.ACTION_DATA_AVAILABLE";
public final static String EXTRA_DATA =
"prov2.flip.EXTRA_DATA";
public final static String DEVICE_DOES_NOT_SUPPORT_UART =
"prov2.flip.DEVICE_DOES_NOT_SUPPORT_UART";
public static final UUID TX_POWER_UUID = UUID.fromString("00001804-0000-1000-8000-00805f9b34fb");
public static final UUID TX_POWER_LEVEL_UUID = UUID.fromString("00002a07-0000-1000-8000-00805f9b34fb");
public static final UUID CCCD = UUID.fromString("00002902-0000-1000-8000-00805f9b34fb");
public static final UUID FIRMWARE_REVISON_UUID = UUID.fromString("00002a26-0000-1000-8000-00805f9b34fb");
public static final UUID DIS_UUID = UUID.fromString("0000180a-0000-1000-8000-00805f9b34fb");
public static final UUID RX_SERVICE_UUID = UUID.fromString("6e400001-b5a3-f393-e0a9-e50e24dcca9e");
public static final UUID RX_CHAR_UUID = UUID.fromString("6e400002-b5a3-f393-e0a9-e50e24dcca9e");
public static final UUID TX_CHAR_UUID = UUID.fromString("6e400003-b5a3-f393-e0a9-e50e24dcca9e");
// Implements callback methods for GATT events that the app cares about. For example,
// connection change and services discovered.
private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
String intentAction;
if (newState == BluetoothProfile.STATE_CONNECTED) {
intentAction = ACTION_GATT_CONNECTED;
mConnectionState = STATE_CONNECTED;
broadcastUpdate(intentAction);
Log.i(TAG, "Connected to GATT server.");
// Attempts to discover services after successful connection.
Log.i(TAG, "Attempting to start service discovery:" +
mBluetoothGatt.discoverServices());
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
intentAction = ACTION_GATT_DISCONNECTED;
mConnectionState = STATE_DISCONNECTED;
Log.i(TAG, "Disconnected from GATT server.");
broadcastUpdate(intentAction);
}
}
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
Log.w(TAG, "mBluetoothGatt = " + mBluetoothGatt );
broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED);
} else {
Log.w(TAG, "onServicesDiscovered received: " + status);
}
}
@Override
public void onCharacteristicRead(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic,
int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
}
}
@Override
public void onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) {
broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
}
};
private void broadcastUpdate(final String action) {
final Intent intent = new Intent(action);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
private void broadcastUpdate(final String action,
final BluetoothGattCharacteristic characteristic) {
final Intent intent = new Intent(action);
// This is special handling for the Heart Rate Measurement profile. Data parsing is
// carried out as per profile specifications:
// http://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.heart_rate_measurement.xml
if (TX_CHAR_UUID.equals(characteristic.getUuid())) {
// Log.d(TAG, String.format("Received TX: %d",characteristic.getValue() ));
intent.putExtra(EXTRA_DATA, characteristic.getValue());
} else {
}
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
public class LocalBinder extends Binder {
BLEService getService() {
return BLEService.this;
}
}
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
@Override
public boolean onUnbind(Intent intent) {
// After using a given device, you should make sure that BluetoothGatt.close() is called
// such that resources are cleaned up properly. In this particular example, close() is
// invoked when the UI is disconnected from the Service.
close();
return super.onUnbind(intent);
}
private final IBinder mBinder = new LocalBinder();
/**
* Initializes a reference to the local Bluetooth adapter.
*
* @return Return true if the initialization is successful.
*/
public boolean initialize() {
// For API level 18 and above, get a reference to BluetoothAdapter through
// BluetoothManager.
if (mBluetoothManager == null) {
mBluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
if (mBluetoothManager == null) {
Log.e(TAG, "Unable to initialize BluetoothManager.");
return false;
}
}
mBluetoothAdapter = mBluetoothManager.getAdapter();
if (mBluetoothAdapter == null) {
Log.e(TAG, "Unable to obtain a BluetoothAdapter.");
return false;
}
return true;
}
/**
* Connects to the GATT server hosted on the Bluetooth LE device.
*
* @param address The device address of the destination device.
*
* @return Return true if the connection is initiated successfully. The connection result
* is reported asynchronously through the
* {@code BluetoothGattCallback#onConnectionStateChange(android.bluetooth.BluetoothGatt, int, int)}
* callback.
*/
public boolean connect(final String address) {
if (mBluetoothAdapter == null || address == null) {
Log.w(TAG, "BluetoothAdapter not initialized or unspecified address.");
return false;
}
// Previously connected device. Try to reconnect.
if (mBluetoothDeviceAddress != null && address.equals(mBluetoothDeviceAddress)
&& mBluetoothGatt != null) {
Log.d(TAG, "Trying to use an existing mBluetoothGatt for connection.");
if (mBluetoothGatt.connect()) {
mConnectionState = STATE_CONNECTING;
return true;
} else {
return false;
}
}
final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
if (device == null) {
Log.w(TAG, "Device not found. Unable to connect.");
return false;
}
// We want to directly connect to the device, so we are setting the autoConnect
// parameter to false.
mBluetoothGatt = device.connectGatt(this, false, mGattCallback);
Log.d(TAG, "Trying to create a new connection.");
mBluetoothDeviceAddress = address;
mConnectionState = STATE_CONNECTING;
return true;
}
/**
* Disconnects an existing connection or cancel a pending connection. The disconnection result
* is reported asynchronously through the
* {@code BluetoothGattCallback#onConnectionStateChange(android.bluetooth.BluetoothGatt, int, int)}
* callback.
*/
public void disconnect() {
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
Log.w(TAG, "BluetoothAdapter not initialized");
return;
}
mBluetoothGatt.disconnect();
// mBluetoothGatt.close();
}
/**
* After using a given BLE device, the app must call this method to ensure resources are
* released properly.
*/
public void close() {
if (mBluetoothGatt == null) {
return;
}
Log.w(TAG, "mBluetoothGatt closed");
mBluetoothDeviceAddress = null;
mBluetoothGatt.close();
mBluetoothGatt = null;
}
/**
* Request a read on a given {@code BluetoothGattCharacteristic}. The read result is reported
* asynchronously through the {@code BluetoothGattCallback#onCharacteristicRead(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattCharacteristic, int)}
* callback.
*
* @param characteristic The characteristic to read from.
*/
public void readCharacteristic(BluetoothGattCharacteristic characteristic) {
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
Log.w(TAG, "BluetoothAdapter not initialized");
return;
}
mBluetoothGatt.readCharacteristic(characteristic);
}
/**
* Enables or disables notification on a give characteristic.
*
* @param characteristic Characteristic to act on.
* @param enabled If true, enable notification. False otherwise.
*/
/*
public void setCharacteristicNotification(BluetoothGattCharacteristic characteristic,
boolean enabled) {
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
Log.w(TAG, "BluetoothAdapter not initialized");
return;
}
mBluetoothGatt.setCharacteristicNotification(characteristic, enabled);
if (UUID_HEART_RATE_MEASUREMENT.equals(characteristic.getUuid())) {
BluetoothGattDescriptor descriptor = characteristic.getDescriptor(
UUID.fromString(SampleGattAttributes.CLIENT_CHARACTERISTIC_CONFIG));
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
mBluetoothGatt.writeDescriptor(descriptor);
}
}*/
/**
* Enable TXNotification
*
* @return
*/
public void enableTXNotification()
{
/*
if (mBluetoothGatt == null) {
showMessage("mBluetoothGatt null" + mBluetoothGatt);
broadcastUpdate(DEVICE_DOES_NOT_SUPPORT_UART);
return;
}
*/
BluetoothGattService RxService = mBluetoothGatt.getService(RX_SERVICE_UUID);
if (RxService == null) {
showMessage("Rx service not found!");
broadcastUpdate(DEVICE_DOES_NOT_SUPPORT_UART);
return;
}
BluetoothGattCharacteristic TxChar = RxService.getCharacteristic(TX_CHAR_UUID);
if (TxChar == null) {
showMessage("Tx charateristic not found!");
broadcastUpdate(DEVICE_DOES_NOT_SUPPORT_UART);
return;
}
mBluetoothGatt.setCharacteristicNotification(TxChar,true);
BluetoothGattDescriptor descriptor = TxChar.getDescriptor(CCCD);
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
mBluetoothGatt.writeDescriptor(descriptor);
}
public void writeRXCharacteristic(byte[] value)
{
BluetoothGattService RxService = mBluetoothGatt.getService(RX_SERVICE_UUID);
showMessage("mBluetoothGatt null"+ mBluetoothGatt);
if (RxService == null) {
showMessage("Rx service not found!");
broadcastUpdate(DEVICE_DOES_NOT_SUPPORT_UART);
return;
}
BluetoothGattCharacteristic RxChar = RxService.getCharacteristic(RX_CHAR_UUID);
if (RxChar == null) {
showMessage("Rx charateristic not found!");
broadcastUpdate(DEVICE_DOES_NOT_SUPPORT_UART);
return;
}
RxChar.setValue(value);
boolean status = mBluetoothGatt.writeCharacteristic(RxChar);
Log.d(TAG, "write TXchar - status=" + status);
}
private void showMessage(String msg) {
Log.e(TAG, msg);
}
/**
* Retrieves a list of supported GATT services on the connected device. This should be
* invoked only after {@code BluetoothGatt#discoverServices()} completes successfully.
*
* @return A {@code List} of supported services.
*/
public List<BluetoothGattService> getSupportedGattServices() {
if (mBluetoothGatt == null) return null;
return mBluetoothGatt.getServices();
}
}
Comments