NAV
Swift Java

Welcome

Welcome to Mudra SDK. This document enables creating your own unique experiences based on the Mudra Band™ and Mudra API. Here we will explain how to use the band as well as interface with your device. Our API includes language bindings for Swift (iOS), Java (Android) and C# (Unity Plugin). You can find links to a sample application for each of iOS, Android or Unity under the Sample Applications section.

Device Led Status

Band Wearing

To put on the wristband correctly, make sure to check whether the logo is positioned on the left or right hand.

Access the API

iOS

Android

// gradle.properties file:
authToken=<Your Jitpack Token>


// settings.gradle file:
dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
        maven { url 'https://jitpack.io'
            credentials { username authToken }}
    }
}


// build.gradle file:
dependencies {
    .
    .
    .
    implementation 'com.github.wearable-devices:Dev_MudraAndroidSDK:1.5.11.18'
}

// manifest file:    
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

Unity

Licenses

Mudra.getLicenseForEmailFromCloud(email: "-----@------") { success , errorResult in
    if success {
        print("licenses set successfully.")
    } else {
        print("failed to set licenses : \(errorResult)")
    }

}
Mudra.getInstance().getLicenseForEmailFromCloud("-----@------", (success, errorResult) -> {
    if( success ) {
        Log.d(TAG , "licenses set successfully.");
    } else {
        Log.d(TAG , "failed to set licenses : " + errorResult +".");
    }
});

To utilize certain features of the SDK, a license is required.

  1. Sign up a new user for the MudraBand application on iOS.
  2. Contact Tom at tom.y@wearabledevices.co.il to obtain licenses for using features in the SDK.
License Features
Main Pressure, Gesture recognition, Air Mouse, ACC NORM
RawData SNC, IMU GYRO, IMU ACC

Initialization and Connection

iOS

//ContentViewModel that implements the MudraDelegate
import Mudra
import Foundation

class ContentViewModel : ObservableObject {
    static let shared = ContentViewModel()
    @Published var contentModel : ContentModel = ContentModel()

}

extension ContentViewModel: MudraDelegate {
    func onBluetoothStateChanged(_ state: Bool) {
        DispatchQueue.main.async {
            //Update the UI Here!
        }
    }

    func onDeviceConnectedByIos(_ device: MudraDevice) {
        //Event : when mudra device connects to the iPhone operating system "iOS"
        DispatchQueue.main.async {
            //Update the UI Here!
        }
    }

    func onDeviceDisconnectedByIos(_ device: MudraDevice) {
        //Event : when mudra device disconnects from the iPhone operating system "iOS"
        DispatchQueue.main.async {
            //Update the UI Here!
        }
    }

    func onMudraDeviceConnected(_ device: MudraDevice) {
        //Event : when mudra device connects to the app
        DispatchQueue.main.async {
            //Update the UI Here!
        }
    }

    func onMudraDeviceDisconnected(_ device: MudraDevice) {
        //Event : when mudra device disconnects from the app
        DispatchQueue.main.async {
            //Update the UI Here!
        }
    }

    func onBatteryLevelChanged(_ device: MudraDevice) {
        //Event : when battery level changed for connected device
        DispatchQueue.main.async {
            //Update the UI Here!
        }
    }
}

//--------------------------------------------------------------------------------------------------------------------

// AppDelegate
import Mudra
import UIKit

class AppDelegate: UIResponder, UIApplicationDelegate, ObservableObject {

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        print("application launched")
        self.setMudraDelegate()  //<--
        self.setLicense()        //<--
        self.initBluetouth()     //<--
        return true
    }

    func setMudraDelegate() {
        Mudra.shared.delegate = ContentViewModel.shared  //<-- "ContentViewModel which implements the MudraDelegate"
    }

    func setLicense() {
        // Set your licenses (sent by Wearable Devices for expanded features)
        Mudra.getLicenseForEmailFromCloud(email: "-----@------") { success , errorResult in
            if success {
                print("licenses set successfully.")
            } else {
                print("failed to set licenses : \(errorResult)")
            }

        }
    }

    func initBluetouth() {
        print("initBlueTouth")
        Mudra.shared.initBluetouth()
    }
}


Event Description
func onBluetoothStateChanged(_ state: Bool) Called when the bluetooth state is changed. When the bluetooth is turened on/off the state becomes true/false.
func onDeviceConnectedByIos(_ device: MudraDevice) Called for each device which appeared as connected on the iOS BLE settings. This callback is called right after the bluetooth is finished Initializing (2).
func onDeviceDisconnectedByIos(_ device: MudraDevice) Called when a device is disconnected by the iOS.
func onMudraDeviceConnected(_ device: MudraDevice) Called when a device is connected to the application.
func onMudraDeviceDisconnected(_ device: MudraDevice) Called when a device is disconnected by the application.
func onBatteryLevelChanged(_ device: MudraDevice) Called when the battery level is changed.
Description Function
To connect a device call the connect function device.connect()
To disconnect a device call the disconnect function device.disconnect()

Android

public class MainActivity extends AppCompatActivity {

    private ActivityMainBinding binding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        binding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());
        initializeMudra();
    }

    private void initializeMudra()
    {
        Mudra.getInstance().requestAccessPermissions(this);
        Mudra.getInstance().getLicenseForEmailFromCloud("-----@------", (success, errorResult) -> {
            if( success ) {
                Log.d(TAG , "licenses set successfully.");
            } else {
                Log.d(TAG , "failed to set licenses : " + errorResult +".");
            }
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }
}
Event Description
public void onDeviceDiscovered(MudraDevice mudraDevice) Called when a device is discoverd by the application.
public void onDeviceConnected(MudraDevice mudraDevice) Called when a device is connected to the application.
public void onDeviceDisconnected(MudraDevice mudraDevice) Called when a device is disconnected by the application.
Description Function
To connect a device call the connect function mudraDevice.connect(Context context)
To disconnect a device call the disconnect function mudraDevice.disconnect()
To scan for a Mudra device Mudra.getInstance().scan(Context context);
To stop scaning for a Mudra device Mudra.getInstance().stopScan();
To get the paried Mudra devices to the OS Mudra.getInstance().getBondedDevices(Context context);
//--------------------------------------------------------------------------------------------------------------------
private void setMudraDelegate() {
    Mudra.getInstance().setMudraDelegate(new MudraDelegate() {
        @Override
        public void onDeviceDiscovered(MudraDevice mudraDevice) {

        }

        @Override
        public void onDeviceConnected(MudraDevice mudraDevice) {

        }

        @Override
        public void onDeviceDisconnected(MudraDevice mudraDevice) {

        }
    });
}

Unity

Function Description
public void SetAirmouseState(bool state) Sets airmouse on/off.
public void SetScale(int scale) Sets the pressure scale.
public void SetPressureSensitivity(int sens) Sets the pressure sensitivity.
public void SetAirMouseSpeed(int speed) Set the airmouse speed.
public void SetHand(int hand) Set the main hand of the user.

General

MudraDevice properties

mudraDevice.battery // Int, Indicating the device's battery level.

mudraDevice.firmwareVersion // Optinal String, Indicating the device's firmware version, or **nil** in case there is no firmware version.

mudraDevice.serialNumber // Optinal Int, Indicating the device's serial number, or **nil** in case there is no serial number.

mudraDevice.bandNumber // Optinal String, Indicating the device's bandNumber, or **nil** in case there is no band number.
mudraDevice.getBatteryLevel() // int, Returns the device's battery level.

mudraDevice.getFirmwareVersion() // String, Returns the device's firmware version, returns **empty string** in case there is no firmware version.

mudraDevice.getSerialNumber() // long, Returns the device's the device's serial number, or **0** in case there is no serial number.

mudraDevice.getDeviceNumberByName() // String, Returns the device's band number, or **0** in case there is no band number.

Once you have acquired the MudraDevice, you can request additional information from the device by accessing the following properties:

General Events

mudraDevice.setOnChargingStatusChanged { isCharging in

}

mudraDevice.setOnBatteryLevelChangedCallBack{ batteryLevel in

}

mudraDevice.setOnFirmwareVersionReceivedCallBack{ version in

}

mudraDevice.setOnChargingStatusChange(new OnChargingStatusChanged() {
    @Override
    public void run(boolean isCharging) {

    }
});

mudraDevice.setOnFirmwareVersionRead(new OnFirmwareVersionRead() {
    @Override
    public void run(String firmware) {

    }
});

mudraDevice.setOnBatteryLevelChanged(new OnBatteryLevelChanged() {
    @Override
    public void run(int batteryLevel) {

    }
});

Once you have obtained the MudraDevice, you can register to receive notifications for various events that occur on the device:

  1. Charging State Change: This event is triggered whenever the MudraDevice is connected to or disconnected from the charger.

  2. Battery Level Change: This event occurs whenever there is a change in the battery level.

  3. Firmware Version Update: This event is triggered when the firmware version has been successfully retrieved.

Set Hand

//To set hand
mudraDevice.hand = .Right
mudraDevice.hand = .Left
//To set hand
mudraDevice.setHand(HandType.RIGHT);
mudraDevice.setHand(HandType.LEFT);

When the device is connected, you need to update its settings via the API depending on whether you wear the band on your left or right hand.

AI_Models

//To change the algorithm model
mudraDevice.setModelType(.NeuralClicker);
mudraDevice.setModelType(.Embedded);
//To change the algorithm model
mudraDevice.setModelType(ModelType.NeuralClicker);
mudraDevice.setModelType(ModelType.Embedded);

It is possible to change the AI algorithem that runs "Under the hood".

Sensors

SNC

//To enable register, for the callback.
mudraDevice.setOnSncPackageReady{ (timestamp,data) in
    // data's length is 24
    // [0-7)   is SNC_1
    // [8-15)  is SNC_2
    // [15-23) is SNC_3
}

//To disable put nil.
mudraDevice.setOnSncPackageReady(nil)

//To check if the callback is set.
mudraDevice.onSncBlock != nil // returns true in case the callback is set, false otherwise.
//To enable register, for the callback.
mudraDevice.setOnSncReady(new OnSncReady() {
    @Override
    public void run(long timestamp, float[] data) {
        // data's length is 24
        // [0-7)   is SNC_1
        // [8-15)  is SNC_2
        // [15-23) is SNC_3

    }
});

//To disable put null.
mudraDevice.setOnSncReady(null)

//To check if the callback is set.
mudraDevice.isOnSncCallbackSet(); // returns true in case the callback is set, false otherwise.

Functionality for exposing raw SNC (Surface Nerve Conductance) sensor values. This function may incur an additional fee (We will send a license with instructions for those who are interested in this functionality).

Gyroscope

//To enable register, for the callback.
mudraDevice.setImuGyroReady{ (timestamp,data) in
        // data's length is 24
        // [0, 3, 6, 9 , 12, 15, 18, 21]   is GYRO_1
        // [1, 4, 7, 10, 13, 16, 19, 22]   is GYRO_2
        // [2, 5, 8, 11, 14, 17, 20, 23]   is GYRO_3
}

//To disable put nil.
mudraDevice.setImuGyroReady(nil)

//To check if the callback is set.
mudraDevice.onImuGyroBlock != nil // returns true in case the callback is set, false otherwise.
//To enable register, for the callback.
mudraDevice.setOnImuGyroReady(new OnImuGyroReady() {
        @Override
        public void run(long timestamp, float[] data) {
        // data's length is 24
        // [0, 3, 6, 9 , 12, 15, 18, 21]   is GYRO_1
        // [1, 4, 7, 10, 13, 16, 19, 22]   is GYRO_2
        // [2, 5, 8, 11, 14, 17, 20, 23]   is GYRO_3

        }
});

//To disable put null.
mudraDevice.setOnImuGyroReady(null)

//To check if the callback is set.
mudraDevice.isOnImuGyroCallbackSet(); // returns true in case the callback is set, false otherwise.

Functionality for exposing raw GYRO (Gyroscope) sensor values. This function may incur an additional fee (We will send a license with instructions for those who are interested in this functionality).

Accelerometer

//To enable register, for the callback.
mudraDevice.setImuAccRawReady{ (timestamp,data) in
        // data's length is 24
        // [0, 3, 6, 9 , 12, 15, 18, 21]   is ACC_1
        // [1, 4, 7, 10, 13, 16, 19, 22]   is ACC_2
        // [2, 5, 8, 11, 14, 17, 20, 23]   is ACC_3

}

//To disable put nil.
mudraDevice.setImuAccRawReady(nil)

//To check if the callback is set.
mudraDevice.onImuAccRawBlock != nil // returns true in case the callback is set, false otherwise.
//To enable register, for the callback.
mudraDevice.setOnImuAccRawReady(new OnImuGyroReady() {
        @Override
        public void run(long timestamp, float[] data) {
        // data's length is 24
        // [0, 3, 6, 9 , 12, 15, 18, 21]   is ACC_1
        // [1, 4, 7, 10, 13, 16, 19, 22]   is ACC_2
        // [2, 5, 8, 11, 14, 17, 20, 23]   is ACC_3

        }
});

//To disable put null.
mudraDevice.setOnImuAccRawReady(null)

//To check if the callback is set.
mudraDevice.isOnImuAccRawCallbackSet(); // returns true in case the callback is set, false otherwise.

Functionality for exposing raw ACC (Accelerometer Characterization Capability) sensor values. This function may incur an additional fee (We will send a license with instructions for those who are interested in this functionality).

Accelerometer Norm

//To enable register, for the callback.
mudraDevice.setOnImuAccNormPackageReady{ (timestamp,data) in

}

//To disable put nil.
mudraDevice.setOnImuAccNormPackageReady(nil)

//To check if the callback is set.
mudraDevice.onImuAccNormBlock != nil // returns true in case the callback is set, false otherwise.
//To enable register, for the callback.
mudraDevice.setOnImuAccNormReady(new OnImuAccNormReady() {
        @Override
        public void run(long timestamp, float[] floats) {

        }
});

//To disable put null.
mudraDevice.setOnImuAccNormReady(null)

//To check if the callback is set.
mudraDevice.isOnImuAccNormCallbackSet(); // returns true in case the callback is set, false otherwise.

Returns the Root Mean Square (RMS) value of the three-axis (X, Y, Z) acceleration measurements, which are normalized for gravity. Removing the effects of gravity from the acceleration data, providing a more accurate representation of the band motion in three dimensions.

Features

Pressure Level

//To enable register, for the callback.
mudraDevice.setOnProportionalReady{ (pressure) in  

}

//To disable put nil.
mudraDevice.setOnProportionalReady(nil)

//To check if the callback is set.
mudraDevice.onProportionalBlock != nil // returns true in case the callback is set, false otherwise.
//To enable register, for the callback.
mudraDevice.setOnPressureReady(new OnPressureReady() {
    @Override
    public void run(float pressure) {

    }
});

//To disable put null.
mudraDevice.setOnPressureReady(null)

//To check if the callback is set.
mudraDevice.isOnPressureReadySet(); // returns true in case the callback is set, false otherwise.

In order to esstimate the amount of finger tip pressure, use the descriped API. The returned pressure parameter indecates 1.0 for the most amount of pressure while 0.0 indecates the lowest.

Gesture Recognition

//To register for tap event:
mudraDevice.setOnAirMouseButtonChanged{ buttonEvent in 
    // buttonEvent == .Release, in case release event
    // buttonEvent == .Press, in case press event
}
//To register for tap event:
lastConnectedDevice.setOnAirMouseButtonChanged(new OnAirMouseButtonChanged() {
    @Override
    public void run(AirMouseCommand command) {
        // buttonEvent == AirMouseCommand.Release, in case release event
        // buttonEvent == AirMouseCommand.Press, in case press event
    }
});

To register for an event that is triggered whenever the chosen model detects a click or release, you can use the following approach:

mudraDevice.setAirMousePointerActive(active: true)   // to enable the air-mouse pointer
mudraDevice.setAirMousePointerActive(active: false)  // to disbale the air-mouse pointer

//In order to check if the air-mouse pointer is enabled
mudraDevice.isAirMousePointerActive
mudraDevice.setAirMousePointerActive(true); // to enable the air-mouse pointer
mudraDevice.setAirMousePointerActive(false); // to disbale the air-mouse pointer

//In order to check if the air-mouse pointer is enabled
mudraDevice.isAirMousePointerActive() 

To activate the Air-Mouse-Pointer, you need to execute the following command:

HID commands

Mouse Left Button Action

//To trigger a "Press" or "Release" action in your application, you can use the appropriate API methods provided by the mudraDevice. Here's how you can implement them:
mudraDevice.sendAirMouseButton(.Release); // This line sends a release command
mudraDevice.sendAirMouseButton(.Press);   // This line sends a press command
//To trigger a "Press" or "Release" action in your application, you can use the appropriate API methods provided by the mudraDevice. Here's how you can implement them:
mudraDevice.sendAirMouseButton(AirMouseCommand.Release); // This line sends a release command
mudraDevice.sendAirMouseButton(AirMouseCommand.Press);   // This line sends a press command

Using mouse profile, supporting left button press and release.

Experiences

Air-Touch

mudraDevice.setAirMousePointerActive(active: true)   // To activate the Air-Mouse-Pointer
mudraDevice.setAirMousePressReleaseActive(active: true)   // To activate press and release


mudraDevice.setAirMousePointerActive(active: false)  // To deactivate the Air-Mouse-Pointer
mudraDevice.setAirMousePressReleaseActive(active: false)   // To deactivate press and release


//To verify if these commands are enabled, execute the following command:
mudraDevice.isAirMousePointerActive
mudraDevice.isAirMousePressReleaseActive
mudraDevice.setAirMousePointerActive(true); // To activate the Air-Mouse-Pointer
mudraDevice.setAirMousePressReleaseActive(false); // To activate press and release


mudraDevice.setAirMousePointerActive(true);  // To deactivate the Air-Mouse-Pointer
mudraDevice.setAirMousePressReleaseActive(false);   // To deactivate press and release


//To verify if these commands are enabled, execute the following command:
mudraDevice.isAirMousePointerActive() 
mudraDevice.isAirMousePressReleaseActive() 

Enable or disable the air touch.

When the Air-Touch is enabled, the device start to simulate mouse actions like clicks or movements. The device then sends the clicks and movement to any operating system using the HID (Human Interface Device) protocol.

Sample Applications

Troubleshooting

Problem OS Solution
Mudra does not connect to host device Android Check your Bluetooth version, we recommend 4.2 and above.
Mudra does not connect to host device All Check if your device's LED flashes red, if so recharge (LED will flash blue)
Mudra gestures are not correctly recognize All Make sure that the electrodes are in contact with your skin.
Missing dll error Unity Make sure installation created an environment variable path and unpacked the dlls inside. If not, try running Setup.msi as administrator

Please contact support@wearabledevices.co.il for any additional questions or suggestions.