Hello MT_dialog,
I already used the template project yith cust1 and cust2 services, and now I want to have 100 fields, so what could be the best way to do that ?
Should I have just one service with 100 fields or create for exemple 5 services and 20 fields per service ?
Otherwise , is there any better solution ? because I need to send 100 variables in connected mode to my BLE app.
Thank you,
Keywords:
Device:
Hello,
I tried to create 20 fields in the cust1 service , but when I run the project , I got the error : RESET_MEM_ALLOC_FAIL (0xF2F2F2F2) in the wrap_platform_reset function. could it be fixed ? or I just reached the limits ?
Thank you,
The idea of having 100 characteristics seems bad. The service discovery time will take very long time and the memory allocations needed for all data structures would probably take up quite some large RAM.
What is it you would like to do?
If you need to have the ability to set multiple variables remotely, you should implement some simple protocol using one characteristic, since you have your custom service anyway.
One solution is that when you write to the characteristic from your central, use the first byte to indicate which variable you would like to write to. The rest of the bytes consists of the actual value. Then in your gatt characteristic write handler, you simply check what the first byte is and act on that.
如果你还需要能够阅读你的变量,you will not be able to use gatt read procedure directly. Instead enable notifications and have a way that if a write command is sent with a particular value (that will indicate you want to read), you send back a notification to the central that contains the value (which should also include which variable is being sent). Or if you have notifications you would like to send without the central requesting it, do the same by including both the variable id and the data in your characteristic value. To be sure notifications and writes don't interfere with each other over one characteristic, make sure you actually never use the attmdb_att_set_value in your write command handler.
Thank you,
I already thought about this idea but the problem is that I want to send about 100 values to my Smartphone application that will display this data , and if I use just one characteristic , I should make 100 send operation before getting all values on the Smartphone app , so it will take a long time too and will be more complex.
But here just with 20 characteristic I get memory allocation fail , so I think I don't have so many choices..
How large are your values? Maybe you can pack them together and send many values in one notification?
It won't be any performance changes if you send a notification of the same characteristic multiple times or if you have many characteristics and send one notification each. It can still only send one packet at a time.
Let's say 2 bytes per variable, I think the maximum size of a characteristic is 16 bytes right ? so if it's true , I need more than 10 characteristics..
Hi.
You can send 20 bytes in one notification.
That means you will have to send 10 notifications if you pack everything.
Most smartphones tolerate 3-4 packets per connection event. That means you would need about 3 connection events to send everything. With a connection interval of 50 ms (Android's default), that will take 150 ms.
Hi bensalemsaif,
As Joacimwe suggested having 100 characteristics its a bad idea, and you should try as suggested to use somekind of a protocol and merge your values in one or more characteristics.
The fact that you ve got this indication (platform reset) means that you ve exausted the memory allocated for the database. How large the database can be depends on how memory the 580 can allocate for db purpose. Please check the below post on how to make your bd heap largerhttp://support.dialog-semiconductor.com/increasing-dbheapsz, but still packing your data in one or a bit more characteristics is a better choice.
Thanks MT_dialog
Hello,
Thank both of you for your answers, I think merging my values would be the best choice, but could you please explain to me how to do that ? until now let's say here is what I have :
- Field UUID : 128-bits
- Field char Len
- Field User Descr
- att_char128_desc
- and in my database : field_char , field_val , and field_user_desc
I know that this function will update the databse because my data will change dynamically (i will get it using uart) :
attmdb_att_update_value(handle, length, offset, value)
So now if I want to merge my values as you suggested in one field , should I just call the update function with a buffer containing all my values ? I did like that and I could put more than 20 bytes how is it possible ?
Here attached a screenshot with reading a buffer of 40 bytes
Thank you,
The attributes themselves can be larger than 20 bytes, but notifications can only be 20 bytes (unless you increase MTU).
Your central most likely uses a GATT feature called "Read Long Characteristic Values". (See Bluetooth specification for more info.)
That procedure uses ATT Read Blob Requests repeatedly to retrieve all parts of the characteristic. In each request-response pair only 22 bytes can be transferred. The downside with this procedure is that it is ineffective. It takes approximately two roundtrips per part. If that is no problem for you, you can do it that way. With notifications you can send all of them at once (as many as can fit in one connection event).
If your central supports, I'd also suggest you increase your MTU to be able to send larger packets.
你也可以看看GATT part of the Bluetooth specification to see all available options.
What SDK are you using? If you use SDK5 and the custom service, to send notifications you use the CUSTS1_VAL_NTF_REQ message. When it has been processed and is ready to receive the next one, you will receive the CUSTS1_VAL_NTF_CFM message in user_peripheral.c. If you go for the Read Long Characteristic Values method, you simply send the message CUSTS1_VAL_SET_REQ and set your large characteristic value. Then the stack automatically handles the read requests from your central.
Hello,
I'm using SDK 5.0.3 and in my gapm.c file I have this value : GAP_MAX_LE_MTU_VAR = 512 , so It seems that my MTU = 512 right ?
Now for notifications, I'm able to send my data just with those two lines once I get the new values over UART :
attmdb_att_update_value((custs1_env.shdl + CUST1_IDX_FIELD1_VAL), length, offset, new_value)
prf_server_send_event((prf_env_struct *)&custs1_env, 0, (custs1_env.shdl + CUST1_IDX_FIELD1_VAL))
and I can see my new values updating dynamically if I enable notifications in Smartphone application, is it correct ?
Thanks,
Hi bensalemsaif,
Yes, only if you enable the notifications on your phone side you should be able to receive data on your client. Regarding the code that you are using to send the data, why you dont the message and let the custom profile handle the rest, you can just allocate a CUSTS1_VAL_NTF_REQ and the corresponding handler (custs1_val_ntf_req_handler) will update the values by using the same code that you are using.
Thanks MT_dialog