No bikespeed data while fit data recording

Hi folks!

I'm new at sw development for garmin devices.

Because I'm a wheelchair triathlete and there is no wheelchair app on garmin, I'm using the normal Bicycle and Running apps for Handbike and Racing Wheelchair.

I've bought the garmin bikespeed sensor to record my speed data indoor. Because i've not found a way to use this sensor in the garmin running apps, I've deicded to programm my own very simple Indoor Wheelchair app.

There are some problems i've run into while programming, but i've made an app which is working in the simulator.

But on my garmin fenix5 if i start the fit recording (the "on select" function) i'll get no more speed data.

The hartrate data is fine, eighter with external hartrate sensor or with the internal one in the watch.

Here's my code:

using Toybox.WatchUi;
using Toybox.System;
using Toybox.Graphics;
using Toybox.Lang;
using Toybox.Activity;
using Toybox.ActivityMonitor;
using Toybox.ActivityRecording;
using Toybox.Timer;
using Toybox.AntPlus;
using Toybox.FitContributor;
using Toybox.Sensor;
using Toybox.Time.Gregorian;
using Toybox.Communications;

var session = null; // set up session variable

var speed,heartrate,field_heartrate=null,field_speed=null;

var activityInfo = new Activity.Info();

var time=null;

var x=0;

//var sensorInfo = new Sensor.Info(); 

class RacingWheelchairDelegate extends WatchUi.BehaviorDelegate {

	function timerCallback(){
		WatchUi.requestUpdate();
		}
		
		
	function initialize() {
        BehaviorDelegate.initialize();
    }


	function onMenu(){
	System.println("onMenu");
	if ((session!=null) && !(session.isRecording())){
		System.println("session saved!");
		session.save();
		Sensor.unregisterSensorDataListener();//listener mehtod deaktivieren
		Sensor.setEnabledSensors([]); //disable all sensors
		field_heartrate = null;
       	field_speed = null;
		session = null;
		
	
	}
	}
	// use the select Start/Stop or touch for recording
	function onSelect() {

	
	System.println("onSelect");
	

	
   		if (Toybox has :ActivityRecording ) {                          // check device for activity recording
       	if ((session == null)) {
           	session = ActivityRecording.createSession({          // set up recording session
                 :name=>"Indoor Wheelchair",                    // set session name
                 :sport=>ActivityRecording.SPORT_RUNNING,       // set sport type
                 :subSport=>ActivityRecording.SUB_SPORT_GENERIC // set sub sport type
           });
           //Felder welche im FIT file gespeichert werden
           field_speed = session.createField("speed", 0, FitContributor.DATA_TYPE_FLOAT, {:mesgType=>FitContributor.MESG_TYPE_RECORD,:units=>"m/s"});      
           field_heartrate = session.createField("heartrate", 1, FitContributor.DATA_TYPE_SINT32, {:mesgType=>FitContributor.MESG_TYPE_RECORD,:units=>"bpm"});
           session.start();                                                // call start session
           System.println("Session started");
           
      	}

       	else if ((session != null) && session.isRecording()) {
       		
           session.stop();  
           x=1;
           
           }
           
        else if ((session != null))
        {
        	session.start();
        	
        }
       
       
       
   }
   return true;                // return true for onSelect function
}
}

class RacingWheelchairView extends WatchUi.View {

    function initialize() {
        View.initialize();
    }

    // Load your resources here
    function onLayout(dc) {

        
        //Bike speed Sensor aktivieren
        Sensor.setEnabledSensors([Sensor.SENSOR_BIKESPEED,Sensor.SENSOR_HEARTRATE]);
        Sensor.enableSensorEvents(method(:onSensor));
        
        
    }

	function onSensor(sensorInfo){
		speed = sensorInfo.speed;
		heartrate = sensorInfo.heartRate;
		if(speed != null){
		speed = speed*3.6;
		speed = speed.format("%.1f");
		}
		
		if((field_heartrate != null) && (heartrate != null)){
		field_heartrate.setData(heartrate);
		}
		if((field_speed !=null) && (speed != null)){
		field_speed.setData(sensorInfo.speed);
		}
		WatchUi.requestUpdate();

	}
    // Called when this View is brought to the foreground. Restore
    // the state of this View and prepare it to be shown. This includes
    // loading resources into memory.
    function onShow() {
    }

    // Update the view
    function onUpdate(dc) {
        System.println("onUpdate");
        //zeit aktualisieren
		var sec = 0,min = 0,hour = 0;
		
        if(session != null){
        	time = activityInfo.timerTime;
	
        	sec = time/1000;
        	min = sec / 60;
        	hour = min / 60;
        	min = min % 60;
        	sec = sec % 60;

        }
        activityInfo = activityInfo.getActivityInfo();

          
        //hintergrund schwarz malen        
        dc.setColor(Graphics.COLOR_BLACK, Graphics.COLOR_TRANSPARENT);
        dc.fillRectangle(0, 0, dc.getWidth(), dc.getHeight());
        //texte schreiben
        dc.setColor(Graphics.COLOR_WHITE, Graphics.COLOR_BLACK);
        if(time/*activityInfo.timerTime*/ != null){
		dc.drawText(dc.getWidth()/2 , 50, Graphics.FONT_LARGE,hour + ":" + min + ":" + sec, Graphics.TEXT_JUSTIFY_CENTER);
		}
		if(speed!=null){
		dc.drawText(dc.getWidth()/2 , 100, Graphics.FONT_LARGE, speed + "km/h", Graphics.TEXT_JUSTIFY_CENTER);
		}
		else{
		dc.drawText(dc.getWidth()/2 , 100, Graphics.FONT_LARGE, "no speed" , Graphics.TEXT_JUSTIFY_CENTER);
		}
		if(heartrate!=null){
		dc.drawText(dc.getWidth()/2 , 150, Graphics.FONT_LARGE, heartrate+"bpm", Graphics.TEXT_JUSTIFY_CENTER);
		}
		else{
		dc.drawText(dc.getWidth()/2 , 150, Graphics.FONT_LARGE, "no heartrate", Graphics.TEXT_JUSTIFY_CENTER);
		}
		
		//linien zeichnen
		dc.setColor(Graphics.COLOR_BLUE, Graphics.COLOR_TRANSPARENT);
		dc.drawLine(0, 90, dc.getWidth(),90);
		dc.drawLine(0, 150, dc.getWidth(), 150);
		
		
        
    }

    // Called when this View is removed from the screen. Save the
    // state of this View here. This includes freeing resources from
    // memory.
    function onHide() {
    }



	
}

What am I doing wrong? 

Sorry for the german comments and other failures.... I've tryed so much  but i can't do it..

Thanks for the help!

Regards Andreas

  • Just a couple if thoughts..  

    1) Maybe try SPORT_CYCLING instead of SPORT_RUNNING, as you're trying to use the bike sensor.

    2) Maybe try looking at SENSOR_BIKECADENCE in addition to SENSOR_BIKESPEED and see if you get anything there

  • Thanks for the quick answer!

    I've tried it. SPORT_CYCLING fixed it. SPORT_GENERIC is also not working.

    But thats a problem... Because i want to have different apps for hanbike (cycling) and racing wheelchair (running) because i ever need to change the sport type and the equipment after a training in order to get my statistic right....

    Is there any other way??

    Maybe if i use the bikespeed sensor with the ant toybox? But i've not managed to initalize the sensor with this toybox... the API docs are underdocumented for me to use it...

    Or is there a way to change the type of the activation automaticly in the app?

    And sorry but there is another question.... How can i sync the watch with my phone after completing the workout? I always get the "sync failed" prompt on the watch. And i have to start it via my cellphone. 

    BIG THANKS!

  • Different sports do things differently in the FW, so SPORT_CYCLING working with the bike sensors doesn't surprise me.

    SPORT_GENERIC  is really the catch all for things ("other") on watches.

    You might be able to do your own ANT, but you might also run into an issue if the sensor is already paired in the FW.

  • Hi guy's,

    late reply ;) 
    I was able to do it! I tryed to enable the sensors a second time directly after calling the session.start().

    Now it's working and i'm getting all the data in the fit file i need.

    Thanks for the input that the running session is disabling all the bike sensors.

    Regards, 

    Andreas

  • Wht might have happened is when you enable the sensors (which you should do before you start recording), is how you did it.

    for example, 

    Sensor.setEnabledSensors([Sensor.SENSOR_HEARTRATE,Sensor.SENSOR_TEMPERATURE,Sensor.SENSOR_FOOTPOD]);

    will enable all three

    but

    Sensor.setEnabledSensors([Sensor.SENSOR_HEARTRATE]);

    Sensor.setEnabledSensors([Sensor.SENSOR_TEMPERATURE]);

    Sensor.setEnabledSensors([Sensor.SENSOR_FOOTPOD]);

    really only enables the footpod.  It overrides the first two.

  • Hi jim,

    yes thats how i did it like you can see in code line 107 in the first post. 
    i‘ve put the same line another time directly after the session.start command. Since then it‘s working. Even with a running session.

  • Hi,

    I am a para triathlete - is there a way you can share this implementation with me so that I can use a speed sensor for ‘running’ in my racing chair too - thanks

  • Hi,

    Sorry for the late reply. I'm afraid I lost the data due to a hard drive crash.

    The app is only uploaded as beta and cannot be shared in this state.
    And it was only for fenix 5.

    Also the app was very basic. only three fields with: Heartrate, Timer, Speed. 

    It also was only Indoor without GPS.

    Please tell me if you are still intrested in the app. Then i can check how to reprogramm it from the code above. But it will need some time because I'm no professional programmer.

    Best regards,

    Andreas

  • THanks Andreas

    I am going to try and do it myself using your sample above - just working out the Garmin Ecosystem!  im not a developer either but if i can get it working it would be really helpfull for me and alot of friends. 

    (I only really need Speed, heart rate but GPS and Elevation would be good i guess for outdoor training)