当前位置:   article > 正文

基于STM32+ESP8266+FreeRTOS+安卓App上位机+MQTT连接OneNET的智能家居项目(软件开源篇附百度网盘链接)_探索者 freertos 开源项目

探索者 freertos 开源项目

  本篇文章主要是分享智能家居项目中的下位机STM32+FreeRTOS的代码部分。以下是项目最终的效果

stm32 esp8266 语音控制智能家居_哔哩哔哩_bilibili

  另外附上main函数中的部分代码,完整代码会在文章末尾放上百度网盘链接,可以自行下载。

  1. #include "includes.h"
  2. /* 项目名称:胖虎智能家居系统
  3. * 作者:板栗焖小鸡,CSDN B站 抖音同名
  4. * 简介:这是一个智能家居系统项目,基于STM32F103RET6微控制器+ESP8266(WIFI模块)+FreeRTOS嵌入式实时操作系统。
  5. * 使用说明:
  6. * 一、连接OneNET如下配置:
  7. * esp8266.c文件中,ESP8266_WIFI_INFO:配置wifi或者热点名称和密码。
  8. * ESP8266_WIFI_INFO "AT+CWJAP=\"leo\",\"20030927\"\r\n"//连接的Wifi名 密码
  9. * esp8266.c文件中,ESP8266_WIFI_INFO:配置连接OneNet的IP端口号。
  10. * ESP8266_ONENET_INFO "AT+CIPSTART=\"TCP\",\"183.230.40.39\",6002\r\n"//连接上OneNet的MQTT
  11. */
  12. /* 待解决:读取OneNET平台数据时,设备会掉线*/
  13. /***************************** 内核对象句柄 *****************************/
  14. /*
  15. * 信号量,消息队列,事件标志组,软件定时器这些都属于内核的对象,要想使用这些内核
  16. * 对象,必须先创建,创建成功之后会返回一个相应的句柄。实际上就是一个指针,后续我
  17. * 们就可以通过这个句柄操作这些内核对象。
  18. * 内核对象说白了就是一种全局的数据结构,通过这些数据结构我们可以实现任务间的通信,
  19. * 任务间的事件同步等各种功能。至于这些功能的实现我们是通过调用这些内核对象的函数
  20. * 来完成的
  21. *
  22. */
  23. QueueHandle_t Test_Queue =NULL;
  24. /**************************************************全局变量*************/
  25. //主题设置
  26. char *Tips = "ESP";
  27. const char *topics[] = {"ESP"};
  28. char *onenet_req; //ONENET下发指令
  29. uint8_t IR_Key = 0;//红外接收遥控器键值
  30. uint16_t Tempreture = 0;//18B20温度传感器数据
  31. uint8_t LightValue = 0;//光敏值
  32. uint8_t KeyValue[]={0xFF ,0xFF, 0xFF, 0xFF, 0xFF, 0xFF};//RCC522 卡A密钥
  33. extern uint8_t Voice_Data;
  34. /**************************** 任务句柄 ********************************/
  35. /*
  36. * 任务句柄是一个指针,用于指向一个任务,当任务创建好之后,它就具有了一个任务句柄
  37. * 以后我们要想操作这个任务都需要通过这个任务句柄,如果是自身的任务操作自己,那么
  38. * 这个句柄可以为NULL。
  39. */
  40. static TaskHandle_t AppTaskCreate_Handle = NULL;/* 创建任务句柄 */
  41. static TaskHandle_t Test_Task_Handle = NULL;/* LED任务句柄 */
  42. static TaskHandle_t Voice_Task_Handle = NULL;/* Voice_Task句柄 */
  43. static TaskHandle_t Tempreture_Task_Handle = NULL;/* Tempreture_Task句柄 */
  44. static TaskHandle_t Light_Task_Handle = NULL;/* Light_Task句柄 */
  45. static TaskHandle_t IRRX_Task_Handle = NULL;/* IRRX_Task句柄 */
  46. static TaskHandle_t OneNet_Task_Handle = NULL;/* OneNet_Task句柄 */
  47. static TaskHandle_t OneNet_Receive_Task_Handle = NULL;/* OneNET_Receive_Task句柄 */
  48. static TaskHandle_t FingerPrint_Task_Handle = NULL;/* FingerPrint_Task句柄 */
  49. static TaskHandle_t RC522_Task_Handle = NULL;/* RC522_Task句柄 */
  50. /***************************** 内核对象句柄 *****************************/
  51. /*
  52. * 信号量,消息队列,事件标志组,软件定时器这些都属于内核的对象,要想使用这些内核
  53. * 对象,必须先创建,创建成功之后会返回一个相应的句柄。实际上就是一个指针,后续我
  54. * 们就可以通过这个句柄操作这些内核对象。
  55. *
  56. *
  57. 内核对象说白了就是一种全局的数据结构,通过这些数据结构我们可以实现任务间的通信,
  58. * 任务间的事件同步等各种功能。至于这些功能的实现我们是通过调用这些内核对象的函数
  59. * 来完成的
  60. *
  61. */
  62. SemaphoreHandle_t FP_BinarySem_Handle =NULL;
  63. SemaphoreHandle_t RC522_BinarySem_Handle =NULL;
  64. /*************************** 宏定义 ************************************/
  65. /*
  66. * 当我们在写应用程序的时候,可能需要用到一些宏定义。
  67. */
  68. #define QUEUE_LEN 4 /* 队列的长度,最大可包含多少个消息 */
  69. #define QUEUE_SIZE 4 /* 队列中每个消息大小(字节) */
  70. /*
  71. *************************************************************************
  72. * 函数声明
  73. *************************************************************************
  74. */
  75. /*硬件相关*/
  76. void Hardware_Init(void);/* 初始化硬件 */
  77. void OneNET_SendReadData(void);/* ONENET收发数据 */
  78. void OneNET_ConnectInit(void);/* ONENET连接初始化 */
  79. /*FreeRTOS相关*/
  80. static void AppTaskCreate(void);/* 用于创建任务 */
  81. static void Voice_Task(void* parameter);/* Voice_Task任务实现 */
  82. static void Tempreture_Task(void* parameter);/* Tempreture_Task任务实现 */
  83. static void Light_Task(void* parameter);/* Light_Task任务实现 */
  84. static void IRRX_Task(void* parameter);/* IRRX_Task任务实现 */
  85. static void OneNet_Task(void* parameter);/* OneNet_Task任务实现 */
  86. static void OneNET_Receive_Task(void* parameter);/* OneNET_Receive_Task任务实现 */
  87. static void FingerPrint_Task(void* parameter);/* FingerPrint_Task任务实现 */
  88. static void RC522_Task(void* parameter);/* RC522_Task任务实现 */
  89. /***********************************************************************
  90. * @ 函数名 : Hardware_Init
  91. * @ 功能说明: 初始化硬件
  92. * @ 参数 : 无
  93. * @ 返回值 : 无
  94. **********************************************************************/
  95. void Hardware_Init(void)
  96. {
  97. /*
  98. * STM32中断优先级分组为4,即4bit都用来表示抢占优先级,范围为:0~15
  99. * 优先级分组只需要分组一次即可,以后如果有其他的任务需要用到中断,
  100. * 都统一用这个优先级分组,千万不要再分组,切忌。
  101. */
  102. NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4);
  103. delay_init();/*延时初始化*/
  104. USART_Config();/*串口1初始化*/
  105. printf(" 胖虎智能家居系统 \r\n");
  106. printf("一个基于STM32+FreeRTOS的智能家居系统\r\n");
  107. printf("作者:板栗焖小鸡,CSDN B站 抖音同名\r\n");
  108. LED_Config();/*LED初始化*/
  109. OLED_Init();/*OLED初始化*/
  110. OLED_Display_Init();/*OLED UI初始化*/
  111. EXTI_Key_Config();/*外部中断按键初始化*/
  112. ESP8266_Usartx_Init(115200);/*ESP8266串口初始化*/
  113. DS18B20_Init();/*温度传感器初始化*/
  114. StepMotor_Init();/*步进电机初始化*/
  115. Remote_Init();/*红外遥控初始化*/
  116. ADC_Mode_Init();/*ADC采集初始化*/
  117. BEEP_PWM_Init(9, 8000-1);/*蜂鸣器初始化*/
  118. RC522_Init();/*RC522射频模块初始化*/
  119. PcdReset ();/*RC522相关*/
  120. M500PcdConfigISOType ( 'A' );/*RC52射频模 设置工作方式*/
  121. AS608_Config();/*初始化指纹模块配置*/
  122. rx_queue_init();/*初始化环形缓冲区*/
  123. while(Connect_Test());/*测试STM32与指纹模块的通信*/
  124. Voice_USART_Config();/*语音模块初始化*/
  125. printf("Hardware init OK!\r\n");
  126. }
  127. /***********************************************************************
  128. * @ 函数名 :main
  129. * @ 功能说明:程序运行的地方
  130. * @ 参数 : 无
  131. * @ 返回值 : 无
  132. **********************************************************************/
  133. int main(void)
  134. {
  135. BaseType_t xReturn = pdPASS;/* 定义一个创建信息返回值,默认为pdPASS */
  136. Hardware_Init();/*初始化硬件*/
  137. /* 创建AppTaskCreate任务 */
  138. xReturn = xTaskCreate((TaskFunction_t )AppTaskCreate, /* 任务入口函数 */
  139. (const char* )"AppTaskCreate",/* 任务名字 */
  140. (uint16_t )1024, /* 任务栈大小 */
  141. (void* )NULL,/* 任务入口函数参数 */
  142. (UBaseType_t )1, /* 任务的优先级 */
  143. (TaskHandle_t* )&AppTaskCreate_Handle);/* 任务控制块指针 */
  144. /* 启动任务调度 */
  145. if(pdPASS == xReturn)
  146. vTaskStartScheduler(); /* 启动任务,开启调度 */
  147. else
  148. return -1;
  149. while(1); /* 正常不会执行到这里 */
  150. }
  151. /***********************************************************************
  152. * @ 函数名 : AppTaskCreate
  153. * @ 功能说明: 为了方便管理,所有的任务创建函数都放在这个函数里面
  154. * @ 参数 : 无
  155. * @ 返回值 : 无
  156. **********************************************************************/
  157. static void AppTaskCreate(void)
  158. {
  159. BaseType_t xReturn = pdPASS;/* 定义一个创建信息返回值,默认为pdPASS */
  160. taskENTER_CRITICAL(); //进入临界区
  161. /* 创建 FP_BinarySem_Handle */
  162. FP_BinarySem_Handle = xSemaphoreCreateBinary();
  163. if (NULL != FP_BinarySem_Handle)
  164. printf("FP_BinarySem_Handle 二值信号量创建成功!\r\n");
  165. /* 创建 RC522_BinarySem_Handle */
  166. RC522_BinarySem_Handle = xSemaphoreCreateBinary();
  167. if (NULL != FP_BinarySem_Handle)
  168. printf("RC522_BinarySem_Handle 二值信号量创建成功!\r\n");
  169. /* 创建OneNet_Task任务 */
  170. xReturn = xTaskCreate((TaskFunction_t )OneNet_Task, /* 任务入口函数 */
  171. (const char* )"OneNet_Task",/* 任务名字 */
  172. (uint16_t )1024, /* 任务栈大小 */
  173. (void* )NULL, /* 任务入口函数参数 */
  174. (UBaseType_t )4, /* 任务的优先级 */
  175. (TaskHandle_t* )&OneNet_Task_Handle);/* 任务控制块指针 */
  176. if(pdPASS == xReturn)
  177. //printf("创建OneNet_Task任务成功!\r\n");
  178. /* 创建Voice_Task任务 */
  179. xReturn = xTaskCreate((TaskFunction_t )Voice_Task, /* 任务入口函数 */
  180. (const char* )"Voice_Task",/* 任务名字 */
  181. (uint16_t )512, /* 任务栈大小 */
  182. (void* )NULL,/* 任务入口函数参数 */
  183. (UBaseType_t )4, /* 任务的优先级 */
  184. (TaskHandle_t* )&Voice_Task_Handle);/* 任务控制块指针 */
  185. if(pdPASS == xReturn)
  186. //printf("创建Voice_Task任务成功!\r\n");
  187. /* 创建Tempreture_Task任务 */
  188. xReturn = xTaskCreate((TaskFunction_t )Tempreture_Task, /* 任务入口函数 */
  189. (const char* )"Tempreture_Task",/* 任务名字 */
  190. (uint16_t )512, /* 任务栈大小 */
  191. (void* )NULL,/* 任务入口函数参数 */
  192. (UBaseType_t )2, /* 任务的优先级 */
  193. (TaskHandle_t* )&Tempreture_Task_Handle);/* 任务控制块指针 */
  194. if(pdPASS == xReturn)
  195. // printf("创建Tempreture_Task任务成功!\r\n");
  196. /* 创建FingerPrint_Task任务 */
  197. xReturn = xTaskCreate((TaskFunction_t )FingerPrint_Task, /* 任务入口函数 */
  198. (const char* )"FingerPrint_Task",/* 任务名字 */
  199. (uint16_t )512, /* 任务栈大小 */
  200. (void* )NULL,/* 任务入口函数参数 */
  201. (UBaseType_t )3, /* 任务的优先级 */
  202. (TaskHandle_t* )&FingerPrint_Task_Handle);/* 任务控制块指针 */
  203. if(pdPASS == xReturn)
  204. // printf("创建FingerPrint_Task任务成功!\r\n");
  205. /* 创建FingerPrint_Task任务 */
  206. xReturn = xTaskCreate((TaskFunction_t )RC522_Task, /* 任务入口函数 */
  207. (const char* )"RC522_Task",/* 任务名字 */
  208. (uint16_t )512, /* 任务栈大小 */
  209. (void* )NULL,/* 任务入口函数参数 */
  210. (UBaseType_t )3, /* 任务的优先级 */
  211. (TaskHandle_t* )&RC522_Task_Handle);/* 任务控制块指针 */
  212. if(pdPASS == xReturn)
  213. // printf("创建RC522_Task任务成功!\r\n");
  214. /* 创建Light_Task任务 */
  215. xReturn = xTaskCreate((TaskFunction_t )Light_Task, /* 任务入口函数 */
  216. (const char* )"Light_Task",/* 任务名字 */
  217. (uint16_t )512, /* 任务栈大小 */
  218. (void* )NULL,/* 任务入口函数参数 */
  219. (UBaseType_t )2, /* 任务的优先级 */
  220. (TaskHandle_t* )&Light_Task_Handle);/* 任务控制块指针 */
  221. if(pdPASS == xReturn)
  222. //printf("创建Light_Task任务成功!\r\n");
  223. vTaskDelete(AppTaskCreate_Handle); //删除AppTaskCreate任务
  224. taskEXIT_CRITICAL(); //退出临界区
  225. }
  226. /***********************************************************************
  227. * @ 函数名 :OneNet_Task
  228. * @ 功能说明:发送、接收OneNET的数据任务
  229. * @ 参数 : 无 +
  230. * @ 返回值 : 无
  231. **********************************************************************/
  232. static void OneNet_Task(void* parameter)
  233. {
  234. OneNET_ConnectInit(); /*连接OneNET*/
  235. while(1)
  236. {
  237. vTaskDelay(10);
  238. OneNet_SendData(); //发送数据
  239. ESP8266_Clear();
  240. }
  241. }
  242. /***********************************************************************
  243. * @ 函数名 :Voice_Task
  244. * @ 功能说明:处理语音数据
  245. * @ 参数 : 无
  246. * @ 返回值 : 无
  247. **********************************************************************/
  248. static void Voice_Task(void* parameter)
  249. {
  250. while(1)
  251. {
  252. //printf("Voice_Task run\r\n");
  253. switch (Voice_Data)
  254. {
  255. case 0xFF :/* 唤醒胖虎,回传数据 */
  256. Voice_Data = 0;
  257. OLED_ShowString (0, 4, " ", 16);
  258. OLED_ShowCHinese(0,4,10);
  259. OLED_ShowCHinese(16,4,11);
  260. OLED_ShowCHinese(32,4,12);
  261. OLED_ShowCHinese(48,4,13);
  262. OLED_ShowCHinese(64,4,14);
  263. OLED_ShowCHinese(80,4,15);
  264. OLED_ShowCHinese(96,4,16);
  265. // vTaskDelay(500);
  266. // OLED_ShowString (0, 4, " ", 16);
  267. break;
  268. case 0x01 :/* 开灯 */
  269. Voice_Data = 0;
  270. GPIO_ResetBits(LED1_GPIO_PORT, LED1_GPIO_PIN);
  271. GPIO_ResetBits(LED2_GPIO_PORT, LED2_GPIO_PIN);
  272. break;
  273. case 0x02 :/* 关灯 */
  274. Voice_Data = 0;
  275. GPIO_SetBits(LED1_GPIO_PORT, LED1_GPIO_PIN);
  276. GPIO_SetBits(LED2_GPIO_PORT, LED2_GPIO_PIN);
  277. break;
  278. case 0x03 :/* 开蜂鸣器 */
  279. Voice_Data = 0;
  280. BEEP_OUT;
  281. break;
  282. case 0x04 :/* 关蜂鸣器 */
  283. Voice_Data = 0;
  284. BEEP_STOP;
  285. break;
  286. case 0x05:/* 开门 */
  287. Voice_Data = 0;
  288. Open_Door();
  289. break;
  290. case 0x06 :/* 关门 */
  291. Voice_Data = 0;
  292. Close_Door();
  293. break;
  294. case 0x07 :/* 开启指纹识别模式 */
  295. Voice_Data = 0;
  296. BEEP_TOGGLE(3, 100);
  297. xSemaphoreGive( FP_BinarySem_Handle );//给出二值信号量
  298. break;
  299. case 0x08 :/* 开启RC522刷卡模式 */
  300. Voice_Data = 0;
  301. BEEP_TOGGLE(3, 100);
  302. xSemaphoreGive( RC522_BinarySem_Handle );//给出二值信号量
  303. break;
  304. default :
  305. Voice_Data = 0;
  306. break;
  307. }
  308. vTaskDelay(10);
  309. }
  310. }
  311. /***********************************************************************
  312. * @ 函数名 :FingerPrint_Task
  313. * @ 功能说明:指纹识别
  314. * @ 参数 : 无
  315. * @ 返回值 : 无
  316. **********************************************************************/
  317. static void FingerPrint_Task(void* parameter)
  318. {
  319. static uint8_t Timeout;
  320. BaseType_t xReturn = pdPASS;/* 定义一个创建信息返回值,默认为 pdPASS */
  321. while(1)
  322. {
  323. //获取二值信号量 xSemaphore,没获取到则一直等待
  324. xReturn = xSemaphoreTake(FP_BinarySem_Handle,/* 二值信号量句柄 */
  325. portMAX_DELAY); /* 等待时间 */
  326. if (pdTRUE == xReturn)
  327. printf("FP_BinarySem_Handle 二值信号量获取成功!\n\n");
  328. Timeout++;
  329. vTaskDelay(1000);
  330. while(!MyCompare_FR())/*比对指纹*/
  331. {
  332. if(Timeout>=5)
  333. {
  334. Timeout = 0;
  335. break;
  336. }
  337. }
  338. BEEP_TOGGLE(1, 200);
  339. Voice_Send("AS608 OK");
  340. vTaskDelay(900);
  341. Open_Door();
  342. vTaskDelay(300);
  343. Close_Door();
  344. }
  345. }
  346. /***********************************************************************
  347. * @ 函数名 :RC522_Task
  348. * @ 功能说明:刷卡模式
  349. * @ 参数 : 无
  350. * @ 返回值 : 无
  351. **********************************************************************/
  352. static void RC522_Task(void* parameter)
  353. {
  354. uint32_t writeValue = 100;
  355. uint32_t readValue;
  356. char cStr [ 30 ];
  357. uint8_t ucArray_ID [ 4 ]; /*先后存放IC卡的类型和UID(IC卡序列号)*/
  358. uint8_t ucStatusReturn; /*返回状态*/
  359. static uint8_t Rc_Timeout;
  360. BaseType_t xReturn = pdPASS;/* 定义一个创建信息返回值,默认为 pdPASS */
  361. while(1)
  362. {
  363. //获取二值信号量 xSemaphore,没获取到则一直等待
  364. xReturn = xSemaphoreTake(RC522_BinarySem_Handle,/* 二值信号量句柄 */
  365. portMAX_DELAY); /* 等待时间 */
  366. if (pdTRUE == xReturn)
  367. printf("RC522_BinarySem_Handle 二值信号量获取成功!\n\n");
  368. /*寻卡*/
  369. while( ( ucStatusReturn = PcdRequest ( PICC_REQALL, ucArray_ID ) ) != MI_OK )
  370. {
  371. /*若失败再次寻卡*/
  372. Rc_Timeout++;
  373. vTaskDelay(100);
  374. printf ( "寻卡失败\n" );
  375. ucStatusReturn = PcdRequest ( PICC_REQALL, ucArray_ID ); //PICC_REQALL PICC_REQIDL
  376. if(Rc_Timeout >= 10)
  377. {
  378. Rc_Timeout = 0;
  379. break;
  380. }
  381. }
  382. if ( ucStatusReturn == MI_OK )
  383. {
  384. printf ( "寻卡成功\n" );
  385. Voice_Send("RC522 OK");
  386. vTaskDelay(2000);
  387. BEEP_TOGGLE(1, 100);
  388. Open_Door();
  389. vTaskDelay(300);
  390. Close_Door();
  391. }
  392. }
  393. }
  394. /***********************************************************************
  395. * @ 函数名 :Tempreture_Task
  396. * @ 功能说明:读取温度任务
  397. * @ 参数 : 无
  398. * @ 返回值 : 无
  399. **********************************************************************/
  400. static void Tempreture_Task(void* parameter)
  401. {
  402. uint8_t i;
  403. float temp;
  404. while(1)
  405. {
  406. temp = Get_18B20();
  407. if(temp>0&&temp<50)
  408. Tempreture = temp;
  409. //printf("Temp: %d\r\n", Tempreture);
  410. vTaskDelay(1000);
  411. }
  412. }
  413. /***********************************************************************
  414. * @ 函数名 :Light_Task
  415. * @ 功能说明:读取光照强度值
  416. * @ 参数 : 无
  417. * @ 返回值 : 无
  418. **********************************************************************/
  419. static void Light_Task(void* parameter)
  420. {
  421. while(1)
  422. {
  423. /*获取光敏电阻值*/
  424. LightValue = Get_Light_Value();
  425. //printf("LightValue:%d\r\n", LightValue);
  426. vTaskDelay(200);
  427. }
  428. }
  429. /***********************************************END*********************************************************/

链接:https://pan.baidu.com/s/1IS-OMLy2_pyWyMU3UIhzTg?pwd=qozw
提取码:qozw
--来自百度网盘超级会员V3的分享

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/339416
推荐阅读
相关标签
  

闽ICP备14008679号