Coder Social home page Coder Social logo

myonnaise's Introduction

Myonnaise 🍯

projectlogo

An Android library to interact with your Thalmic Myo, written in Kotlin and using RxJava2.

This repo contains also a sample app that showcases the usage of the library: Myo EMG Visualizer. With this app you can stream EMG Raw data from your device and save it as a CSV. The app is also available on the play store:

DISCLAIMER: If you don't know what a Myo is, please go here: support.getmyo.com. Please note that you need a Myo in order to use this library/app.

Getting Started 👣

Myonnaise is distributed through JCenter. To use it you need to add the following Gradle dependency to your android app gradle file (NOT the root file).

Example 🚸

After setting up the Gradle dependency, you will be able to access two main classes: Myonnaise and Myo.

  • Myonnaise is the entry point where you can trigger a bluetooth scan to search for nearby devices. A scan will return you one or mode BluetoothDevice (from the android framework). If you don't know your Myo's address a priori, you need to show those devices to the user and allow him to pick one.

  • Myo is the class that will allow you to connect to your device, send commands and start the streaming. You need a BluetoothDevice in order to create a Myo.

Searching for a Myo

First, you need to find a Myo with a bluetooth scan.

** ⚠️ Please note that you need to request the user the ACCESS_COARSE_LOCATION permission. If not, the scan will be empty ⚠️ **

To start a bluetooth scan, you can use the startScan() method:

Myonnaise(context).startScan()
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe({
                // Do something with the found device
                println(it.address)
            })

This method will return a Flowable that will publish all the BluetoothDevice that are discovered nearby. Please note that the scan will stop only when you cancel the Flowable.

Alternatively, you can also provide a timeout and the scan will stop after the timeout:

Myonnaise(context).startScan(5, TimeUnit.MINUTES)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe({
                // Do something with the found device
                println(it.address)
            })

Once you found a BluetoothDevice that is a Myo, you can get a Myo instance from it.

val myMyo = Myonnaise.getMyo(foundDevice)

Connecting to a Myo

Connecting or disconnecting to a Myo is really easy:

// To Connect
myMyo.connect(getContext())

// To Disconnect
myMyo.disconnect()

Connecting and disconnecting are not syncronous operations. You have to wait that the device is successfully connected before start sending commands. You can get notified of status updates using the RxJava statusObservable.

myMyo.statusObservable()
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe {
            when (it) {
                MyoStatus.CONNECTED -> { ... }
                MyoStatus.CONNECTING -> { ... }
                MyoStatus.READY -> { ... }
                else -> { ... } // DISCONNECTED
            }
        }

In order to send command to your Myo, your Myo should be in the READY state. If the Myo is not ready, commands will be ignored.

Sending a Command

To send a command you can use the sendCommand() method. For example, you can let your device vibrate with:

myMyo.sendCommand(CommandList.vibration1())

Commands will be processed by the library and sent to the device (the library has a queue to process all the commands).

List of all available commands is in the CommandList.kt file.

Starting the Streaming

You can start/stop the streaming using again the sendCommand method:

// Start Streaming
myMyo.sendCommand(CommandList.emgUnfilteredOnly())

// Stop Streaming
myMyo.sendCommand(CommandList.stopStreaming())

You will start receiving the streaming of data as a Flowable<FloatArray> through the dataFlowable() method. To collect the data, just subscribe to the flowable:

myMyo.dataFlowable()
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe {
            println(it) // it is an array of 8 floats.
        }

Streaming Frequency

You can change the streaming frequency to receive less data. By default data is streamed at 200Hz (the max supported by the device). You can subsample the data if you set the frequency property:

myMyo.frequency = 50 // Streaming at 50Hz

Allowed values are from 0 (reset to default) to 200.

Keep Alive

The Myo will go to sleep if he receives no intereaction within some seconds. For this reason we are sending a CommandList.unSleep() every 10 seconds, in order to keep the connection always on.

If you don't want this behavior, just turn off the keep alive:

myMyo.keepAlive = false

Features 🎨

  • 100% Kotlin (but you don't need Kotlin to use it)!
  • Uses RxJava. You don't need to poll for status update, the library will call you.
  • Unleash the full Myo power, Raw Data Streaming at 200Hz! 💪
  • Small footprint: The AAR is just 36Kb
  • API >= 21 compatible (due to BluetoothLE limitations).
  • Easy to integrate (just a gradle implementation line).

Test App 📲

You can find the test app (Myo Emg Visualizer) inside the app module.

This app allows you to:

  • Scan for a Myo
  • Connect to a Myo, control the frequency and send vibration.
  • See a graph of the EMG data.
  • Export the EMG data as a CSV file

Some technical features are:

  • The app is 100% Kotlin.
  • Architecture pattern used: MVP.
  • Dagger Android to inject the views.
  • Use AndroidX.
  • Use the Material Design Components library.

Videos

Searching for a Myo

Starting the Streaming

Exporting to CSV

Building/Testing ⚙️

CircleCI CircleCI

This projects is built with Circle CI 2.0. The CI environment takes care of building the library .AAR, the example app and to run the JUnit tests. Test and lint reports are exposes in the artifacts section at the end of every build.

Codecov codecov

Circle CI is responsible of uploading Jacoco reports to Codecov. When opening a Pull Request, Codecov will post a report of the diff of the test coverage.

Please don't ignore it! PR with new features and without are likely to be discarded 😕

Building locally

Before building, make sure you have the following updated components from the Android SDK:

  • tools
  • platform-tools
  • build-tools-28.0.1
  • android-28

Then just clone the repo locally and build the .AAR with the following command:

git clone [email protected]:cortinico/myonnaise.git
cd myonnaise/
./gradlew app:assemble

The assembled .AAR (library) will be inside the myonnaise/build/outputs/aar folder. The assembled .APK (application) will be inside the app/build/outputs/apk/debug folder.

Testing

Once you're able to build successfully, you can run JUnit tests locally with the following command.

./gradlew test 

Please note that there are tests inside the myonnaise and the app module. The app module contains test for the presenters. The myonnaise module contains tests for the library.

Make sure your tests are all green ✅ locally before submitting PRs.

Contributing 🤝

Looking for contributors! Don't be shy. 😁 Feel free to open issues/pull requests to help me improve this project.

  • When reporting a new Issue, make sure to attach Screenshots of the problem you are reporting.
  • Debugging
  • When submitting a new PR, make sure tests are all green. Write new tests if necessary (would be great if the code coverage doesn't decrease).

myonnaise's People

Contributors

szhangbiao avatar

Stargazers

Lowell avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.