Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

eugiel

macrumors newbie
Original poster
Aug 5, 2012
3
0
Hi,

I have an Cocoa App that communicates with a USB device. It's as simple as it gets as its my first app. The USB device sends data to the host computer spontaneously. What I want to do is make a loop that repeatedly reads the data sent by the USB device and display it. Hopefully, it updates fast enough so that the reading is updated when I turn the potentiometer knob on my USB device.

Here's my code so far. It just reads the data once:

Code:
#import "AppDelegate.h"
#import "libusb.h"

#define TURN_LED_ON 1

@implementation AppDelegate

- (void) awakeFromNib {
    int result;
    
    result = libusb_init(&ctx);
    if (result < 0)
        return;
    
    [toggleLED setEnabled:FALSE];
    [self openDeviceAndClaimInterface];
    [self startReceivingUSBInterruptData];
}

- (void) applicationWillTerminate {
    libusb_release_interface(dev, 0);
    libusb_close(dev);
	libusb_exit(ctx);
}

- (void) openDeviceAndClaimInterface {
    int result;
    
    dev = libusb_open_device_with_vid_pid(ctx, 5824, 1500);
    
    if (dev == NULL) {
        NSLog(@"Cannot find device");
        return;
    } else {
        NSLog(@"Device opened");
        [toggleLED setEnabled:TRUE];
    }
    
    result = libusb_claim_interface(dev, 0);
    if (result < 0)
        NSLog(@"Cannot claim device interface");
}

- (void) startReceivingUSBInterruptData {
	dispatch_async(dispatch_get_global_queue(0, 0), ^{
		int readData = [self readUSBInterruptData];
		dispatch_async(dispatch_get_main_queue(), ^{
            NSString *reading = [NSString stringWithFormat:@"%d", readData];
            [voltageReading setStringValue:reading];
        });
	});
}

- (int) readUSBInterruptData {
    unsigned char buffer[16];
    int nBytes;
    int len = 0;
    
    nBytes = libusb_interrupt_transfer(dev, LIBUSB_ENDPOINT_IN | 1, buffer, sizeof(buffer), &len, 5000);
    
    if (nBytes < 0) {
        NSLog(@"USB error: %s", libusb_error_name(nBytes));
        return 0;
    } else {
        return buffer[0];
    }
}

- (IBAction)toggleLED:(id)sender {
    NSLog(@"Toggle LED button pressed");
    int nBytes = 0;
    char buffer[16];
    
    nBytes = libusb_control_transfer(
                dev,
                LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_IN,
                TURN_LED_ON,
                0,
                0,
                buffer,
                sizeof(buffer),
                5000);
    
    if (nBytes < 0)
        NSLog(@"USB error: %s", libusb_error_name(nBytes));
}
@end

My question is, where do I put a loop to make the app read data repeatedly from the device? Please help.
 
If you have to use a synchronous libusb interface then you will need to create a separate thread to read the data. If you write a loop in the main thread then you will block the UI.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.