ECE 4180 Medication Adherence Smart Pill-Dispenser Prototype

Smart Pill-Dispenser

Group Member: Xiannan Di, Yuhao Lin, Zhipeng Shao

Description

This design is created for ECE 4180 final project as well as for an initial prototype of ECE 4011/4012 Senior Design project. For more information on our Senior Design project on Medication Adherence, please check out our proposal.

This prototype utilizes nRF52 board's built-in BLE function to receive commands from smartphone app. The LCD screen will display the commanded number of pills each time. The dispenser, based on a small geared DC motor driven by MOSFET, revolves and drops the specified amount of pills at a constant rate.

Parts List

Software

nRF Connect app scans for nRF52 board nRF Connect app establishes connection with the board One is able to read and write pill number from app to the board

The nRF Connect is a mobile app developed by Nordic Semiconductor. It is available on both iOS and Android, and supports BLE communication with the nRF52-DK board.

Schematic

/media/uploads/xdi3/wechat_image_20171212160125.png

Source Code

main.cpp

#include "mbed.h"
#include "ble/BLE.h"
#include "uLCD_4DGL.h"

uLCD_4DGL uLCD(p6,p8,p11);
BLEDevice ble;
DigitalOut led(LED1); 
PwmOut Ctrl(p19);
DigitalOut drop_led(LED2); 
uint16_t PILL_SERVICE_UUID  = 0xA000; // service UUID
uint16_t readCharUUID       = 0xA001; // read characteristic UUID
uint16_t writeCharUUID      = 0xA002; // write characteristic UUID
int pill_num = 0;

const static char     DEVICE_NAME[]  = "PILL_DROP";
static const uint16_t uuid16_list[] = {PILL_SERVICE_UUID}; 
static uint8_t readValue[1] = {0};
ReadOnlyArrayGattCharacteristic<uint8_t, sizeof(readValue)> readChar(readCharUUID, readValue);

static uint8_t writeValue[1] = {0};
WriteOnlyArrayGattCharacteristic<uint8_t, sizeof(writeValue)> writeChar(writeCharUUID, writeValue);
// Set up pill service
GattCharacteristic *characteristics[] = {&readChar, &writeChar};
GattService         pillService(PILL_SERVICE_UUID, characteristics, sizeof(characteristics) / sizeof(GattCharacteristic *));

void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
{
    //(void) params;
    BLE::Instance().gap().startAdvertising();
}
/* 
 *  handle writes to writeCharacteristic
*/
void writeCharCallback(const GattWriteCallbackParams *params)
{
    // check to see what characteristic was written, by handle
    if(params->handle == writeChar.getValueHandle() && params->len == 1) {
        
        pill_num = params->data[0];
        led = params->data[0];
        uLCD.printf("%x pill(s)\n\r",pill_num);//
        //(params->data[0] == 0x00) ? printf("\n\rled on ") : printf("\n\rled off "); // print led toggle
        for(int i = 1; i <= pill_num; i++){
          Ctrl = 0.95f;
          drop_led = 1;
          wait(7);
          Ctrl = 1.0f;
          drop_led = 0;
          wait(5);
        }
        //Pill drop code
        ble.updateCharacteristicValue(readChar.getValueHandle(), params->data,params->len);
    }
    // update the readChar with the value of writeChar    
}

/*
 *  main loop
*/ 
int main(void)
{
    Ctrl = 1.0f;
    /* Initialization */
    ble.init();
    ble.gap().onDisconnection(disconnectionCallback);
    ble.gattServer().onDataWritten(writeCharCallback);
    
    /* setup advertising */
        // BLE only, no classic BT
    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list));
    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME));
    ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
    /* 1000ms. */
    ble.gap().setAdvertisingInterval(1000); /* 1000ms. */
    
    ble.addService(pillService);
  
    ble.gap().startAdvertising();
    uLCD.printf("Hello, BLE connection successful\n\r");
    // infinite loop waiting for BLE interrupt events
    while (true) {
       ble.waitForEvent(); //Save power
    }
}

Photos

/media/uploads/xdi3/wechat_image_20171212160105.jpg

Demo Video


Please log in to post comments.