How to get wheel rpm or circumference from speed sensor?

I need to know the wheel exact circumference for my gear calculator app. ATM there is a manual data from properties. But there is the speed sensor, that have an automatic calculated wheel circumference data and that sensor have an RPM that help to calculate that number. The problem is, I did not found any way to reach those informations.

The Toybox.AntPlus.BikeSpeedInfo have only speed and distance method.

The ANT+ protocol said, the sensor must be support this datas:

  • Latest Speed Event Time
  • Cumulative Wheel Revolutions
  • Stopped flag indicating zero speed (optional)
  • Battery level (optional)
  • Cumulative Operating Time (optional)
  • Manufacturer ID and Serial Number
  • Hardware Version, Software Version and Model Number

Any idea how to get it?

  • Make a direct connection the bike sensor using the CIQ Ant.GenericChannel class (which provides a generic way to communicate with both ANT and ANT+ sensors). (ANT+ is basically just ANT on a dedicated network with standard profiles, anyway). 

    You will receive raw ANT messages from the sensor, which you will need to decode yourself, based on the ANT+ profile for bike speed and cadence sensors.

    Maybe this typescript github example will help with ANT+ profile details: https://github.com/Loghorn/ant-plus/blob/master/src/speed-cadence-sensors.ts 

    For an example of using the CIQ Ant.GenericChannel class, check out the SDK MoxyField sample (CTRL/CMD-SHIFT-P > Monkey C: Open Samples).

    I can tell you from talking to Stryd engineers that if you lose the connection during an activity, the way to recover is destroy the instance of Ant.GenericChannel and create a new instance to re-establish the connection. At least that's how it was for 2017-era watches like FR935, when communicating with a Stryd sensor.

  • Yep, that is a possible way to rewrite the whole speed sensor class :) 

    But I find it quite surprising that a sensor that can only measure how many times it has turned cannot extract this data, only calculated information. Not to mention that if I can see the calculated wheel circumference information on the Garmin device, why can't it be read by the speed sensor if it already provides calculated information? I constantly feel that the entire SDK is full of ill-conceived solutions. But maybe I'm just too old-fashioned :)

  • For your project to get the exact wheel circumference for mechanical gear shift systems via SDK it is - imho - of no help if you know the exact count of wheel rotations: you do not know the exact distance your bike has moved for that time!

    It's a kind of vicious circle:
    For the exact wheel circumference you need both: the number of wheel rotations and the exact distance you moved for a time.
    For exact speed you need both: the number of wheel rotations and the exact wheel circumference.
    The speed sensor delivers only the one of both: wheel rotations per time. 

    Therefore, you must define the wheel circumference and enter it in the speed sensor details of your Edge device.

    Yes, there is an “Automatic Wheel Circumference” mode on Edge devices – however, this works with GPS distance measurement, which is far too inaccurate for your purposes – and, what's more, it varies constantly because it is recalculated at specific intervals.

    IMHO there is only one way for a gear shift calculation: to enter the measured wheel circumference into the datafield‘s settings and to use the manual wheel circumference mode on your Edge for the speed sensor.

  • I constantly feel that the entire SDK is full of ill-conceived solutions.

    You're not alone. There were so many design decisions which made me scratch my head - like, could they not see this would be issue down the road (or immediately). To their credit, for some of these things, they actually created a solution years later to work around the original problem (like the ability to mark certain string resources as dedicated to app settings, which can save a lot of memory for apps on older devices.)

    Same with how Monkey Types - compile-time type checking - was eventually added to the language. (To be fair, Monkey C was released way before TypeScript gained widespread adoption.)

    But maybe I'm just too old-fashioned :)

    Haha quite the opposite. A lot of ppl who look at Garmin's software, whether it's the Connect app UI or the design of CIQ / Monkey C, come away feeling like Garmin is stuck 10-20 years in the past. And these comments come from all types of users (regular end users, developers, tech enthusiasts, etc.) 

    When CIQ was introduced 10 years ago (wow), there were a bunch of disappointed comments on reddit about how the language lacked a lot of modern features that were already seen as essential, such as string interpolation and functional programming.

    I mean, look, it took Garmin 10 years to monetize their own app store....

    To give Garmin credit, they have obviously tried to modernize and improve things on several fronts, like moving to VS Code for CIQ development.

    But the pace of change seems glacial. And there's also the bad kind of modernization, like moving to subscription-based services.

  • Its true, but if you using a long enough distance and you have a revolution number, you can count a good enough C for the wheel. I mean my wheel C is 2151mm, so ~465 revoultion in 1km. If I refresh the calculation every 5 or 10Km or only 1km, I bet it is precise enough for a gear calculation. That will never 100% correct, it is only a help for the users to set the circumference that is not easy to measure and changing when your weight or the tube pressure change.

    So in nutshell, yes, the easy way is to ask the user, give me a wheel C mm. But I am sure, if I get wheel revolution I can calculate easily a good enough C. Anyway in the predicted gear calculation you must use tolerance, like 1km/h is still a possible ratio speed.

  • "feeling like Garmin is stuck 10-20 years in the past"

    I've been in the business even longer than that :D For me, for example handling variables is too "modern". Everything object-oriented, and basic things like comparing two strings or assigning the value of one variable to another like Array become complicated compared to how they originally worked, when a variable only had the function of storing data.

  • it is only a help for the users to set the circumference that is not easy to measure and changing when your weight or the tube pressure change

    Yes, you might be right, it may work for a longer distance...

    What I do for user assistance: they can adjust the circumference "on the fly". 

  • and basic things like comparing two strings or assigning the value of one variable to another like Array become complicated

    Haha…

    I‘m coming from MS Visual Basic 6.0 (the only programming language I learned by doing before Monkey C) and I was surprised that:

    var a = „Green“
    var b = „Green“
    ( a == b ) = false 

    Joy

  • I can show you more crazy.

    private const ABC = ["a", "b", "c"];
    
            var abc = ABC;
            abc.add("d");
            System.println(ABC);
            

    The result:

    [a, b, c, d]

     you just changed a CONSTANT :D 

  • Not to mention that if I can see the calculated wheel circumference information on the Garmin device, why can't it be read by the speed sensor if it already provides calculated information?

    The speed sensor doesn’t get data from the head unit. 

    It doesn’t need the wheel circumference to do its job.

    (It wouldn’t make too much sense to receive this number (repeatedly) and transmitting this data (repeatedly) since it kinda doesn’t change.)

    ==================

    There are speed sensors that work independently and don’t need a head unit. But they don’t seem to be common.

    www.cannondale.com/.../cannondale-wheel-sensor