![](/media/cache/group/default_image.jpg.50x50_q85.jpg)
Working Menu with selectable fields yet to add comparison with healthy temperature ranges
Dependencies: TMP102_02
Diff: 17665328_SmartVeterinaryThermometer.cpp
- Revision:
- 9:483d03b3e1bc
- Child:
- 10:62da82b9b6de
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/17665328_SmartVeterinaryThermometer.cpp Fri Feb 04 09:00:38 2022 +0000 @@ -0,0 +1,756 @@ +/******************************************************************************* +Edward Hindley +Assistive Health device - measure temperature in an energy efficient and easy to use way +Board is initialised and awaits edge triggered interrupts to enable + a menu, measurement type selection and an average temperature reading. + + +* Craig A. Evans, University of Leeds, TMP102 Library, Feb 2016 +* Dr Edmond Nurellari, University of Lincoln, Joystick, N5110 Libraries, Feb 2022 + +*******************************************************************************/ + +#include "mbed.h" //Include all header files to be used throughout +#include "Timer.h" +#include "TMP102.h" +#include "Bitmap.h" +#include "N5110.h" +#include "Joystick.h" + +/******************************************************************************* +Set-up of all vital peripherals +Note that the following values correspond to these notes + NOTE_C4 262, NOTE_CS4 277, NOTE_D4 294, NOTE_DS4 311 + NOTE_E4 330, NOTE_F4 349, NOTE_FS4 370, NOTE_G4 392 + NOTE_GS4 415, NOTE_A4 440, NOTE_AS4 466, NOTE_B4 494 + NOTE_C5 523, NOTE_CS5 554, NOTE_D5 587, NOTE_DS5 622 + NOTE_E5 659, NOTE_F5 698, NOTE_FS5 740, NOTE_G5 784 + NOTE_GS5 831, NOTE_A5 880, NOTE_AS5 932, NOTE_B5 988 + NOTE_C6 1047 + *Author Jorge Rancé, PUBLISHED December 4, 2017 +*******************************************************************************/ +TMP102 tmp102(I2C_SDA,I2C_SCL); +N5110 lcd(PTC9,PTC0,PTC7,PTD2,PTD1,PTC11); +Joystick joystick(PTB10,PTB11,PTC16); +InterruptIn StartButton(PTC5); +InterruptIn BackButton(PTB19); +InterruptIn MenuOnButton(PTB3); //Open Menu +InterruptIn MenuOffButton(PTB18); //Close Menu +InterruptIn YButton(PTC12); //Set contrast +DigitalIn AButton(PTB9); //Submit Joystick Position +DigitalIn BButton(PTD0); //As Yet Unused +BusOut LedStatus(PTA1, PTA2, PTC2, PTC3, PTC4, PTD3); +PwmOut Buzz(PTC10); +AnalogIn Pot(PTB2); +Serial pc(USBTX,USBRX); +/******************************************************************************* +Initiate Variables and Voids +*******************************************************************************/ +volatile int G_RepeatNum; //Global variables denoted G_ +volatile float G_TempR; // TempR = Temp read from sensor +volatile float G_TempAve; +volatile int G_MLayerFlag; // MenuLayer flags = Maintains while loops whilst navigating menus +volatile bool G_APressed; +volatile bool G_BPressed; +volatile int G_PageNum; +volatile int G_PagePos; +volatile int G_SpeciesSelect; + +Timer MLayer1Time; +Timer MLayer2Time; +Timer ReviewTime; //Create Flag reset timer to initiate sleep in inactivity + +void SetContrast(); +void initDevice(); +void FillAnimal(); +void OpenLayer1(); +void OpenLayer2(); +void PageOne(); +void PageTwo(); +void PageThree(); +void PG2_0(); +void PG2_1(); +void PG2_2(); +void PG2_3(); +void PG2_4(); +void PG3_0(); +void PG3_1(); +void PG3_2(); +void PG3_3(); +void PG3_4(); +void TakeRdng(); +void Display(); +void HealthCheck(); +void CloseMenu(); +void RemPrompt(); + +typedef struct Animal{ + float UTemp; + float LTemp; +}; + +//****************************************************************************** +void SetContrast() +{ //Move Potentiometer to required position and Press Y to Set + float PotValue = Pot.read(); + printf("Brightness %f\n",PotValue); + lcd.setBrightness(PotValue); +} + +void initDevice() +{ + pc.baud(9600); //Set compatible to Terminal software + lcd.init(); //Use library initialisation function for onboard devices + tmp102.init(); + joystick.init(); + StartButton.mode(PullDown); //Set so rise is press and fall is release + BackButton.mode(PullDown); + MenuOnButton.mode(PullDown); + MenuOffButton.mode(PullDown); + AButton.mode(PullDown); + BButton.mode(PullDown); + YButton.mode(PullDown); + printf("Hardware Initialisation Complete \n"); +} + +void FillAnimal() +{ + Animal Dog[2]; + { + Dog.UTemp = 39.2; + Dog.LTemp = 37.5; + } + Animal Horse[2]; + { + Horse.UTemp = 38.6; + Horse.LTemp = 37.5; + } + Animal Rabbit[2]; + { + Rabbit.UTemp = 40.0; + Rabbit.LTemp = 38.5; + } + Animal Snake[2]; + { + Snake.UTemp = 31.1; + Snake.LTemp = 23.8; + } +} + +//****************************************************************************** Separator to aid readability +void OpenLayer1() +{ + G_MLayerFlag = 1; + MLayer1Time.start(); //MLayer1Time timer started in case this is first time + MLayer1Time.reset(); // running and reset incase this is not first time running + PageOne(); + wait(2.0); + if (G_PageNum==1) + { + while(G_MLayerFlag==1) + { + //printf("G_MLayerFlag is True \n"); + Direction d = joystick.get_direction(); //Upon each cycle of while, check joystick direction and buttons statuses + //printf("Direction %i \n", d); + G_APressed = AButton.read(); + G_BPressed = BButton.read(); + printf("A Button Status : %d \n", G_APressed); + wait(0.1); + float TimeGone = MLayer1Time.read(); + + if(TimeGone >= 10) //Set value for timer comparitor called TimeGone (Seconds) + { + CloseMenu(); + } + else if(d==1) //1 corresponds to North in the Enumerator (from joystick header) + { + printf("North Time is %.1f \n", TimeGone); + G_PagePos = 1; + G_SpeciesSelect = 1; + PageTwo(); + MLayer1Time.reset(); + wait(0.05); + } + else if(d==3) //3 corresponds to East in the Enumerator (from joystick header) + { + printf("East Time is %.1f \n", TimeGone); + G_PagePos = 2; + G_SpeciesSelect = 2; + PageTwo(); + MLayer1Time.reset(); + wait(0.2); + } + else if(d==5) //5 correspsonds to South in the Enumerator (from joystick header) + { + printf("South Time is %.1f \n", TimeGone); + G_PagePos = 3; + G_SpeciesSelect = 3; + PageTwo(); + MLayer1Time.reset(); + wait(0.05); + } + else if(d==7) //7 corresponds to West in the Enumerator (from joystick header) + { + printf("West Time is %.1f \n", TimeGone); + G_PagePos = 4; + G_SpeciesSelect = 4; + PageTwo(); + MLayer1Time.reset(); + wait(0.05); + } + else if(TimeGone >=2) + { + PG2_0(); + } + if(G_BPressed==1) + { + if(G_PageNum==1) + { + printf("Go to CloseMenu"); + CloseMenu(); + } + else if(G_PageNum==2) + { + printf("Go to PageOne"); + PageOne(); + } + } + } + } + else if(G_PageNum==2) + { + OpenLayer2(); //if MLayer2Flag == 1 should return to OpenLayer2 + } + else if(G_PageNum==0) + { + printf("Menue Closed"); + } +} +//****************************************************************************** +void PageOne() +{ + float PotValue = Pot.read(); + lcd.setBrightness(PotValue); + printf("Start Page"); + lcd.clear(); + lcd.drawLine(1,1,84,1,1); + lcd.printString(" Veterinary ",0,1); + lcd.printString("Thermometer",0,2); + lcd.printString(" ",0,3); + lcd.printString("EJH - Feb '22",0,4); + lcd.drawLine(1,47,84,47,1); + wait(1.0); + lcd.refresh(); + G_PageNum = 1; + return; +} + +void PageTwo() +{ + G_PageNum = 2; + if(G_PagePos==1) + { + PG2_1(); + } + else if(G_PagePos==2) + { + PG2_2(); + } + else if(G_PagePos==3) + { + PG2_3(); + } + else if(G_PagePos==4) + { + PG2_4(); + } + return; +} +void PG2_0() +{ + lcd.clear(); + lcd.drawLine(1,1,84,1,1); + lcd.printString(" Dog",0,1); + lcd.printString(" Horse",0,2); + lcd.printString(" Rabbit",0,3); + lcd.printString(" Snake",0,4); + lcd.drawLine(1,47,84,47,1); + wait(0.05); + lcd.refresh(); + return; +} +void PG2_1() +{ + lcd.clear(); + lcd.drawLine(1,1,84,1,1); + lcd.printString("-> Dog",0,1); + lcd.printString(" Horse",0,2); + lcd.printString(" Rabbit",0,3); + lcd.printString(" Snake",0,4); + lcd.drawLine(1,47,84,47,1); + wait(0.05); + lcd.refresh(); + if (G_APressed==1) + { + G_PageNum=2; + G_MLayerFlag=2; + OpenLayer2(); + } + else + { + return; + } +} +void PG2_2() +{ + lcd.clear(); + lcd.drawLine(1,1,84,1,1); + lcd.printString(" Dog",0,1); + lcd.printString("-> Horse",0,2); + lcd.printString(" Rabbit",0,3); + lcd.printString(" Snake",0,4); + lcd.drawLine(1,47,84,47,1); + wait(0.05); + lcd.refresh(); + if (G_APressed==1) + { + G_PageNum=2; + G_MLayerFlag=2; + OpenLayer2(); + } + else + { + return; + } +} +void PG2_3() +{ + lcd.clear(); + lcd.drawLine(1,1,84,1,1); + lcd.printString(" Dog",0,1); + lcd.printString(" Horse",0,2); + lcd.printString("-> Rabbit",0,3); + lcd.printString(" Snake",0,4); + lcd.drawLine(1,47,84,47,1); + wait(0.05); + lcd.refresh(); + if (G_APressed==1) + { + G_PageNum=2; + G_MLayerFlag=2; + OpenLayer2(); + } + else + { + return; + } +} +void PG2_4() +{ + lcd.clear(); + lcd.drawLine(1,1,84,1,1); + lcd.printString(" Dog",0,1); + lcd.printString(" Horse",0,2); + lcd.printString(" Rabbit",0,3); + lcd.printString("-> Snake",0,4); + lcd.drawLine(1,47,84,47,1); + wait(0.05); + lcd.refresh(); + if (G_APressed==1) + { + G_PageNum=2; + G_MLayerFlag=2; + OpenLayer2(); + } + else + { + return; + } +} +//****************************************************************************** +void OpenLayer2() +{ + wait(1.0); + MLayer2Time.start(); //MLayer2Time timer started in case this is first time + MLayer2Time.reset(); // running and reset incase this is not first time running + + if(G_PageNum==2) + { + while(G_MLayerFlag==2) + { + //printf("G_MLayerFlag is True \n"); + Direction d = joystick.get_direction(); //Upon each cycle of while, check joystick direction and buttons statuses + printf("Direction %i \n", d); + bool G_APressed = AButton.read(); + bool G_BPressed = BButton.read(); + //printf("A Button Status : %d \n", G_APressed); + wait(0.05); + float TimeGone2 = MLayer2Time.read(); + + if(TimeGone2 >= 10) //Set value for timer comparitor called TimeGone (Seconds) + { + OpenLayer1(); + } + else if(d==1) //1 corresponds to North in the Enumerator (from joystick header) + { + printf("North Time is %.1f \n", TimeGone2); + G_PagePos = 5; + PageThree(); + MLayer2Time.reset(); + wait(0.05); + } + else if(d==3) //3 corresponds to East in the Enumerator (from joystick header) + { + printf("East Time is %.1f \n", TimeGone2); + G_PagePos = 6; + PageThree(); + MLayer2Time.reset(); + wait(0.05); + } + else if(d==5) //5 correspsonds to South in the Enumerator (from joystick header) + { + printf("South Time is %.1f \n", TimeGone2); + G_PagePos = 7; + PageThree(); + MLayer2Time.reset(); + wait(0.05); + } + else if(d==7) //7 corresponds to West in the Enumerator (from joystick header) + { + printf("West Time is %.1f \n", TimeGone2); + G_PagePos = 8; + PageThree(); + MLayer2Time.reset(); + wait(0.05); + } + else if(TimeGone2 >=2) + { + PG3_0(); + } + else if(G_BPressed==1) + { + G_PageNum=1; + OpenLayer1(); + } + } + if (G_MLayerFlag==3) + { + TakeRdng(); + } + } + else if(G_PageNum==1) + { + OpenLayer1(); //if MLayer2Flag == 1 should return to OpenLayer2 + } +} +//****************************************************************************** + +void PageThree() +{ + //G_PageNum = 3; + if(G_PagePos==5) + { + PG3_1(); + } + else if(G_PagePos==6) + { + PG3_2(); + } + else if(G_PagePos==7) + { + PG3_3(); + } + else if(G_PagePos==8) + { + PG3_4(); + } + return; +} +void PG3_0() +{ + lcd.clear(); + lcd.drawLine(1,1,84,1,1); + lcd.printString(" 1 Reading",0,1); + lcd.printString(" 5 Readings",0,2); + lcd.printString(" 20 Readings",0,3); + lcd.printString(" 100 Readings",0,4); + lcd.drawLine(1,47,84,47,1); + wait(0.05); + lcd.refresh(); + return; +} +void PG3_1() +{ + lcd.clear(); + lcd.drawLine(1,1,84,1,1); + lcd.printString("->1 Reading",0,1); + lcd.printString(" 5 Readings",0,2); + lcd.printString(" 20 Readings",0,3); + lcd.printString(" 100 Readings",0,4); + lcd.drawLine(1,47,84,47,1); + wait(0.05); + lcd.refresh(); + bool G_APressed = AButton.read(); + if (G_APressed==1) + { + G_RepeatNum = 1; + G_MLayerFlag=3; + //TakeRdng(); + } + else + { + return; + } +} +void PG3_2() +{ + lcd.clear(); + lcd.drawLine(1,1,84,1,1); + lcd.printString(" 1 Reading",0,1); + lcd.printString("->5 Readings",0,2); + lcd.printString(" 20 Readings",0,3); + lcd.printString(" 100 Readings",0,4); + lcd.drawLine(1,47,84,47,1); + wait(0.05); + lcd.refresh(); + bool G_APressed = AButton.read(); + if (G_APressed==1) + { + G_RepeatNum = 5; + G_MLayerFlag=3; + //TakeRdng(); + } + else + { + return; + } +} +void PG3_3() +{ + lcd.clear(); + lcd.drawLine(1,1,84,1,1); + lcd.printString(" 1 Reading",0,1); + lcd.printString(" 5 Readings",0,2); + lcd.printString("->20 Readings",0,3); + lcd.printString(" 100 Readings",0,4); + lcd.drawLine(1,47,84,47,1); + wait(0.05); + lcd.refresh(); + bool G_APressed = AButton.read(); + if (G_APressed==1) + { + G_RepeatNum = 20; + G_MLayerFlag=3; + //TakeRdng(); + } + else + { + return; + } +} +void PG3_4() +{ + lcd.clear(); + lcd.drawLine(1,1,84,1,1); + lcd.printString(" 1 Reading",0,1); + lcd.printString(" 5 Readings",0,2); + lcd.printString(" 20 Readings",0,3); + lcd.printString("->100 Readings",0,4); + lcd.drawLine(1,47,84,47,1); + wait(0.05); + lcd.refresh(); + bool G_APressed = AButton.read(); + if (G_APressed==1) + { + G_RepeatNum = 100; + G_MLayerFlag=3; + //TakeRdng(); + } + else + { + return; + } +} +void CloseMenu() +{ + lcd.setBrightness(0.00); + G_PageNum = 0; + G_MLayerFlag = 0; + lcd.clear(); + lcd.refresh(); + printf("Menu Closed and Flag Reset \n"); +} + + +void TakeRdng() +{ + float TempSum = 0; + G_TempR = tmp102.get_temperature(); // read temperature save to variable TempR + for(int i=0; i<G_RepeatNum; i++) { //change G_RepeatNum set by user in menu + printf("Temp was %.2f \n", G_TempR); + TempSum = TempSum + G_TempR; + printf("TempSum = %.2f \n",TempSum); + /*Buzz.period(1.0/523.0); + Buzz = 0.5; + wait(0.5); //Rough time between readings + */Buzz = 0; + if(G_BPressed==1) + { + G_RepeatNum = 0; + OpenLayer2(); + } + } + G_TempAve = TempSum / G_RepeatNum; //Average Temperature Calculation using the RepeatNum + HealthCheck(); // variable as number of elements in average +} +enum SpeciesPage +{ + SpeciesDog=1, + SpeciesHorse=2, + SpeciesRabbit=3, + SpeciesSnake=4, + SpeciesState=5, +}; +void Display() +{ + int DisplayType = SpeciesState; + int NextDisplayType = SpeciesState; + switch(DisplayType) + { + case SpeciesState: + { + if(G_SpeciesSelect == 1) + { + NextDisplayType = SpeciesDog; + } + else if(G_SpeciesSelect == 2) + { + NextDisplayType = SpeciesHorse; + } + else if(G_SpeciesSelect == 3) + { + NextDisplayType = SpeciesRabbit; + } + else if(G_SpeciesSelect == 4) + { + NextDisplayType = SpeciesSnake; + } + } + case SpeciesDog: + { + lcd.clear(); + lcd.drawLine(1,1,84,1,1); + lcd.printString("Dog Health",0,1); + char buffer[14]; + int length = sprintf(buffer,"T=%.3f 'C", G_TempAve); + if (length <= 14) //check string fits on screen (14 lots of 6 wide characters) + lcd.printString(buffer,0,2); + lcd.drawLine(1,47,84,47,1); + lcd.refresh(); + if (G_TempAve >= Dog.LTemp and G_TempAve <= Dog.UTemp) + { + lcd.printString("Temperature OK",0,3); + } + } + case SpeciesHorse: + { + lcd.clear(); + lcd.drawLine(1,1,84,1,1); + lcd.printString("Horse Health",0,1); + char buffer[14]; + int length = sprintf(buffer,"T=%.3f 'C", G_TempAve); + if (length <= 14) //check string fits on screen (14 lots of 6 wide characters) + lcd.printString(buffer,0,2); + lcd.drawLine(1,47,84,47,1); + lcd.refresh(); + if (G_TempAve >= Horse.LTemp and G_TempAve <= Horse.UTemp) + { + lcd.printString("Temperature OK",0,3); + } + } + case SpeciesRabbit: + { + lcd.clear(); + lcd.drawLine(1,1,84,1,1); + lcd.printString("Rabbit Health",0,1); + char buffer[14]; + int length = sprintf(buffer,"T=%.3f 'C", G_TempAve); + if (length <= 14) //check string fits on screen (14 lots of 6 wide characters) + lcd.printString(buffer,0,2); + lcd.drawLine(1,47,84,47,1); + lcd.refresh(); + if (G_TempAve >= Rabbit.LTemp and G_TempAve <= Rabbit.UTemp) + { + lcd.printString("Temperature OK",0,3); + } + } + case SpeciesSnake: + { + lcd.clear(); + lcd.drawLine(1,1,84,1,1); + lcd.printString("Snake Health",0,1); + char buffer[14]; + int length = sprintf(buffer,"T=%.3f 'C", G_TempAve); + if (length <= 14) //check string fits on screen (14 lots of 6 wide characters) + lcd.printString(buffer,0,2); + lcd.drawLine(1,47,84,47,1); + lcd.refresh(); + if (G_TempAve >= Snake.LTemp and G_TempAve <= Snake.UTemp) + { + lcd.printString("Temperature OK",0,3); + } + } + } + /*printf("Average Reading = %.2f \n",G_TempAve); + lcd.clear(); + char buffer[14]; + int length = sprintf(buffer,"T=%.3f 'C", G_TempAve); + if (length <= 14) //check string fits on screen (14 lots of 6 wide characters) + lcd.printString(buffer,0,1); + lcd.refresh(); */ +} +void RemPrompt() +{ + lcd.clear(); + lcd.drawLine(1,1,84,1,1); + lcd.printString("Device may",0,1); + lcd.printString("sleep soon!",0,2); + lcd.printString("A to keep Temp",0,3); + lcd.printstring("B to main menu",0,4); + lcd.drawLine(1,47,84,47,1); + lcd.refresh(); +} //Prompts user to allow screen to sleep +void HealthCheck() +{ + ReviewTime.start(); //ReviewTime timer started in case this is first time + bool G_APressed = AButton.read(); + Display(); + while(ReviewTime<=30) + { + if(ReviewTime>=10) + { + RemPrompt(); + } + if (G_APressed==1) + { + ReviewTime.reset(); + } + else if(G_BPressed==1) + { + G_MLayerFlag =1; + G_PageNum =1; + OpenLayer1(); + } + } + CloseMenu(); +} + +int main() +{ + initDevice(); + FillAnimal(); //Initiate Hardware + YButton.rise(&SetContrast); //Interrupts connected to voids + StartButton.rise(&TakeRdng); + MenuOnButton.rise(&OpenLayer1); + MenuOffButton.rise(&CloseMenu); //Obselete +} \ No newline at end of file