Direct Bluetooth connection from App(No Particle Cloud)


Sorry for the newbie question.

So lets say I want to connect to the Bluz module from my app. I do not want to communicate through the Particle cloud which I am familiar with. Instead I want to send commands to the module directly from my application. Is this possible somehow? If so how do I receive the data sent from the app in firmware? Is there some sort of handler for this? I poked around on the forum and didn’t see exactly what I was looking for. Is this possible? If so what can I read up on for it?

Connect and Receive data directly from Bluz on iOS
SPI tutorial or notes anyone?

Good question. Yes, this is perfectly possible, though there is no current user-level API for it.

There are two ways this can be accomplished, the first is to piggy back on the service we already have set up. So this would send data over the same characteristics that we use for the socket data and other communication items between bluz and the gateway.

The other way is to implement a new service and characteristics.

We plan to add user-level API’s for both of these in the near future. The first option could be done today with minimal changes to the underlying firmware, if you would like to try it. I can give you instructions on what o modify and how to send the data. Or you could wait for the user-level API’s, I don’t have an exact date yet as we are still focusing al our energy on shipping all the product. Once we get through that, we will get into a more regular release cycle for firmware updates.


Hi Eric,

I am not afraid of a little library development by any means. We plan to offer the Bluz module in our product line as a direct connection alternative so people can operate devices in locations where WiFi is not available.

I am imagining a service/class that just has a socket for the Bluetooth interface to read and write data(bytes). Is there already a bluetooth socket object that I can open streams to to read and write data? If so where could I find some information on that(Github perhaps)?

Thank you Eric,


I just wrote this up the other day, so this is a simple copy+paste! For the app side, you would need to look at the documentation for iOS/Android respectively, we don’t have a mobile SDK yet, but will at some point. I could also give you access to the app source code, which is currently closed while I clean it up and try to make the SDK from it.

You will need to local compile to send data down to bluz, and you can use a local programmer (STLink or JLink) or you can compile locally and use ‘particle flash’ from the CLI to send code to bluz. If you are modifying the underlying firmware drivers, you will need to update both the system and user parts. If you need help with how to do this please let me know.

To send your own data to bluz, you can do the following:

Once you do that, you can now write data to our characteristic from any app. You will include a “header” on your data where the first byte is always 3 (which corresponds to the definition you made) and then the remaining data will get sent to your DataCallback function. You also always need to send a separate 2-byte data packet when you are done transmitting that is [0x03, 0x04]. That needs to be a separate write to the characteristic. If your data is larger than 512 bytes, you should also split it up so that you send your data with 0x03 appended to the front, then the trailing write with [0x03, 0x04] then do it again with your next chunk of data.

Please let me know if that makes sense or if you have any more questions. Again, I will add hooks to all of this in a future release so that the “app layer” can talk through this data channel as well, just haven’t gotten there yet.


Hi @eric

What would be the make command for compiling. For Photon I use:
make APP=myapp PLATFORM=photon

Do I just need to change the photon argument to something like bluz?

I’m setting up a development environment in Eclipse so I can flash from there.


Yup! If you are using the 1.0.47 branch, your command should just be:

make PLATFORM=bluz APP=yourApp

If you are compiling from the develop branch, you would need to add PARTICLE_DEVELOP=1, same as for the Photon.


Thanks @eric

I am getting somewhere but my build is throwing an error. My make command is:


However there is an error [-Waggressive-loop-optimizations]

Seems to be caused by line 155 in ota_flash_hal.c Here is the console output on build:

15:57:04 **** Incremental Build of configuration Build (GNU) for project Bluz_Custom ****
make APP=myapp PLATFORM=bluz PARTICLE_DEVELOP=1 all 
Building firmware for Bluz Production, platform ID: 103, product ID: 103
/Applications/ -C ./communication 
make[1]: Nothing to be done for `all'.
/Applications/ -C ./hal 
Building file: src/bluz/ota_flash_hal.c
Invoking: ARM GCC C Compiler
mkdir -p ../build/target/hal/platform-103/./src/bluz/
arm-none-eabi-gcc -DSTM32_DEVICE -DNRF51 -DPLATFORM_THREADING=0 -DPLATFORM_ID=103 -DPLATFORM_NAME=bluz -DUSBD_VID_SPARK=0x1D50 -DUSBD_PID_DFU=0x607F -DUSBD_PID_CDC=0x607D -g3 -Os -mcpu=cortex-m0 -mthumb -mfloat-abi=soft -mabi=aapcs -DSOFTDEVICE_PRESENT -DBLE_STACK_SUPPORT_REQUIRED -DS110_SUPPORT_REQUIRED -DNRF51 -DNRF51822_QFAA_CA -DBLE_STACK_SUPPORT_REQD -DUSE_CUSTOM_STATIC_ASSERT -DBLUZ  -DUSE_STDPERIPH_DRIVER -DDFU_BUILD_ENABLE -DSYSTEM_VERSION_STRING=1.0.47 -DRELEASE_BUILD -Werror -I./inc -I./shared -I./src/bluz -I../platform/shared/inc -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/device -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/drivers_nrf/common -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/drivers_nrf/config -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/drivers_nrf/gpiote -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/drivers_nrf/hal -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/drivers_nrf/ppi -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/drivers_nrf/simple_uart -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/drivers_nrf/spi_master -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/drivers_nrf/ble_flash -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/drivers_nrf/pstorage -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/drivers_nrf/pstorage/config -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/drivers_nrf/timer -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/drivers_nrf/twi_master -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/drivers_nrf/uart -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/softdevice/common/softdevice_handler -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/ble/common -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/ble/device_manager -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/ble/ble_radio_notification -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/ble/device_manager/config -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/ble/ble_error_log -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/ble/ble_debug_assert_handler -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/libraries/bootloader_dfu -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/libraries/crc16 -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/libraries/timer -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/libraries/pwm -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/libraries/scheduler -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/libraries/gpiote -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/libraries/fifo -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/libraries/button -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/libraries/trace -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/libraries/util -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/softdevice/s110/headers -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/libraries/timer -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/toolchain -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/toolchain/gcc -I../platform/MCU/NRF51/SPARK_Firmware_Driver/inc -I../services/inc -I../dynalib/inc -I../bootloader/src/bluz -I../bootloader/src/bluz/config -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/libraries -I. -MD -MP -MF ../build/target/hal/platform-103/./src/bluz/ota_flash_hal.o.d -ffunction-sections -fdata-sections -Wall -Wno-switch -Wno-error=deprecated-declarations -fmessage-length=0 -fno-strict-aliasing -DSPARK=1 -DPARTICLE=1 -DSTART_DFU_FLASHER_SERIAL_SPEED=14400 -DSTART_YMODEM_FLASHER_SERIAL_SPEED=28800 -std=gnu99 -Wno-pointer-sign -std=gnu99 -c -o ../build/target/hal/platform-103/./src/bluz/ota_flash_hal.o src/bluz/ota_flash_hal.c
src/bluz/ota_flash_hal.c: In function 'HAL_System_Info':
src/bluz/ota_flash_hal.c:155:17: error: iteration 3u invokes undefined behavior [-Werror=aggressive-loop-optimizations]
                 fetch_module(info->modules+i, module_bounds[i], false, MODULE_VALIDATION_INTEGRITY);
src/bluz/ota_flash_hal.c:154:13: note: containing loop
             for (int i=0; i<module_bounds_length; i++) {
cc1: all warnings being treated as errors
make[1]: *** [../build/target/hal/platform-103/./src/bluz/ota_flash_hal.o] Error 1
make: *** [hal] Error 2

15:57:04 Build Finished (took 387ms)

This seems to be an overflow issue with a variable but I can’t put my finger on it. Any ideas?

Locally connect the nrf BLE to Bluz gateway

This is a compiler version thing. What version of gcc are you using?


Thanks @eric
arm-none-eabi-gcc version is 4.9.3


The one surefire way to get rid of it is to use GCC 4.8, the latest version will work:

I should go back and fix this. Or a PR is welcome!

Local compiling on Ubuntu 14.04 (Linux Mint 17.3 Rosa)

Thanks @eric

Haha, if I knew what the issue was I would sure do a PR, but uh… Really not sure on this one. I can’s see anything that is out of whack. I will update my gcc and get back with you.

Thanks again.


Yeah, I had run into it at one point and then figured out what it was, but I honestly can’t remember at the moment. It is just the compiler attempting to look for errors in the iterations of a loop, I dont remember why it throws this warning exactly.

I will add it to my list!


Hey @eric

Where is the gcc compiler invoked? I cannot seem to find that anywhere. I need to add an argument there to see if it works.


You want to add a compiler flag? You can add one here to test it out:


@eric, I am compiling with 4.9.3 without problems. I have the latest dev and compiling from \modules using make clean all PLATFORM=bluz PARTICLE_DEVELOP=1 APP=tinker, I get no errors. :slightly_smiling:


Success @eric, sort of.

I added a compiler flag to the C compiler, and the CPP compiler for good measure, and the build went through successfully with GCC version 4.9

Here is the altered file:

# Define ARM tools

# Define the compiler/tools prefix
GCC_PREFIX ?= arm-none-eabi-

include $(COMMON_BUILD)/

# default flags for targeting ARM

# C compiler flags
CFLAGS +=  -g3 -Os -mcpu=cortex-m0 -mthumb -mfloat-abi=soft -mabi=aapcs -DSOFTDEVICE_PRESENT -DBLE_STACK_SUPPORT_REQUIRED -DS110_SUPPORT_REQUIRED -DNRF51 -DNRF51822_QFAA_CA -DBLE_STACK_SUPPORT_REQD -DUSE_CUSTOM_STATIC_ASSERT -DBLUZ -fno-aggressive-loop-optimizations

# C++ specific flags
CPPFLAGS += -fno-exceptions -fno-rtti -fno-aggressive-loop-optimizations

CONLYFLAGS += -std=gnu99


LDFLAGS += -Xlinker --gc-sections -lc -lnosys

ifeq ($(COMPILE_LTO),y)
CFLAGS += -flto
LDFLAGS += -flto -Os -fuse-linker-plugin

Added flag -fno-aggressive-loop-optimizations


Thanks for the input @peekay123

I have been compiling from the project root directory. I could try switching my compile director to /modules and see how that works. Maybe that has been my problem all along. Either way it is working now with that compiler flag.


Hey @peekay123

Yep, I switched my compile directory to /modules and it works without the flags. Sheesh…


@IOTrav, I’m so used to doing that with Particle, it’s second nature. :smirk:


Yeah, I actually had my environment setup to compile for Photon from the root directory as well but compiling from the /modules directory seems to be the way to go.