A medication alert and dispense system with adjustable dosage time and compliance monitor.
CS 3651 Summer 2013 - Summet
Automatic
Medication
Dispenser
/****** MikroPot.c *****************************************************
*
* Suvrat Jain's touchscreen pot with 0-255 output
**********************************************************************/
#include "p24FJ256GB110.h" // PIC24 register and bit definitions
#include "AlphaFont.h" // 12x16-pixel font set
#include "Mikro.c" // LCD variables, functions, macros
#include "MikroTouch.c" // Touchscreen variables, functions
#include "MikroMeasureTime.c" // Start, Stop, Send, ASCIIn, Blankn functions
/****** Configuration selections **************************************/
_CONFIG1(JTAGEN_OFF & GWRP_OFF & FWDTEN_OFF & ICS_PGx2);
_CONFIG2(PLLDIV_DIV2 & POSCMOD_HS & FNOSC_PRIPLL & IOL1WAY_OFF);
/****** Global variables **********************************************/
char Handlestr[] = "\001\002Automated Med Dispenser";
char Currenttimestr[] = "\002\002Current Time: 10:00:00 AM";
char Nextdosestr[] = "\003\002Next Dose: 10:30:00 AM";
char Setupstr[] = "\005\013Setup";
char Tracker[] = "\007\013Records";
char Daystr1[] = "\001\010Sunday";
char Daystr2[] = "\002\010Monday";
char Daystr3[] = "\003\010Tuesday";
char Daystr4[] = "\004\010Wednesday";
char Daystr5[] = "\005\010Thursday";
char Daystr6[] = "\006\010Friday";
char Daystr7[] = "\007\010Saturday";
char Exitstr[] = "\010\014Exit";
char Mon1str[] = "\001\002Morning: 8:00:00 AM";
char Mon2str[] = "\002\002Afternoon: 12:00:00 PM";
char Mon3str[] = "\003\002Evening: 6:00:00 PM";
char Mon4str[] = "\004\002Late Night: 9:00:00 PM";
char Mon5str[] = "\005\002Monday's Schedule";
char Tues1str[] = "\001\002Morning: 8:00:00 AM";
char Tues2str[] = "\002\002Afternoon: 12:00:00 PM";
char Tues3str[] = "\003\002Evening: 6:00:00 PM";
char Tues4str[] = "\004\002Late Night: 9:00:00 PM";
char Tues5str[] = "\005\002Tuesday's Schedule";
char Wed1str[] = "\001\002Morning: 8:00:00 AM";
char Wed2str[] = "\002\002Afternoon: 12:00:00 PM";
char Wed3str[] = "\003\002Evening: 6:00:00 PM";
char Wed4str[] = "\004\002Late Night: 9:00:00 PM";
char Wed5str[] = "\005\002Wednesday's Schedule";
char Thurs1str[] = "\001\002Morning: 8:00:00 AM";
char Thurs2str[] = "\002\002Afternoon: 12:00:00 PM";
char Thurs3str[] = "\003\002Evening: 6:00:00 PM";
char Thurs4str[] = "\004\002Late Night: 9:00:00 PM";
char Thurs5str[] = "\005\002Thursday's Schedule";
char Fri1str[] = "\001\002Morning: 8:00:00 AM";
char Fri2str[] = "\002\002Afternoon: 12:00:00 PM";
char Fri3str[] = "\003\002Evening: 6:00:00 PM";
char Fri4str[] = "\004\002Late Night: 9:00:00 PM";
char Fri5str[] = "\005\002Friday's Schedule";
char Sat1str[] = "\001\002Morning: 8:00:00 AM";
char Sat2str[] = "\002\002Afternoon: 12:00:00 PM";
char Sat3str[] = "\003\002Evening: 6:00:00 PM";
char Sat4str[] = "\004\002Late Night: 9:00:00 PM";
char Sat5str[] = "\005\002Saturday's Schedule";
char Sun1str[] = "\001\002Morning: 8:00:00 AM";
char Sun2str[] = "\002\002Afternoon: 12:00:00 PM";
char Sun3str[] = "\003\002Evening: 6:00:00 PM";
char Sun4str[] = "\004\002Late Night: 9:00:00 PM";
char Sun5str[] = "\005\002Sunday's Schedule";
char Recordhead[] = "\001\002Last 6 Medications";
char Record1[] = "\002\002Wed 9:00:00 PM";
char Record2[] = "\003\002Wed 6:00:00 PM";
char Record3[] = "\004\002Wed 12:00:00 PM";
char Record4[] = "\005\002Wed 8:00:00 AM";
char Record5[] = "\006\002Tues 9:00:00 PM";
char Record6[] = "\007\002Tues 6:00:00 PM";
unsigned int ALIVECNT = 0;
char Potstr[] = "\010\030120";
unsigned char flag;
unsigned char flag2 = 0;
unsigned char flag3 = 0;
unsigned char day = 0;
int sliderVal = 160;
int sliderValy = 120;
int oldSliderVal = 160;
int oldSliderValy = 120;
/****** Function prototypes *******************************************/
void Initial(void);
void InitPot(void);
void BlinkAlive(void);
void Menu(void);
//////// Main program //////////////////////////////////////////////////
int main()
{
Initial();
while (1) // Looptime without Sleep = 20.35 ms
{
Menu();
_LATA3 ^= 1; // Toggle pin 50 of Mikro board
DetectTouch();
//Start(); // Measure pot execution time
MoveSlider();
BlinkAlive();
while (!_T5IF); // Loop time = 10 ms
_T5IF = 0;
}
}
/****** Initial ********************************************************
*
* Initialize LCD Screen (PMP + configuration + initial display).
* Initialize Timer5 for a loop time of 10 ms.
**********************************************************************/
void Initial()
{
AD1PCFGL = 0xFFFF; // Make all ADC pins default to digital pins
PMP_Init(); // Configure PMP module for LCD
LCD_Init(); // Configure LCD controller
InitBackground(); // Paint screen royal blue
InitPot(); // Create pot
_TRISA3 = 0; // Make RA3 an output (pin 50 of Mikro board)
TMR5 = 0; // Clear Timer5
PR5 = 19999; // Set period of Timer5 to 10 ms
T5CON = 0x8020; // Clock Timer5 with Fcy/64 = 250 kHz
Display(BKGD,Handlestr); // Display Handles Initally
}
/****** InitPot ********************************************************
*
* Create initial screen potentiometer
*
**********************************************************************/
void InitPot()
{
// initializes value to zero for reading
DrawRectangle(145, 105, 160, 120, WHITE);
}
/****** BlinkAlive *****************************************************
*
* This function toggles a square of pixels every second.
* With a loop time of 10 ms, this is every 100 looptimes.
**********************************************************************/
void BlinkAlive()
{
ALIVECNT++;
if (ALIVECNT == 100) // Write black square
{
DrawRectangle(0, 0, 5, 5, BLACK);
}
if (ALIVECNT >= 200) // Clear black square
{
ALIVECNT = 0;
DrawRectangle(0, 0, 5, 5, BKGD);
}
}
/****** MoveSlider *****************************************************
*
* Moves the slider around on touch
*
***********************************************************s***********/
void MoveSlider()
{
// Set initial Values
if (tsx != -1) // Set the borders of the screen
{
sliderVal = tsx;
if (sliderVal < 25)
sliderVal = 25;
if (sliderVal > 320)
sliderVal = 320;
}
if (tsy != -1)
{
sliderValy = tsy;
if (sliderValy < 25)
sliderValy = 25;
if (sliderValy > 215)
if(sliderVal > 200)
sliderValy = 215;
}
flag = 0;
if ((sliderVal != oldSliderVal) || (sliderValy != oldSliderValy))
{
_LATF12 = 0; // Enable display;
DrawRectangle(oldSliderVal - 15, oldSliderValy-15, oldSliderVal, oldSliderValy, BKGD);
DrawRectangle(sliderVal - 15, sliderValy-15, sliderVal, sliderValy, WHITE);
_LATF12 = 1; // Disable display;
scaledSliderVal = (((long) sliderVal * 255) - 7650) / 270;
scaledSliderValy = (((long) sliderValy * 255) - 7650) / 270;
if (scaledSliderVal < 0)
scaledSliderVal = 0;
else if (scaledSliderVal > 0xFF)
scaledSliderVal = 0xFF;
LONGNUM = scaledSliderValy;
if (scaledSliderValy < 0)
scaledSliderValy = 0;
else if (scaledSliderValy > 0xFF)
scaledSliderValy = 0xFF;
// Overwrite conditions
oldSliderVal = sliderVal;
oldSliderValy = sliderValy;
oldScaledSliderVal = scaledSliderVal;
oldScaledSliderValy = scaledSliderValy;
flag = 1;
}
}
void Menu(){
if(flag2 == 0){
Display(BKGD, Handlestr);
Display(BKGD,Currenttimestr);
Display(BKGD,Nextdosestr);
Display(GREEN,Setupstr);
Display(GREEN,Tracker);
if(flag){
if(((sliderValy - 15) > (Setupstr[0]*24)-20) && ((sliderValy - 15) < (Setupstr[0]*24)+7) && ((sliderVal - 15) > 110) && ((sliderVal - 15) < 185)){
flag2 = 1;
DrawRectangle(0,0,320,215, BKGD);
} else if(((sliderValy - 15) > (Tracker[0]*24)-20) && ((sliderValy - 15) < (Tracker[0]*24)+7) && ((sliderVal - 15) > 110) && ((sliderVal - 15) < 185)){
flag2 = 3;
DrawRectangle(0,0,320,215, BKGD);
}
}
} else if(flag2 == 1) {
Display(GREEN,Daystr1);
Display(GREEN,Daystr2);
Display(GREEN,Daystr3);
Display(GREEN,Daystr4);
Display(GREEN,Daystr5);
Display(GREEN,Daystr6);
Display(GREEN,Daystr7);
Display(GREEN,Exitstr);
if(flag){
if(((sliderValy - 15) > (Daystr1[0]*24)-20) && ((sliderValy - 15) < (Daystr1[0]*24)+7) && ((sliderVal - 15) > 110) && ((sliderVal - 15) < 185)){
day = 1;
flag2 = 2;
DrawRectangle(0,0,320,215, BKGD);
} else if(((sliderValy - 15) > (Daystr2[0]*24)-20) && ((sliderValy - 15) < (Daystr2[0]*24)+7) && ((sliderVal - 15) > 110) && ((sliderVal - 15) < 185)){
day = 2;
flag2 = 2;
DrawRectangle(0,0,320,215, BKGD);
}else if(((sliderValy - 15) > (Daystr3[0]*24)-20) && ((sliderValy - 15) < (Daystr3[0]*24)+7) && ((sliderVal - 15) > 110) && ((sliderVal - 15) < 185)){
day = 3;
flag2 = 2;
DrawRectangle(0,0,320,215, BKGD);
}else if(((sliderValy - 15) > (Daystr4[0]*24)-20) && ((sliderValy - 15) < (Daystr4[0]*24)+7) && ((sliderVal - 15) > 110) && ((sliderVal - 15) < 185)){
day = 4;
flag2 = 2;
DrawRectangle(0,0,320,215, BKGD);
}else if(((sliderValy - 15) > (Daystr5[0]*24)-20) && ((sliderValy - 15) < (Daystr5[0]*24)+7) && ((sliderVal - 15) > 110) && ((sliderVal - 15) < 185)){
day = 5;
flag2 = 2;
DrawRectangle(0,0,320,215, BKGD);
}else if(((sliderValy - 15) > (Daystr6[0]*24)-20) && ((sliderValy - 15) < (Daystr6[0]*24)+7) && ((sliderVal - 15) > 110) && ((sliderVal - 15) < 185)){
day = 6;
flag2 = 2;
DrawRectangle(0,0,320,215, BKGD);
}else if(((sliderValy - 15) > (Daystr7[0]*24)-20) && ((sliderValy - 15) < (Daystr7[0]*24)+7) && ((sliderVal - 15) > 110) && ((sliderVal - 15) < 185)){
day = 7;
flag2 = 2;
DrawRectangle(0,0,320,215, BKGD);
}else if(((sliderValy - 15) > (Exitstr[0]*24)-20) && ((sliderValy - 15) < (Exitstr[0]*24)+7) && ((sliderVal - 15) > 110) && ((sliderVal - 15) < 185)){
flag2 = 0;
DrawRectangle(0,0,320,215, BKGD);
}
}
} else if(flag2 == 2){
Display(GREEN, Exitstr);
switch(day){
case 2:
Display(BKGD,Mon1str);
Display(BKGD,Mon2str);
Display(BKGD,Mon3str);
Display(BKGD,Mon4str);
Display(BKGD,Mon5str);
break;
case 3:
Display(BKGD,Tues1str);
Display(BKGD,Tues2str);
Display(BKGD,Tues3str);
Display(BKGD,Tues4str);
Display(BKGD,Tues5str);
break;
case 4:
Display(BKGD,Wed1str);
Display(BKGD,Wed2str);
Display(BKGD,Wed3str);
Display(BKGD,Wed4str);
Display(BKGD,Wed5str);
break;
case 5:
Display(BKGD,Thurs1str);
Display(BKGD,Thurs2str);
Display(BKGD,Thurs3str);
Display(BKGD,Thurs4str);
Display(BKGD,Thurs5str);
break;
case 6:
Display(BKGD,Fri1str);
Display(BKGD,Fri2str);
Display(BKGD,Fri3str);
Display(BKGD,Fri4str);
Display(BKGD,Fri5str);
break;
case 7:
Display(BKGD,Sat1str);
Display(BKGD,Sat2str);
Display(BKGD,Sat3str);
Display(BKGD,Sat4str);
Display(BKGD,Sat5str);
break;
case 1:
Display(BKGD,Sun1str);
Display(BKGD,Sun2str);
Display(BKGD,Sun3str);
Display(BKGD,Sun4str);
Display(BKGD,Sun5str);
break;
default:
break;
}
if(((sliderValy - 15) > (Exitstr[0]*24)-20) && ((sliderValy - 15) < (Exitstr[0]*24)+7) && ((sliderVal - 15) > 110) && ((sliderVal - 15) < 185)){
flag2 = 0;
DrawRectangle(0,0,320,215, BKGD);
}
} else if(flag2 == 3){
Display(BKGD,Recordhead);
Display(GREEN,Record1);
Display(RGB(255,0,0),Record2);
Display(GREEN,Record3);
Display(RGB(255,0,0),Record4);
Display(RGB(255,0,0),Record5);
Display(GREEN,Record6);
Display(RGB(255,0,255),Exitstr);
if(((sliderValy - 15) > (Exitstr[0]*24)-20) && ((sliderValy - 15) < (Exitstr[0]*24)+7) && ((sliderVal - 15) > 110) && ((sliderVal - 15) < 185)){
flag2 = 0;
DrawRectangle(0,0,320,215, BKGD);
}
}
}