目录一、项目概述二、实现功能1、功能详解2、项目清单3、演示视频三、硬件介绍PCB硬件设计四、程序设计五、项目成品效果图六、项目总结七、包含资料一、项目概述本项目基于STM32F103C8T6单片机设计了一款智能拐杖。系统通过光敏传感器采集环境光照强度HC-SR04检测与前方障碍物距离MPU6050检测是否发生跌倒GPS模块获取经纬度信息。各项数据实时显示在OLED屏幕上用户可通过按键进入系统设置界面设置时间、光照阈值及距离阈值并切换手动/自动模式。自动模式下光照不足时开启LED照明灯距离过近时蜂鸣器报警发生跌倒时蜂鸣器报警且手机App收到“跌倒请注意”提示手动模式下可通过按键控制LED照明灯和蜂鸣器。系统通过BT04A蓝牙模块与手机App通信可接收光照、距离、经纬度信息及跌倒提示并下发控制指令。二、实现功能1、功能详解1环境采集通过光敏传感器采集环境光照强度HC-SR04超声波传感器检测与前方障碍物距离MPU6050陀螺仪检测是否发生跌倒GPS模块获取经纬度信息。2数据显示OLED屏幕显示当前时间、光照强度、与前方障碍物距离及经纬度信息。3阈值设定可通过按键进入系统设置界面设置当前时间、光照阈值及距离阈值。4模式切换可通过按键切换手动模式和自动模式。5自动模式当环境光照强度小于阈值时开启LED照明灯当超声波检测距离小于阈值时蜂鸣器报警提醒当发生跌倒时蜂鸣器报警提醒且手机App收到“跌倒请注意”信息。6手动模式可通过按键控制LED照明灯和蜂鸣器报警。7蓝牙App通过蓝牙App可接收当前光照情况、超声波与前方障碍物距离、GPS经纬度发生跌倒时接收信息并在最后一行显示“跌倒请注意”可通过按钮下发控制指令按钮次序为A模块、B灯光、C报警。2、项目清单1主控STM32F103C8T6最小系统板2显示模块OLED显示屏4针IIC协议3跌倒检测MPU6050陀螺仪传感器4定位模块GPS模块5光照检测光敏传感器6距离检测HC-SR04超声波传感器7蓝牙模块BT04A蓝牙模块8执行模块照明模块、LED灯9报警模块蜂鸣器10输入模块按键3、演示视频哔哩哔哩视频链接点击观看https://www.bilibili.com/video/BV1CPNY6LEHg/?share_sourcecopy_webvd_sourcef4437c8e4429101e5bf1054c39d5474f三、硬件介绍PCB硬件设计四、程序设计#include led.h #include delay.h #include sys.h #include usart.h #include string.h #include beep.h #include key.h #include timer.h #include oled.h #include iic.h #include hc-sr04.h #include adc.h #include mpu6050.h #include dht11.h #include timer2.h #include GPS.h #include esp8266.h #include aliyun.h /**** 数据变量 ****/ int temp_door 38; int oxy_door 90; int heart_door 100; int mq135_door 2000; int light_door 2000; int dist_door 50; int tempi_door 35; int hum_door 35; int distance_door50; unsigned char display[16]; int auto_mode 0; //自动模式开关 0关闭 1开启 uint8_t send_time 3; uint8_t printd_flag 0; float axx,ayy,adz; float acc,acc2; int tiltFlag 0; int fallTime 0; int Beep_status0; int LED_status0; /**** 菜单变量 ****/ uint8_t option 0; //阈值选项 uint8_t key_num 0; //按键赋值 uint8_t page_id 1; //页面ID uint8_t net_flag 1; /**** 功能函数声明 ****/ void oled_show_onepage(); //第一屏显示内容 void oled_show_twopage(); //第二屏显示内容 void oled_show_Threepage(); //第三屏显示内容 void oled_show_Fourpage(); //第四屏显示内容 void oled_show_Fivepage(); //第五屏显示内容 void net_page(); void get_all_sensor_data(); //传感器数据采集 void Sensor_Data_Handle(); //不同模式下控制效果 void Key_event_handle(void); int main(void) { delay_init(); //系统延时函数初始化 delay_ms(200); OLED_Init(); //OLED初始化 delay_ms(200); uart2_init(9600); //串口2初始化波特率9600 USART1_Config(); //串口1初始化波特率9600 uart3_init(115200); //串口3初始化波特率9600 BEEP_Init(); //蜂鸣器初始化 KEY_Init(); //按键初始化 // oled_show_onepage(); MPU6050_Init(); // 初始化 HC_SR04_Init(); //超声波测距初始化 Timer2_Init(9,14398); //定时器初始化 Adc_Init(); LED_Init(); TIME_Config(); //定时器初始化 HC_SR04_Init(); //超声波测距初始化 Timer2_Init(9,14398); //定时器初始化 net_page(); while(net_flag){ key_num KEY_Scan(0); //按键扫描赋值 if(key_num1){net_flag0;} else if(key_num2){net_flag0;ESP8266_Init();} } OLED_Clear(); while(1) { Key_event_handle(); if(Time_Period[1]1000) //Time_Period[1] 在定时器中累加 { Time_Period[1] 0; // beep !beep; get_all_sensor_data(); //传感器数据采集 Mqtt_Publiash_Aliyun(); } Sensor_Data_Handle(); //数据处理 if(page_id 1){ //屏幕更新 oled_show_onepage(); }else if(page_id 2){ oled_show_twopage(); }else if(page_id3){ oled_show_Threepage(); } } } void Key_event_handle(void) //Key按键 event事情、逻辑handle处理 { key_num KEY_Scan(0); //按键扫描赋值 switch(key_num) { case 1: //按键1按下 if(page_id1){ //如果页面1 page_id2;option0; //页面2 选项0不选择 OLED_Clear();oled_show_twopage(); //屏幕清楚显示第二页面 }else if(page_id2){ //如果页面2 page_id3;option0; //页面3 选项0 OLED_Clear();oled_show_Threepage(); //屏幕清楚显示第三页面 }else if(page_id3){ //如果页面3 page_id1;option0; //页面1 选项0 OLED_Clear();oled_show_onepage(); //屏幕清楚显示第一页面 } break; case 2: //按键2按下 if(page_id2){ //如果页面2 option; //选项增加 if(option3){ //如果选项3 option0; //选择0 } }else if(page_id3){ //如果页面3 option; //选择增加 if(option2){ //如果选项2 option0; //选项0 } } break; case 3: //按键3按下 if(page_id2){ //如果页面2 if(option1){ //选项1 auto_mode1; //开启自动模式 }else if(option2)light_door25; //选项2 光照阈值25 else if(option3)distance_door; //选项3 距离阈值1 }else if(page_id3){ //页面3 if(option1){ //如果选项1 LED_status1; //照明开启 }else if(option2){ //如果选项2 Beep_status1; //报警开启 } } break; case 4: //按键4按下 if(page_id2){ //如果页面2 if(option1){ //选项1 auto_mode0; //开启手动模式 }else if(option2)light_door-25; //选项2 光照阈值-25 else if(option3)distance_door--; //选项3 距离阈值-1 }else if(page_id3){ //页面3 if(option1){ //选项1 LED_status0; //照明关闭 }else if(option2){ //选项2 Beep_status0; //报警关闭 } } break; } } void Sensor_Data_Handle() { if(auto_mode1){ //如果在自动模式下 if(Light_Valuelight_door){ //光照阈值 LED_status1; //照明开启 }else if(Light_Valuelight_door){ //光照阈值 LED_status0; //关闭照明 } if(distancedistance_door){ //距离阈值 Beep_status1; //报警开启 }else if(distancedistance_door){ //距离阈值 Beep_status0; //报警关闭 } } LEDLED_status; //照明开关照明状态 beepBeep_status; //报警开关报警状态 } void get_all_sensor_data() //获取数据 { short gyro[3]; // 陀螺仪xyz short acce[3]; // 加速度xyz HC_SR04_Deboanle(distance); Get_Light_Value(Light_Value); MPU6050ReadAcc(acce); // 读取三轴加速度 axxacce[0]; ayyacce[1]; if(axx0)axx-axx; if(ayy0)ayy-ayy; if(axx10000){ tiltFlag1; //摔倒 }else{ tiltFlag0; } } // 心(0) 率(1) 血(2) 氧(3) 体(4) 温(5) ℃(6) 宠(7) 物(8) 状(9) 态(10) 正(11) 常(12) 经(13) 纬(14) 度(15) 阈(16) 值(17) // 活(18) 动(19) 老(20) 人(21) 摔(22) 倒(23) 超(24) 声(25) 波(26) 报(27) 警(28) 开(29) 关(30) //自(31) 动(32) 手(33) 距(34) 离(35) 模(36) 式(37) 有(38) 无(39) 光(40) 照(41) 强(42) 度(43) //空(44) 气(45) 质(46) 量(47) 温(48) 度(49) 湿(50) 度(51) 照(52) 明(53) void oled_show_onepage(){ OLED_ShowChinese(16*0,16*0,34,16,1); //距 OLED_ShowChinese(16*1,16*0,35,16,1); //离 OLED_ShowChar(16*2,16*0,:,16,1); OLED_ShowNum(16*28,16*0,distance,3,16,1); //数据 OLED_ShowChinese(16*0,16*1,40,16,1); //光 OLED_ShowChinese(16*1,16*1,41,16,1); //照 OLED_ShowChar(16*2,16*1,:,16,1); OLED_ShowNum(16*28,16*1,Light_Value,4,16,1); //数据1 OLED_ShowString(16*48,16*1,Lux,16,1); if(tiltFlag1){ OLED_ShowChinese(16*4,16*0,20,16,1); //活 OLED_ShowChinese(16*5,16*0,21,16,1); //动 OLED_ShowChinese(16*6,16*0,22,16,1); //正 OLED_ShowChinese(16*7,16*0,23,16,1); //常 }else { OLED_ShowChinese(16*4,16*0,18,16,1); //老 OLED_ShowChinese(16*5,16*0,19,16,1); //人 OLED_ShowChinese(16*6,16*0,11,16,1); //摔 OLED_ShowChinese(16*7,16*0,12,16,1); //倒 } sprintf((char *)display,%10.6f ,newlon); OLED_ShowChinese(16*0,32,54,16,1); //经 OLED_ShowChinese(16*1,32,49,16,1); //度 OLED_ShowChar(16*2,32,:,16,1); OLED_ShowString(16*28,32,(u8*)display,16, 1);//显示经度 sprintf((char *)display,%10.6f ,newlat); OLED_ShowChinese(16*0,48,55,16,1); //纬 OLED_ShowChinese(16*1,48,49,16,1); //度 OLED_ShowChar(16*2,48,:,16,1); OLED_ShowString(16*28,48,(u8*)display,16, 1);//显示纬度 OLED_Refresh(); } void oled_show_twopage(){ uint8_t a,b,c,d; if(option1){a0;b1;c1;d1;} else if(option2){a1;b0;c1;d1;} else if(option3){a1;b1;c0;d1;} else if(option4){a1;b1;c1;d0;} else {a1;b1;c1;d1;} OLED_ShowChinese(16*0,16*0,56,16,1); //模 OLED_ShowChinese(16*1,16*0,57,16,1); //式 OLED_ShowChar(16*2,16*0,:,16,1); if(auto_mode1){ OLED_ShowChinese(16*28,16*0,31,16,a); //自 OLED_ShowChinese(16*38,16*0,32,16,a); //动 }else if(auto_mode0){ OLED_ShowChinese(16*28,16*0,33,16,a); //手 OLED_ShowChinese(16*38,16*0,32,16,a); //动 } OLED_ShowChinese(16*0,16*1,40,16,1); // “光” OLED_ShowChinese(16*1,16*1,41,16,1); // “照” OLED_ShowChinese(16*2,16*1,16,16,1); // “阈” OLED_ShowChinese(16*3,16*1,17,16,1); // “值” OLED_ShowChar(16*4,16*1,:,16,1); // “” OLED_ShowNum(16*48,16*1,light_door,4,16,b); // OLED_ShowChinese(16*0,16*2,34,16,1); // “距” OLED_ShowChinese(16*1,16*2,35,16,1); // “离” OLED_ShowChinese(16*2,16*2,16,16,1); // “阈 OLED_ShowChinese(16*3,16*2,17,16,1); // “值” OLED_ShowChar(16*4,16*2,:,16,1); // “” OLED_ShowNum(16*48,16*2,distance_door,3,16,c); // heart_door1 OLED_Refresh(); } void oled_show_Threepage() { uint8_t a,b,c,d; if(option1){a0;b1;c1;d1;} else if(option2){a1;b0;c1;d1;} else if(option3){a1;b1;c0;d1;} else if(option4){a1;b1;c1;d0;} else {a1;b1;c1;d1;} OLED_ShowChinese(16*0,16*0,52,16,1); // “照” OLED_ShowChinese(16*1,16*0,53,16,1); // “明” OLED_ShowChar(16*2,16*0,:,16,1); // “” if(LED_status1) OLED_ShowChinese(16*28,16*0,29,16,a); //开 else OLED_ShowChinese(16*28,16*0,30,16,a); //关 OLED_ShowChinese(16*0,16*1,58,16,1); // “报” OLED_ShowChinese(16*1,16*1,59,16,1); // “警” OLED_ShowChar(16*2,16*1,:,16,1); // “” if(Beep_status1) OLED_ShowChinese(16*28,16*1,29,16,b); //开 else OLED_ShowChinese(16*28,16*1,30,16,b); //关 OLED_Refresh(); } void TIM3_IRQHandler(void) { if(TIM_GetITStatus(TIM3,TIM_IT_Update)SET) //检测更新中断是否发生 { Time_Period[0]; Time_Period[1]; TIM_ClearITPendingBit(TIM3,TIM_IT_Update); //清楚更新中断标志位如果不清除会一直进中断 } } void net_page() { uint8_t a,b,c,d,i; if(option1){a0;b1;c1;d1;} else if(option2){a1;b0;c1;d1;} else if(option3){a1;b1;c0;d1;} else {a1;b1;c1;d1;} i 60; OLED_ShowChinese(16*2,16,i,16,1); // “是” OLED_ShowChinese(16*3,16,i1,16,1); // “否” OLED_ShowChinese(16*4,16,i2,16,1); // “配” OLED_ShowChinese(16*5,16,i3,16,1); // “网” OLED_ShowChar(16*6,16,?,16,1); // “” OLED_ShowString(16*0,32,KEY1 KEY2,16,1); OLED_ShowChinese(16*0,48,i4,16,1); // “跳” OLED_ShowChinese(16*1,48,i5,16,1); // “过” OLED_ShowChinese(16*6,48,i6,16,1); // “确” OLED_ShowChinese(16*7,48,i7,16,1); // “认” OLED_Refresh(); }五、项目成品效果图六、项目总结本项目成功实现了光照、障碍物距离、跌倒及定位信息的实时监测、显示与蓝牙远程监控结合阈值报警和手动/自动模式切换提升了老人出行辅助的智能化水平。系统运行稳定各模块协同良好具备较强的实用性和扩展性适用于智能养老及物联网教学实践。七、包含资料本资料免费分享获取全套资料请看主页并将告诉助手需要资料的项目编号助手收到消息后会发送资料。文章若对你有所帮助期待点赞收藏后续会持续分享各类单片机实战案例。内容仅作为学习参考有任何不妥之处欢迎大家一起探讨资料获取查看主页介绍“充哥单片机设计以上归充哥单片机设计工作室所有侵权盗图抄袭必究法律责任