List index too large. using ble blocks with listpicker

Hi! I am using BLE blocks for an application and I am receiving the error that the list is to large when I select the device to connect from the ListPicker. I don’t know what to do, I have tried so many things (like connect with address instead of connect index) and I don’t know how to solve that. Please I need some help.



This is the error that shows when I select the device from ListaDispositivos (ListPicker’s name)
image

We need to see the list on your Android device Iman. Use the built-in screenshot function and post the image here.

1 Like


This is my listPicker view @ChrisWard . Thank you in advance

The error message about selecting item 2 of a list ((0 0)) suggests that a list was coerced into a string. Should that List Picker be loaded by Elements, or by ElementsFromString?
I would expect that a DeviceList is a List, so it would be loaded into Elements.

1 Like

That’s the correct use of ElementsFromString. I’ve tried to connect ListPicker.Elementos with BluetoothLE1.DeviceList and it’s not possible. @ABG

what about using Do it to find out, what will be returned?

my guess is, the error occurs further down in the AfterPicking event... the part which is not provided in the screenshot

Taifun


Trying to push the limits! Snippets, Tutorials and Extensions from Pura Vida Apps by Taifun.

1 Like


Please export your project and post it here.

1 Like

monitorEdema (1).aia (222.7 KB)
This is my project @ABG

See the attached.
We need to see your sketch to straighten this out.

1 Like

@ABG I’m not using Arduino. I coded my program in MBED. Here is the sketch from the Nordic app

That’s not the code Iman…

1 Like

I cannot upload the file cause it’s from MBED and has a “.hex” extension. @ChrisWard.
Here’s a copy from my Service class:
#ifndef BLE_PULSOS_SENSOR_RATE_SERVICE_H
#define BLE_PULSOS_SENSOR_RATE_SERVICE_H

#define UUID_PULSOS_SENSOR_RATE_SERVICE 0x8A05
#define UUID_PULSOS_SENSOR_RATE_MEASUREMENT_CHAR 0x5A06
#define UUID_LEG_SENSOR_LOCATION_CHAR 0x4A07
#define UUID_PULSOS_SENSOR_RATE_CONTROL_FUENTE_CHAR 0x6A09

#include “BLE.h”

class PulsosSensorRateService {
public:
/**
* enum Localización del sensor
* brief Localización del sensor en las piernas derecha o izquierda
/
enum {
LOCATION_OTHER = 0, /
!< Other location. /
LOCATION_PIERNA_DERECHA, /
!< Pierna Derecha. /
LOCATION_PIERNA_IZQUIERDA, /
!< Pierna Izquierda. */
};

public:
/**
* brief Constructor con un valor de psrCounter (PulsosSensorRate Counter) de 8bits.
*
* param[ref] _ble
* Reference to the underlying BLE.
* param[in] psrCounter (8-bit)
* Valor inicial para psrRate (número de pulsos)
* param[in] location
* Localización del sensor
*/
PulsosSensorRateService(BLE &_ble, uint8_t psrCounter, uint8_t location, uint8_t controlFuente) :
ble(_ble),
valueBytes(psrCounter),
psrRate(UUID_PULSOS_SENSOR_RATE_MEASUREMENT_CHAR, valueBytes.getPointer(),
valueBytes.getNumValueBytes(), PulsosSensorRateValueBytes::MAX_VALUE_BYTES,
GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY),
psrLocation(UUID_LEG_SENSOR_LOCATION_CHAR, &location),
controlPoint(UUID_PULSOS_SENSOR_RATE_CONTROL_FUENTE_CHAR, &controlFuente) {
setupService();
}

PulsosSensorRateService(BLE &_ble, uint16_t psrCounter, uint8_t location,uint8_t controlFuente) :
    ble(_ble),
    valueBytes(psrCounter),
    psrRate(UUID_PULSOS_SENSOR_RATE_MEASUREMENT_CHAR, valueBytes.getPointer(),
            valueBytes.getNumValueBytes(), PulsosSensorRateValueBytes::MAX_VALUE_BYTES,
            GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY),
    psrLocation(UUID_LEG_SENSOR_LOCATION_CHAR, &location),
    controlPoint(UUID_PULSOS_SENSOR_RATE_CONTROL_FUENTE_CHAR, &controlFuente) {
    setupService();
}

/**
 * brief Establece un nuevo valor de 8 bits para los pulsos del sensor.  
 *
 * param[in] psrCounter
 *                  Número de pulsos.
 */
void updatePulsosSensorRate(uint8_t psrCounter) {
    valueBytes.updatePulsosSensorRate(psrCounter);
    ble.gattServer().write(psrRate.getValueHandle(), valueBytes.getPointer(), valueBytes.getNumValueBytes());
}

/**
 * Establece un nuevo valor de 16 bit para el número de pulsos. 
 *
 * param[in] psrCounter
 *                  Número de pulsos.
 */
void updatePulsosSensorRate(uint16_t psrCounter) {
    valueBytes.updatePulsosSensorRate(psrCounter);
    ble.gattServer().write(psrRate.getValueHandle(), valueBytes.getPointer(), valueBytes.getNumValueBytes());
}

/** Devuelve el valor del atributo Gatt controlPoint*/

GattAttribute::Handle_t getValueHandle() const
{
    return controlPoint.getValueHandle();
}


/**
 * Esta callback permite al pulsos sensor rate service recibir actualizacion de controlPoint. 
 * param[in] params
 *     Información de la característica actualizada
 */
virtual void onDataWritten(const GattWriteCallbackParams *params) {
    if (params->handle == controlPoint.getValueAttribute().getHandle()) {
   
    }
}

protected:
void setupService(void) {
GattCharacteristic *charTable[] = {&psrRate, &psrLocation, &controlPoint};
GattService psrService(UUID_PULSOS_SENSOR_RATE_SERVICE, charTable, sizeof(charTable) / sizeof(GattCharacteristic *));

    ble.addService(psrService);
    ble.onDataWritten(this, &PulsosSensorRateService::onDataWritten);
}

protected:
/Representación privada interna de los bytes que trabajan con el valor de la característica numero de pulsos rate/
struct PulsosSensorRateValueBytes {
static const unsigned MAX_VALUE_BYTES = 5; /* Flags, and up to two bytes for heart rate. */
static const unsigned FLAGS_BYTE_INDEX = 0;

    static const unsigned VALUE_FORMAT_BITNUM = 0;
    static const uint8_t  VALUE_FORMAT_FLAG   = (1 << VALUE_FORMAT_BITNUM);

    PulsosSensorRateValueBytes(uint8_t psrCounter) : valueBytes() {
        updatePulsosSensorRate(psrCounter);
    }

    PulsosSensorRateValueBytes(uint16_t psrCounter) : valueBytes() {
        updatePulsosSensorRate(psrCounter);
    }

    void updatePulsosSensorRate(uint8_t psrCounter) {
        valueBytes[FLAGS_BYTE_INDEX]    &= ~VALUE_FORMAT_FLAG;
        valueBytes[FLAGS_BYTE_INDEX + 1] = psrCounter;
    }

    void updatePulsosSensorRate(uint16_t psrCounter) {
        valueBytes[FLAGS_BYTE_INDEX]    |= VALUE_FORMAT_FLAG;
        valueBytes[FLAGS_BYTE_INDEX + 1] = (uint8_t)(psrCounter & 0xFF);
        valueBytes[FLAGS_BYTE_INDEX + 2] = (uint8_t)(psrCounter >> 8);
    }

    uint8_t       *getPointer(void) {
        return valueBytes;
    }

    const uint8_t *getPointer(void) const {
        return valueBytes;
    }

    unsigned       getNumValueBytes(void) const {
        return 1 + ((valueBytes[FLAGS_BYTE_INDEX] & VALUE_FORMAT_FLAG) ? sizeof(uint16_t) : sizeof(uint8_t));
    }

private:
    /* Primer byte: 8-bit values, no extra info. Segundo byte: uint8_t PSR value */
    uint8_t valueBytes[MAX_VALUE_BYTES];
};

protected:
BLE &ble;

PulsosSensorRateValueBytes  valueBytes;

GattCharacteristic                   psrRate;
ReadOnlyGattCharacteristic<uint8_t>  psrLocation;
WriteOnlyGattCharacteristic<uint8_t> controlPoint;

};

#endif /* #ifndef BLE_PULSOS_SENSOR_RATE_SERVICE_H*/

It's your code we would like to see - you obviously do not write the code in hex :grin:

The point is, The device Script and your App have to be matched - i.e. what is being sent must be in a format that is expected by the App. Your App blocks are expecting a data stream whose individual values are separated by '|' but it would seem that is not the case - possibly because the Script does not format the data with that separator or possibly because of the data type - only strings and number values can use separators in that way - if the original data type sent is bytes, that would be an issue.

It is also important that the Script has an end-of-data marker, typically a newline character (\n), ascii char 10.

1 Like

…looking at your Blocks, you have attempted to convert bytes to text before creating the list. So is the BLE device sending text? Seems like it. Use the App Inventor BLE strings block instead of the bytes block. Note that strings that consist of numbers rather than text are handled as numbers by App Inventor as appropriate.

1 Like