Has anyone an example of DataField with access to Sensor

Hello:

I own a Garmin Edge 520 and I would like to learn some Monkey C in order to write my own data fields. I've installed Eclipse and the Connect IQ SDK in Debian and I've run the sample Simple Data Field.

Now I would like to read the temperature and pressure builtin sensors in the 520. I think this data must be retrieved via the Toybox.Sensor class, am I rigth? But all my attempts were wrong. Has someone a code example of such project? It's important for me that work with a DataField instead of App, because the first is esier and simpler.

Thanks
  • To access the Sensor Module in a DF, it needs to be done with a background process for the data field. On a number of watches, you can access SensorHistory from the app itself (without doing backgrounding), but SensorHistory isn't available on Edge devices.

    I did Developer Blog post about Creating a Background Service and while I show an example for a watch face, it's the same concept in a data field.
  • To access the Sensor Module in a DF, it needs to be done with a background process for the data field. On a number of watches, you can access SensorHistory from the app itself (without doing backgrounding), but SensorHistory isn't available on Edge devices.

    I did Developer Blog post about Creating a Background Service and while I show an example for a watch face, it's the same concept in a data field.


    Thank you very much for your answer. I'll try to explain what I trying to do:

    I'm trying to read the altitude derived from the barometer in my Edge 520. I can see in the Connect IQ API doc (https://developer.garmin.com/connect-iq/api-docs/) that there is three attributes called 'altitude'. One in Toybox:Sensor:Info, other in Toybox:Position:Info and the third one in Toybox:Activity:Info. The documentation of the 'altitude' from Sensor and Position classes says that "Elevation is derived from the most accurate source: Barometer or GPS in order of descending accuracy. If no GPS is present, then barometer readings will be used", but the one from Activity says nothing about the source. I've tried to show the altitude from Activity:Info using the simple data field project (in the compute() method) in the SDK and I suspect the data comes from the GPS as it varies second by second about 10-15 meters, which is a common uncertainty for autonomous code GPS positioning. But if I inspect the altitudes in a fit file generated by the same Edge 520 they come apparently from the barometer as there is not so big differences between contiguous positions. So my questions are: from which source takes the altitude the Edge 520 for an activity that will be stores in a fit file? Is available the altitude from the barometer from a DataField connect IQ project?

    If no, I would like to derive it from the barometer and temperature readings. As you said me in your answer, these data can be accessed from a DataField project through a background process, but after reading your post in https://developer.garmin.com/index.p...ground-service I'm a bit confused. First of all, I would like to ask what is the frequency the compute() method is called. Maybe each second although in the 520 the option smart is configured for data storing? The other question is about if the background process can be permanently open in order that the compute() method could call the pressure and temperature attributes. I can read in your post that a background process "Temporal events can fire at most every 5 minutes, and will run at most 30 seconds each time it runs".

    I'm starting with connect IQ and I apologize if some of my questions sounds simple
  • I'll start with this part.
    As you said me in your answer, these data can be accessed from a DataField project through a background process, but after reading your post in https://developer.garmin.com/index.p...ground-service I'm a bit confused. First of all, I would like to ask what is the frequency the compute() method is called.

    Once a second. The recording mode (smart or 1 sec doesn't matter)
    The other question is about if the background process can be permanently open in order that the compute() method could call the pressure and temperature attributes. I can read in your post that a background process "Temporal events can fire at most every 5 minutes, and will run at most 30 seconds each time it runs".

    At most every 5 minutes and for at most 30 seconds at a time. That's all it can run. Once the temporal event fires, the data is passed back to the main is by way of a call to Background.exit(), and the background terminates. There's no shared data space.
    I'm starting with connect IQ and I apologize if some of my questions sounds simple


    No problem! We all were just starting out at one time :)

  • As far as the first part, 2.4.x has some new stuff relating to pressure, and I've actually not really looked at it yet (ambient vs adjusted, etc)

    Another thing to note, is even if you calculate your own altitude, you can display it, but not override what's in the .fit file. You can add it as user data to the .fit though.
  • As far as the first part, 2.4.x has some new stuff relating to pressure, and I've actually not really looked at it yet (ambient vs adjusted, etc)

    Another thing to note, is even if you calculate your own altitude, you can display it, but not override what's in the .fit file. You can add it as user data to the .fit though.


    Thank you for your answer (and for the one in https://forums.garmin.com/forum/developers/connect-iq/1264264-connect-iq-2-4-0-beta-sdk-now-available?p=1279661#post1279661). Actually I want to compute the slope of my ride (the Edge 520 has this field in his options, but it cannot be accessed from connect IQ), so I need the barometer altitude because the GPS one has so much error to do this computation. This is the reason because I want to know exactly if the altitude attribute in Activity::Info is GPS or barometric. The connect IQ API doc is not clear about. Only in the altitude attribute from Sensor and Position says "the best of", but it does not explain the criteria for "best". But in the Activity::Info::altitude there is not any information about GPS or barometer. I think it is barometric because inspecting the data recorded in the fit file the altitude does not have abrupt changes. But also there is not information about if the barometric altitude is drift corrected using the GPS altitudes or not at certain times (I found the API doc not very good). So this is the reason because I want to compute my own barometric altitude via pressure and temperature. Now with the SDK v2.4.0 I can access to pressure from Activity::Info (anyone knows when this new SDK supports the Edge 520?) but not to temperature, but as for the slope computation there are only used relative altitudes between near points the temperature correction is not really important. I don't need absolute altitudes because I need the slope only for visualization in the DataField.

    Another question I would like to ask is about the Activity class and the access fron a DataField application. Are the data in Activity::Info only available after the start button for a ride in the Edge 520 was pressed?

    In the near future I wand also to compute the vertical speed and I want to present the data in one field together with the slope, one data above the other. Is there any example about how present multiple data in a single data field?

    Thanks
  • Activity.Info (seen as info in the compute(info) call in a DF)

    Some of the data will be there right away, and some won't be available until you start recording. Some will change when you're paused, and some won't. It depends on what you are looking for.

    You always want to null check things in Activity.Info.

    timerTime won't start until you start recording, and will stop when you pause, while elapsedTime will start when you start recording, and only stop when you end recording, for example.

    You can see the state in timerState to see how you handle the various bits of data.
  • I wrote a DF to generate the grade of the road. It displays grade, vertical rate, elevation and total ascent in one DF. The grade was tricky and it took me a few weeks of tweaking the algorithm and experimenting on the road to get it to display a responsive, accurate grade with minimal noise (values that jump around too much). The issue was a tradeoff in being responsive but not noisey, since I had to work with distance and altitude data from Activity.Info. Altitude is derived from the barometer. It works well now. My DF is called ELEVx4.
  • I wrote a DF to generate the grade of the road. It displays grade, vertical rate, elevation and total ascent in one DF. The grade was tricky and it took me a few weeks of tweaking the algorithm and experimenting on the road to get it to display a responsive, accurate grade with minimal noise (values that jump around too much). The issue was a tradeoff in being responsive but not noisey, since I had to work with distance and altitude data from Activity.Info. Altitude is derived from the barometer. It works well now. My DF is called ELEVx4.


    Thank you for your answer, Dave:

    From the mathematical point of view:
    ------------------------------------------------------

    I compute the grade using the last four pairs of (Activity::Info::altitude, Activity::Info::elapsedDistance). In order to minimize the altitude noise I perform a least squares adjustment to a line h=s*x+b, where h and d are altitude and distance increments referred to the first point in the 4 data array, ans s is the slope. Well, by this way we get the sin of the angle instead of the tan, as the distance is the correspondent to the hypotenuse instead to the leg, but the error is minimum. I'll introduce some more conditionsin my algorithm, such as a minimum and maximun distance thresholds in order to not compute the grade when the distance between the last and the first point is too short (<10 m for example) or not to use all points when de distance is too long. Having also data from Activity::Info::elapsedTime the vertical speed is easy to compute using the altitude increment the one obtained in the line adjustment.

    Ahother possibility could be to adjust a parabola or a polynomial of grade 3 (in this case I should use more than 4 points) and compute its derivative at the last point in order to get the slope, but I suspect that such method could be a lot work for the Edge 520 processor. Also I suspect this method won't produce good results because the computation is done at an extreme of the data.

    From the coding and visualization point of view:
    ---------------------------------------------------------------------

    I'm newbie to Connect IQ programming and I find difficult the layouts and data presentation on the screen. I would like to present in a single data field the grade and the vertical speed, one above the other. But I can't find any example of such schema. Have you any code snippet about? I have also problems to show things as the % symbol after the grade information, just as you do in your ELEVx4 data field. How can I do it?

    Thanks
  • I'm newbie to Connect IQ programming and I find difficult the layouts and data presentation on the screen. I would like to present in a single data field the grade and the vertical speed, one above the other. But I can't find any example of such schema. Have you any code snippet about? I have also problems to show things as the % symbol after the grade information, just as you do in your ELEVx4 data field. How can I do it?
    Thanks


    With a simple DF, you return a value from compute and it gets displayed, with a label. With a complex DF, you do your own screen in onUpdate(), and can use layouts of direct DC calls, and can pretty much do what ever you want, including the text, font, colors, etc.

    How are you trying to display the %? in a simple DF, the following should work:

    return value.toString()+"%";

  • From the coding and visualization point of view:
    ---------------------------------------------------------------------

    I'm newbie to Connect IQ programming and I find difficult the layouts and data presentation on the screen. I would like to present in a single data field the grade and the vertical speed, one above the other. But I can't find any example of such schema. Have you any code snippet about? I have also problems to show things as the % symbol after the grade information, just as you do in your ELEVx4 data field. How can I do it?

    Thanks



    Interesting math insight. I use simple averages but my window is variable. I provide a user setting so I can adjust the window size on the fly to experiment. I've settled on the last 5 readings (seconds). But then I add intelligence to limit grade change per second, and limit max grade allowable. For example, I only allow X% grade change per second. If you instantly go from -10% to 20% grade, it'll take 6 seconds to get there (5% per second). But if that 20% was due to a bad reading, then it'll smooth that out. Also if you stop, I reset grade to zero and clear the 5 sec history. There are a few other little things I do to try to present an accurate grade. I'll consider the LS idea. THANK YOU.

    In terms of presenting. It is easy to write out a VALUE on more than one line - just add a "\n" character to the string. And you should be able to simple add a "%" symbol - as that is an allowable symbol for both the string and numeric font sets.

    I think you wanted to include TEMP to compensate and improve the barometric reading. However, in my experience, you can not trust the device temp value, as direct sunlight will often heat up the device to 10+ degrees over ambient.