How to access Tempe on FR920XT

Former Member
Former Member
Hello,

i would like to know how i can access the Tempe by Monkey C on a Freerunner 920XT.

So specific i would like to know how this datafield does it: https://apps.garmin.com/de-DE/apps/c745113e-64a5-423e-bfe6-e2124089fa31
I played a bit around and got the idea that they implement the hole Ant+ connection procedure in it. So i searched for a documentation about the protocoll. But i didnt find anything so i am asking your help. If anybody knows something i would be glad to get some more informations.


Best regards Leachim.
  • Have you tried setting the channel period to 8192?

    I've done a lot of testing using SimulANT+, but noticed this morning that it doesn't seem to support simulating an environment sensor.

    Travis
  • Former Member
    Former Member over 9 years ago
    @sharkbait_au Thanks for the Device Profile it works exactly how i want to with 0,5Hz. But i am still searching for my failure what i am doing wrong with Antware II. I also just set Channel Assignment --> Slave
    Channel ID --> 0,25,0
    Basic --> Set Radio Frequency --> 57
    Basic --> Channel Period --> 65535 (becouse of the defauls setting of the Sensor)
    Auto-Open

    with your template that Settings work perfect, so what do i miss?


    My actual Code to talk with the Tempe is:
    const DEVICE_TYPE = 25; //Tempe
    const PERIOD = 65535; //0,5 Hz


    function initialize()
    {
    // Get the channel
    chanAssign = new Ant.ChannelAssignment(
    Ant.CHANNEL_TYPE_RX_NOT_TX,
    Ant.NETWORK_PLUS);
    GenericChannel.initialize(method(:onMessage), chanAssign);

    // Set the configuration
    deviceCfg = new Ant.DeviceConfig( {
    :deviceNumber => 0, //Wildcard our search
    :deviceType => DEVICE_TYPE,
    :transmissionType => 0,
    :messagePeriod => PERIOD,
    :radioFrequency => 57, //Ant+ Frequency
    :searchTimeoutLowPriority => 18, //Timeout in 45s
    :searchThreshold => 0} ); //Pair to all transmitting sensors
    GenericChannel.setDeviceConfig(deviceCfg);

    data = new TempeData();
    searching = true;
    System.println("Ant initalized");
    }


    function open()
    {
    // Open the channel
    GenericChannel.open();

    data = new TempeData();
    pastEventCount = 0;
    searching = true;
    System.println("Ant channel opened");
    }

    function closeSensor()
    {
    GenericChannel.close();
    }


    function onMessage(msg)
    {
    System.println("Ant message recieved ID:"+ msg.messageId);
    System.println("Device Typ:"+ msg.deviceType);
    System.println("transmission Typ:"+ msg.transmissionType);
    System.println("RSSI:"+ msg.rssi);
    // Parse the payload
    var payload = msg.getPayload();

    if( Ant.MSG_ID_BROADCAST_DATA == msg.messageId )
    {
    if( TempeDataPage.PAGE_NUMBER == (payload[0].toNumber() & 0xFF) )
    {
    System.println("Tempe datea recieved");
    // Were we searching?
    if(searching)
    {
    searching = false;
    // Update our device configuration primarily to see the device number of the sensor we paired to
    deviceCfg = GenericChannel.getDeviceConfig();
    }
    var dp = new TempeDataPage();
    dp.parse(msg.getPayload(), data);
    // Check if the data has changed and we need to update the ui
    if(pastEventCount != data.eventCount)
    {
    Ui.requestUpdate();
    pastEventCount = data.eventCount;
    System.println("new Tempe Data");
    }
    else
    {
    System.println("Tempe Data not new");
    }
    }
    }
    else if( Ant.MSG_ID_CHANNEL_RESPONSE_EVENT == msg.messageId )
    {
    if( Ant.MSG_ID_RF_EVENT == (payload[0] & 0xFF) )
    {
    if( Ant.MSG_CODE_EVENT_CHANNEL_CLOSED == (payload[1] & 0xFF) )
    {
    // Channel closed, re-open
    open();
    }
    else if( Ant.MSG_CODE_EVENT_RX_FAIL_GO_TO_SEARCH == (payload[1] & 0xFF) )
    {
    searching = true;
    Ui.requestUpdate();
    }
    }
    else
    {
    //It is a channel response.
    }
    }
    }



    So its pretty much exactly what the Mo2 Sample does.
    When i launch it it does not recieve any broadcast data.

    my DeviceX.txt sais just something like:
    7203.828 { 279945562} Rx - [A4][03][40][00][01][07][E1]
    7203.906 { 279945640} Tx - [A4][01][4B][00][EE][00][00]
    7203.906 { 279945640} Rx - [A4][03][40][00][4B][00][AC]
    7233.828 { 279975562} Rx - [A4][03][40][00][01][01][E7]
    7233.828 { 279975562} Rx - [A4][03][40][00][01][07][E1]
    7233.906 { 279975640} Tx - [A4][01][4B][00][EE][00][00]
    7233.906 { 279975640} Rx - [A4][03][40][00][4B][00][AC]
    7263.828 { 280005562} Rx - [A4][03][40][00][01][01][E7]
    7263.828 { 280005562} Rx - [A4][03][40][00][01][07][E1]
    7263.906 { 280005640} Tx - [A4][01][4B][00][EE][00][00]
    7263.906 { 280005640} Rx - [A4][03][40][00][4B][00][AC]
    7293.828 { 280035562} Rx - [A4][03][40][00][01][01][E7]
    7293.828 { 280035562} Rx - [A4][03][40][00][01][07][E1]
    7293.906 { 280035640} Tx - [A4][01][4B][00][EE][00][00]
    7293.906 { 280035640} Rx - [A4][03][40][00][4B][00][AC]
    7323.828 { 280065562} Rx - [A4][03][40][00][01][01][E7]
    7323.828 { 280065562} Rx - [A4][03][40][00][01][07][E1]
    7323.906 { 280065640} Tx - [A4][01][4B][00][EE][00][00]
    7323.906 { 280065640} Rx - [A4][03][40][00][4B][00][AC]
    7353.828 { 280095562} Rx - [A4][03][40][00][01][01][E7]
    7353.828 { 280095562} Rx - [A4][03][40][00][01][07][E1]
    7353.906 { 280095640} Tx - [A4][01][4B][00][EE][00][00]
    7353.906 { 280095640} Rx - [A4][03][40][00][4B][00][AC]
    7383.828 { 280125562} Rx - [A4][03][40][00][01][01][E7]
    7383.828 { 280125562} Rx - [A4][03][40][00][01][07][E1]
    7383.906 { 280125640} Tx - [A4][01][4B][00][EE][00][00]
    7383.906 { 280125640} Rx - [A4][03][40][00][4B][00][AC]
    7413.828 { 280155562} Rx - [A4][03][40][00][01][01][E7]
    7413.828 { 280155562} Rx - [A4][03][40][00][01][07][E1]
    7413.906 { 280155640} Tx - [A4][01][4B][00][EE][00][00]
    7413.906 { 280155640} Rx - [A4][03][40][00][4B][00][AC]
    7443.828 { 280185562} Rx - [A4][03][40][00][01][01][E7]
    7443.828 { 280185562} Rx - [A4][03][40][00][01][07][E1]
    7443.906 { 280185640} Tx - [A4][01][4B][00][EE][00][00]
    7443.906 { 280185640} Rx - [A4][03][40][00][4B][00][AC]
    7473.828 { 280215562} Rx - [A4][03][40][00][01][01][E7]
    7473.828 { 280215562} Rx - [A4][03][40][00][01][07][E1]
    7473.906 { 280215640} Tx - [A4][01][4B][00][EE][00][00]
    7473.906 { 280215640} Rx - [A4][03][40][00][4B][00][AC]
    7503.828 { 280245562} Rx - [A4][03][40][00][01][01][E7]
    7503.828 { 280245562} Rx - [A4][03][40][00][01][07][E1]
    7503.906 { 280245640} Tx - [A4][01][4B][00][EE][00][00]
    7503.906 { 280245640} Rx - [A4][03][40][00][4B][00][AC]
    7533.828 { 280275562} Rx - [A4][03][40][00][01][01][E7]
    7533.828 { 280275562} Rx - [A4][03][40][00][01][07][E1]
    7533.906 { 280275640} Tx - [A4][01][4B][00][EE][00][00]
    7533.906 { 280275640} Rx - [A4][03][40][00][4B][00][AC]
    7563.828 { 280305562} Rx - [A4][03][40][00][01][01][E7]
    7563.828 { 280305562} Rx - [A4][03][40][00][01][07][E1]
    7563.906 { 280305640} Tx - [A4][01][4B][00][EE][00][00]
    7563.906 { 280305640} Rx - [A4][03][40][00][4B][00][AC]
    7593.828 { 280335562} Rx - [A4][03][40][00][01][01][E7]
    7593.844 { 280335578} Rx - [A4][03][40][00][01][07][E1]
    7593.906 { 280335640} Tx - [A4][01][4B][00][EE][00][00]
    7593.906 { 280335640} Rx - [A4][03][40][00][4B][00][AC]
    7623.828 { 280365562} Rx - [A4][03][40][00][01][01][E7]
    7623.828 { 280365562} Rx - [A4][03][40][00][01][07][E1]
    7623.906 { 280365640} Tx - [A4][01][4B][00][EE][00][00]
    7623.906 { 280365640} Rx - [A4][03][40][00][4B][00][AC]
    7653.828 { 280395562} Rx - [A4][03][40][00][01][01][E7]
    7653.828 { 280395562} Rx - [A4][03][40][00][01][07][E1]
    7653.906 { 280395640} Tx - [A4][01][4B][00][EE][00][00]
    7653.906 { 280395640} Rx - [A4][03][40][00][4B][00][AC]
    7683.328 { 280425062} Rx - [A4][03][40][00][01][01][E7]
    7683.328 { 280425062} Rx - [A4][03][40][00][01][07][E1]
    7683.406 { 280425140} Tx - [A4][01][4B][00][EE][00][00]
    7683.406 { 280425140} Rx - [A4][03][40][00][4B][00][AC]
    7713.078 { 280454812} Rx - [A4][03][40][00][01][01][E7]
    7713.078 { 280454812} Rx - [A4][03][40][00][01][07][E1]
    7713.109 { 280454843} Tx - [A4][01][4B][00][EE][00][00]
    7713.109 { 280454843} Rx - [A4][03][40][00][4B][00][AC]
    7743.078 { 280484812} Rx - [A4][03][40][00][01][01][E7]
    7743.078 { 280484812} Rx - [A4][03][40][00][01][07][E1]
    7743.109 { 280484843} Tx - [A4][01][4B][00][EE][00][00]
    7743.109 { 280484843} Rx - [A4][03][40][00][4B][00][AC]
    7772.578 { 280514312} Rx - [A4][03][40][00][01][01][E7]
    7772.578 { 280514312} Rx - [A4][03][40][00][01][07][E1]
    7772.609 { 280514343} Tx - [A4][01][4B][00][EE][00][00]
    7772.609 { 280514343} Rx - [A4][03][40][00][4B][00][AC]
    7802.578 { 280544312} Rx - [A4][03][40][00][01][01][E7]
    7802.578 { 280544312} Rx - [A4][03][40][00][01][07][E1]
    7802.609 { 280544343} Tx - [A4][01][4B][00][EE][00][00]
    7802.609 { 280544343} Rx - [A4][03][40][00][4B][00][AC]
    7832.578 { 280574312} Rx - [A4][03][40][00][01][01][E7]
    7832.578 { 280574312} Rx - [A4][03][40][00][01][07][E1]
    7832.609 { 280574343} Tx - [A4][01][4B][00][EE][00][00]
    7832.609 { 280574343} Rx - [A4][03][40][00][4B][00][AC]



    Leachim
  • Former Member
    Former Member over 9 years ago
    I think what you are maybe failing to realize is that you have received your data.

    The payload is your data. You have successfully retrieved the data page
    var payload = msg.getPayload();

    The page numbers correspond to the Data pages from pg15 onwards in ANT_Device_Profile_Environment.pdf
    TempeDataPage.PAGE_NUMBER == (payload[0].toNumber() & 0xFF)

    You must extract the bytes & bits to decode the data. So if you wanted to extract the temperature for example (see 6.4, pg 16), you could do it like this...
    var lsb = payload[6];
    var msb = payload[7];
    // Shift the MSB bits to their correct place
    msb = msb << 8;
    var currentTemp = msb + lsb;


    If you wanted to read the low you also need to mask the bits, eg..
    // 0xF0 = b11110000 Note bit order 7-0.
    var low temp = (payload[4] & 0xF0) << 8 + payload[3];


    Does that help?
  • Former Member
    Former Member over 9 years ago
    I understood that the Payload is the Data and how to logically split it. That was pretty clear from the sample code. I also finished already some functions to do it. But thats not where i stuck.

    I dont get to the point where i really recieve some Broadcast Data. There is just Ant.MSG_ID_CHANNEL_RESPONSE_EVENT that arrives

    Leachim
  • Former Member
    Former Member over 9 years ago
    Got ya.

    So I looked a little closer. Your search priority is an incorrect value. Even though the documentation state a range of 0-12 in the past it did not allow higher than 10. Personally I leave both search params out of the config and allow the defaults.
  • Former Member
    Former Member over 9 years ago
    @sharkbait_au

    Your great! that was it! Big Thx!
  • Former Member
    Former Member over 8 years ago
    Negative Values

    Right now i have the following Problem:

    positive temperatures worked pretty good but right now it is getting colder. And it seems that i have a big Problem with negative temperatures.

    As an example the min Temp code is:

    hidden function minTemp(payload)
    {
    // 0xF0 = b11110000 Note bit order 7-0.
    Sys.println( (payload[4] & 0xF0).toString() +"\n" );
    Sys.println( payload[3].toString() +"\n" );
    Sys.println(((payload[4] & 0xF0) << 4 + payload[3]).toString() +"\n" );
    return ((payload[4] & 0xF0) << 4 + payload[3]) / 10f;
    }


    Console output:
    240

    20

    3860

    Return Value is: 386.000000

    The Real Temperature (known from original Garmin Tempe Data Field) is: -23.5
    I dont really get the point how i have to process the Value to get the correct neg value
    3860 --> -235

    does anyone see what i miss?

    Thanks Michael
  • Former Member
    Former Member over 8 years ago
    It's late and i'm tired. Deleted last message because thought I had missed something. I don't think I had. So yeah...

    I think you need to shift the MSN 8 places. You are only shifting it 4. It needs to move 8 places to clear the LSB.
  • To get the lowest recorded value, we want to get the 4 most significant bits (1 nibble) of the 4th payload byte into the third nibble of a 12-bit value. It seems to me the logic should be...

    // payload[3] = 0xBC;
    // payload[4] = 0xAF;
    // payload[5] = 0xDE;

    // remember to mask out the bits in payload[4] that we don't want to consider for each calculation
    // it is necessary because half of payload[4] is used for the min temp, and the other half is used
    // for the max temp.

    var min_temp = ((payload[4] & 0xF0) << 4) | payload[3];
    // result = (0xA0 << 4) | 0xBC;
    // result = (0xA00) | 0xBC;
    // result = 0xABC;

    var max_temp = (payload[5] << 4) | (payload[4] & 0x0F);
    // result = (0xDE << 4) | (0xAF & 0x0F)
    // result = (0xDE0) | (0x0F)
    // result = 0xDEF


    Once you have built up the correct value from the bits, you can decode it to decimal...

    function decode_12b_temperature(value)
    {
    // handle special value
    if (value == 0x800) {
    value = null;
    }

    // handle negative values
    else if (value & 0x800) {
    // clear the sign bit
    value &= 0x7FF;

    // sign extend and scale
    value *= -0.1;
    }

    // handle positive values
    else {
    value *= 0.1;
    }

    return value;
    }


    Here is a test that you can use to verify it...

    (:test) function test_decode_12b_temperature(logger)
    {
    decode_12b_temperature(logger, 0x000, 0.0);
    decode_12b_temperature(logger, 0x001, 0.1);

    decode_12b_temperature(logger, 0x7FE, 204.6);
    decode_12b_temperature(logger, 0x7FF, 204.7);
    decode_12b_temperature(logger, 0x800, null);
    decode_12b_temperature(logger, 0x801, -0.1);
    decode_12b_temperature(logger, 0x802, -0.2);

    decode_12b_temperature(logger, 0xFFE, -204.6);
    decode_12b_temperature(logger, 0xFFF, -204.7);

    return true;
    }


    The calculation is the similar for a 16-bit value.

    Travis
  • It should be noted that there appears to be a bit of rounding error at the extremes. The value 0x7FF becomes 204.600006 and 204.699997. You can avoid this by using double precision (multiply by -1.0d and 1.0d) if you need the actual value to be exact. Otherwise you can format the value to a string and fix the rounding error when you present it (with value.format("%.1f)).

    Travis