使用Arduino的自动药物提醒

原文:https://circuitdigest.com/microcontroller-projects/arduino-medicine-reminder

使用Arduino的自动药物提醒

ARDUINO PROJECTS

经过**阿比曼尤·潘迪(Abhiemanyu Pandit)** 2019年1月22日
在这里插入图片描述使用Arduino的医学提醒

对于我们所爱的人,我们始终希望保持他们的健康和健康。但是,如果他们生病而忘记按时吃药,将会发生什么。我们会担心,对吗?在医院里,有很多病人,很难提醒每个病人准时吃药。传统方式需要人工来提醒他们按时服药。数字时代并没有随之而来,我们可以使用机器来做到这一点。Smart Medicine Reminder的应用范围非常广泛,可以被家庭患者,医院的医生以及许多其他地方使用。关于提醒,可以有多种提醒方法:

  1. 在显示器上显示
  2. 通过电子邮件或电话发送通知
  3. 使用行动应用程式
  4. 蜂鸣警报
  5. 使用蓝牙/ Wi-Fi
  6. 接电话
  7. 提醒下一次服药时间,同时提醒当前时间

我们可以根据需要结合多种方式。为了使事情简单,我们使用Arduino创建了一个简单的药品提醒,提醒我们每天服用1或2或3次药物。可以使用按钮选择时隙。此外,它还显示当前的日期和时间。我们将其进一步扩展到IoT项目传入的文章,在该文章中,电子邮件或SMS通知将发送给用户。该用药提醒也可以与患者监测系统集成。

使用Arduino的自动药物提醒所需的组件

  1. Arduino Uno(我们也可以使用其他Arduino开发板,例如Pro mini,Nano)
  2. RTC DS3231模块
  3. 16x2 LCD显示屏
  4. 蜂鸣器
  5. LED(任何颜色)
  6. 面包板
  7. 按按钮
  8. 10K电位器
  9. 10K,1K电阻器
  10. 跳线

使用Arduino Circuit的Arduino Medicine提醒

下面显示了 使用Arduino构建智能药箱的完整电路图
在这里插入图片描述
以下是Arduino与不同外设的引脚连接

Arduino****引脚外围引脚

  • 2 -----------------------------> Dx的16x2 LCD显示屏
  • 3 -----------------------------> D6的16x2 LCD显示屏
  • 4 -----------------------------> D5的16x2 LCD显示屏
  • 5 -----------------------------> D4的16x2 LCD显示屏
  • 7 ----------------------------->第三个按钮
  • 8 ----------------------------->第二个按钮
  • 9 ----------------------------->第一个按钮
  • 11 -----------------------------> 16x2 LCD显示屏的EN引脚
  • 12 -----------------------------> 16x2 LCD显示器的RS引脚
  • 13 -----------------------------> +蜂鸣器和LED的Ve引脚
  • A0 ----------------------------->停止按钮
  • A4 -----------------------------> DS3231的SDA
  • A5 -----------------------------> DS3231的SCL
  • 3.3V -----------------------------> DS3231的Vcc
  • Gnd ----------------------------->Gnd
    在这里插入图片描述

在此医学提醒项目中,RTC DS3231通过I2C协议与Arduino Uno接口。您还可以使用 RTC IC DS1307与Arduino读取时间。RTC DS3231还具有内置的32k存储器,可用于存储其他数据。RTC模块通过Arduino uno的3.3V引脚供电。甲16×2 LCD显示器使用SPI接口。一个buzze R用于警示和提醒,它的时间服药。四个按钮用于每个都有独特选择功能的地方。第一个按钮用于提醒每天服药一次。第二个按钮每天提醒两次,第三个按钮每天提醒三次。当用户听到警报时,第四个按钮用于停止蜂鸣器。

自动药品提示系统的工作

丸提醒警报使用5V电源供电。当它第一次启动时,它会显示一个欢迎按摩,如" Welcome to Circuit Digest “。LCD屏幕设置为在三个屏幕之间循环。1个ST屏幕显示按摩为"保持健康,早日康复”。第二个屏幕是一个帮助屏幕,告诉您按选择按钮以选择任何一个要提醒的时间段(一天一次/两次/三次)。该时隙可在程序中更改,并可进行相应配置。现在,我们将其固定为三个时段,即上午8点,下午2点和晚上8点。

我们将时隙分为三种模式。模式1用于选择吃药一次/天在早上8时,用户按下1个ST按钮。当用户按下第二个按钮时,模式2选择每天两次在上午8点和晚上8点服药。模式3个选择吃药三次/天上午8点,下午2点和下午8点,如果用户按压3次按钮。
在这里插入图片描述
我们还可以添加一项功能,使蜂鸣器暂停10分钟(此项目不包括此功能)。当用户通过按下按钮选择所需的插槽时,将记录用户输入,并从RTC中获取时间。当时间与选定的时隙匹配时,蜂鸣器开始蜂鸣。用户可以通过按"停止"按钮来停止蜂鸣器。下一个插槽提醒将继续相同的过程。本节末尾的视频中显示了完整的过程。

编程Arduino UNO进行医学提醒

一旦想到了提醒服用药丸的方法,编写程序就非常容易。此处将在显示屏上显示提醒,对蜂鸣器进行蜂鸣并使用LED进行指示。它还具有选择三个时隙(每天一次/两次/三次)的选项,并且当时间到时将开始通过蜂鸣器的蜂鸣来提醒患者。然后整个系统将如下所示:

用户在显示屏上获得帮助说明>用户选择时隙(一次/天,两次/天,三次/天)>在显示屏上显示确认消息>计时开始>当时间与用户选择的时隙相匹配时蜂鸣器和LED响起>用户停止按下停止按钮>结束

如果要添加更多功能,我们可以更改程序和硬件。为了以更简单的方式理解,我们将程序分解为小功能。这些功能易于理解和实现。完整的程序在该项目的末尾给出。让我们从程序开始。

由于我们使用了其他外设,例如16x2 LCD显示器,RTC DS3231,因此我们首先必须包含库f或那个。所需的库如下:

<LiquidCrystal.h>   
<RTClib.h>(https://github.com/adafruit/RTClib)
<EEPROM.h> 
<Wire.h>

如果未打开Arduino,则EEPROM库用于跟踪用户选择输入。而且,当用户打开Arduino电源时,它会使用EEPROM库获得按钮的先前状态。之所以使用Wire.h库,是因为RTC DS3231模块是使用I2C进行通信的。

始终检查RTC接线是否正确或是否已损坏,因为RTC在整个提醒系统的计时中将发挥重要作用。

  if(!rtc.begin()){//检查rtc是否已连接
    Serial.println("找不到RTC"); 
    while(1); 
  }
if(rtc.lostPower()){ 
    Serial.println(" RTC掉电,请设置时间!"); 
  }

时间调整可以通过两种方式完成,要么自动使用系统编译时间,要么手动输入。设置时间后,除非您想再次更改RTC时间,否则请注释以下几行。

rtc.adjust(DateTime(F(__ DATE__),F(__ TIME__)));        
//rtc.adjust(DateTime(2019,1,10,7,59,52));

该**switch语句用于读取按钮的先前保存状态,**并在适当和准确的提醒时间恢复该状态。

val2 = EEPROM.read(addr); //读取先前保存的按钮值,从先前保留的位置开始进行
  switch(val2){
    case 1:
      Serial.println("Set for 1 / day"); 
      push1state = 1; 
      push2state = 0; 
      push3state = 0; 
      pushVal = 01; 
      break; 

    case 2:
      Serial.println(" Set for 2 / day");
      push1state = 0; 
      push2state = 1; 
      push3state = 0;
      pushVal = 10; 
      break; 
   
    case 3:
      Serial.println(" Set for 3 / day")
      push1state = 0; 
      push2state = 0; 
      push3state = 1;
      pushVal = 11; 
      break; 
  }

此语句用于使毫秒数用于定时和控制已定义的间隔屏幕循环。

currentMillisLCD = millis(); //在定义的时间间隔内启动毫秒以进行LCD屏幕切换

开始读取连接到按钮的数字引脚。

push1state = digitalRead(push1pin);                  
push2state = digitalRead(push2pin); 
push3state = digitalRead(push3pin); 
stopinState = digitalRead(stopPin);  

以下功能用于读取按钮状态并将其写入EEPROM。每当按下按钮时,状态就会写入EEPROM。它还在所选用户输入选项的LCD显示屏上打印消息。类似地,使用函数push2()push3()

void push1(){//
  if(push1state == 1){ 
    push1state = 0; 
    push2state = 0; 
    push3state = 0; 
// pushPressed = true; 
    EEPROM.write(addr,1); 
    Serial.print(" Push1 Written:"); Serial.println(EEPROM.read(addr)); //用于调试
    pushVal = 1; //保存按钮1的状态
    lcd.clear(); 
    lcd.setCursor(0,0); 
    lcd.print(" Reminder set"); 
    lcd.setCursor(0,1); 
    lcd.print("每天一次!"); 
    delay(1200); 
    lcd.clear(); 
  } 
}

以下功能用于停止蜂鸣器和指示灯。提出建议总是好的。在"用温水服药"显示屏上打印建议消息。

void stopPins(){//

  if(stopinState == 1)
用户按下停止按钮时停止嗡嗡声的功能{ // stopinState = 0; 
// pushPressed = true; 
    pushval= 1; 
    lcd.clear(); 
    lcd.setCursor(0,0); 
    lcd.print(" Take Medicine"); 
    lcd.setCursor(0,1); 
    lcd.print("带温水"); 
    delay(1200); 
    lcd.clear(); 
  } 
}

以下功能与计时无关,但始终在三个屏幕上循环,这对用户有帮助。由于我们一直在照顾患者,因此请打印问候语,因为我们知道情感支持对于更快地治愈患者非常有帮助。您可以选择自己的创意信息。让我们打印一条消息,“保持健康,早日康复”。

第二个屏幕用于向患者发出指示,例如"按提醒按钮…"。 第三个屏幕仅用于显示当前日期和时间

void changeScreen() {                 //function for Screen Cycling

  // Start switching screen every defined intervalLCD
  if (currentMillisLCD - previousMillisLCD > intervalLCD)             // save the last time you changed the display
  {
    previousMillisLCD = currentMillisLCD;
    screens++;
    if (screens > maxScreen) {
      screens = 0;  // all screens over -> start from 1st
    }
    isScreenChanged = true;
  }

  // Start displaying current screen
  if (isScreenChanged)   // only update the screen if the screen is changed.
  {
    isScreenChanged = false; // reset for next iteration
    switch (screens)
    {
      case getWellsoon:
        gwsMessege();                // get well soon message
        break;
      case HELP_SCREEN:              
        helpScreen();               // instruction screen
        break;
      case TIME_SCREEN:
        timeScreen();                  // to print date and time
        break;
      default:
        //NOT SET.
        break;
    }
  }
}

如果已达到所选时间,则此功能可用于同时开始蜂鸣和LED闪烁

void startBuzz() {                    // function to start buzzing when time reaches to defined interval
//  if (pushPressed == false) {
 
if (pushpressed == 0) {
    Serial.println("pushpressed is false in blink");
    unsigned long currentMillis = millis();
    
if (currentMillis - previousMillis >= interval) {
      previousMillis = currentMillis;         // save the last time you blinked the LED
      Serial.println("Start Buzzing");
      
if (ledState == LOW) {                  // if the LED is off turn it on and vice-versa:
        ledState = HIGH;
      }  else {
        ledState = LOW;
      }
      digitalWrite(ledPin, ledState);
    }
  }
  
else if (pushpressed == 1) {
    Serial.println("pushpressed is true");
    ledState = LOW;
    digitalWrite(ledPin, ledState);
  }
}

*此功能用于比较用户在上午8点选择的时隙,并开始蜂鸣蜂鸣器并使LED闪烁,直到用户按下停止按钮为止。类似地,*void at2pm()*void at8pm的***功能用于启动蜂鸣器,并在2pm和8pm引导。

void at8am(){//函数从上午8点开始嗡嗡声
  DateTime now = rtc.now(); 
  if(int(now.hour())> = buzz8amHH){ 
    if(int(now.minute())> = buzz8amMM){ 
      if(int(now.second())> buzz8amSS){ 
        // /// 
        startBuzz() ; 
        / /// 
      } 
    } 
  } 
}

这是您可以使用Arduino简单地制作自己的自动药品提醒的方法。您还可以将ESP8266与Arduino结合使用,使其成为一个IoT项目,该项目将能够向用户发送电子邮件警报。

完整的代码和演示视频如下。

代码

//Medicine Reminder using Arduino Uno
// Reminds to take medicine at 8am, 2pm, 8pm 
/*  The circuit:
   LCD RS pin to digital pin 12
   LCD Enable pin to digital pin 11
   LCD D4 pin to digital pin 5
   LCD D5 pin to digital pin 4
   LCD D6 pin to digital pin 3
   LCD D7 pin to digital pin 2
   LCD R/W pin to ground
   LCD VSS pin to ground
   LCD VCC pin to 5V
   10K resistor:
   ends to +5V and ground
   wiper to LCD VO pin (pin 3)*/

#include <LiquidCrystal.h>
#include <Wire.h>
#include <RTClib.h>
#include <EEPROM.h>

int pushVal = 0;                           
int val;
int val2;
int addr = 0;

RTC_DS3231 rtc;

const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;                 // lcd pins
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

#define getWellsoon 0                                           
#define HELP_SCREEN 1
#define TIME_SCREEN 2

//bool pushPressed;                               //flag to keep track of push button state 
int pushpressed = 0;
const int ledPin =  LED_BUILTIN;                        // buzzer and led pin
int ledState = LOW;
int Signal = 0;

int buzz = 13;                                      
int push1state, push2state, push3state, stopinState = 0;     // 
int push1Flag, push2Flag, Push3Flag = false;              // push button flags 
int push1pin = 9;
int push2pin = 8;
int push3pin = 7;
int stopPin = A0;
int screens = 0;              // screen to show
int maxScreen = 2;            // screen count
bool isScreenChanged = true;

long previousMillis = 0;           
long interval = 500;                   // buzzing interval
unsigned long currentMillis;

long previousMillisLCD = 0;    // for LCD screen update
long intervalLCD = 2000;          // Screen cycling interval
unsigned long currentMillisLCD;

//   Set Reminder Change Time
int buzz8amHH = 8;          //    HH - hours         ##Set these for reminder time in 24hr Format 
int buzz8amMM = 00;          //    MM - Minute
int buzz8amSS = 00;          //    SS - Seconds

int buzz2pmHH = 14;          //    HH - hours
int buzz2pmMM = 00;          //    MM - Minute
int buzz2pmSS = 00;          //    SS - Seconds

int buzz8pmHH = 20;          //    HH - hours
int buzz8pmMM = 00;          //    MM - Minute
int buzz8pmSS = 00;          //    SS - Seconds

int nowHr, nowMin, nowSec;                     // to show current mm,hh,ss

// All messeges
void gwsMessege(){               // print get well soon messege
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Stay Healthy :)");     // Give some cheers
    lcd.setCursor(0, 1);
    lcd.print("Get Well Soon :)");    // wish 
}

void helpScreen() {              // function to display 1st screen in LCD
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Press Buttons");
    lcd.setCursor(0, 1);
    lcd.print("for Reminder...!");
    
 }

void timeScreen() {              // function to display Date and time in LCD screen
  DateTime now = rtc.now();             // take rtc time and print in display
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Time:");
    lcd.setCursor(6, 0);
    lcd.print(nowHr = now.hour(), DEC);
    lcd.print(":");
    lcd.print(nowMin = now.minute(), DEC);
    lcd.print(":");
    lcd.print(nowSec = now.second(), DEC);
    lcd.setCursor(0, 1);
    lcd.print("Date: ");
    lcd.print(now.day(), DEC);
    lcd.print("/");
    lcd.print(now.month(), DEC);
    lcd.print("/");
    lcd.print(now.year(), DEC);
}

void setup() {

  Serial.begin(9600);                      // start serial debugging
  if (! rtc.begin()) {                      // check if rtc is connected 
    Serial.println("Couldn't find RTC");
    while (1);
  }
  if (rtc.lostPower()) {
    Serial.println("RTC lost power, lets set the time!");
  }

//    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));            // uncomment this to set the current time and then comment in next upload when u set the time
  rtc.adjust(DateTime(2019, 1, 10, 7, 59, 30));                // manual time set

  lcd.begin(16, 2);
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Welcome To");                                      // print a messege at startup
  lcd.setCursor(0, 1);
  lcd.print("Circuit Digest");
  delay(1000);
  pinMode(push1pin, INPUT);                                    // define push button pins type
  pinMode(push2pin, INPUT);
  pinMode(push3pin, INPUT);
  pinMode(stopPin, INPUT);
  pinMode(ledPin, OUTPUT);
  delay(200);
  Serial.println(EEPROM.read(addr));
  val2 = EEPROM.read(addr);                         // read previosuly saved value of push button to start from where it was left previously
  switch (val2) {
    case 1:
      Serial.println("Set for 1/day");
      push1state = 1;
      push2state = 0;
      push3state = 0;
      pushVal = 1;
      break;
    case 2:
      Serial.println("Set for 2/day");
      push1state = 0;
      push2state = 1;
      push3state = 0;
      pushVal = 2;

      break;
    case 3:
      Serial.println("Set for 3/day");
      push1state = 0;
      push2state = 0;
      push3state = 1;
      pushVal = 3;

      break;
  }

}

void loop() {
  push1();                                             //call to set once/day 
  push2();                                             //call to set twice/day 
  push3();                                             //call to set thrice/day 
    if (pushVal == 1) {                                // if push button 1 pressed then remind at 8am
    at8am();                                           //function to start uzzing at 8am 
  }
  else if (pushVal == 2) {                             // if push button 2 pressed then remind at 8am and 8pm
    at8am();                                            
    at8pm();                                           //function to start uzzing at 8mm
  }
  else if (pushVal == 3) {                             // if push button 3 pressed then remind at 8am and 8pm
    at8am();
    at2pm();                                            //function to start uzzing at 8mm
    at8pm();
  }
  
  currentMillisLCD = millis();                         // start millis for LCD screen switching at defined interval of time
  push1state = digitalRead(push1pin);                  // start reading all push button pins
  push2state = digitalRead(push2pin);
  push3state = digitalRead(push3pin);
  stopinState = digitalRead(stopPin);
  
  stopPins();                                            // call to stop buzzing
  changeScreen();                                        // screen cycle function

}

// push buttons
void push1() {                   // function to set reminder once/day 
  if (push1state == 1) {
    push1state = 0;
    push2state = 0;
    push3state = 0;
//    pushPressed = true;
    EEPROM.write(addr, 1);
    Serial.print("Push1 Written : "); Serial.println(EEPROM.read(addr));  // for debugging
    pushVal = 1;                                             //save the state of push button-1 
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Reminder set ");
    lcd.setCursor(0, 1);
    lcd.print("for Once/day !");
    delay(1200);
    lcd.clear();
  }
}

void push2() {                      //function to set reminder twice/day
  if (push2state == 1) {
    push2state = 0;
    push1state = 0;
    push3state = 0;
//    pushPressed = true;
    EEPROM.write(addr, 2);
    Serial.print("Push2 Written : "); Serial.println(EEPROM.read(addr));
    pushVal = 2;
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Reminder set ");
    lcd.setCursor(0, 1);
    lcd.print("for Twice/day !");
    delay(1200);
    lcd.clear();
  }
}

void push3() {                    //function to set reminder thrice/day
  if (push3state == 1) {
    push3state = 0;
    push1state = 0;
    push2state = 0;
//    pushPressed = true;
    EEPROM.write(addr, 3);
    Serial.print("Push3 Written : "); Serial.println(EEPROM.read(addr));
    pushVal = 3;
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Reminder set ");
    lcd.setCursor(0, 1);
    lcd.print("for Thrice/day !");
    delay(1200);
    lcd.clear();
  }
}

void stopPins() {                   //function to stop buzzing when user pushes stop push button
  if (stopinState == 1) {
//    stopinState = 0;
//    pushPressed = true;
    pushpressed = 1;
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Take Medicine  ");
    lcd.setCursor(0, 1);
    lcd.print("with Warm Water");
    delay(1200);
    lcd.clear();
  }
}

void startBuzz() {                    // function to start buzzing when time reaches to defined interval

//  if (pushPressed == false) {
 if (pushpressed == 0) {
    Serial.println("pushpressed is false in blink");
    unsigned long currentMillis = millis();
    if (currentMillis - previousMillis >= interval) {
      previousMillis = currentMillis;         // save the last time you blinked the LED
      Serial.println("Start Buzzing");
      if (ledState == LOW) {                  // if the LED is off turn it on and vice-versa:
        ledState = HIGH;
      }  else {
        ledState = LOW;
      }
      digitalWrite(ledPin, ledState);
    }
  }
  else if (pushpressed == 1) {
    Serial.println("pushpressed is true");
    ledState = LOW;
    digitalWrite(ledPin, ledState);
  }
}

void at8am() {                      // function to start buzzing at 8am
  DateTime now = rtc.now();
  if (int(now.hour()) >= buzz8amHH) {
    if (int(now.minute()) >= buzz8amMM) {
      if (int(now.second()) > buzz8amSS) {
        /

        startBuzz();
        /
      }
    }
  }
}

void at2pm() {                          // function to start buzzing at 2pm
  DateTime now = rtc.now();
  if (int(now.hour()) >= buzz2pmHH) {
    if (int(now.minute()) >= buzz2pmMM) {
      if (int(now.second()) > buzz2pmSS) {
       
        ///
        startBuzz();
        //
      }
    }
  }
}

void at8pm() {                           // function to start buzzing at 8pm
  DateTime now = rtc.now();
  if (int(now.hour()) >= buzz8pmHH) {
    if (int(now.minute()) >= buzz8pmMM) {
      if (int(now.second()) > buzz8pmSS) {
        
        /
        startBuzz();
        /
      }
    }
  }
}

//Screen Cycling
void changeScreen() {                 //function for Screen Cycling
  // Start switching screen every defined intervalLCD
  if (currentMillisLCD - previousMillisLCD > intervalLCD)             // save the last time you changed the display
  {
    previousMillisLCD = currentMillisLCD;
    screens++;
    if (screens > maxScreen) {
      screens = 0;  // all screens over -> start from 1st
    }
    isScreenChanged = true;
  }

  // Start displaying current screen
  if (isScreenChanged)   // only update the screen if the screen is changed.
  {
    isScreenChanged = false; // reset for next iteration
    switch (screens)
    {
      case getWellsoon:
        gwsMessege();                // get well soon message
        break;
      case HELP_SCREEN:              
        helpScreen();               // instruction screen
        break;
      case TIME_SCREEN:
        timeScreen();                  // to print date and time
        break;
      default:
        //NOT SET.
        break;
    }
  }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值