系统基于STM32的智能药盒系统:实现更加高效的用药安全

提示:记录毕设

文章目录

  • 前言
  • 一、任务书
  • 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单片机定做设计。嵌入式类设计定做。联系扣扣见代码顶部

    六、喜欢请点赞哦!

    物联沃分享整理
    物联沃-IOTWORD物联网 » 系统基于STM32的智能药盒系统:实现更加高效的用药安全

    发表评论