赞
踩
Hi,大家好,这里是丹成学长,今天向大家介绍一个学长做的单片机项目
基于STM32的智能药箱系统设计与实现
大家可用于 课程设计 或 毕业设计
单片机-嵌入式毕设选题大全及项目分享:
https://blog.csdn.net/m0_71572576/article/details/125409052
照顾老人, 特别是提醒老人准时吃药已经成为了一个社会关心的问题。长期记录吃药种类、 吃药时间能为分析老人的病理提供有力的依据。
基于目 前市场需求, 学长设计了一款基于 STM32F103 并结合网络来提醒老人按时吃药的系统。
整个智能药箱系统分为智能药箱端与远程服务器端两个部分, 智能药箱端用于提醒, 服务器端用于记录监督
整个系统经过多次测试和应用, 各功能模块都可以正常运行, 符合设计要求。 具有的功
能包括: 从服务器端的数据库中实时获取药物信息, 闹钟信息等并存储。 播放音频文件提醒老人用药, 在液晶屏上提示吃药信息, 老人可以根据显示信息正确用药。 智能药箱端能记录药箱中每种药的数目, 并进行药量检测, 在药量不足时发出提醒, 提示用户配药。 另外还可以对老人取药动作进行记录, 将取药状态通过互联网传输给服务器监控端, 为以后看病做依据。 另外, 智能药箱端通过程序界面方便的配置智能药箱内部的网络信息,包括服务器地址、端口、 网关等。
它的主要功能分为下面几个部分:
服务器中记录下的取药时间可以作为以后看病的有力依据, 使医生能够准确对老人的病情做出判断, 减少一定的医学失误。
尽管智能药箱的发展并没有早期预期的那么快。 但是, 它的应用价值极高, 针对性也很
强, 可以有效的管理老年人用药, 减少儿女对父母吃药问题上的担心。 所以, 随着科技的发展, 智能药箱的普及将指日可待。
设计上必须从上图架构出发, 从上图可以得出智能药箱系统的总体功能:
略,内容相对冗余,也不是本文介绍的重点,需要详细设计方案,可以在文章末尾联系学长。
程序包括模块的驱动与功能操作, 驱动主要是硬件的驱动, 每个模块只有在硬件驱动成功后, 才能执行其余功能。
下图是闹铃提醒的程序流程图, STM32 从 TF 卡中读取 512 字节数据, 按顺序传输给VS1003 进行音频转换和播放。 然后, 依次读取下一个扇区的 512 个字节进行播放。 如果播放过程中检测到药箱打开, 则停止闹铃并退出。
下图是闹铃提醒的程序流程图, STM32 从 TF 卡中读取 512 字节数据, 按顺序传输给VS1003 进行音频转换和播放。 然后, 依次读取下一个扇区的 512 个字节进行播放。 如果播放过程中检测到药箱打开, 则停止闹铃并退出。
存储信息的过程如下:
当智能药箱接收网络参数, 药物信息时, 首先对数据按协议正确处理, 然后向 24C08 发送存储地址, 如果地址上已经有数据, 则读取。 然后将地址上的数据清空, 将刚才接收并处理的信息与从存储芯片读取的数据进行统一处理, 保留不变的, 修改已改变的数据, 再存入地址中。 如果需要读取存储芯片上的数据, 则向 24C08 发送地址读取数据即可, 程序流程图如下图所示。
智能药箱与服务器之间每半小时需要药数目的校正, 以便两者之间可以同步。 当药箱内部药量不足时, 就会触发蜂鸣器以示提醒。 蜂鸣器采用是有源蜂鸣器, 接通电流就会发声,整个报警的程序流程图如下图所示。
#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 5 bool 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 DEBUG Serial.println("rorate right " + String(targetRotation) + " step to open."); Serial.println("向右旋转 " + String(targetRotation) + " 步以开盖."); #endif for (int i = 0; i < targetRotation; i++) { taskRotate(RIGHT); boxdisplacement++; } } else { #ifdef DEBUG Serial.println("rorate left " + String(-targetRotation) + " step to open."); Serial.println("向左旋转 " + String(-targetRotation) + " 步以开盖."); #endif for (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 DEBUG Serial.println("rorate right " + String(targetRotation) + " step to close."); Serial.println("向右旋转 " + String(targetRotation) + " 步以关盖."); #endif for (int i = 0; i < targetRotation; i++) { taskRotate(RIGHT); boxdisplacement++; } } else { #ifdef DEBUG Serial.println("rorate right " + String(-targetRotation) + " step to close."); Serial.println("向左旋转 " + String(-targetRotation) + " 步以关盖."); #endif for (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 DEBUG Serial.println("rorate right " + String(targetRotation) + " step to take pills."); Serial.println("向右旋转 " + String(targetRotation) + " 步以取药."); #endif for (int i = 0; i < targetRotation; i++) { taskRotate(RIGHT); boxdisplacement++; } } else { #ifdef DEBUG Serial.println("rorate right " + String(-targetRotation) + " step to take pills."); Serial.println("向左旋转 " + String(-targetRotation) + " 步以取药."); #endif for (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 DEBUG Serial.println("rorate right " + String(targetRotation) + " step to add pills."); Serial.println("向右旋转 " + String(targetRotation) + " 步以换(加)药."); #endif for (int i = 0; i < targetRotation; i++) { taskRotate(RIGHT); boxdisplacement++; } } else { #ifdef DEBUG Serial.println("rorate right " + String(-targetRotation) + " step to add pills."); Serial.println("向左旋转 " + String(-targetRotation) + " 步以换(加)药."); #endif for (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 DEBUG Serial.println("boxName: " + String(boxName)); Serial.println("pillsNumber: " + String(pillsNumber)); #endif takePills(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
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。