Communicating with PM5 via VB

Post questions and issues with Concept2 PM3 SDK
Phil_M
Paddler
Posts: 30
Joined: November 23rd, 2014, 10:10 am

Communicating with PM5 via VB

Post by Phil_M » November 23rd, 2014, 10:42 am

Hello all,

I bought a Concept2 a couple of weeks ago and have been trying to get it to talk to my laptop ever since. I have downloaded the SDK and the PMI active-x controls and I am trying to work my way through the 147 page manual, but I am stuck on the first exercise.

The manual explains the process via VBA inside excel (which is something I am quite familiar with) but I don't have excel on my laptop, so I am trying to do it via VB in MS Visual Studio instead, which I have never used before. The manual says it should be fine though, and I like expanding my horizons so a project outside of excel is probably good for me.

So I created a new "Windows Forms Application" in Visual Studio.
Following the instruction manual, in section 2.4, I have brought the active-x controls into my project.
I have then dragged the IFace control into my userform, and per the manual (which is working in excel) thats good enough for my first program to run and show me a force graph.

However when I connect it to the PM5, I get an error message which from the googling I have done is pretty generic and is an SEHException. I assume that in Excel VBA takes care of the more technical stuff for me, where as in VB I am expected to know what I am doing.

My guess is that I need to make some changes in either of the two other files which are included in my Windows Forms Application project to reference the right library or something. The first is "My Project" which appears to be some sort of advanced options, and the second is "App.Config" which currently contains:

Code: Select all

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
</configuration>
Can anyone help explain to me what I am doing wrong? If you need any more information, please let me know, I can get a screenshot of the error message if required.

I know that there isn't a problem with the connection between the PM5 and the laptop because I have been able to get tijmenvangulik's web based tool which he linked on 2nd November to recognize my rowing. His code flew several miles over my head though.

Thanks,
Phil

User avatar
Citroen
SpamTeam
Posts: 8010
Joined: March 16th, 2006, 3:28 pm
Location: A small cave in deepest darkest Basingstoke, UK

Re: Communicating with PM5 via VB

Post by Citroen » November 23rd, 2014, 10:56 am

There's a very high probability that Chris Brett's PMI stuff doesn't recognise a PM5 because the USB VID/PID and the product ID will be different.

You'd need to replace the version of the C2 SDK runtime libraries with http://software.concept2.com/sdk/PMSDKSetup.exe to even have a fighting chance.

Send an email to chrisbrett [at] drivephase [dot] net and see if he has a version that works with the PM5.

Phil_M
Paddler
Posts: 30
Joined: November 23rd, 2014, 10:10 am

Re: Communicating with PM5 via VB

Post by Phil_M » November 23rd, 2014, 11:13 am

Thanks Citroen, Ill send Chris an email and see where that gets me.

Phil_M
Paddler
Posts: 30
Joined: November 23rd, 2014, 10:10 am

Re: Communicating with PM5 via VB

Post by Phil_M » November 25th, 2014, 5:35 pm

I ended up getting a delivery failure from trying to email Chris. =(. Do you know if he checks these boards at all?

I have downloaded the latest library from the file you linked, I think I already had this version on my laptop though.

Ideally I would like to use VB as it is only marginally outside my comfort zone, but failing that, I am willing to try C#.

Can anyone point me in the direction of the simplest example of a working program which connects the ergo to a laptop and shows any old output like pace or strokes per minute, just to get me off the ground, and then I can expand from there. The kind of things you guys are building are just too big for me to get my head round in a new language without a simple anchor point to get me started.

dsissitka
Paddler
Posts: 29
Joined: June 29th, 2014, 4:48 am

Re: Communicating with PM5 via VB

Post by dsissitka » November 25th, 2014, 6:27 pm

PyRow includes a couple of simple examples.

If JavaScript is an option chrome.hid is pretty simple. You can find a chrome.hid sample app here.

Good luck!

Phil_M
Paddler
Posts: 30
Joined: November 23rd, 2014, 10:10 am

Re: Communicating with PM5 via VB

Post by Phil_M » November 25th, 2014, 6:40 pm

Thank you dsissitka, at first glance that looks like it goes over my head too, but I will start reading up. I have started learning javascript in the past and stopped through lack of focus. Python is probably something I should be learning too, so I might start there.

Just to check I am understanding correctly, the Chrome.hid links you provided, are a method for catching, for want of a better word, the signal from the concept2? I would then need to write my own code to interpret those signals? Then presumably if I hunted around in the Software Development Kit files I would find some details on what signal refers to the number of meters rowed, and what signal refers to the strokes per minute etc?

dsissitka
Paddler
Posts: 29
Joined: June 29th, 2014, 4:48 am

Re: Communicating with PM5 via VB

Post by dsissitka » November 25th, 2014, 7:19 pm

Pretty much.

If you look in the SDK you'll find a file named something along the lines of "Communications Interface Definition.pdf". You can find an old one here. Appendix A lists the supported commands.

It looks like the chrome.hid sample app I linked to is basically a USB HID REPL. You might be able to use it to interact with your performance monitor.

I'll try to post some sample code tomorrow.

Phil_M
Paddler
Posts: 30
Joined: November 23rd, 2014, 10:10 am

Re: Communicating with PM5 via VB

Post by Phil_M » November 25th, 2014, 7:35 pm

Thanks dsissitka, that would be very helpful.

I'm really enjoying my shiny new toy, 10km a day since I got it, but I am itching to rig up some sort of 'ghost' row logger so I can compete against my PBs.

dsissitka
Paddler
Posts: 29
Joined: June 29th, 2014, 4:48 am

Re: Communicating with PM5 via VB

Post by dsissitka » November 26th, 2014, 3:12 pm

I tried chrome.hid but it doesn't work for me on Ubuntu or Windows.

Here's a simple PyUSB example. Note that PyUSB 1.0.0a2 is required.

Code: Select all

import os
import usb

device        = usb.core.find(idVendor=6052)
configuration = device[0]
interface     = configuration[(0, 0)]
inEndpoint    = interface[0]
outEndpoint   = interface[1]

data = [
    1,   # Report ID
    241, # Standard Frame Start Flag

    # Command
    #
    # 128 is 0x80 in hexidecimal. If you check Appendix A you'll find that 0x80
    # is CSAFE_GETSTATUS_CMD's command ID.
    128,

    128, # Checksum
    242, # Frame Stop Flag

    # Padding. Standard frames are 21 bytes.
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
]

device.write(outEndpoint.bEndpointAddress, data)

response = device.read(inEndpoint.bEndpointAddress, inEndpoint.wMaxPacketSize)

print "%s" % response

# Prints:
#
#     array('B', [
#         1,   # Report ID
#         241, # Standard Frame Start Flag
#
#         # Command Response
#         #
#         # If you search for "CSAFE machine states" you'll find that 1 means
#         # ready. I'm not sure why but if I execute CSAFE_GETSTATUS_CMD
#         # multiple times its return value alternates between 1 and 129. 129
#         # doesn't appear to be documented.
#         1,
#
#         1,   # Checksum
#         242, # Frame Stop Flag
#
#         # Padding
#         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
#    ])
Hope it helps!

Phil_M
Paddler
Posts: 30
Joined: November 23rd, 2014, 10:10 am

Re: Communicating with PM5 via VB

Post by Phil_M » November 26th, 2014, 4:29 pm

thank you again dsissitka.

I am part way through a lot of downloading of software such as Pyhub, libusb a python compiler and probably a lot of things I haven't realized I need yet. I will report back when I get to a stage where I can link up to the ergo.

Phil_M
Paddler
Posts: 30
Joined: November 23rd, 2014, 10:10 am

Re: Communicating with PM5 via VB

Post by Phil_M » November 26th, 2014, 6:45 pm

Hi Disissitka,

I tried running your code and got an error: "No module named 'usb'

Have I missed a step? Should I be including any files from Pyusb or Libusb in the same folder with your program?

I also downloaded Pyrow as you instructed, but I am having a different problem with that one. When I run either of the two demo files which come with it, they compile and appear to run, but I just get what looks like a command prompt window saying "press any key to continue..." which then kicks me out of the program. This happened whether I was connected to the Ergo or not. I don't know if you have dabbled with Pyrow. If not, I can head over to the Pyrow forum topic, and post my issue there.

dsissitka
Paddler
Posts: 29
Joined: June 29th, 2014, 4:48 am

Re: Communicating with PM5 via VB

Post by dsissitka » November 26th, 2014, 7:10 pm

You need to install PyUSB. On Windows it looks like you need to:

- Download pyusb-1.0.0b2.zip.
- Unzip pyusb-1.0.0b2.zip.
- Run "python setup.py install" in the directory that was created when you unzipped pyusb-1.0.0b2.zip.

Have you done that?

dsissitka
Paddler
Posts: 29
Joined: June 29th, 2014, 4:48 am

Re: Communicating with PM5 via VB

Post by dsissitka » November 26th, 2014, 8:18 pm

I figured out why chrome.hid wouldn't work for me. I'll post a simple chrome.hid example tomorrow.

dsissitka
Paddler
Posts: 29
Joined: June 29th, 2014, 4:48 am

Re: Communicating with PM5 via VB

Post by dsissitka » November 27th, 2014, 9:25 am

OK, here's a simple chrome.hid example. Chrome 38 or later is required. Create a new directory. Save this as (New Directory)/background.js:

Code: Select all

function disconnect(connection) {
    chrome.hid.disconnect(connection.connectionId, function() {
        handleError('chrome.hid.disconnect');
    });
}

function handleError(errorPrefix) {
    var error = chrome.runtime.lastError;

    if (error) {
        console.error(errorPrefix + ' Error: '  + error);

        return true;
    }

    return false;
}

function uint8ArrayToArray(uint8Array) {
    var array = [];

    for (var i = 0,j = uint8Array.length;i < j;i++) {
        array.push(uint8Array[i]);
    }

    return array;
}

var filters = [
    {vendorId: 6052}
];

// Find performance monitors.
chrome.hid.getDevices({filters: filters}, function(devices) {
    if (handleError('chrome.hid.getDevices')) return;

    if (!devices.length) {
        console.error('chrome.hid.getDevices Error: No performance monitors found.');

        return;
    }

    var device = devices[0];

    // Connect to the performance monitor.
    chrome.hid.connect(device.deviceId, function(connection) {
        if (handleError('chrome.hid.connect')) return;

        var commandData = new ArrayBuffer(20);
        var commandView = new Uint8Array(commandData);

        commandView[0] = 241; // Standard frame start flag.

        // Command
        //
        // 128 is 0x80 in hexidecimal. If you check Appendix A you'll find that 0x80 is
        // CSAFE_GETSTATUS_CMD's command ID.
        commandView[1] = 128;

        commandView[2] = 128; // Checksum
        commandView[3] = 242; // Frame stop flag.

        console.log('Command:' + JSON.stringify(uint8ArrayToArray(commandView)));

        // Send the command.
        chrome.hid.send(connection.connectionId, 1, commandData, function() {
            if (handleError('chrome.hid.send')) {
                disconnect(connection);

                return;
            }

            // Handle the response.
            chrome.hid.receive(connection.connectionId, function(reportId, responseData) {
                if (handleError('chrome.hid.receive')) {
                    disconnect(connection);

                    return;
                }

                var responseView = new Uint8Array(responseData);

                console.log('Response: ' + JSON.stringify(uint8ArrayToArray(responseView)));

                disconnect(connection);
            });
        });
    });
})
Save this as (New Directory)/manifest.json:

Code: Select all

{
    "manifest_version": 2,
    "name":             "chrome.hid Concept2 Sample",
    "version":          "0",

    "app": {
        "background": {
            "scripts": ["background.js"]
        }
    },

    "permissions": [
        "hid",

        {
            "usbDevices": [
                {"vendorId": 6052, "productId": 1},
                {"vendorId": 6052, "productId": 2},
                {"vendorId": 6052, "productId": 3}
            ]
        }
    ]
}
The directory you created is an unpacked Chrome extension. Load it. There is no GUI. You'll find the command and response logged on the extensions page:

http://i.imgur.com/PsFdcRV.png

Phil_M
Paddler
Posts: 30
Joined: November 23rd, 2014, 10:10 am

Re: Communicating with PM5 via VB

Post by Phil_M » November 27th, 2014, 5:55 pm

Hi Dsissitka,

Thank you again for your responses. I am sorry that I haven't figured it out yet.

I copied your Chrome.hid example, and I got no errors but also got no results. I am using Chrome v39. When I compare to your linked image, I see the same except for the two lines: Command and Response. This was the case whether I was connected to the PM5 or not, and no matter how many times I refreshed the extensions page, as it says in the Loading instructions that you also helpfully linked. I am hoping I have missed a really obvious step somewhere again. Could it be anything to do with the VendorID that you reference? 6052? Citron mentioned earlier in this topic that the Vendor ID and Product ID would be different on a PM5. I tried googling and reading through the SDK stuff, but couldn't find any information on VendorIDs to know whether I need to reference a different number.

Going back to Pyusb, and the python route you were helping me with. I have definitely installed Pyusb.1.0.0a2, and done the "Python setup.py install" step (which worked after a massive amount of faffing about). I haven't tried version b2, which you suggested overnight, but I will try that tomorrow/the weekend as I have run out of time tonight. I am pretty sure that version a2 had worked though, as once I had managed to install it, it eliminated a number of errors from the PyRow application (or at least allowed it to compile).

For some reason I decided to go back a stage to look at the Software Development Kit with all the dll's and the demo program, and realized I may have missed a crucial first step. When I downloaded Libusb, it instructed me to save the dll's down in my System32 folder. This is something I hadn't done with the SDK Dll's, so I tried to do that, and then tried to register them using "regsvr32 xxxxxx.dll" (which I found through some more googling) but this came up with the error "the dll is read but the DLLRegistryServer entry point is not found". Could my lack of registered Dll's be the root of all these problems?

Since Tijmen's online tool works for me, I tried to have a look at his code to see if I could find why it works but nothing else seems to at the moment, and mostly I just ended up baffled. It looks to me (no guarantee of anything) that the dlls have been rewritten into his code package or something like that, so the fact that i haven't installed them correctly is bypassed. I'm just guessing at this point though.

Post Reply