Help needed! can't read accelerometer data - when updating to new API

I used to use this code to access accelerometer data:

    //device.accelerometer.sampleFrequency = 100.0

    //streamingEvents.insert(device.accelerometer.dataReadyEvent)
    //device.accelerometer.dataReadyEvent.startNotificationsAsync { (obj, error) in

            //if let obj = obj {

var acc_x  = obj.x

}

When I updated to code

    let signal = mbl_mw_acc_bosch_get_acceleration_data_signal(self.device.board)!
    mbl_mw_datasignal_subscribe(signal, bridge(obj: self)) { (context, obj) in
            let acceleration: MblMwCartesianFloat = obj!.pointee.valueAs()
            let _self: DeviceDetailViewController = bridge(ptr: context!)

var acc_x = acceleration.x            

}

I get this error:
"A C function pointer cannot be formed from a closure that captures context.."

Please help !!

Comments

  • edited March 2020

    ok so you have self.device.board and then you have self.board ... which one is it? read your code, it's got errors.
    THESE ARE NOT SDK ERRORS. THERE ARE CODING ERRORS. Brush up on your swift.

  • edited March 2020

    Laura, yes - i am not a swift guy - but was able to use the previous SDK - having issues using the current one -
    I am not saying that there are issues with the SDK at all.

    My expertise is ML and I am trying to get the job done here - and asking for help !

    1. Yes - that is an obvious error - i was trying something else when I took the screenshot.
    2. If you look at the pasted code, it doesn't contain that error
    3. This issue is the same as in posted earlier - but the solution wasn't clear in that ticket:
      https://mbientlab.com/community/discussion/3198/difficulty-getting-accelerometer-data-in-ios#latest

    Thanks!

  • So what is your error? Will close this thread if no proper error is posted.

  • edited March 2020

    Please see a sample function below:

    How do I use the variable "mult" inside the closure?

    Currently, I am getting an error: "A C function pointer cannot be formed from a closure that captures context"

  • Please note -
    1. I agree that this is not an SDK error
    2. My existing app is not building with the updated code and my clients are complaining.
    3. I could hire a swift developer - but this is the only error i need to fix and have a short timeline.

  • edited March 2020
    mbl_mw_datasignal_subscribe(signal, bridge(obj: self)) { (context, obj) in
            let acceleration: MblMwCartesianFloat = obj!.pointee.valueAs()
    }
    
  • edited March 2020

    Works for me on swift 4. Are you on swift 5?
    Never mind I tried it on swift 5 and it works fine too.

    Your code looks fine. Can you check against my sample app? https://github.com/mbientlab/MetaWear-SDK-iOS-macOS-tvOS/tree/master/MetaWearApiTest -> lots of examples of closures there.

  • Laura,
    Yes, the above works, fine. My question is about using a variable that is inside the function - in the closure.
    In the example below -

    when i use: _self.mult_outside ; code works fine
    but not sure how to use variable: mult_inside

  • edited March 2020

    what is your end goal exactly?

    You need to treat the closure as a sort of separate function that lives in it's own world (it knows nothing about print_accel_data - it just gets called/does something when the data signal comes back with data): https://docs.swift.org/swift-book/LanguageGuide/Closures.html

    The closure might not have any context of mult_inside but mult_outside looks global so it would have context (I don't have your entire code so this is a bit of an assumption).

    I liked this tutorial, does a decent job of explaining closures: https://medium.com/the-andela-way/closures-in-swift-8aef8abc9474

  • Appreciate your patience Laura (and i know it's not really your job to explain these things - so appreciate the help! )

    I was able to bring all the variables i had declared inside the function in the closure and code is working fine now.

  • Swift closures don't work as usual when calling into C code. They are treated as C style functions meaning they have the same limitations with regards to scope. To work around this, all callback function signature have a context parameter that the caller can use to pass in local variables, mult_inside in your case.

    The bridge functions are convenience methods for converting Swift objects into void* typing.

    https://github.com/mbientlab/MetaWear-SDK-iOS-macOS-tvOS/blob/d1c417c36071ce76adf8a91b7899ecec95e7886d/MetaWear/Core/Bridging.swift

    Google the "A C function pointer cannot be formed from a closure that captures context.." error message if you want more details.

  • Thanks Eric.
    I just created a work around. Declared a ton of variables globally lol. Btw, the app is now in the app store.
    Uses a DL model to count and time reps for metawear. Built on top of your template app.
    https://apps.apple.com/us/app/repmonk-app/id1502523312

Sign In or Register to comment.