How to make haptic buzzer vibrate several times on ANCS event?

I need to produce several consequent vibrations with pause between them when new notification is caught by ANCS MBLEvent.
I tried to use sleepForTimeInterval:, eventWithPeriod:repeatCount with following programCommandsToRunOnEvent: and even recursive blocks - all failed.
Does someone know how to do that?

Of course I use setConfiguration:handler: to program MetaWear device to log data offline and reacting on events.

Thanks in advance for any help.


  • Thanks for the question, but unfortunately that feature is currently in development and not yet available.  The solution will involve setting up a periodic event to trigger the vibrate, then having the ANCS even call "start" on the periodic event.

    Stay tuned for new SDK releases.

  • Here is a relevant snippit:

    // Whatever should trigger the buzzing
    MBLEvent *trigger = self.device.mechanicalSwitch.switchUpdateEvent;
    // Program a timer to fire 3 times, 1000 ms apart
    MBLTimerEvent *timer = [self.device.timer eventWithPeriod:1000 repeatCount:3 autoStart:NO];

    [[timer programCommandsToRunOnEventAsync:^{
        // Each time the timer fires we perform a buzz
        [self.device.hapticBuzzer startHapticWithDutyCycleAsync:255 pulseWidth:250 completion:nil];
    }] continueWithSuccessBlock:^id _Nullable(BFTask * _Nonnull task) {
        // Then each time our trigger event occurs we start the timer, thus starting the buzzing
        return [trigger programCommandsToRunOnEventAsync:^{
            [timer start];

  • We are trying to do something like this with a twist.  The idea is to have some leds,  controlled by fets turn on and off at 500ms intervals....on for 500ms,  off for 500ms for a total of 5 times. 

    We are trying to do this in Swift and are stuck trying to get the LED to flash on and off.  Our code is below.  Currently it turns our LED on and it stays on.  Is this possible and if so,  any idea of what we are doing wrong?  Also,  how should we be chaining things to get this to happen for a total of five times and then stop?

    let leftTurnLEDOnEvent: MBLTimerEvent = (device.timer?.eventWithPeriod(500, repeatCount: 1))!
    let leftTurnLEDOffEvent: MBLTimerEvent = (device.timer?.eventWithPeriod(500, repeatCount: 1))!


    leftTurnLEDOnEvent.programCommandsToRunOnEventAsync {
    }.continueWithSuccessBlock({ (task) -> AnyObject! in
        return leftTurnLEDOffEvent.programCommandsToRunOnEventAsync {


    leftTurnLEDOffEvent.programCommandsToRunOnEventAsync {
  • Stephen is still out of the office.  I've let him know to take a look at this thread when he's back.
  • You can achieve that functionality by using the following (since I didn't have an external LED, I substituted for the on-device LED in this example)

    // Every 1000 ms we need to turn on the LED, and we want it to turn on 5 times
    let leftTurnLEDOnEvent: MBLTimerEvent = (self.device.timer?.eventWithPeriod(1000, repeatCount: 5, autoStart: false))!
    // Once the LED turns on we want to turn it off after 500 ms
    let leftTurnLEDOffEvent: MBLTimerEvent = (self.device.timer?.eventWithPeriod(500, repeatCount: 1, autoStart: false, triggerOnStart: false))!

    // This event must shut down the LED
    leftTurnLEDOffEvent.programCommandsToRunOnEventAsync {
        self.device.led?.setLEDOnAsync(false, withOptions: 1)
    }.continueWithSuccessBlock { _ in
        // This event powers on the LED and then starts the turn-off timer
        return leftTurnLEDOnEvent.programCommandsToRunOnEventAsync {
            self.device.led?.setLEDColorAsync(UIColor.greenColor(), withIntensity: 1.0)
    }.continueWithSuccessBlock { _ in
        // Now that these events are programmed, we can start it anytime by calling start
        return leftTurnLEDOnEvent.start()
    }.success { _ in
    }.failure { error in
        print (error)

  • Thanks, Stephen -- it works great for individual LEDs, but we do run into a memory issue when we try to simultaneously use more than one GPIO. 

    Code=111 "MetaWear out of memory, can't perform action.  Reset the MetaWear and use no more than 8 entities"

  • Are you programming the same device multiple times without calls to eraseCommandsToRunOnEventAsync?  Really the code sample I provided should be contained within the runOnDeviceBoot method of an MBLRestorable object.

    Then when you make changes during enabling you will have to reprogram the device which fully resets it.
This discussion has been closed.