Infectious Disease Exposure Alerting Device - BLE Based
Team Members
- Fengrui Zuo (Georgia Tech, BSEE, 21)
- Benjamin Leverett (Georgia Tech, BSEE, 21)
- Rahil Ajani (Georgia Tech, BSEE, 20)
- Kombundit Chitranuwatkul (Georgia Tech, BSEE, 20)
Overview
Due to coronavirus pandemic, hundreds of thousands of people are at risk from being infected with this deadly virus. We wanted to build an effective way to alert people at risk and track the virus to prevent its spread. This project demonstrates the capability of Bluetooth technology to estimate the proximity of infectious persons or zones by using its built-in Received Signal Strength Indicator (RSSI) functionality. A Bluetooth beacon is emulated with an iPhone to be used as an infectious area. A hand-held alerting device is built using a mbed, an uLCD module, a UART BLE module, an SD card logger and a speaker.
Demonstration
Presentation
Slide Deck Link - Google Slide Link
Presentation Link
Hardware
The following are the hardware components that are used in this project with links to purchase the components
- mbed - LPC1768: https://www.sparkfun.com/products/9564
- Adafruit Bluetooth LE UART Friend: https://www.adafruit.com/product/2479
- MicroSD Breakout: https://www.sparkfun.com/products/544
- uLCD: https://www.sparkfun.com/products/11377
- Transistor https://www.sparkfun.com/products/521
- Speaker: https://www.sparkfun.com/products/11089
- Red LED: https://www.sparkfun.com/products/9590
- Yellow LED: https://www.sparkfun.com/products/532
- Green LED: https://www.sparkfun.com/products/9650
Pin Connections
Adafruit Bluetooth LE UART Friend
mbed | Adafruit BLE |
---|---|
GND | GND |
VU (5V) | VIN (3.3-16V) |
- | RTS |
GND | CTS |
p14 (Serial RX) | TXO |
p13 (Serial TX) | RXI |
p18 | MOD |
Wiki Page: Adafruit Bluetooth LE UART Friend
MicroSD Breakout
mbed | MicroSD |
---|---|
p8 (DigitalOut CS) | CS |
p5 (SPI mosi) | DI |
VOUT (3.3V) | VCC |
p7 (SPI sclk) | SCK |
GND | GND |
p6 (SPI miso) | DO |
- | CD |
Wiki Page: MicroSD Breakout
uLCD
mbed | uLCD Header | uLCD Cable |
---|---|---|
VU (5V) | 5V | 5V |
GND | GND | GND |
TX=p28 | RX | TX |
RX=p27 | TX | RX |
p30 | RES | RES |
Wiki Page: uLCD
Transistor and Speaker
mbed | Transistor | Speaker |
---|---|---|
VOUT (3.3V) | -- | (+) |
GND | Emitter (1) | -- |
p21 + (1KOhm) | Base (2) | -- |
-- | Collector (3) | (-) |
Wiki Page: Class D Audio Amplifier Breakout and Speaker
Green LED
mbed | Green LED | (Optional) |
---|---|---|
p24 | longer leg | |
GND | shorter leg | 100-300 Ohms Resistor |
Wiki Page: LEDs
Yellow LED
mbed | Yellow LED | (Optional) |
---|---|---|
p25 | longer leg | |
GND | shorter leg | 100-300 Ohms Resistor |
Wiki Page: LEDs
Red LED
mbed | Red LED | (Optional) |
---|---|---|
p26 | longer leg | |
GND | shorter leg | 100-300 Ohms Resistor |
Wiki Page: LEDs
Circuit
Program
Import programFinal_Project
Fengrui Zuo, Benjamin Leverett, Rahil Ajani, Kombundit Chitranuwatkul
RTOS Wiki Page: https://os.mbed.com/handbook/RTOS
Sample SD Card Output
Date & time: Tuesday 28, April 2020 10:13:29 Risk Level: 3 47, 44, 45, 48, 57, 52, 57, 47, 49, 44, 61, 73, 68, 79, 83 Date & time: Tuesday 28, April 2020 10:13:47 Risk Level: 1 79, 94, 80, 10, 79, 95, 73, 92, 95, 75, 83, 71, 88, 94, 87 Date & time: Tuesday 28, April 2020 10:14:05 Risk Level: 3 98, 84, 88, 71, 58, 61, 62, 66, 67, 69, 67, 57, 69, 63, 51 Date & time: Tuesday 28, April 2020 10:14:23 Risk Level: 2 57, 61, 56, 51, 57, 62, 61, 57, 52, 58, 49, 51, 59, 60, 54
Project Code
#include "mbed.h" #include "rtos.h" #include "ATParser.h" #include "uLCD_4DGL.h" #include "SDFileSystem.h" #include "Speaker.h" #include <string> #include <iostream> using namespace std; //Hardware setups DigitalOut cmdMode(p18); Serial pc(USBTX, USBRX); BufferedSerial ble(p13,p14); DigitalOut cmdstuff(p18); DigitalOut greenLED(p24); DigitalOut yellowLED(p25); DigitalOut redLED(p26); uLCD_4DGL uLCD(p28,p27,p30); SDFileSystem sd(p5, p6, p7, p8, "sd"); PwmOut speaker(p21); //AT command data handlers char delimiter[] = "\r\n"; int buffer_size = 256; int timeout = 100; bool debug = false; ATParser at(ble, delimiter, buffer_size, timeout, debug); char buffer[10]; //RTOS Mutex Lock Mutex mutex_lock; //Global Data points and arrays volatile int risk_level = 0; int averageCount = 0; volatile int datalogged = 0; volatile int RSSI_array[15]; time_t seconds; //Responsible for logging on SD card void log_sd_card() { mutex_lock.lock(); FILE *fp = fopen("/sd/mydir/sdtest.txt", "w"); if(fp == NULL) { error("Could not open file for write\n"); } int curr_time = (int)ctime(&seconds) % 86400; int curr_hour = curr_time / 3600; int curr_min = curr_time / 60; int curr_sec = curr_time % 60; fprintf(fp, "Date & time: Tuesday 28, April 2020 "); fprintf(fp, "%i", curr_hour); fprintf(fp, ":"); fprintf(fp, "%i", curr_min); fprintf(fp, ":"); fprintf(fp, "%i", curr_sec); fprintf(fp, "\n"); fprintf(fp, "Risk Level: "); fprintf(fp, "%i", risk_level); fprintf(fp, "\n"); for (int i = 0; i < 15; i++) { fprintf(fp, "%i", RSSI_array[i]); if (i < 14) { fprintf(fp, ", "); } } fprintf(fp, "\n\n"); fclose(fp); mutex_lock.unlock(); } //This portion of the code handles RSSI readings int calculate_average(volatile int *input, int size) { int average; for(int i = 0; i< size; i++) { average = average + input[i]; } average = average/size; return average; } void parse_RSSI() { mutex_lock.lock(); at.send("AT+BLEGETRSSI") && at.read(buffer, 10); if(buffer[0] == '-') { datalogged = 1; pc.printf("RSSI: "); pc.putc(buffer[1]); pc.putc(buffer[2]); pc.printf("\n"); int digit1 = buffer[1] - 48; //Converts char to int int digit2 = buffer[2] - 48; int total = 10*digit1 + digit2; if (averageCount <= 15) { RSSI_array[averageCount] = total; } averageCount++; if(averageCount > 15 && buffer[0] == '-') { averageCount = 0; int average = calculate_average(RSSI_array, 15); if(average < 55) { risk_level = 3; } else if(average > 55 && average < 70) { risk_level = 2; } else if(average > 70 && average < 90) { risk_level = 1; } else { risk_level = 0; } log_sd_card(); } } mutex_lock.unlock(); } //Responsible for speaker void speaker_alarm() { while(1) { if(risk_level == 2 && datalogged) { for (int i=0; i<10; i=i+2) { speaker.period(1.0/969.0); speaker = float(i)/50.0; wait(.8); speaker.period(1.0/800.0); wait(.8); speaker = 0; } } else if(risk_level == 3 && datalogged) { for (int i=0; i<10; i=i+2) { speaker.period(1.0/969.0); speaker = float(i)/50.0; wait(.25); speaker.period(1.0/800.0); wait(.25); speaker = 0; } } else if(risk_level <= 1 && datalogged) { speaker = 0; } else { speaker = 0; } } } //Code to blink leds based on risk level void blink_leds() { while(1) { if(risk_level <= 1 && datalogged) { greenLED = 1; redLED = 0; yellowLED = 0; } else if(risk_level == 2 && datalogged) { yellowLED = 1; greenLED = 0; redLED = 0; } else if(risk_level == 3 && datalogged) { redLED = 1; yellowLED = 0; greenLED = 0; } else { redLED = 0; yellowLED = 0; greenLED = 0; } } } //Displays risk level on uLCD void display_ulcd() { mutex_lock.lock(); uLCD.color(WHITE); mutex_lock.unlock(); while(1) { mutex_lock.lock(); if(risk_level <= 1 && datalogged) { mutex_lock.lock(); uLCD.cls(); uLCD.locate(5, 7); uLCD.text_width(2); uLCD.text_height(2); uLCD.background_color(GREEN); uLCD.textbackground_color(GREEN); uLCD.printf("Safe"); mutex_lock.unlock(); } else if(risk_level == 2 && datalogged) { mutex_lock.lock(); uLCD.cls(); uLCD.locate(1, 7); uLCD.text_width(2); uLCD.text_height(2); uLCD.background_color(0xFFFF00); uLCD.textbackground_color(0xFFFF00); uLCD.printf("Cautious"); mutex_lock.unlock(); } else if(risk_level == 3 && datalogged) { mutex_lock.lock(); uLCD.cls(); uLCD.locate(3, 7); uLCD.text_width(2); uLCD.text_height(2); uLCD.background_color(RED); uLCD.textbackground_color(RED); uLCD.printf("Hazard"); mutex_lock.unlock(); } mutex_lock.unlock(); } } //Runs application int main() { cmdstuff = 1; at.send("AT") && at.recv("OK"); at.send("AT+AB ChangeDefaultBaud [9600]", 3) && at.recv("OK"); ble.baud(9600); set_time(1588068804); Thread ULCD_Thread(display_ulcd); Thread LED_Thread(blink_leds); Thread Speaker_Thread(speaker_alarm); while(1) { parse_RSSI(); } }
Please log in to post comments.