Author Topic: Two wiimotes at a time... strange behaviour  (Read 12301 times)

Offline romlel

  • *
  • Posts: 13
  • Karma: +3/-0
    • View Profile
on: January 22, 2008, 12:15:08 PM
Hello,

I'm working on the current whiteboard app to allow the use of multiple wiimotes (2 for now). I just slightly reorganized the source code to use multiple "warpers", I create 2 wiimote objects, and call the "Wiimote.Connect()" for each one.

So I pair my two wiimotes in the windows bluetooth tool (each one has a unique ID), and I launch my program... In a matter of seconds, I loose the second wiimote paring, but I keep receiving the incoming IR data from the first one...  :(

If I don't register any wiimote events, the connect works and I don't loose the pairing (but my app don't do anything... of course). As I was afraid my multithreading approach (locks, mutexes, etc) would break the wiimote data acquisition, I also tried to remove any thread interaction... but the link is still broken for one of the wiimotes.

Perhaps the wiimotelib has a bug on that functionality, but it should have been tested before as the source code do everything needed to handle the multiple connections fine.

Has anybody tried to collect data from 2 wiimotes ?
Where could I find a reference code (from wiimitelib sample perhaps) to compare with mine ?

Thanks in advance,
cheers



Offline ZaPPZion

  • *
  • Posts: 137
  • Karma: +11/-1
    • View Profile
Reply #1 on: January 22, 2008, 03:38:30 PM
So it doesn't work when you're just polling the wiimotes? i think there are some issues with the threads in the wiimotelib.
by the way, i'm pretty sure that you can connect a second wiimote in the headtracking VR from johnny lee



Offline romlel

  • *
  • Posts: 13
  • Karma: +3/-0
    • View Profile
Reply #2 on: January 23, 2008, 02:19:20 AM
Thanks, I'll review the headtracking source code then.

By the way, the C++ spinoff of WiimoteLib, http://wiiyourself.gl.tter.org/, claims to manage multiple wiimotes... Perhaps I'll change to it, at least for a first try.



Offline Paamayim

  • *
  • Posts: 1
  • Karma: +4/-0
    • View Profile
Reply #3 on: January 28, 2008, 05:55:33 PM
Hi. I was having the same problem, but I've figured it out. WiimoteLib doesn't record how many times you call Wiimote.Connect(), so no matter what, it will return the first Wiimote connected. Here's my fix:

Code: [Select]
public static List<Wiimote> GetConnectedWiimotes() {
    List<Wiimote> motes = new List<Wiimote>();

    int index = 0;
    bool found = false;
    Guid guid;

    // get the GUID of the HID class
    HIDImports.HidD_GetHidGuid(out guid);

    // get a handle to all devices that are part of the HID class
    // Fun fact:  DIGCF_PRESENT worked on my machine just fine.  I reinstalled Vista, and now it no longer finds the Wiimote with that parameter enabled...
    IntPtr hDevInfo = HIDImports.SetupDiGetClassDevs(ref guid, null, IntPtr.Zero, HIDImports.DIGCF_DEVICEINTERFACE);// | HIDImports.DIGCF_PRESENT);

    // create a new interface data struct and initialize its size
    HIDImports.SP_DEVICE_INTERFACE_DATA diData = new HIDImports.SP_DEVICE_INTERFACE_DATA();
    diData.cbSize = Marshal.SizeOf(diData);

    // get a device interface to a single device (enumerate all devices)
    while (HIDImports.SetupDiEnumDeviceInterfaces(hDevInfo, IntPtr.Zero, ref guid, index, ref diData)) {
        UInt32 size;

        // get the buffer size for this device detail instance (returned in the size parameter)
        HIDImports.SetupDiGetDeviceInterfaceDetail(hDevInfo, ref diData, IntPtr.Zero, 0, out size, IntPtr.Zero);

        // create a detail struct and set its size
        HIDImports.SP_DEVICE_INTERFACE_DETAIL_DATA diDetail = new HIDImports.SP_DEVICE_INTERFACE_DETAIL_DATA();

        // yeah, yeah...well, see, on Win x86, cbSize must be 5 for some reason.  On x64, apparently 8 is what it wants.
        // someday I should figure this out.  Thanks to Paul Miller on this...
        if (IntPtr.Size == 8)
            diDetail.cbSize = 8;
        else
            diDetail.cbSize = 5;

        // actually get the detail struct
        if (HIDImports.SetupDiGetDeviceInterfaceDetail(hDevInfo, ref diData, ref diDetail, size, out size, IntPtr.Zero)) {
            Debug.WriteLine(index + " " + diDetail.DevicePath + " " + Marshal.GetLastWin32Error());

            // open a read/write handle to our device using the DevicePath returned
            SafeFileHandle mHandle = HIDImports.CreateFile(diDetail.DevicePath, FileAccess.ReadWrite, FileShare.ReadWrite, IntPtr.Zero, FileMode.Open, HIDImports.EFileAttributes.Overlapped, IntPtr.Zero);

            // create an attributes struct and initialize the size
            HIDImports.HIDD_ATTRIBUTES attrib = new HIDImports.HIDD_ATTRIBUTES();
            attrib.Size = Marshal.SizeOf(attrib);

            // get the attributes of the current device
            if (HIDImports.HidD_GetAttributes(mHandle.DangerousGetHandle(), ref attrib)) {
                // if the vendor and product IDs match up
                if (attrib.VendorID == VID && attrib.ProductID == PID) {
                    Debug.WriteLine("Found it!");
                    found = true;

                    Wiimote mote = new Wiimote();
                    mote.mStream = new FileStream(mHandle, FileAccess.ReadWrite, REPORT_LENGTH, true);
                    mote.mHandle = mHandle;

                    // start an async read operation on it
                    mote.BeginAsyncRead();

                    // read the calibration info from the controller
                    try {
                        mote.ReadCalibration();
                    } catch {
                        // if we fail above, try the alternate HID writes
                        mote.mAltWriteMethod = true;
                        mote.ReadCalibration();
                    }


                    // force a status check to get the state of any extensions plugged in at startup
                    mote.GetStatus();

                    motes.Add(mote);
                } else {
                    // otherwise this isn't the controller, so close up the file handle
                    mHandle.Close();
                }
            }
        } else {
            // failed to get the detail struct
            throw new Exception("SetupDiGetDeviceInterfaceDetail failed on index " + index);
        }

        index++;
    }

    // clean up our list
    HIDImports.SetupDiDestroyDeviceInfoList(hDevInfo);

    // if we didn't find a Wiimote, throw an exception
    if (!found)
        throw new Exception("Wiimote not found in HID device list.");

    return motes;
}



Offline romlel

  • *
  • Posts: 13
  • Karma: +3/-0
    • View Profile
Reply #4 on: January 29, 2008, 02:23:52 AM
Thanks, i'll try that ! (must borrow another wiimote)



Offline romlel

  • *
  • Posts: 13
  • Karma: +3/-0
    • View Profile
Reply #5 on: February 22, 2008, 07:36:17 AM
Excellent ! It works !
After the fix, I was still loosing the connection, but this time it was the low battery fault :)

You should suggest this correction to the wiimoteLib author...

So, I'm back on track for a new version of the whiteboard, with "parallax depth detection"...



Offline tarantula78

  • *
  • Posts: 6
  • Karma: +0/-0
    • View Profile
Reply #6 on: February 25, 2008, 01:39:09 AM
um sorry im more of a vb developer where do i place the code for the fix? i have a bad track record with C lol no matter what i do it always gives me errors >.<



Offline romlel

  • *
  • Posts: 13
  • Karma: +3/-0
    • View Profile
Reply #7 on: February 25, 2008, 10:18:11 AM
Hello

Just cut and paste the code somwhere in the middle of the file, between two functions block, and then call the new function isntead of the old "Connect" function...




Offline kaokengoku

  • *
  • Posts: 1
  • Karma: +0/-0
    • View Profile
Reply #8 on: May 13, 2008, 02:34:45 PM
hi there, i noticed romlel has 2 wiimotes working together. i have a bluetooth dongle that only will reliably connect to one wiimote device correctly (i know, odd) during bluetooth sync. i was wondering if anyone here can tell me a bluetooth dongle that DOES connect to multiple wiimotes at the same time. one such as romlel. thank you.



Offline steve6

  • *
  • Posts: 15
  • Karma: +0/-0
    • View Profile
Reply #9 on: May 28, 2008, 07:41:36 PM
Hello!!!
I have try to paste the code for connect two wiimote. But i have the problem when i compile. "errore CS0006: Impossibile trovare il file di metadati 'C:\Users\steve\Desktop\WiimoteCS\WiimoteLib\bin\Debug\WiimoteLib.dll'"
Any ideas??

Very thanks
Steve