Pages: [1] 2   Go Down
Author Topic: BGLib Arduino library for Bluegiga BLE112 Bluetooth Low Energy module  (Read 14353 times)
0 Members and 1 Guest are viewing this topic.
Roanoke, VA
Offline Offline
Jr. Member
**
Karma: 6
Posts: 66
Creating order out of chaos!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hey everyone,

I just posted the first release of an Arduino implementation of BGLib, the binary protocol used to interface with the Bluegiga BLE112 Bluetooth Low Energy module. I also sell a breakout board for this module if you're interested in prototyping with it.

BGLib is a typical event-driven protocol; it has commands, responses, and events. All of these are documented in detail (though short on examples) in Bluegiga's API reference manual, and Bluegiga even provides a sample ANSI C implementation of BGLib. However, it is a little bit more complicated to use than I prefer, so rather than porting everything, I wrote this one to be more consistent with how I like to write libraries. It's still not commented very well, but it's pretty basic and the currently included demo sketch makes for a decent quick-start guide. Here's a basic synopsis:

Commands are pre-defined in the library. They take individual parameters according to the API docs. (I did keep the exact command names and parameter structures the same so that the Bluegiga API docs would still apply.)

Responses are defined as function pointers with no default implementation. They don't need to be defined, but you can supply your own handlers if you want. Responses typically come back right after commands are issued, but there is some tiny delay sometimes, so for ultimate efficiency they had to be implemented as callbacks (or ignored). Response callbacks left undefined are ignored whenever they occur.

Events are also defined as function pointers with no default implementation. Event function pointers which are not set to real functions are simply ignored whenever they occur. Events may happen at any time based on module configuration.

You can see the demo BGLib_scanner.ino sketch here to see this architecture in action. This demo is built for the Arduino Uno, set to have the PC connected to the hardware serial port and the BLE112 connected to a SoftwareSerial port running at 9600 baud on pins 2 and 3.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi Jeff,

Thanks for that, really useful.
I've been experimenting a bit, I'm using USART 0 rather than one on pins P1_4 & P1_5. According to the spec, there is a special 'packet' mode that can be defined in the hardware.xml for using BGApi over a serial port without flow control. It just requires adding a length byte to the start of the command - I added this to your code and it seems to work fine.
I'm wondering about using BGApi over SPI, as the docs suggest this is possible, however it's not clear to me how this would be achieved in terms of which end is master and which end is slave, and how the slave end sends data when the master end isn't clocking any across.

Toby
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Just heard back from BlueGiga support:

"Hello,

BGAPI is not supported over SPI at the moment, you can use this over UART and USB at this time. SPI can support things like sensors and displays for now.

Best regards,

Sam Pullen"

It would help if the BlueGiga docs were consistent - Various diagrams etc show BGAPI being connected to a microcontroller via SPI.

Logged

Roanoke, VA
Offline Offline
Jr. Member
**
Karma: 6
Posts: 66
Creating order out of chaos!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I haven't tried that method (BGAPI over SPI) personally yet, though from a hardware standpoint, the CC2540 should technically be able to do it. Maybe the BLE112's custom stack just doesn't support it. Where in the docs have you seen the diagram that suggests otherwise?
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 2
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi Jeff,

I was wondering what kind of "hardware flow control issues" you are having with the BLE112? I am working with this device on the MSP430 and I am also seeing some hardware flow control problems. Specifically the BLE does not ever assert the CTS line to throttle the MSP430 and the buffer overflows almost immediately. I am transmitting at 115200 baud. Also I have seen DMA recommended for the CC2540 at these baud rates, but there does not appear to be any way to explicitly enable this using the Bluegiga API (unless it occurs automatically in the Bluegiga SW for this setting).

With regard to SPI connectivity, I also tried to implement this based on the documentation from Bluegiga, but got very odd responses on the scope. I eventually contacted Bluegiga and received the same response as TheBarrelShifter, above i.e. it is not implemented yet. The diagrams in the API_53 guide (pg smiley-cool, BLE_Stack_API_reference_v1.3 (also pg 8.), BLE_getting_started_v1.3 (pg 15), etc all show an SPI interface between the host and the BGAPI protocol.
Logged

Roanoke, VA
Offline Offline
Jr. Member
**
Karma: 6
Posts: 66
Creating order out of chaos!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I was wondering what kind of "hardware flow control issues" you are having with the BLE112? I am working with this device on the MSP430 and I am also seeing some hardware flow control problems. Specifically the BLE does not ever assert the CTS line to throttle the MSP430 and the buffer overflows almost immediately. I am transmitting at 115200 baud. Also I have seen DMA recommended for the CC2540 at these baud rates, but there does not appear to be any way to explicitly enable this using the Bluegiga API (unless it occurs automatically in the Bluegiga SW for this setting).

This "packet mode" setting must be enabled by adding ' mode="packet" ' to the <usart /> tag in hardware.xml. In my test setup with an Arduino, I've actually not had that particular problem. My errors seem to be more like UART timing errors than flow control errors; the very first byte is a spurious 0xFE or 0xFF, and/or the last byte is the same. I am using SoftwareSerial though, and I suspect that is the problem. I have not yet tried sending large amounts of data to the module from the Arduino yet though. My demo sketch receives a lot of data, but that's it. I do also have the CTS pin on the BLE tied to ground, but this is not likely to affect your issue.

SPI as implemented on the module doesn't have any flow control or DMA buffering; using SPI for generic bidirectional data transfer is not easy even without using BGAPI. I guess they may add support for it later.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 2
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi Jeff,

Thanks for the reply and the additional details. I obtained a software update for the stack from Blugiga and now the hardware flow control works as expected. I am transmitting 20 byte packets every ~20ms and as far as I can tell initially, this is reliable.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi Jeff,

I'm experiencing some odd behaviour, specifically when the binary size of my application gets about about 17,000 bytes - Under this size BGLib and BGAPI over serial using SoftwareSerial work very reliably, but above this kind of size strange things begin to happen such as the BLE112 not responding to commands, or either the BLE112 or Arduino spontaneously resetting.

In trying to get the bottom of this problem I've rebuilt my application from the base up, and repeated my observation that the odd behaviour begins at around the 17,000 byte binary size.

I wonder whether you've exercised BGLib more than running your test application? Or whether you've used it within the context of a larger application?

To give you some idea of the functions and callbacks I'm making use of, these are:

  ble112.ble_rsp_system_hello
  ble112.ble_rsp_gap_set_scan_parameters
  ble112.ble_rsp_gap_discover
  ble112.ble_rsp_gap_end_procedure
  ble112.ble_rsp_sm_set_bondable_mode
  ble112.ble_rsp_gap_set_mode
  ble112.ble_rsp_attributes_write
  ble112.ble_rsp_sm_set_parameters
  ble112.ble_rsp_sm_encrypt_start
  ble112.ble_rsp_sm_passkey_entry
  ble112.ble_rsp_sm_get_bonds
  ble112.ble_evt_system_boot
  ble112.ble_evt_gap_scan_response
  ble112.ble_evt_attributes_value
  ble112.ble_evt_connection_status
  ble112.ble_evt_sm_passkey_request
  ble112.ble_evt_sm_passkey_display
  ble112.ble_evt_sm_bonding_fail
  ble112.ble_evt_sm_bond_status
  ble112.ble_evt_connection_version_ind
  ble112.ble_evt_connection_disconnected
ble_cmd_system_reset
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi Jeff,

I'm experiencing some odd behaviour, specifically when the binary size of my application gets about about 17,000 bytes - Under this size BGLib and BGAPI over serial using SoftwareSerial work very reliably, but above this kind of size strange things begin to happen such as the BLE112 not responding to commands, or either the BLE112 or Arduino spontaneously resetting.

In trying to get the bottom of this problem I've rebuilt my application from the base up, and repeated my observation that the odd behaviour begins at around the 17,000 byte binary size.

I wonder whether you've exercised BGLib more than running your test application? Or whether you've used it within the context of a larger application?

To give you some idea of the functions and callbacks I'm making use of, these are:

  ble112.ble_rsp_system_hello
  ble112.ble_rsp_gap_set_scan_parameters
  ble112.ble_rsp_gap_discover
  ble112.ble_rsp_gap_end_procedure
  ble112.ble_rsp_sm_set_bondable_mode
  ble112.ble_rsp_gap_set_mode
  ble112.ble_rsp_attributes_write
  ble112.ble_rsp_sm_set_parameters
  ble112.ble_rsp_sm_encrypt_start
  ble112.ble_rsp_sm_passkey_entry
  ble112.ble_rsp_sm_get_bonds
  ble112.ble_evt_system_boot
  ble112.ble_evt_gap_scan_response
  ble112.ble_evt_attributes_value
  ble112.ble_evt_connection_status
  ble112.ble_evt_sm_passkey_request
  ble112.ble_evt_sm_passkey_display
  ble112.ble_evt_sm_bonding_fail
  ble112.ble_evt_sm_bond_status
  ble112.ble_evt_connection_version_ind
  ble112.ble_evt_connection_disconnected
  ble_cmd_system_reset
  ble_cmd_system_hello
  ble_cmd_sm_set_parameters
  ble_cmd_gap_set_mode
  ble_cmd_sm_set_bondable_mode
  ble_cmd_sm_encrypt_start
  ble_cmd_sm_passkey_entry
  ble_cmd_connection_disconnect
  ble_cmd_sm_set_bondable_mode
  ble_cmd_attributes_write

 Thanks in advance for any ideas you may have about this odd behaviour,

Toby




Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I've boiled the problem down to a simple addition of a large array to your original test program (attached).

With a single byte array, the program runs as expected, increase the array size to 2048 or similar and the program no longer runs correctly.

Any ideas?

Toby

* BGLib_scanner.ino.zip (3.04 KB - downloaded 49 times.)
Logged

Roanoke, VA
Offline Offline
Jr. Member
**
Karma: 6
Posts: 66
Creating order out of chaos!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

With a single byte array, the program runs as expected, increase the array size to 2048 or similar and the program no longer runs correctly.

The behavior you describe is consistent with an AVR chip running out of memory--it does all sorts of weird things. The ATMEGA328P datasheet says that the chip only has 2KBytes of internal SRAM, and if you declare a variable like that--especially since I think "int" is a 16-bit integer and therefore a 1024-position array is 2048 bytes--you're basically eating up the entire memory pool right from the start. Is there a reason you need a whole lot of data to be loaded into RAM? If it's constant, I would use PROGMEM or something to keep the data in the program flash space, to keep the SRAM available for other things.

Either that, or you're stuck with using an MCU with more RAM. For example, the ATmega1280/2560 has 8KBytes of internal SRAM, so it should work fine assuming the same project code.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 4
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi. What kind of firmware have I to load in BLE112 in order to use your BGLib porting?

Thank you very much

Logged

Roanoke, VA
Offline Offline
Jr. Member
**
Karma: 6
Posts: 66
Creating order out of chaos!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi. What kind of firmware have I to load in BLE112 in order to use your BGLib porting?

You can use the example projects here, just updated:

https://github.com/jrowberg/bglib/tree/master/BLEFirmware

One has a non-sleeping UART1/Alt1 API connection (USB enabled), and the other (wakeup16) disables USB and enables sleep modes, with the P1_6 pin used for an active-high wake-up pin. In this arrangement, the wake-up pin needs be driven high before sending API commands over UART so that the module will receive them. It can be dropped low again as soon as you are finished sending the command; the module will wake itself up as needed to send its own data back to the connected host.
« Last Edit: August 28, 2013, 10:48:34 pm by Jeff Rowberg » Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 1
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi Jeff,

Do you have a link to the bluegiga reference manual?

Thanks!
Logged

Roanoke, VA
Offline Offline
Jr. Member
**
Karma: 6
Posts: 66
Creating order out of chaos!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Do you have a link to the bluegiga reference manual?

The latest API Reference Guide can be found on the BLE112 product page of Bluegiga's Tech Forum:

https://techforum.bluegiga.com/ble112?downloads

You'll need to create a free account if you don't already have one, but that's simple enough.
Logged

Pages: [1] 2   Go Up
Jump to: