文章目录

  • 1 简介
  • 2 绪论
    • 2.1 课题背景
    • 2.2 实现功能
  • 3 系统设计
    • 3.1 系统架构
    • 3.2 硬件设计
      • 3.2.1 wifi电路设计
      • 3.2.2 其他电路设计
    • 3.3 软件设计
      • 3.3.1 软件工作流程
      • 3.3.2 闹铃提醒程序设计
      • 3.3.3 液晶显示程序设计
      • 3.3.4 信息存储程序设计
      • 3.3.5 报警电路程序设计
    • 3.4 部分实现代码
  • 4 最后

1 简介

Hi,大家好,这里是丹成学长,今天向大家介绍一个学长做的单片机项目

基于STM32的智能药箱系统设计与实现

大家可用于 课程设计 或 毕业设计

单片机-嵌入式毕设选题大全及项目分享:

https://blog.csdn.net/m0_71572576/article/details/125409052

2 绪论

2.1 课题背景

照顾老人, 特别是提醒老人准时吃药已经成为了一个社会关心的问题。长期记录吃药种类、 吃药时间能为分析老人的病理提供有力的依据。

基于目 前市场需求, 学长设计了一款基于 STM32F103 并结合网络来提醒老人按时吃药的系统。

整个智能药箱系统分为智能药箱端与远程服务器端两个部分, 智能药箱端用于提醒, 服务器端用于记录监督

2.2 实现功能

整个系统经过多次测试和应用, 各功能模块都可以正常运行, 符合设计要求。 具有的功
能包括: 从服务器端的数据库中实时获取药物信息, 闹钟信息等并存储。 播放音频文件提醒老人用药, 在液晶屏上提示吃药信息, 老人可以根据显示信息正确用药。 智能药箱端能记录药箱中每种药的数目, 并进行药量检测, 在药量不足时发出提醒, 提示用户配药。 另外还可以对老人取药动作进行记录, 将取药状态通过互联网传输给服务器监控端, 为以后看病做依据。 另外, 智能药箱端通过程序界面方便的配置智能药箱内部的网络信息,包括服务器地址、端口、 网关等。

它的主要功能分为下面几个部分:

    1. 提醒功能
    1. 取药监督
    1. 记录吃药时间
    1. 对老人是否吃药及时做出反应
    1. 显示吃药信息

服务器中记录下的取药时间可以作为以后看病的有力依据, 使医生能够准确对老人的病情做出判断, 减少一定的医学失误。

尽管智能药箱的发展并没有早期预期的那么快。 但是, 它的应用价值极高, 针对性也很
强, 可以有效的管理老年人用药, 减少儿女对父母吃药问题上的担心。 所以, 随着科技的发展, 智能药箱的普及将指日可待。

3 系统设计

3.1 系统架构

设计上必须从上图架构出发, 从上图可以得出智能药箱系统的总体功能:

  • a) 闹钟提醒吃药
  • b) 液晶显示吃药信息
  • c) 实时采集取药状态
  • d) 存储从服务器端获取的信息
  • e) 配置界面配置药箱端的网络参数
  • f) 实时检测药数量, 不足提醒用户
  • g) 增加服务器端, 记录药物信息, 闹钟, 取状态药等信息

3.2 硬件设计

3.2.1 wifi电路设计

3.2.2 其他电路设计

略,内容相对冗余,也不是本文介绍的重点,需要详细设计方案,可以在文章末尾联系学长。

3.3 软件设计

3.3.1 软件工作流程


程序包括模块的驱动与功能操作, 驱动主要是硬件的驱动, 每个模块只有在硬件驱动成功后, 才能执行其余功能。

3.3.2 闹铃提醒程序设计

下图是闹铃提醒的程序流程图, STM32 从 TF 卡中读取 512 字节数据, 按顺序传输给VS1003 进行音频转换和播放。 然后, 依次读取下一个扇区的 512 个字节进行播放。 如果播放过程中检测到药箱打开, 则停止闹铃并退出。

3.3.3 液晶显示程序设计

下图是闹铃提醒的程序流程图, STM32 从 TF 卡中读取 512 字节数据, 按顺序传输给VS1003 进行音频转换和播放。 然后, 依次读取下一个扇区的 512 个字节进行播放。 如果播放过程中检测到药箱打开, 则停止闹铃并退出。

3.3.4 信息存储程序设计

存储信息的过程如下:

当智能药箱接收网络参数, 药物信息时, 首先对数据按协议正确处理, 然后向 24C08 发送存储地址, 如果地址上已经有数据, 则读取。 然后将地址上的数据清空, 将刚才接收并处理的信息与从存储芯片读取的数据进行统一处理, 保留不变的, 修改已改变的数据, 再存入地址中。 如果需要读取存储芯片上的数据, 则向 24C08 发送地址读取数据即可, 程序流程图如下图所示。

3.3.5 报警电路程序设计

智能药箱与服务器之间每半小时需要药数目的校正, 以便两者之间可以同步。 当药箱内部药量不足时, 就会触发蜂鸣器以示提醒。 蜂鸣器采用是有源蜂鸣器, 接通电流就会发声,整个报警的程序流程图如下图所示。

3.4 部分实现代码

#include <Arduino.h>#include "MAX30105.h"
#include "heartRate.h"
#include "motor.h"#define DEBUG#define OUT_POSITION 1
#define TAKE_POSITION 2
#define OPEN_POSITION 5bool isTaskTake = false;
int boxdisplacement = 0;
int pillsParameters[2] = {3, 1};
enum BOXNAME { BOX1 = 1, BOX2, BOX3, BOX4, BOX5, BOX6 };
TaskHandle_t taskGreenLEDHandler;void rotateToOpen(int boxName);
void rotateToClose(int boxName);
void rotateToTake(int boxName);
void rotateToOut(int boxName);
void takePills(int boxName, int pillsNumber);
void taskTakePills(void *pvParameters);
void takePillsTest();
void setup() {Serial.begin(115200);delay(1000);motor_init();// xTaskCreate(taskPrint, "taskPrint", 1000, NULL, 1, NULL);
}void loop() {if (Serial.available()) {char message = ' ';message = Serial.read();if (message == 't') {if (!isTaskTake) {isTaskTake = true;Serial.println("*************\n*开始取药过程*\n*************");// xTaskCreate(taskTakePills, "taskTakePills", 20000,// pillsParameters, 1, NULL);takePills(3, 1);} else {Serial.println("已经有一个取药任务了");}}if (message == 'i') {  //开盖if (!isTaskTake) {isTaskTake = true;taskOpenBox(NULL);isTaskTake = false;} else {Serial.println("已经有一个取药任务了");}}if (message == 'j') {  //关盖if (!isTaskTake) {isTaskTake = true;taskCloseBox(NULL);digitalWrite(PIN_ENABLE, HIGH);isTaskTake = false;} else {Serial.println("已经有一个取药任务了");}}if (message == 'm') {  //关盖if (!isTaskTake) {isTaskTake = true;digitalWrite(PIN_ENABLE, LOW);takePillsTest();digitalWrite(PIN_ENABLE, HIGH);isTaskTake = false;} else {Serial.println("已经有一个取药任务了");}}if (message == 'g') {  //左旋if (!isTaskTake) {isTaskTake = true;digitalWrite(PIN_ENABLE, LOW);taskRotate(LEFT);boxdisplacement--;digitalWrite(PIN_ENABLE, HIGH);isTaskTake = false;} else {Serial.println("已经有一个取药任务了");}}if (message == 'h') {  //右旋if (!isTaskTake) {isTaskTake = true;digitalWrite(PIN_ENABLE, LOW);taskRotate(RIGHT);boxdisplacement++;digitalWrite(PIN_ENABLE, HIGH);isTaskTake = false;} else {Serial.println("已经有一个取药任务了");}}if (message == 'k') {if (!isTaskTake) {isTaskTake = true;Serial.println("开始推出药盒");digitalWrite(PIN_ENABLE, LOW);taskPushBoxOut(NULL);delay(1000);Serial.println("开始推入药盒");taskPullBoxIn(NULL);digitalWrite(PIN_ENABLE, HIGH);isTaskTake = false;} else {Serial.println("已经有一个取药任务了");}}if (message == '3') {taskPillsOut(NULL);}if (message == 'a') {  //开气泵openPump();}if (message == 'b') {  //关气泵closePump();}}
}void rotateToOpen(int boxName) {int currentPosition = boxName + boxdisplacement;int targetRotation = OPEN_POSITION - currentPosition;if (targetRotation >= 0) {#ifdef DEBUGSerial.println("rorate right " + String(targetRotation) +" step to open.");Serial.println("向右旋转 " + String(targetRotation) + " 步以开盖.");
#endiffor (int i = 0; i < targetRotation; i++) {taskRotate(RIGHT);boxdisplacement++;}} else {#ifdef DEBUGSerial.println("rorate left " + String(-targetRotation) +" step to open.");Serial.println("向左旋转 " + String(-targetRotation) + " 步以开盖.");
#endiffor (int i = 0; i < -targetRotation; i++) {taskRotate(LEFT);boxdisplacement--;}}
}
void rotateToClose(int boxName) {int currentPosition = boxName + boxdisplacement;int targetRotation = OPEN_POSITION - currentPosition;if (targetRotation >= 0) {#ifdef DEBUGSerial.println("rorate right " + String(targetRotation) +" step to close.");Serial.println("向右旋转 " + String(targetRotation) + " 步以关盖.");
#endiffor (int i = 0; i < targetRotation; i++) {taskRotate(RIGHT);boxdisplacement++;}} else {#ifdef DEBUGSerial.println("rorate right " + String(-targetRotation) +" step to close.");Serial.println("向左旋转 " + String(-targetRotation) + " 步以关盖.");
#endiffor (int i = 0; i < -targetRotation; i++) {taskRotate(LEFT);boxdisplacement--;}}
}
void rotateToTake(int boxName) {int currentPosition = boxName + boxdisplacement;int targetRotation = TAKE_POSITION - currentPosition;if (targetRotation >= 0) {#ifdef DEBUGSerial.println("rorate right " + String(targetRotation) +" step to take pills.");Serial.println("向右旋转 " + String(targetRotation) + " 步以取药.");
#endiffor (int i = 0; i < targetRotation; i++) {taskRotate(RIGHT);boxdisplacement++;}} else {#ifdef DEBUGSerial.println("rorate right " + String(-targetRotation) +" step to take pills.");Serial.println("向左旋转 " + String(-targetRotation) + " 步以取药.");
#endiffor (int i = 0; i < -targetRotation; i++) {taskRotate(LEFT);boxdisplacement--;}}
}
void rotateToOut(int boxName) {int currentPosition = boxName + boxdisplacement;int targetRotation = OUT_POSITION - currentPosition;if (targetRotation >= 0) {#ifdef DEBUGSerial.println("rorate right " + String(targetRotation) +" step to add pills.");Serial.println("向右旋转 " + String(targetRotation) + " 步以换(加)药.");
#endiffor (int i = 0; i < targetRotation; i++) {taskRotate(RIGHT);boxdisplacement++;}} else {#ifdef DEBUGSerial.println("rorate right " + String(-targetRotation) +" step to add pills.");Serial.println("向左旋转 " + String(-targetRotation) +" 步以换(加)药.");
#endiffor (int i = 0; i < -targetRotation; i++) {taskRotate(LEFT);boxdisplacement--;}}
}
void takePills(int boxName, int pillsNumber) {digitalWrite(PIN_ENABLE, LOW);// taskPillsUp(NULL);rotateToOpen(boxName);taskOpenBox(NULL);rotateToTake(boxName);// stepper2.runToNewPosition(5000);midToLeft();openPump();// stepper2.runToNewPosition(6400);delay(1000);digitalWrite(PIN_STEPPER2_DIR, LOW);for (int j = 0; j <= 5; j++) {for (int i = 0; i < 500; i++) {digitalWrite(PIN_STEPPER2_STEP, HIGH);delayMicroseconds(400);digitalWrite(PIN_STEPPER2_STEP, LOW);delayMicroseconds(400);}delay(500);digitalWrite(PIN_STEPPER2_DIR, HIGH);for (int k = 0; k < 500; k++) {digitalWrite(PIN_STEPPER2_STEP, HIGH);delayMicroseconds(400);digitalWrite(PIN_STEPPER2_STEP, LOW);delayMicroseconds(400);}digitalWrite(PIN_STEPPER2_DIR, LOW);}// stepper2.setMaxSpeed(2500);// stepper2.setAcceleration(1500);// stepper2.runToNewPosition(-20000);leftToMid();taskMidToRight(NULL);closePump();openAir();delay(3000);closeAir();delay(2000);taskPillsOut(NULL);taskRightToMid(NULL);// xTaskCreate(taskRightToMid, "taskRightToMid", 1000, NULL, 1, NULL);isTaskTake = false;digitalWrite(PIN_ENABLE, HIGH);
}void taskTakePills(void *pvParameters) {int boxName = ((int *)pvParameters)[0];int pillsNumber = ((int *)pvParameters)[1];
#ifdef DEBUGSerial.println("boxName: " + String(boxName));Serial.println("pillsNumber: " + String(pillsNumber));
#endiftakePills(boxName, pillsNumber);vTaskDelete(NULL);
}
void takePillsTest() {midToLeft();openPump();// stepper2.runToNewPosition(6400);delay(1000);digitalWrite(PIN_STEPPER2_DIR, LOW);for (int j = 0; j <= 5; j++) {for (int i = 0; i < 500; i++) {digitalWrite(PIN_STEPPER2_STEP, HIGH);delayMicroseconds(400);digitalWrite(PIN_STEPPER2_STEP, LOW);delayMicroseconds(400);}delay(500);digitalWrite(PIN_STEPPER2_DIR, HIGH);for (int k = 0; k < 500; k++) {digitalWrite(PIN_STEPPER2_STEP, HIGH);delayMicroseconds(400);digitalWrite(PIN_STEPPER2_STEP, LOW);delayMicroseconds(400);}digitalWrite(PIN_STEPPER2_DIR, LOW);}// stepper2.setMaxSpeed(2500);// stepper2.setAcceleration(1500);// stepper2.runToNewPosition(-20000);leftToMid();taskMidToRight(NULL);closePump();openAir();delay(3000);closeAir();taskRightToMid(NULL);
}

作品展示:

单片机-嵌入式毕设选题大全及项目分享:

https://blog.csdn.net/m0_71572576/article/details/125409052

4 最后

【毕业设计】基于STM32的智能药箱系统设计与实现 - 物联网 单片机相关推荐

  1. 【毕业设计】基于STM32的智能路灯设计与实现 - 物联网 嵌入式 单片机

    文章目录 1 简介 2 绪论 2.1 项目背景 2.2 需求分析 3 系统设计 3.1 功能设计 3.1.1 系统角色分析 3.1.2 开发环境 3.2 总体设计 3.3 硬件部分 3.3.1 整体架 ...

  2. 基于STM32的智能花盆系统设计与实现(华为云IOT)

    一.设计需求 1.1 设计需求总结 伴随着人们生活水平以及现在科学技术的急速发展,越来越多的人喜欢在家庭栽培一些盆栽植物.可是当代生活节奏过快,导致盆栽大多数都不能得到很好的补充水分和阳光照射,从而导 ...

  3. 毕业设计 基于zigbee的智能家居系统设计与实现

    文章目录 1 简介 2前言 2.1 系统目标 3 系统架构 3.1 网关板设计: 3.2 ZigBee网络感知层 3.3 显示控制平台及数据保存 3.4 NB-IOT模块实现 实现效果 4 最后 1 ...

  4. 【毕业设计】基于STM32 的电子计步器的设计与实现 - 物联网 单片机 嵌入式

    文章目录 1 简介 2 项目介绍 3 具体实现 3.1 整体架构 3.2 MPU6050 3.2.1 什么是MPU6050 3.2.2 MPU6050的特点: 4 如何实现记步 4.1 峰值判断记步法 ...

  5. 毕业设计 基于stm32的火灾报警系统设计与实现 - 单片机 物联网

    文章目录 1 简介 2 设计方案 3 实现效果 4 外围器件 4.1 DS18B20 4.2 MQ-2传感器 5 部分实现代码 6 最后 1 简介 Hi,大家好,今天向大家介绍一个学长做的单片机项目 ...

  6. 基于STM32的智能家居系统设计

    目录 第1章 前言 1 1.1 课题研究的背景和实际意义 1 1.1.1课题背景 1 1.1.2实际意义 1 1.2国内外发展现状.存在问题以及前景 2 1.2.1发展现状 2 1.2.2存在问题 2 ...

  7. 毕业设计——基于STM32的智能窗户系统(物联网、智能家居、APP控制、APP显示温湿度等信息、自动工作模式)

    本工程包括一下功能:1.远程控制工作功能:手机端app远程控制窗户开关(手机app自主开发) 2.自动监测工作功能:自动监测天气,并控制窗户开关 3.远程监测数据功能:温度.可燃气体浓度及各种状态在手 ...

  8. 毕业设计——基于STM32的智能家具控制系统(ESP-01S(8266)、手机app远程控制、远程显示温度)

    智能家具系统分为两个不同版本系列: ①系列一:手机app远程控制.远程检测温湿度显示在app,(云平台)    ---------本文章 ②系列二:语音识别控制                http ...

  9. 毕业设计 基于STM32的智能宠物投喂系统(全套资料)

    文章目录 0 前言 1 系统说明 2 背景意义 3 系统设计 3.1 总体方案 3.2 硬件设计 3.2.1 STC89C52 3.2.2 CLS150TD舵机 3.2.3 压力传感器 3.2.4 H ...

  10. STM32项目设计:基于stm32的智能家居系统设计

    文章目录 @[toc] 一.项目功能概述 二.项目原理图 三.程序设计 四.扩展功能 五.项目展示: 项目资料链接:https://pan.baidu.com/s/1nghgsyOM_isTMALuW ...

最新文章

  1. 129. 火车进栈【栈】
  2. 在Java中设计和使用自己的注解(转载)
  3. 数平精准推荐 | OCR技术之数据篇
  4. Flink-Java版单词计数(批处理流处理)
  5. ORACLE数据库新增表空间的数据存储文件
  6. navicat 解析sql_navicat
  7. 【软考信息系统项目管理师】必背重点之信息化和信息系统
  8. 文件系统FastDFS和阿里云OSS
  9. android官方转圈圈,android 弹出之后,一直转圈圈??
  10. wordpress只在首页显示友情链接方法
  11. 银行制定快捷支付限额原因
  12. 想从事程序员,对学历要求高吗
  13. ji计算机内存不足怎么回事,Win7提示内存不足的原因及应对措施
  14. 报名进行时!邀您一起海外社媒会话跨境直播,实地探访MCN机构
  15. 免备案二级域名 长久稳定+已备案
  16. 当当网资深DBA:DB运维四大现代化的实现
  17. 【SpringBoot应用篇】SpringBoot+Redis实现接口幂等性校验
  18. 1155 服务器芯片组,华硕服务器主板 P8B-E/4L 单路1155针脚 四千兆网卡
  19. 鸿蒙系统明年上市巧,华为:智能手表及笔记本电脑将搭载鸿蒙系统 手机明年上市...
  20. 大数据专业就业方向和考研院校及系统学习路线规划

热门文章

  1. 使用xshell连接腾讯云服务器
  2. 硫自养反硝化滤池处理城市二级出水研究
  3. pwm 正弦波_谈谈逆变器输出的方波与正弦波
  4. css样式给标签加上小手图标
  5. Profinet 协议
  6. 台式计算机怎么设置自动锁屏,台式机win7怎么设置自动锁屏
  7. 主成分分析步骤matlab,主成分分析及matlab实现.ppt
  8. 抖音最火的微信推送教程
  9. .net开通exchange邮箱
  10. 简析FUP LB5CM/LB6CM 落地式低速大容量冷冻离心机