PIC24 Bluetooth Low Energy DK

Thread Starter


Joined Aug 27, 2009
A update to the PIC24FV BLE clone board and app. I converted the source of the the original BLECM demo app to be compatible the latest Android SDK and modified the Java/XML source to interact with my board correctly. The relay outputs control 4 SSR chips that drive 24vdc pneumatic solenoids with 8 ADC 12-bit inputs on the SPI bus from a MCP3208 available to the real Android application. A SPI slave PIC24FV is on-board is for future I/O enhancement.

BLECM2 demo. The ADC inputs are tied to a Vdd-Vss resistor ladder on the analog input connector.

Droid Mini

The updated Android Studio demo app uses the switch widget for the binary 3 bit address of the ADC input on the resistor ladder with an separate update switch to send the selection to the PIC via Bluetooth. The 12-bit value is transmitted back and displayed on the 'progress' bar/decimal value.

Board source: Mplabx/xc16/PIC24FV16KM202:

App source: Android Studio/Java tested with 4.4.4 Droid mini and 6.0.1 Nexus 7
Android Studio can install the app using a USB cable using Android developer mode on the device or it can be installed via a media file.

Thread Starter


Joined Aug 27, 2009
Updated the board firmware to support both RN4020 and RN4871 modules. Fairly easy but wanted to make it work with the old 1.18 RN4871 firmware before an update to the latest version.
http://ww1.microchip.com/downloads/en/DeviceDoc/RN487x Firmware v1.28.3 Release Notes_012618.pdf
http://ww1.microchip.com/downloads/en/DeviceDoc/RN487x Firmware v1.30 Release Notes_030118.pdf

Latest board software source code.

This module doesn't advertise by default the same as the RN4020 so a custom packet had to be made that was compatible with the Android client BLE scanner software.

LS command on chip.

server board code fragment: IA,07 Complete list of 128-bit UUIDs
    // setup advertisement data packet
    BT_SendCommand("IA,Z\r", false); // clear AD data
    BT_SendCommand("IA,01,06\r", false); // set connection flags
    BT_SendCommand("IA,09,424C45434D32\r", false); // AD name
    // set 128-bit UUID in swapped format for client BLECM2 filter
    BT_SendCommand("IA,07,9DEC6AD92C00E086304155EC91872328\r", false);
    BT_SendCommand("A\r", false); // start advertisement
The 128-bit UUID the client uses to filter devices to connect with needs to be little-endian order in the RN4871 packet.

Note the reversed byte order (multibyte values in BLE packets are in little-endian order).

client code: String SERVICE
public class GattServiceAttributes {

/** * 16-bit Service UUIDs */private static String BASE_16_BIT = "0000XXXX-0000-1000-8000-00805f9b34fb";
private static String SERVICE_DEVICE_INFORMATION = "180A";

[B] /** * Private 128-bit Service UUID */private static String SERVICE = "28238791-ec55-4130-86e0-002cd96aec9d";[/B]

/** * Private Characteristics UUIDs */private static String CHARACTERISTIC_BUTTONS = "8f7087bd-fdf3-4b87-b10f-abbf636b1cd5";
private static String CHARACTERISTIC_POTENTIOMETER = "362232e5-c5a9-4af6-b30c-e208f1a9ae3e";
private static String CHARACTERISTIC_LEDS = "cd830609-3afa-4a9d-a58b-8224cd2ded70";
private static String CHARACTERISTIC_RELAYS = "cd83060a-3afa-4a9d-a58b-8224cd2ded70";
private static String CHARACTERISTIC_ADC_CHAN = "cd83060b-3afa-4a9d-a58b-8224cd2ded70";
private static String CHARACTERISTIC_PIC_SLAVE = "cd83060c-3afa-4a9d-a58b-8224cd2ded70";

/** * Generic Characteristic */private static String CHARACTERISTIC_GENERIC = "00002902-0000-1000-8000-00805f9b34fb";

/** * Assigned Characteristics */private static String CHARACTERISTIC_MODEL_NUMBER = "2A24";
private static String CHARACTERISTIC_SERIAL_NUMBER = "2A25";

[B] /** * UUIDs */public static UUID UUID_SERVICE = UUID.fromString(SERVICE);[/B]
/** * BLE Scan Callback for Lollipop devices and higher. */@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private class MicrochipScanCallback extends ScanCallback {

/** * Callback when a BLE advertisement has been found. * * @param callbackType Determines how this callback was triggered. Currently could only be * {@link ScanSettings#CALLBACK_TYPE_ALL_MATCHES}. * @param result A Bluetooth LE scan result. */@Overridepublic void onScanResult(int callbackType, ScanResult result) {
super.onScanResult(callbackType, result);

if(result.getScanRecord() != null && result.getScanRecord().getServiceUuids() != null){
for(ParcelUuid parcelUuid : result.getScanRecord().getServiceUuids()){
[B] if(parcelUuid.getUuid().equals(GattServiceAttributes.UUID_SERVICE)){[/B]
BluetoothDevice device = result.getDevice();
Android scanner code fragment.

Thread Starter


Joined Aug 27, 2009