提示:记录毕设
文章目录
- 前言
- 一、任务书
- 1.1设计(研究)目标:
- 1.2设计(研究)内容:
- 二、框架思路
- 三、硬件及代码
- 四、相关功能介绍
- 五、交流联系
- 六、喜欢请点赞哦!
前言
基于STM32的智能药盒,主控使用STM32F103(正点原子战舰板子)
一、任务书
1.1设计(研究)目标:
该药盒可避免其忘记服药、服药拖延、反复服药等状况,让患者准确无误的做到遵守医嘱按时服药。
- 提醒患者服药
- 监督患者是否已经取药
- 记录下吃药时间
- 未吃药时及时报警提醒
1.2设计(研究)内容:
- 以STM32单片机为主控芯片,
- 外部扩展指纹识别传感器识别家人的身份,然后控制舵机转盘分配相应的药物,从而达到“一对多服务”的目的;
- 条形码识别模块将不同药物的条形码录入到系统中,从而达到精准管理药物的目的(此功能可去掉);
- 语音模块负责语音引导用户操作,显示模块负责显示时间、温度、服药参数等信息,按键模块负责实现各个参数的设定,从而达到人机交互的目的;
- 存储模块负责存储成员的服药参数和药物信息,采用支持掉电不丢失数据的EEPROM芯片来存储信息,为了提高存储效率和方便管理信息,又采用数据分区存储技术。
二、框架思路
三、硬件及代码
- ESP826601s
- OLED
- 按键
- 蜂鸣器(板子自带)
- 继电器模块
- 其他器件参考第二部分框图
QQ2424644692
volatile u8 t=0;
volatile u8 i=0;
volatile u8 key;
volatile u16 led0pwmval = 499;
volatile u16 adcx0;
volatile u16 adcx1;
void main() {
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);
}
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);
}
leftToMid();
taskMidToRight(NULL);
closePump();
openAir();
delay(3000);
closeAir();
taskRightToMid(NULL);
}
四、相关功能介绍
- 服药录入及药物分配单元
药物录入及分配单元由条形码识别传感器和舵机转盘组成。条形码传感器负责将药物条形码录入系统,并且为每种药物设定一个独立的ID。舵机转盘的结构如图3所示,不同层的转盘之间独立旋转,同层转盘放同种药物,药物通过隔板分开,舵机旋转一次则分配1粒药物,最后药物都落入盛药杯,等待服药成员取出。 - 智能加热单元
智能加热单元由温度传感器、加热器和水箱组成。药盒在服药前1小时打开加热器,进入加热阶段,单片机GPIOC(13)引脚控制继电器打开加热器加热水箱里的水,待水温达到100°C时进入保温阶段,将温度维持在40~45°C。当所有的成员完成了本次服药后,则停止智能加热单元工作。 - 数据存储单元
数据存储单元采用AT24C04的EEPROM芯片,储存空间是4KB,512字节,与单片机IIC通信接口相连,用来保存服药信息、药物信息、药物库存、管理员密码和标志位等数据。
五、交流联系
承接stm32单片机定做设计。嵌入式类设计定做。联系扣扣见代码顶部