Cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Heart sensor stop after some times

Hello,

 

Since the last SDK 4.2, I have problem with my Heart Sensor event. After some times, the system no longer passes through the event "reading". I do not know why.

Somebody Know why ? Or have the same issue since the last SDK ?

 

Thanks.

Micka

Best Answer
0 Votes
11 REPLIES 11

Several of my clocks use the heart rate sensor.  I have upgraded a couple of them to SDK 4.2 and have had no such issue.

 

JavaScript is an interpreted language.  So, it will try to run bad code until it crashes -- this means that the bug could actually be elsewhere, causing the entire app to crash after a time.  Do other screen elements continue to run?  If you are debugging through Fitbit Studio, check the Console and Build Output tabs at the bottom for messages.

 

Also, you might verify that your event listeners aren't being added multiple times.  That would cause the events to pile up and after a time, and eventually crash your app.  Without seeing the code, it is difficult to diagnose.  However, I can confirm that I have not experienced any issues with the heart rate monitor events.

Best Answer
0 Votes

Hello,

 

Thanks for your feedback. Yes, others elements continue to run and I have no error on console. I don't understand...

Best Answer
0 Votes

Do you use the BodyPresenceSensor and start/stop the heart sensor?

Best Answer
0 Votes

BodyPresenceSensor no, not yet. But Start / Stop yes but just once.

Best Answer
0 Votes

I would add a "console.log()" message to your "reading" event handler which echoes the sensor value back to the console.  That would tell you whether it successfully starts ... how long it runs ... and whether the values returned are valid.

 

If you aren't seeing any errors, I would guess that it's probably not starting successfully.  Or that it starts, gets stopped, but not restarted (ex. my code calls .stop() when the device display is off, but then listens for the device "change" event to turn it back on and calling .start() when the display is on).

Best Answer
0 Votes

I propose you to put my code source (I use class, I don't know if it's the best way. I use cutom font).

In my heartManager.js:

import { HeartRateSensor } from "heart-rate";
import utils        from "./utils";

export default class HeartManager {
  // Init Heart Manager
  constructor() {
    this.initGraphicElements();
    if (HeartRateSensor) {
      this.hrm = new HeartRateSensor({ frequency: 1 });
      this.start();
    }
  }
  
  // Init graphic elements
  initGraphicElements() {
    this.heartRate_0 = utils.getElementById("heatrate_0");
    this.heartRate_1 = utils.getElementById("heatrate_1");
    this.heartRate_2 = utils.getElementById("heatrate_2");
  }
  
  // Start the sensor
  start() {
    this.hrm.addEventListener("reading", () => {
      console.log("Reading");
      this.updateGraphicElements(this.hrm.heartRate);
    });
    
    console.log("Start");
    this.hrm.start();
  }
  
  // Stop the sensor
  stop() {
    console.log("Stop");
    this.hrm.stop();
  }
  
  // Update graphic elements
  updateGraphicElements(value) {
    if(value < 100) {
      utils.drawDigit("0", this.heartRate_0);
      utils.drawDigit(Math.floor(value / 10), this.heartRate_1);
    } else {
      utils.drawDigit(Math.floor(value / 100), this.heartRate_0);
      utils.drawDigit(Math.floor((value - (Math.floor(value / 100) * 100)) / 10), this.heartRate_1);
    }
    
    utils.drawDigit(Math.floor(value % 10), this.heartRate_2);
  }
}

 

In my index.js:

import { me }               from "appbit";
import clock                from "clock";
import * as settingsManager from "./settingsManager";
//import * as messaging       from "messaging";
import MessagingManager     from "./messagingManager";
import DateTimeManager      from "./dateTimeManager";
import BatteryManager       from "./batteryManager";
import HeartManager         from "./heartManager";
import { memory }           from "system";

clock.granularity = "seconds";
settingsManager.initSettingsManager();

let heartManager = new HeartManager();
//let messagingManager = new MessagingManager();
//let heartManager = new HeartManager();
//let dateTimeManager = new DateTimeManager();
//let batteryManager = new BatteryManager();



clock.ontick = evt => {
  //dateTimeManager.updateDateTime(evt.date);
}

// Register for the unload event
me.onunload = settingsManager.saveSettings();

console.log(`JavaScript memory: used=${memory.js.used},
peak=${memory.js.peak}, total=${memory.js.total}`)

memory.monitor.addEventListener('memorypressurechange', () => {
  console.log(`Memory pressure is ${memory.monitor.pressure}`)
})

 

I put others features in comment to test just heart sensor.

Best Answer
0 Votes

I could be wrong, but it looks like you might be adding a new event listener every time start() is called. In your example above, that's only once, but presumably in your full code you're turning the sensor on and off when the display state changes.

I'm not sure what the consequences of having multiple event listeners would be, but I think it would be best to avoid it.

Peter McLennan
Gondwana Software
Best Answer
0 Votes

Thanks,

I' agree with you I had this issue. But it's don't resolve my issue :(.

My new code:

import { HeartRateSensor } from "heart-rate";
import utils        from "./utils";

export default class HeartManager {
  // Init Heart Manager
  constructor() {
    this.initGraphicElements();
    if (HeartRateSensor) {
      this.hrm = new HeartRateSensor({ frequency: 1 });
      
      this.hrm.addEventListener("reading", () => {
        console.log("Reading");
        this.updateGraphicElements(this.hrm.heartRate);
      });
      
      this.start();
    }
  }
  
  // Init graphic elements
  initGraphicElements() {
    this.heartRate_0 = utils.getElementById("heatrate_0");
    this.heartRate_1 = utils.getElementById("heatrate_1");
    this.heartRate_2 = utils.getElementById("heatrate_2");
  }
  
  // Start the sensor
  start() {
    console.log("Start");
    this.hrm.start();
  }
  
  // Stop the sensor
  stop() {
    console.log("Stop");
    this.hrm.stop();
  }
  
  // Update graphic elements
  updateGraphicElements(value) {
    if(value < 100) {
      utils.drawDigit("0", this.heartRate_0);
      utils.drawDigit(Math.floor(value / 10), this.heartRate_1);
    } else {
      utils.drawDigit(Math.floor(value / 100), this.heartRate_0);
      utils.drawDigit(Math.floor((value - (Math.floor(value / 100) * 100)) / 10), this.heartRate_1);
    }
    
    utils.drawDigit(Math.floor(value % 10), this.heartRate_2);
  }
}
Best Answer
0 Votes

A little precision: if I compile with the 4.1 SDK, all work fine.

Best Answer
0 Votes

I totally agree with Gondwana, and after you updated your code to only add the listener once, I think that fixed a part of it.  When you keep adding multiple event listeners, eventually the number of listeners will pile up and crash the app.

 

As chris_starwf suggested above, if you aren't detecting body presence, and the Fitbit is off-the-wrist (or loosely worn so that the reading fails), the heart rate sensor reading will return a null value.  That null value would certainly crash all of your interface update calculations.

 

If you aren't detecting body presence, you should be checking for nulls.

Best Answer
0 Votes

Hello,

 

It's work fine with the 4.1.

With the 4.2, it's work some sec and suddenly, without change the body precense or other, it no longer works.

I'll add the body presence but is not the issue unfortunately.

Best Answer
0 Votes