随着社会老龄化形势明显,老年人体质弱,易患病,他们对药物需求增加,药箱的需求增加则成为必然,另外,因为认知、或视力或记忆力的退化,老人们不时地会发生错误服药的情形而影响治疗效果,严重的甚至引起事故。因此,为保障人体对药效的最大吸收,按时服药成为了我们需要重视的问题。
本文中提出一个针对中老年人群,按时服药提醒的便携家居保健装置。
这个智能药盒采用3D建模+3D打印的方式构建了外形。结构上主要包括控制箱和药盒主体两部分。
控制箱包括控制箱底座、盖板和复位按键3部分。其中存放了Arduino Uno、扩展板、语音合成模块以及电池等控制元件。
药盒主体包括底座、盖板、转子药盒等部分。其中,底座上安装有限位器、光电传感器。电机和主动轮则安装在盖板上。为了增加转子药盒转动的流畅性,在底座和盖板上都添加了微型轴承。
这个智能药盒的名字是“小亮”。开机时会小亮会与用户打招呼,祝用户身体健康,早日康复。给用户带去心灵上的温暖。
小亮会定时提醒用户吃药。同时将药盒转动到对应的格子,提醒用户吃几颗。用户吃完后,则关闭药盒。
当用户吃完所有的药之后,小亮会提醒用户已经吃完了这个疗程的药,祝用户早日恢复健康。
图1 硬件接线图
1、 限位器OUT端口接入Arduino扩展板的D2口。
2、 光电传感器的OUT端口接入Arduino扩展板的A0口。
3、 电机的负极接D4,正极接D5。
4、 语音合成模块的C口接I2C的SCL接口,D口接I2C的SDA接口。
智能药盒装配图
图2 智能药盒装配图
智能药盒主体部分我们采用3D建模、3D打印的方式制作,使用了PLA和TPU等材料。智能药盒主要分为药盒、控制箱两部分。其中药盒部分包括底座、转动箱、药盒盖、限位器、光电传感器、驱动电机和驱动轮。
第一步:硬件连接
图3 硬件接线实物图
根据图1中的连线方式连接好各个硬件。如图3所示。注意,电机线可能会导致主板无法安装进主板容纳盒。此时需要切开D4、D5背面的塑料部分,从背面插入电机线。
第二步:底座和盖板上分别压入小轴承
图4 小轴承安装
第三步:安装光电传感器
图5 光电感应器安装
如图5所示,使用M3x6螺丝固定光电传感器,如果感觉光电传感器蹭到转子药盒,可以在打印体和光电传感器之间加入1mm厚的垫片。
第四步:安装限位器
图6 限位器安装
先将2颗M3和2颗M2螺母压入底座。然后将限位器用M3x6和M2x10的螺丝与底座固定。限位器前后位置可以微调。可以根据实际情况调节限位器的位置。
第五步:安装电机和主动轮
图7 电机和主动轮安装
先将电机插入盖板的方孔内。方孔比较小,需要一定的力才能顺利插入。然后将主动轮中部安装到电机轴,最后将主动轮外圈套在主动轮中部外。可以使用502或者PLA抛光液固定中部和外圈。
第六步:将电池、语音合成模块装入控制箱。
图8 电池语音合成模块的安装
第七步:将Arduino和扩展板装入控制箱,同时拧上固定螺丝。
图9 Arduino及扩展板的安装
将Arduino及扩展板装入主板容纳盒中。用4颗M3x22的螺丝固定Arduino和主板容纳盒。
第八步:固定语音合成模块。
图10 语音合成模块的固定
用2颗M3x14的螺丝及2颗M3的螺母固定语音合成模块。
第九步:连接药盒、控制箱两部分。
图11 连接药盒与控制箱
在连接部分留有多个空位,用多颗M1.5x8的自攻螺丝固定药盒与控制箱两部分。
第十步:安装转子药盒及盖板
图12 安装转子药盒及盖板
将2颗M4x5单头六角铜柱插入转子药盒的上下端,然后将突出的螺柱插入底座和盖板的轴承中。使用M1.5x5和M1.5x8的自攻螺丝固定底座和盖板。
流程图:
图13 软件流程图
1、 文件结构
由于智能药盒源码有一定复杂度,如果所有代码都发在info文件中不易维护。所以将某些功能模块放在单独的文件中。下图是智能药盒源码的结构文件:
图14 源码结构文件
gapchecker.cpp文件中实现了两个接口:
void InitChecker(int boxNum);
bool IsTargetReached();
InitChecker:初始化计数器,同时设置目标药格。
IsTargetReached:当转动到目标药格,则返回true,否则返回false。
motor.cpp文件中实现了四个接口:
void InitMotor();
void StartMotor();
void ReverseMotor();
void StopMotor();
InitMotor:初始化电机模块,只运行一次
StartMotor:电机正转
ReverseMotor:电机反转
StopMotor:电机停转
zerobtn.cpp文件中实现了一个对外接口:
bool IsZerobtnClicked();
IsZerobtnClicked:当限位按键被按下时返回true,否则返回false。
2、 代码逻辑
智能药盒的逻辑代码涉及到多个状态间的切换有一定的复杂度,所以在loop()函数中实现了一个简单的状态机。该状态机主要包含如下状态:
ZeroDevice:归零状态,让电机反转,直到接触到限位按键。
WaitMedicineState:等待状态,当未达到吃药时间时,设备处于该状态。
RotateBoxState:盒子转动状态,当到了吃药时间,设备会转动转子药盒。
EndTip:结束提醒状态,当吃完所有的要,设备会提醒用户药已吃完。
EndIdle:当以上所有状态都结束,设备会处于这个节电模式。
void loop() {
if(curState == "ZeroDevice"){
……
}
else if(curState == "WaitMedicineState"){
……
}
else if(curState == "RotateBoxState"){
……
}
else if(curState == "EndTip"){
……
}
else if(curState == "EndIdle"){
……
}
}
每一种药都有一些特有的信息,比如药的名称、吃药的时间、每次要吃的量、所在的药格等等。因此源码中建立了一个结构体用于记录这些信息。
struct MedicineMsg {
String msg; // eg:请吃msg药
int num; // eg:请吃num颗
int boxNum; // 药所在的格子 1~7
int startTime; // 开始执行吃药的时间
bool eaten; // 这颗药是不是已经吃了
};
由于用户可能不止吃一种药,因此用户需要吃的所有的药需要用一个数组来表示。
#define MEDICINE_TYPES 3
MedicineMsg medicines[MEDICINE_TYPES] = {
// 时间需要从小到大排列,且两两间隔不能小于20s
{msg : "感冒药", num : 2, boxNum : 1, startTime : 3, eaten : false},
{msg : "头孢", num : 3, boxNum : 4, startTime : 18, eaten : false},
{msg : "阿司匹林", num : 7, boxNum : 7, startTime:38, eaten : false},
};
本项目实施后,对于需要经常吃药的老年人有非常大的帮助,可以真正做到让老年人不漏吃,不错吃药。从而有效避免了因为错吃漏吃药引起的事故。同时小亮的关心也为老年人带去了温暖,有助于老人保持心情愉快,早日恢复健康。
1、由于铜螺柱的直径要比小轴承的内径小,转子药盒的晃动幅度有点大。因此在铜螺柱和小轴承之间添加了1层塑料薄膜,来增加匹配度,减少晃动。
2、建模时没有考虑到电机线会导致扩展板长度增加。因此正常的安装模式无法压入主板和扩展板。最后的解决方案是将D4、D5接线口的背后塑料部分去除,从后面接入电机线。
3、主动轮和转子药盒之间的摩擦力问题。如果主动轮也采用PLA打印,则由于PLA之间的摩擦力较小,药盒转动不够顺畅。之后就采用TPU柔性材料打印主动轮。但由于TPU较软,容易变形而无法跟着电机转轴转动。最后的解决方案是,主动轮分成2部分,中间部分用于连接电机转轴,采用PLA打印的六边形。外部则采用柔性TPU材料打印,增加摩擦力。同时TPU采用20%的填充密度,进一步增加TPU的柔软性和摩擦力。最后用PLA抛光液固定PLA六边形和TPU外圈。
4、光电传感器安装之后会蹭到转子药盒部分,所以添加量1mm的螺丝垫盘,解决了这个问题。
下一版本智能药盒会加入更多的交互模式,加入语音识别功能和显示功能。方便老年人通过语音等方式录入需要的吃的药以及时间。