Android USB Pulling Data

Post questions and issues with Concept2 PM3 SDK
Post Reply
oldsport76
Paddler
Posts: 1
Joined: October 4th, 2017, 9:44 am

Android USB Pulling Data

Post by oldsport76 » June 14th, 2018, 7:09 am

Hi Everyone,

I'm working on an Android application that communicates with the Concept2 Rowing ergometer. My setup is a Concept2 Model D with a PM5. I am aware that the PM5 can communicate with an Android phone through Bluetooth, but I am implementing mine to communicate over a USB cable. I was able to establish a successful USB connection between phone and ergo by opening the device and successfully claim the USBInterface. I am using the Android USB host API. I am writing the app in Kotlin, though Java is just as fine.

Everything goes according to plan with the following two lines.

Code: Select all


usbHidConnection = usbManager.openDevice(usbDevice)
val claimed = usbHidConnection?.claimInterface(usbHidInterface, true)

However, once I try to pull some data from the ergo, the problems begin. I am trying get the distance from the odometer on the PM. Using the long command frame from the documentation, I prepare the following byte sequence: 0xF0, 0xFD, 0x00, 0x9B, 0x9B, 0xF2. I then use the following code to create a USBRequest and wait for a response to it asynchronously.

Code: Select all


val distanceBuffer = listOf(0xF0, 0xFD, 0x00, 0x9B, 0x9B, 0xF2)
val ba = ByteArray(distanceBuffer.size)

var i = 0

while (i < distanceBuffer.size) {
    ba[i] = distanceBuffer[i].toByte()
    i++
}
val byteBuffer = ByteBuffer.wrap(ba)​


val request = UsbRequest()
request.initialize(conceptManager.usbHidConnection, conceptManager.usbHidRead)

doAsync {
 request.queue(byteBuffer)

 if (conceptManager.usbHidConnection?.requestWait() === request) {
   val x = byteBuffer[0]

    // TODO: process info from ergo
 }
}

When I execute this code, nothing happens. I set breakpoints inside the if-clause to check when the response to the UsbRequest arrives. Only once I touch something on the UI of my activity does this breakpoint within the if-clause hit. I check the byteBuffer to see if its contents have been changed to contain the odometer distance, but this is never the case. The buffer is never changed. I also try this synchronously with the bulkTransfer() method from the Android API, but that does not work either.

Does anyone have any ideas as to why my approach is not working? I must admit I do feel kind of stuck here as there are not many examples with Android USB on github to learn from.

Also, I have a second question. In the Android API for USB communication, the framework requires that I send the USB device a ByteBuffer. A ByteBuffer consists of bytes. In Kotlin (and Java), bytes can only be signed. This means they can only assume values from -128 to 127. Since that is the case, and the Concept2 expects unsigned byte values, e.g. 0 to 255, what is to happen? Am I to let Kotlin convert the integers I have ready to signed bytes and the PM5 will convert them on its own to the desired values? Just to clarify, after converting the above values to signed bytes, the frame looks like this:

-16 -3 0 -101 -101 -14

So, yeah. If anyone could share some expertise, I'd be grateful. Thanks in advance.

User avatar
tijmenvangulik
500m Poster
Posts: 64
Joined: November 25th, 2012, 10:24 am

Re: Android USB Pulling Data

Post by tijmenvangulik » June 14th, 2018, 3:36 pm

Maybe you can use c2api library as example. It is open source and uses usb communication on a lot of platforms.

https://github.com/angrytongan/c2api

https://github.com/signal11/hidapi

I even see a android make file in hideapi (but there is not mention in the readme code about android)

Tijmen

Post Reply