Using the indoor bike feature with fitness machine service

I want to read and write data such as incline and resistance from the Zwift app using my nrf52dk device. Based on the information I found online, it seems I need to communicate with the fitness machine service. Since there is no ready example in the Zephyr library, I am struggling. There is a CSC example in Zephyr, and I used it to send speed and cadence values to the Zwift app. However, I still don't understand how to receive data from the Zwift app.

Parents
  • "

    void TreadmillDataAccessNotify(treadmill_Data_t data)
    {
    uint8_t treadmillData[16] = { 0x00 };
    uint16_t flag = data.flags;
    uint16_t flagBit = 0x0001;
    int dataIndex = 2;

    treadmillData[0] = flag & 0xFF;
    treadmillData[1] = (flag >> 8) & 0xFF;
    if ((flag & 0x0001) == 0) {
    uint16_t speedData = (data.instantaneousSpeed); /* Instantaneous Speed */

    addTwoOctData(treadmillData, speedData, dataIndex);
    dataIndex += 2;
    }

    for (int i = 0; i < 11; i++) {
    flagBit = 0x0001 << i;
    if ((flag & flagBit) == flagBit) { /* iterate flag bits*/
    switch (i) {
    case 1: /* Average Speed */
    {
    uint16_t averageData = data.averageSpeed;

    addTwoOctData(treadmillData, averageData, dataIndex);
    dataIndex += 2;
    break;
    }
    case 2: /* Total Distance */
    {
    uint32_t distanceData = data.totalDistance;

    treadmillData[dataIndex] = distanceData & 0xFF;
    treadmillData[dataIndex + 1] = (distanceData >> 8) & 0xFF;
    treadmillData[dataIndex + 2] = (distanceData >> 16) & 0xFF;
    dataIndex += 3;
    break;
    }
    case 3: /* Inclination */
    {
    int16_t inclination = data.inclination;

    addTwoOctData(treadmillData, inclination, dataIndex);
    dataIndex += 2;
    break;
    }
    case 4: /* Elevation Gain */
    {
    uint16_t positiveGain = data.positiveElevationGain;
    uint16_t negativeGain = data.negativeElevationGain;

    addTwoOctData(treadmillData, positiveGain, dataIndex);
    dataIndex += 2;
    addTwoOctData(treadmillData, negativeGain, dataIndex);
    dataIndex += 2;
    break;
    }
    case 7: /* Expended Energy */
    {

    uint16_t energy = data.totalEnergy;
    uint16_t energyPerHour = data.energyPerHour;
    uint8_t energyPerMinute = data.energyPerMinute;

    addTwoOctData(treadmillData, energy, dataIndex);
    dataIndex += 2;
    addTwoOctData(treadmillData, energyPerHour, dataIndex);
    dataIndex += 2;
    treadmillData[dataIndex] = energyPerMinute;
    dataIndex += 1;
    break;
    }
    case 8: /* Heart Rate */
    {
    uint8_t heartRate = data.heartRate;

    treadmillData[dataIndex] = heartRate;
    dataIndex += 1;
    break;
    }
    case 10: /* Elapsed Time */
    {
    uint16_t time = data.elapsedTime;

    addTwoOctData(treadmillData, time, dataIndex);
    dataIndex += 2;
    break;
    }
    default:
    break;
    }
    }
    }

    bt_gatt_notify(NULL, &ftm_svc.attrs[3], &treadmillData[0], dataIndex);
    }"
    This piece of code seems to be processing data from the treadmill. So, how can I process indoor bike data?

Reply
  • "

    void TreadmillDataAccessNotify(treadmill_Data_t data)
    {
    uint8_t treadmillData[16] = { 0x00 };
    uint16_t flag = data.flags;
    uint16_t flagBit = 0x0001;
    int dataIndex = 2;

    treadmillData[0] = flag & 0xFF;
    treadmillData[1] = (flag >> 8) & 0xFF;
    if ((flag & 0x0001) == 0) {
    uint16_t speedData = (data.instantaneousSpeed); /* Instantaneous Speed */

    addTwoOctData(treadmillData, speedData, dataIndex);
    dataIndex += 2;
    }

    for (int i = 0; i < 11; i++) {
    flagBit = 0x0001 << i;
    if ((flag & flagBit) == flagBit) { /* iterate flag bits*/
    switch (i) {
    case 1: /* Average Speed */
    {
    uint16_t averageData = data.averageSpeed;

    addTwoOctData(treadmillData, averageData, dataIndex);
    dataIndex += 2;
    break;
    }
    case 2: /* Total Distance */
    {
    uint32_t distanceData = data.totalDistance;

    treadmillData[dataIndex] = distanceData & 0xFF;
    treadmillData[dataIndex + 1] = (distanceData >> 8) & 0xFF;
    treadmillData[dataIndex + 2] = (distanceData >> 16) & 0xFF;
    dataIndex += 3;
    break;
    }
    case 3: /* Inclination */
    {
    int16_t inclination = data.inclination;

    addTwoOctData(treadmillData, inclination, dataIndex);
    dataIndex += 2;
    break;
    }
    case 4: /* Elevation Gain */
    {
    uint16_t positiveGain = data.positiveElevationGain;
    uint16_t negativeGain = data.negativeElevationGain;

    addTwoOctData(treadmillData, positiveGain, dataIndex);
    dataIndex += 2;
    addTwoOctData(treadmillData, negativeGain, dataIndex);
    dataIndex += 2;
    break;
    }
    case 7: /* Expended Energy */
    {

    uint16_t energy = data.totalEnergy;
    uint16_t energyPerHour = data.energyPerHour;
    uint8_t energyPerMinute = data.energyPerMinute;

    addTwoOctData(treadmillData, energy, dataIndex);
    dataIndex += 2;
    addTwoOctData(treadmillData, energyPerHour, dataIndex);
    dataIndex += 2;
    treadmillData[dataIndex] = energyPerMinute;
    dataIndex += 1;
    break;
    }
    case 8: /* Heart Rate */
    {
    uint8_t heartRate = data.heartRate;

    treadmillData[dataIndex] = heartRate;
    dataIndex += 1;
    break;
    }
    case 10: /* Elapsed Time */
    {
    uint16_t time = data.elapsedTime;

    addTwoOctData(treadmillData, time, dataIndex);
    dataIndex += 2;
    break;
    }
    default:
    break;
    }
    }
    }

    bt_gatt_notify(NULL, &ftm_svc.attrs[3], &treadmillData[0], dataIndex);
    }"
    This piece of code seems to be processing data from the treadmill. So, how can I process indoor bike data?

Children
No Data
Related