提示:记录毕设

文章目录

  • 前言
  • 一、任务书
  • 1.1设计(研究)目标:
  • 1.2设计(研究)内容:
  • 二、框架思路
  • 三、硬件及代码
  • 四、相关功能介绍
  • 五、交流联系
  • 六、喜欢请点赞哦!

前言

基于STM32的智能药盒,主控使用STM32F103(正点原子战舰板子)

一、任务书

1.1设计(研究)目标:

该药盒可避免其忘记服药、服药拖延、反复服药等状况,让患者准确无误的做到遵守医嘱按时服药。

  • 提醒患者服药
  • 监督患者是否已经取药
  • 记录下吃药时间
  • 未吃药时及时报警提醒
1.2设计(研究)内容:
  • 以STM32单片机为主控芯片,
  • 外部扩展指纹识别传感器识别家人的身份,然后控制舵机转盘分配相应的药物,从而达到“一对多服务”的目的;
  • 条形码识别模块将不同药物的条形码录入到系统中,从而达到精准管理药物的目的(此功能可去掉);
  • 语音模块负责语音引导用户操作,显示模块负责显示时间、温度、服药参数等信息,按键模块负责实现各个参数的设定,从而达到人机交互的目的;
  • 存储模块负责存储成员的服药参数和药物信息,采用支持掉电不丢失数据的EEPROM芯片来存储信息,为了提高存储效率和方便管理信息,又采用数据分区存储技术。

二、框架思路

基于stm32智能仓库管理 基于stm32智能药盒的任务书_单片机

三、硬件及代码

  • ESP826601s
  • OLED
  • 按键
  • 蜂鸣器(板子自带)
  • 继电器模块
  • 其他器件参考第二部分框图

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单片机定做设计。嵌入式类设计定做。