Internet of Things

Develop Wi-Fi, BLE, MQTT in iOS and iPadOS, Android, and Windows.
Everything could be connected. Everything shall be connected.

Bluetooth Low Energy

Compared to Classic Bluetooth, Bluetooth Low Energy or BLE is intended to provide considerably reduced power consumption and cost while maintaining a similar communication range. Mobile operating systems including iOS, Android and Windows Phone, as well as macOS, Linux, Windows 8 and Windows 10, natively support Bluetooth Low Energy.


Central in Android with Java to control BLE swarmusing android.bluetooth

1. Set Variables
Code in BluetoothLeActivity:
BluetoothManager mBluetoothManager = getSystemService( Context.BLUETOOTH_SERVICE );

BluetoothAdapter mBluetoothAdapter = mBluetoothManager.getAdapter( );

BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback(){};

2. Scan BLE devices
Code in BluetoothLeActivity:
// Start to Scan
mBluetoothAdapter.startLeScan( mLeScanCallback );

// Call back when Devices are found
mLeScanCallback. onLeScan  ( BluetoothDevice device, int rssi , byte[] scanRecord )  {
         // Saved in Array
         mName[] = device.getName();
         mAddress[] = device.getAddress();
         mRSSI[] = rssi;
}

3. Bind Android Service ( BluetoothLeActivity ) with Android Activity ( BluetoothLeService )
Code in BluetoothLeActivity:
BluetoothLeService mBluetoothLeService;
ServiceConnection mServiceConnection =
new ServiceConnection() {};
Intent mGattServiceIntent =
new Intent( this, mBluetoothLeService.class );
bindService( mGattServiceIntent, mServiceConnection, BIN_AUTO_CREATE );
// Fire automatically
mServiceConnection.onServiceConnected   ( ComponentName componentName, IBinder service ) { 
        mBluetoothLeService = service.getService();
        mBluetoothLeService.initialize();
}
Code in BluetoothLeService:
initialize() {
  BluetoothManager nBluetoothManager =
  getSystemService   
  ( Context.BLUETOOTH_SERVICE );
  BluetoothAdapter nBluetoothAdapter =
  nBluetoothManager.getAdapter();
}

// Fire automatically
Ibinder nIBinder = new LocalBinder(); 
onBind( Intent intent ) {
	return nIBinder; 
}
LocalBinder(  ) { 
   	BluetoothLeService getService(){
	  	return BluetoothLeServie.this
	}
}

4. Connect
Code in BluetoothLeActivity:
// Connect to 1st Device
mBluetoothLeService.connect( mAddress[0], 1);
// Connect to 2nd Device
mBluetoothLeService.connect( mAddress[1], 2);
…
Code in BluetoothLeService:
// Each device has its own BLE GATT and BLE Service
BluetoothGatt[] nBluetoothGatt;

BluetoothGattCallback nBluetoothGattCallback = BluetoothGattCallback(){};


connect( String address, int n ) {  
    nAddress[n-1] = address;    
    BluetoothDevice device = 
    nBluetoothAdapter.getRemoteDevice( address );
    nBluetoothGatt[n-1] = 
    device.connectGatt( Context this, Boolean 
    autoConnect false, BluetoothGattCallback 
    nBluetoothGattCallback);
}


// Fire automatically
nBluetoothGattCallback() {
onConnectionStateChange( BluetoothGatt gatt, int status, int newState ) { 
  if( status == BluetoothGatt.GATT_SUCCESS ) {
    if ( newState == STATE_CONNECTED ) {
      if( gatt.getDevice().getAddress() == naddress[0] )   
      { nBluetoothGatt[0]. discoverServices(); }
      if( gatt.getDevice().getAddress() == naddress[1] )   
      { nBluetoothGatt[1]. discoverServices(); }
      …
    }
   }
  }
}

5. Search for BLE Service and BLE Characteristics
Code in BluetoothLeActivity:
// Automatically Search for BLE Service and BLE Characteristics
…
Code in BluetoothLeService:
// Each BLE Service has its own BLE Characteristics
BluetoothGattCharacteristic[] nNotifyCharacteristic;
BluetoothGattCharacteristic[] nWriteCharacteristic;
BluetoothGattCharacteristic[] nReadCharacteristic;


// Fire automatically
nBluetoothGattCallback() {
  onServicesDiscovered( BluetoothGatt gatt, int status ) { 
     if ( status == BluetoothGatt.GATT_SUCCESS )  {
      BluetoothGattService service =       
      BluetoothGatt.getService( UUID.fromString(XXXX) );
       if ( service !=  null ) {  //  go on to get characteristic
          if ( gatt.getDevice().getAddress() == nAddress[0] ) {
 	 nNotifyCharacteristic[0] = service.getCharacteristic(UUID.fromString(XXXX));
	 nWriteCharacteristic[0] =   service.getCharacteristic(UUID.fromString(XXXX));
          	 nReadCharacteristic[0] =   service.getCharacteristic(UUID.fromString(XXXX));
          }
         if ( gatt.getDevice().getAddress() == nAddress[1] ) {
	 nNotifyCharacteristic[1] = service.getCharacteristic(UUID.fromString(XXXX));
	 nWriteCharacteristic[1] =   service.getCharacteristic(UUID.fromString(XXXX));
          	 nReadCharacteristic[1] =   service.getCharacteristic(UUID.fromString(XXXX)); 	
         }
       }
     }
  }
}

6. Send Messages
Code in BluetoothLeActivity:
// Send Data to 1st Device
mBluetoothLeService.writeData( 1, data ) 
// Send Data to 2nd Device
mBluetoothLeService.writeData( 2, data ) 
…
Code in BluetoothLeService:
writeData( int n, byte[] data ) {
  nWriteCharacteristic[n].setValue( data );  
  nBluetoothGatt[n].writeCharacteristic  
  ( nWriteCharacteristic[n] );
}


// Fire automatically
nBluetoothGattCallback() { 
  onCharacteristicWrite(BluetoothGatt gatt, 
  BluetoothGattCharacteristic characteristic, 
  int status) {
     if (status == BluetoothGatt.GATT_SUCCESS)   
     {  }
   }
}

7. Receive Messages
Code in BluetoothLeActivity:
// Read Data from 1st Device
mBluetoothLeService.readData ( 1, true );

// Read Data from 2nd Device
mBluetoothLeService.readData ( 2, true );

Code in BluetoothLeService:
readData( int n, Boolean state) {
    if(state) {
      setCharacteristicNotification    
      ( mNotifyCharacteristic[n-1],true );
      nBluetoothGatt[n-1].readCharacteristic 
      ( mNotifyCharacteristic[n-1] );
  }
  else {
      nBluetoothGatt[n-1].   
      setCharacteristicNotification 
      ( mNotifyCharacteristic[n-1],false );
  }
}

// Feedback data to Android Activity with Broadcasting
// Fire automatically
nBluetoothGattCallback() {

  // case 1
  onCharacteristicRead (BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
     if ( status == BluetoothGatt.GATT_SUCCESS ) {   
       if ( gatt.getDevice().getAddress() == nAddress[0] ) {
          broadcastUpdate(ACTION_DATA_AVAILABLE_1, 
          characteristic);
       }
       if ( gatt.getDevice().getAddress() == nAddress[1] )  {  
         broadcastUpdate(ACTION_DATA_AVAILABLE_2, 
         characteristic);
       }
     }
  }
  
  // case 2
  onCharacteristicChanged (BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
     if ( status == BluetoothGatt.GATT_SUCCESS ) {   
       if ( gatt.getDevice().getAddress() == nAddress[0] ) {
          broadcastUpdate(ACTION_DATA_AVAILABLE_1, 
          characteristic);
       }
       if ( gatt.getDevice().getAddress() == nAddress[1] )  {  
         broadcastUpdate(ACTION_DATA_AVAILABLE_2, 
         characteristic);
       }
     }
  }
  
}

// This function send message from Android Service to Android Activity
broadcastUpdate (String action, BluetoothGattCharacteristic characteristic) {
	final Intent intent = new Intent(action);
	if ( UUID.fromString(XXXX).equals( characteristic.getUuid() ) ) {
		final byte[] data = characteristic.getValue();
		if (data != null && data.length > 0) {
			intent.putExtra(EXTRA_DATA,data);
		}
	}
	sendBroadcast(intent);
}

8. Disconnect
Code in BluetoothLeActivity:
// Disconnect from 1st Device
mBluetoothLEService. Disconnect(1);

// Disconnect from 2nd Device
mBluetoothLEService.disconnect(2);
…

// Unbind
unbindService( mServiceConnection );
mBluetoothLeService = null;
Code in BluetoothLeService:
disconnect (int n) {

     nBluetoothGatt[n-1].disconnect();

}



Central in iOS and iPadOS with Swift to control BLE swarm using CoreBluetooth

1. Set Variables
// Central Device
var mCentralManager: CBCentralManager!

// Peripheral Devices
Var mPeripheral_1: CBPeripheral!
Var mPeripheral_2: CBPeripheral!
…

// Identifier of Peripheral
var mUUID_1: UUID
var mUUID_2: UUID
…

// Service
Var mService_1: CBService!
Var mService_2: CBService!
…
  
// Characteristic
Var mWriteCharacteristic_1: CBCharacteristic!
Var mReadCharacteristic_1: CBCharacteristic!
Var mNotifyCharacteristic_1: CBCharacteristic!
…
Var mWriteCharacteristic_2: CBCharacteristic!
Var mReadCharacteristic_2: CBCharacteristic!
Var mNotifyCharacteristic_2: CBCharacteristic!
…

2. Scan BLE devices
// Initial Central Device
self.mCentralManager = CBCentralManager(delegate: self, queue: nil)
…


// Check Bluetooth Hardwire State
// Fire automatically
func centralManagerDidUpdateState(_ central: CBCentralManager) {

      switch( central.state ){
       	case CBManagerState.poweredOn:
        // Scan
        self.mCentralManager.scanForPeripherals(withServices: nil, options: nil)
      }

}


// Response when discovered Bluetooth Device Pepherial
// Fire automatically
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {

  // UUID of peripheral, name, RSSI
  // 1st Callback
  mPeripheral_1 = peripheral
  mUUID_1 = mPeripheral_1.identifier
  // 2nd Callback
  mPeripheral_2 = peripheral
  mUUID_2 = mPeripheral_2.identifier
  
  …
  
}

3. Connect
// Connect to mPeripheral_1
mCentralManager.connect(mperipheral_1, options: nil)

// Connect to mPeripheral_2
mCentralManager.connect(mperipheral_2, options: nil)

…

// Response when connected to a Bluetooth Device Pepherial
// Fire automatically
func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {

   if( peripheral.identifier == mUUID_1){

   		// mPeripheral_1 is connected
   }

   if( peripheral.identifier == mUUID_2){

		// mPeripheral_2 is connected
   }
    
   …
   
}
// Check the connect state of Peripheral

mPeripheral_1.discoverServices(nil)

mPeripheral_2.discoverServices(nil)


// Response to discover Service
func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) { 
  if( peripheral == mPeripheral_1 ){             
    if( peripheral.services?.count != 0 )
		for service in peripheral.services! {
			if service.uuid.uuidString.contains(“XXXX"){
			  	mService_1 = service as CBService
           		// Discovered Servie “XXXX"
           		// go on to discover Characteristic
				peripheral.discoverCharacteristics(nil, for: service)                  
           }                
     }
  }
}


// Response to discover Service
func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) { 
  if( peripheral == mPeripheral_2 ){             
    if( peripheral.services?.count != 0 )
		for service in peripheral.services! {
			if service.uuid.uuidString.contains(“XXXX"){
			  	mService_2 = service as CBService
           		// Discovered Servie “XXXX"
           		// go on to discover Characteristic
				peripheral.discoverCharacteristics(nil, for: service)                  
           }                
     }
  }
}
// Response to discover Characteristic

func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {

 if( peripheral == mPeripheral_1 ){
  if( service.characteristics!.count != 0 ){
   for Characterisitc in service.characteristics!{
     let mCharacteristic: CBCharacteristic = Characterisitc as CBCharacteristic
     if( mService_1 != nil ){
      if( mService_1 == service ){
       if( mCharacteristic.uuid.uuidString.contains(“xxxx") ){
         mNotifyCharacteristic_1 = mCharacteristic
       }
       if( mCharacteristic.uuid.uuidString.contains(“xxxx") ){
         mWriteCharacteristic_1 = mCharacteristic
       }
	      if( mCharacteristic.uuid.uuidString.contains(“xxxx") ){
         mReadCharacteristic_1 = mCharacteristic
       }
      }
     }
   }
  }
 }

 if( peripheral == mPeripheral_2 ){
  if( service.characteristics!.count != 0 ){
   for Characterisitc in service.characteristics!{
     let mCharacteristic: CBCharacteristic = Characterisitc as CBCharacteristic
     if( mService_2 != nil ){
      if( mService_2 == service ){
       if( mCharacteristic.uuid.uuidString.contains(“xxxx") ){
         mNotifyCharacteristic_2 = mCharacteristic
       }
       if( mCharacteristic.uuid.uuidString.contains(“xxxx") ){
         mWriteCharacteristic_2 = mCharacteristic
       }
	      if( mCharacteristic.uuid.uuidString.contains(“xxxx") ){
         mReadCharacteristic_2 = mCharacteristic
       }
      }
     }
   }
  }
 }
 
 …
 
}

4. Send Messages
// Send Messages to mPeripheral_1

DispatchAfter(after: 0.0) {
	self.mPeripheral_1.setNotifyValue(false, for: self.mNotifyCharacteristic_1)
}
                
DispatchAfter(after: 0.2) {
	self.mPeripheral_1.writeValue(writedata, for: self.mWriteCharacteristic_1, type: CBCharacteristicWriteType.withoutResponse)
}


// Send Messages to mPeripheral_2

DispatchAfter(after: 0.0) {
	self.mPeripheral_2.setNotifyValue(false, for: self.mNotifyCharacteristic_2)
}
                
DispatchAfter(after: 0.2) {
	self.mPeripheral_2.writeValue(writedata, for: self.mWriteCharacteristic_2, type: CBCharacteristicWriteType.withoutResponse)
}

…


5. Receive Messages
// Read Messages from mPeripheral_1
mPeripheral_1?.readValue(for: mReadCharacteristic_1!)

// Read Messages from mPeripheral_2
mPeripheral_2?.readValue(for: mReadCharacteristic_2!)


// Response to Read data
// Fire automatically
func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?){
  if( peripheral.identifier == mUUID_1){
   readdata1[0] = characteristic.value![0]
   readdata1[1] = characteristic.value![1]
   readdata1[2] = characteristic.value![2]
   readdata1[3] = characteristic.value![3]
   readdata1[4] = characteristic.value![4]
   readdata1[5] = characteristic.value![5]
   … 
  }

  if( peripheral.identifier == mUUID_2){
   readdata2[0] = characteristic.value![0]
   readdata2[1] = characteristic.value![1]
   readdata2[2] = characteristic.value![2]
   readdata2[3] = characteristic.value![3]
   readdata2[4] = characteristic.value![4]
   readdata2[5] = characteristic.value![5]
    …
  }
  
  …
  
}

6. Disconnect

self.mCentralManager.cancelPeripheralConnection(self.mPeripheral_1)

self.mCentralManager.cancelPeripheralConnection(self.mPeripheral_2)

…



All Core Codes