Difficulty triggering mbl_mw_timer_start after successful comparator condition
Model: MetaMotion R
Firmware: 1.5.1
Hello, I hope this does not count as a "how do I code"-type question, but I have this piece of code that I believe should function, but does not.
The idea is, a single press of the MetaWear button should cancel a repetitive vibration, and begin a 5-minute countdown (snoozeTimer) to another event (flashing the LED 3 times, green). For some reason, I cannot get the snoozeList.forEach { $0.value } inside the comparator to actually trigger another timer to begin.
func clickListener() {
//dictionaries for activating or removing the actual alarm vibration
var alarmList: [OpaquePointer: () -> Void] = [:]
var alarmCleanup: [OpaquePointer: () -> Void] = [:]
//dictionaries for activating or removing the snooze alarm
var snoozeList: [OpaquePointer: () -> Void] = [:]
var snoozeCleanup: [OpaquePointer: () -> Void] = [:]
//clickListener itself
var clickEvent = mbl_mw_switch_get_state_data_signal(self.device.board)
clickEvent?.counterCreateCount().continueOnSuccessWith { count -> OpaquePointer in
mbl_mw_event_record_commands(count)
//if one click
count.comparatorCreate(op: MBL_MW_COMPARATOR_OP_EQ, mode: MBL_MW_COMPARATOR_MODE_ABSOLUTE, references: [Float(2)]).continueOnSuccessWith { comp in
mbl_mw_event_record_commands(comp)
self.device.flashLED(color: .blue, intensity: 1.0, _repeat: 1)
//turn off first vibration
alarmCleanup.forEach { $0.value() }
//turn on snooze alarm
snoozeList.forEach { $0.value() }
comp.eventEndRecord()
}
return count
}.continueOnSuccessWithTask() { count in
//this timer resets click counter every 2 seconds
self.device.timerCreate(period: 2000).continueOnSuccessWith { repetitive in
clickListenerList[repetitive] = {
mbl_mw_timer_start(repetitive)
}
clickListenerCleanup[repetitive] = {
mbl_mw_timer_stop(repetitive)
}
mbl_mw_event_record_commands(repetitive)
//below is a useful debugging tool to give you a physical indication of when the clickCounter is reset
//mbl_mw_haptic_start_buzzer(self.device.board, 250)
mbl_mw_dataprocessor_counter_set_state(count, UInt32(0))
repetitive.eventEndRecord()
}.continueOnSuccessWith() {
clickListenerList.forEach { $0.value() }
}
}
device.timerCreate(period: 1200).continueOnSuccessWith { repetitive in
alarmList[repetitive] = {
mbl_mw_timer_start(repetitive)
}
alarmCleanup[repetitive] = {
mbl_mw_timer_stop(repetitive)
}
mbl_mw_event_record_commands(repetitive)
print("recording commands")
mbl_mw_haptic_start_buzzer(self.device.board, 250)
repetitive.eventEndRecord().continueOnSuccessWith {
print("repetitive timer set")
}
}.continueOnSuccessWith {
print("starting timer")
//actually triggers event
alarmList.forEach { $0.value() }
}
//this is the snooze alarm
device.timerCreate(period: snoozeTime*1000, repetitions: 1, immediateFire: false).continueOnSuccessWith { snoozeTimer in
snoozeList[snoozeTimer] = {
mbl_mw_timer_start(snoozeTimer)
}
snoozeCleanup[snoozeTimer] = {
mbl_mw_timer_stop(snoozeTimer)
}
mbl_mw_event_record_commands(snoozeTimer)
//debug indication LED below
self.device.flashLED(color: .green, intensity: 1.0, _repeat: 3)
snoozeTimer.eventEndRecord().continueOnSuccessWith {
print("snooze timer set")
}
}
}
Update: After forcing commands sequentially with .continueOnSuccessWith(Executor.mainThread), I get a BAD_ACCESS error - it looks like the MetaWear can only store/reference two timers at once. I might be wrong here, still very new to working with this API.
Update 2: I was able to get past this hurdle by setting:
self.snoozeID = mbl_mw_timer_get_id(snoozeTimer)
Then, when calling timer, using:
mbl_mw_timer_start(mbl_mw_timer_lookup_id(self.device.board, self.snoozeID))
My idea is the pointer to any timer becomes invalid if there are too many timers. Referencing a timer by ID seems to access the timer without needing to retain a pointer that may or may not change on-device. However, this fix produces variable, error-prone behaviour.