如何使用Arduino制作自动药物提醒器

医疗电子

421人已加入

描述

当谈到我们所爱的人时,我们总是希望他们保持健康和健康。但是如果他们生病了,忘记按时吃药会怎么样。我们会担心的,对吧?在医院,病人很多,很难提醒每一位病人按时吃药。传统方式需要人为提醒他们按时服药。数字时代并没有遵循这一点,我们可以使用机器来做到这一点。Smart Medicine Reminder的应用非常广泛,可以在家中的患者、医院的医生以及许多其他地方使用。在提醒方面,可以有多种提醒方式:

在显示器上显示

通过电子邮件或电话发送通知

使用移动应用程序

蜂鸣器

使用蓝牙/Wi-Fi

接电话

在提醒当前时间的同时提醒下次用药时间

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

使用 Arduino 进行自动医学提醒所需的组件

Arduino Uno(我们也可以使用其他 Arduino 板,如 Pro mini、Nano)

RTC DS3231 模块

16x2 液晶显示器

蜂鸣器

LED(任何颜色)

面包板

按按钮

10K电位器

10K,1K电阻

跳线

使用 Arduino 电路的 Arduino 医学提醒

使用 Arduino 构建智能药盒的完整电路图如下所示

Arduino

以下是Arduino 与不同外设的引脚连接

ArduinoArduino

在这个医学提醒项目中,RTC DS3231 通过 I2C 协议与 Arduino Uno 连接。您还可以使用 RTC IC DS1307 通过 Arduino 读取时间。RTC DS3231 还具有内置的 32k 内存,可用于存储附加数据。RTC 模块通过 Arduino uno 的 3.3V 引脚供电。一个16x2 LCD 显示器使用 SPI 接口。蜂鸣器r用于提醒和提醒该吃药了。四个按钮用于每个具有不同选择功能的地方。第一个按钮用于提醒每天吃一次药。第二个按钮用于每天提醒两次,第三个按钮用于每天提醒三次。当用户听到警报时,第四个按钮用于停止蜂鸣器。

自动用药提醒系统的工作

药丸提醒警报器使用5V 电源供电。当它第一次启动时,它会显示一个欢迎按摩“欢迎来到电路文摘”。LCD 屏幕设置为在三个屏幕中循环。第一个屏幕将按摩显示为“保持健康,早日康复”。第二个屏幕是一个帮助屏幕,告诉按选择按钮选择任何一个时间段进行提醒(一天一次/两次/三次)。时隙在程序中是可变的,可以进行相应的配置。现在我们已将其固定为三个持续时间,即上午 8 点、下午 2 点和晚上 8 点。

我们将时隙分为三种模式。当用户按下第一个按钮时,模式 1 选择每天早上 8 点服药一次。当用户按下第二个按钮时,模式 2 选择每天早上 8 点和晚上 8 点服药两次。如果用户按下第三个按钮,模式 3 选择每天早上 8 点、下午 2 点和晚上 8 点服药三次。

Arduino

我们还可以添加一个让蜂鸣器暂停 10 分钟的功能(不包括在这个项目中)。当用户通过按下按钮选择所需的时隙时,用户输入被记录并且时间从 RTC 中获取。当时间与所选时间段匹配时,蜂鸣器开始蜂鸣。用户可以通过按 STOP 按钮停止蜂鸣器。下一个槽提醒继续相同的过程。完整的过程显示在本文末尾给出的视频中。

为医学提醒编程 Arduino UNO

一旦想到了提醒服药的方法,编写程序就很容易了。在这里,它将在显示屏上显示提醒,蜂鸣器发出蜂鸣声并使用 LED 指示。它还可以选择三个时间段(每天一次/两次/三次),当时间到达时,通过蜂鸣器蜂鸣器开始提醒患者。然后整个系统将如下所示:

用户在显示屏上获得帮助说明 》 用户选择时间段(一次/天、两次/天、三次/天) 》 在显示屏上打印确认消息 》 计时开始 》 当时间与用户选择的时间匹配时蜂鸣器和 LED 启动 》 用户停止按下停止按钮 》 结束

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

因为,我们使用了其他外围设备,如 16x2 LCD 显示器、RTC DS3231,所以我们首先必须包含库。所需库如下:

 

   
 (https://github.com/adafruit/RTClib) 
 

 

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

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

 

  if (!rtc.begin()) { // 检查 rtc 是否连接
    Serial.println("Couldn't find RTC"); 
    而(1);
  } 
if (rtc.lostPower()) { 
    Serial.println("RTC 断电,让我们设置时间!"); 
  }

 

时间调整可以通过两种方式完成,或者使用系统编译时间自动进行,或者手动输入。一旦我们设置了时间,请注释以下行,除非您想再次更改 RTC 时间。

 

rtc.adjust(日期时间(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"); 
      推1状态= 1;
      push2state = 0; 
      push3state = 0; 
      pushVal = 01; 
      休息;

    案例2:
      Serial.println("设置为2/天"); 
      推1状态= 0;
      push2state = 1; 
      push3state = 0;
      pushVal = 10; 
      休息; 
   
    案例 3:
      Serial.println("设置为 3/天"); 
      推1状态= 0;
      push2state = 0; 
      push3state = 1; 
      pushVal = 11; 
      休息; 
  }

 

此语句用于获取毫秒以用于对定义的间隔屏幕循环进行计时和控制。

 

currentMillisLCD = 毫秒();// 在定义的时间间隔启动 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 写入:"); Serial.println(EEPROM.read(addr)); // 用于调试
    pushVal = 1; //保存push button-1的状态
    lcd.clear(); 
    lcd.setCursor(0, 0); 
    lcd.print("提醒设置"); 
    lcd.setCursor(0, 1); 
    lcd.print("一次/天!"); 
    延迟(1200);
    lcd.clear(); 
  } 
}

 

以下功能用于停止蜂鸣器和 LED。提出建议总是好的。在“温水服药”显示屏上打印一条建议信息。

 

void stopPins() { //当用户按下停止按钮时停止蜂鸣的功能

  if (stopinState == 1) { 
// stopinState = 0; 
// pushPressed = true; 
    按下= 1;
    lcd.clear(); 
    lcd.setCursor(0, 0); 
    lcd.print("吃药"); 
    lcd.setCursor(0, 1); 
    lcd.print("用温水"); 
    延迟(1200);
    lcd.clear(); 
  } 
}

 

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

第二个屏幕用于向患者发出指示,如“按下按钮提醒......”。  第三个屏幕用于简单地显示当前日期和时间。

 

void changeScreen() { //屏幕循环函数

  // 每隔定义的 intervalLCD 开始切换屏幕
  if (currentMillisLCD - previousMillisLCD > intervalLCD) // 保存上次更改显示的时间
  { 
    previousMillisLCD = currentMillisLCD; 
    屏幕++;
    如果(屏幕> maxScreen){
      屏幕= 0;// 所有屏幕结束 -> 从第一个开始
    } 
    isScreenChanged = true; 
  }

  // 开始显示当前屏幕
  if (isScreenChanged) // 仅当屏幕改变时才更新屏幕。
  { 
    isScreenChanged = false; // 为下一次迭代重置
    switch (screens) 
    { 
      case getWellsoon: 
        gwsMessege(); // 快点好起来消息
        中断;
      案例 HELP_SCREEN:               
        helpScreen(); // 指令屏幕
        中断;
      case TIME_SCREEN: timeScreen 
        (); // 打印日期和时间
        间隔;
      默认值:
        //未设置。
        休息; 
    } 
  } 
}

 

如果选择的时间已到,此功能用于开始同时发出蜂鸣声和 LED 闪烁。

 

void startBuzz() { // 当时间达到定义的时间间隔时开始蜂鸣的函数
// if (pushPressed == false) { 
 
if (pushpressed == 0) { 
    Serial.println("pushpressed is false in blink"); 
    无符号长 currentMillis = millis(); 
    
if (currentMillis - previousMillis >= interval) { 
      previousMillis = currentMillis; // 保存上次闪烁 LED 的时间
      Serial.println("Start Buzzing"); 
      
if (ledState == LOW) { // 如果 LED 关闭,则将其打开,反之亦然:
        ledState = HIGH; 
      } 其他 { 
        ledState = 低;
      } 
      digitalWrite(ledPin, ledState); 
    } 
  }
  
else if (pushpressed == 1) { 
    Serial.println("pushpressed 为真"); 
    ledState = 低;
    数字写入(ledPin,ledState);
  } 
}

 

此功能用于比较用户在上午 8 点选择的时间段,并开始蜂鸣器蜂鸣和 LED 闪烁,直到用户按下停止按钮。同样,函数void at2pm() 和void at8pm用于启动蜂鸣器并在下午 2 点和 8 点引导。

 

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

 

这就是您可以使用 Arduino 轻松制作自己的自动医学提醒的方法。

//Medicine Reminder using Arduino Uno 

// 提醒在早上 8 点、下午 2 点、晚上 8 点吃药 

/* 电路:

   LCD RS 引脚到数字引脚 12 

   LCD 使能引脚到数字引脚 11 

   LCD D4 引脚到数字引脚 5 

   LCD D5 引脚到数字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 电阻:

   连接到+5V 和接地

   抽头到 LCD VO pin (pin 3 )*/

#include  

#include  

#include  

#include

int pushVal = 0;                           

整数值;

诠释 val2; 

整数地址 = 0;

RTC_DS3231 实时时钟;

const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2; // 液晶引脚

LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

#define getWellsoon 0                                            

#define HELP_SCREEN 1 

#define TIME_SCREEN 2

//bool pushPressed; // 跟踪按钮状态的标志 

int pushpressed = 0; 

常量 int ledPin = LED_BUILTIN; // 蜂鸣器和 LED 引脚

int ledState = LOW; 

整数信号 = 0;

国际嗡嗡声= 13;                                      

int push1state,push2state,push3state,stopinState = 0;//  

int push1Flag, push2Flag, Push3Flag = false; // 按钮标志 

int push1pin = 9; 

int push2pin = 8; 

int push3pin = 7; 

int stopPin = A0; 

int屏幕= 0;// 屏幕显示

int maxScreen = 2; // 屏幕计数

bool isScreenChanged = true;

很久以前Millis = 0;           

长间隔 = 500;// 蜂鸣间隔

unsigned long currentMillis;

很久以前MillisLCD = 0; // 液晶屏更新

长间隔LCD = 2000; // 屏幕循环间隔

unsigned long currentMillisLCD;

// 设置提醒更改时间

int buzz8amHH = 8; // HH - hours ##将这些设置为 24 小时的提醒时间 Format  

int buzz8amMM = 00; // MM - 分钟

int buzz8amSS = 00; // SS - 秒

诠释嗡嗡声2pmHH = 14;// HH - 小时

int buzz2pmMM = 00; // MM - 分钟

int buzz2pmSS = 00; // SS - 秒

诠释嗡嗡声8pmHH = 20;// HH - 小时

int buzz8pmMM = 00; // MM - 分钟

int buzz8pmSS = 00; // SS - 秒

int nowHr, nowMin, nowSec; // 显示当前 mm,hh,ss

// 所有消息

void gwsMessege(){ // 打印快点恢复 messege 

    lcd.clear(); 

    lcd.setCursor(0, 0); 

    lcd.print("保持健康:)"); //

    加油 lcd.setCursor(0, 1); 

    lcd.print("快点好起来:)"); // 希望 

}

void helpScreen() { // 在 LCD 中显示第一个屏幕的函数

    lcd.clear(); 

    lcd.setCursor(0, 0); 

    lcd.print("按下按钮"); 

    lcd.setCursor(0, 1); 

    lcd.print("提醒...!"); 

 }

void timeScreen() { // 在 LCD 屏幕上显示日期和时间的函数

  DateTime now = rtc.now(); // 获取 rtc 时间并在显示中打印

    lcd.clear(); 

    lcd.setCursor(0, 0); 

    lcd.print("时间:"); 

    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("日期:"); 

    lcd.print(now.day(), DEC); 

    lcd.print("/"); 

    lcd.print(now.month(), DEC); 

    lcd.print("/"); 

    lcd.print(now.year(), 十二月);

}

无效设置(){

  序列号.开始(9600);// 开始串口调试

  if (!rtc.begin()) { // 检查 rtc 是否连接 

    Serial.println("Couldn't find RTC"); 

    而(1);

  } 

  if (rtc.lostPower()) { 

    Serial.println("RTC 断电,让我们设置时间!"); 

  }

// rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); // 取消注释以设置当前时间,然后在您设置时间时在下次上传时注释

  rtc.adjust(DateTime(2019, 1, 10, 7, 59, 30)); // 手动设置时间

  lcd.begin(16, 2); 

  lcd.clear(); 

  lcd.setCursor(0, 0); 

  lcd.print("欢迎光临"); // 在启动时打印一条消息

  lcd.setCursor(0, 1); 

  lcd.print("电路文摘"); 

  延迟(1000);

  pinMode(push1pin,输入);// 定义按钮引脚类型

  pinMode(push2pin, INPUT); 

  pinMode(push3pin,输入);

  pinMode(stopPin,输入);

  pinMode(ledPin,输出);

  延迟(200);

  Serial.println(EEPROM.read(addr)); 

  val2 = EEPROM.read(addr); // 读取之前保存的按钮值,从之前离开的位置开始

  switch (val2) {

    案例1:

      Serial.println("设置为1/天"); 

      推1状态= 1;

      push2state = 0; 

      push3state = 0; 

      pushVal = 1; 

      休息; 

    案例2:

      Serial.println("设置为2/天"); 

      推1状态= 0;

      push2state = 1; 

      push3state = 0; 

      pushVal = 2;

      休息; 

    案例 3:

      Serial.println("设置为 3/天"); 

      推1状态= 0;

      push2state = 0; 

      push3state = 1; 

      pushVal = 3;

      休息; 

  }

}

无效循环(){

  推1();//调用设置一次/天 

  push2(); //调用设置两次/天 

  push3(); //调用设置三次/天 

    if (pushVal == 1) { // 如果按下按钮 1 则在上午 8 点提醒

    at8am(); // 早上 8 点开始 uzzing 的函数 

  } 

  else if (pushVal == 2) { // 如果按下按钮 2 则在上午 8 点和晚上 8 点提醒

    at8am();                                            

    晚上 8 点();//函数在 8mm 处开始 uzzing 

  }

  else if (pushVal == 3) { // 如果按下按钮 3,则在上午 8 点和晚上 8 点提醒

    at8am(); 

    下午 2 点();//函数在 8 毫米处开始 uzzing 

    at8pm(); 

  } 

  currentMillisLCD = millis(); // 以定义的时间间隔启动 LCD 屏幕切换的

  毫秒 push1state = digitalRead(push1pin); // 开始读取所有按钮引脚

  push2state = digitalRead(push2pin); 

  push3state = digitalRead(push3pin);

  stopinState = digitalRead(stopPin); 

  停止引脚();//调用停止嗡嗡声

  更改屏幕();// 屏幕循环函数

}

// 按钮

void push1() { // 每天设置一次提醒的函数 

  if (push1state == 1) { 

    push1state = 0; 

    push2state = 0; 

    push3state = 0; 

// pushPressed = true; 

    EEPROM.write(addr, 1); 

    Serial.print("Push1 写入:"); Serial.println(EEPROM.read(addr)); // 用于调试

    pushVal = 1; //保存push button-1的状态 

    lcd.clear(); 

    lcd.setCursor(0, 0); 

    lcd.print("提醒设置"); 

    lcd.setCursor(0, 1); 

    lcd.print("一次/天!"); 

    延迟(1200);

    lcd.clear(); 

  } 

}

void push2() { // 每天设置两次提醒的函数

  if (push2state == 1) { 

    push2state = 0; 

    推1状态= 0;

    push3state = 0; 

// pushPressed = true; 

    EEPROM.write(addr, 2); 

    Serial.print("Push2 写的:"); Serial.println(EEPROM.read(addr)); 

    pushVal = 2; 

    lcd.clear(); 

    lcd.setCursor(0, 0); 

    lcd.print("提醒设置"); 

    lcd.setCursor(0, 1); 

    lcd.print("每天两次!"); 

    延迟(1200);

    lcd.clear(); 

  } 

}

void push3() { // 每天设置三次提醒的函数

  if (push3state == 1) { 

    push3state = 0; 

    推1状态= 0;

    push2state = 0; 

// pushPressed = true; 

    EEPROM.write(addr, 3); 

    Serial.print("Push3 写的:"); Serial.println(EEPROM.read(addr)); 

    pushVal = 3; 

    lcd.clear(); 

    lcd.setCursor(0, 0); 

    lcd.print("提醒设置"); 

    lcd.setCursor(0, 1); 

    lcd.print("每天三次!"); 

    延迟(1200);

    lcd.clear(); 

  } 

}

void stopPins() { //当用户按下停止按钮时停止嗡嗡声

  if (stopinState == 1) { 

// stopinState = 0; 

// pushPressed = true; 

    按下= 1;

    lcd.clear(); 

    lcd.setCursor(0, 0); 

    lcd.print("吃药"); 

    lcd.setCursor(0, 1); 

    lcd.print("用温水"); 

    延迟(1200);

    lcd.clear(); 

  } 

}

void startBuzz() { // 当时间到达定义的时间间隔时开始蜂鸣的函数

// if (pushPressed == false) { 

 if (pushpressed == 0) { 

    Serial.println("pushpressed is false in blink"); 

    无符号长 currentMillis = millis(); 

    if (currentMillis - previousMillis >= interval) { 

      previousMillis = currentMillis; // 保存上次闪烁 LED 的时间

      Serial.println("Start Buzzing"); 

      if (ledState == LOW) { // 如果 LED 关闭,则将其打开,反之亦然:

        ledState = HIGH; 

      } 其他 { 

        ledState = 低;

      } 

      digitalWrite(ledPin, ledState); 

    } 

  } 

  else if (pushpressed == 1) { 

    Serial.println("pushpressed 为真");

    ledState = 低;

    数字写入(ledPin,ledState);

  } 

}

void at8am() { // 函数在早上 8 点开始嗡嗡声

  DateTime now = rtc.now(); 

  if (int(now.hour()) >= buzz8amHH) { 

    if (int(now.minute()) >= buzz8amMM) { 

      if (int(now.second()) > buzz8amSS) { 

        ////// ///////////////////////////////////////

        开始嗡嗡声();

        ///////////////////////////////////////// /// 

      } 

    } 

  } 

}

void at2pm() { // 函数在下午 2 点开始嗡嗡声

  DateTime now = rtc.now(); 

  if (int(now.hour()) >= buzz2pmHH) { 

    if (int(now.minute()) >= buzz2pmMM) { 

      if (int(now.second()) > buzz2pmSS) { 

        ////// //////////////////////////////////// 

        startBuzz(); 

        ///////////////////////////////////////// 

      } 

    } 

  } 

}

void at8pm() { // 函数在晚上 8 点开始嗡嗡声

  DateTime now = rtc.now(); 

  if (int(now.hour()) >= buzz8pmHH) { 

    if (int(now.minute()) >= buzz8pmMM) { 

      if (int(now.second()) > buzz8pmSS) { 

        ////// ////////////////////////////////////// 

        startBuzz() ; 

        ///////////////////////////////////////// /// 

      } 

    } 

  } 

}

//屏幕循环

void changeScreen() { //屏幕循环函数

  // 每隔定义的intervalLCD开始切换屏幕

  if (currentMillisLCD - previousMillisLCD > intervalLCD) // 保存上次更改显示的时间

  { 

    previousMillisLCD = currentMillisLCD; 

    屏幕++;

    如果(屏幕> maxScreen){

      屏幕= 0;// 所有屏幕结束 -> 从第一个开始

    } 

    isScreenChanged = true; 

  }

  // 开始显示当前屏幕

  if (isScreenChanged) // 仅当屏幕改变时才更新屏幕。

  { 

    isScreenChanged = false; // 为下一次迭代重置

    switch (screens) 

    { 

      case getWellsoon: 

        gwsMessege(); // 快点好起来消息

        中断;

      案例 HELP_SCREEN:               

        helpScreen(); // 指令屏幕

        中断;

      case TIME_SCREEN: timeScreen 

        (); // 打印日期和时间

        间隔;

      默认值:

        //未设置。

        休息; 

    } 

  } 

}

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分