[uCOS/RTOS] 【RTOS】RT-Thread创新大赛——基于麻雀一号的智能门铃(二)

[复制链接]
2800|3
 楼主| WoodData 发表于 2020-6-13 21:47 | 显示全部楼层 |阅读模式
    本次分享项目智能门铃的软件框架流程。通过按键和简单的菜单选择不同功能,菜单主要是四部分:
1、门外视频监控。可以在LCD屏上查看门外视屏图像。如果wifi连接成功,还可以同时登录他局域网IP地址查看。可以直接扫描LCD屏上二维码进入局域网监控,或者主动输入IP地址和端口号连接。

PS:这部分由于内存分配不足,LCD无法解码JPG文件数据并显示,后面再优化看看,如果实在不行只能阉割部分功能了。在这顺便说下在TjpgDec软件包的例程中没有对内存分配结果检查,导致开始调试显示图片的时候经常会死机,只能通过无线烧写器烧录初始固件。后面我才发现这个问题,修改了一下才没有再次死机。再就是增加了可以指定显示图片的初始XY坐标位置。
   
2、查看今日天气。通过webclient和CJSON获取和解析网络天气服务。使用的是心知天气服务,注册心知天气获取一个验证KEY。它的回复数据是JSON数据格式,很方便。


3、开关门记录和访客记录。待完成

4、WIFI声波配网。微信扫描小程序进入声波配网。接收到WIFI路由信息后自动联网并保存参数到SD卡文件中,上电初始化过程会检查是否有wifi配置文件,如果有就自动联网,没有的话直接进入配网界面。如果不想现在配网可以通过按键返回菜单,取消配网。


在声波配网程序那添加保存配网信息。



软件流程:
    先在Main线程创建用户菜单显示操作线程User Thread。
User Thread内容:
1、初始化显示——》创建按键和GPIO扫描线程并创建按键邮箱——》创建WIFI连接事件和临时线程等待WIFI连接成功后需要处理的线程——》检查wifi配置——》有wifi配置时自动连接wifi,连接wifi成功后发送WIFI连接成功事件使临时线程继续,并进入主菜单界面。无WIFI配置时进入wifi配网菜单。——》循环等待按键邮箱,获取按键信息并进行相应处理。

进入视屏监控菜单——》创建局域网监控图片和LCD显示图片的线程,还可以通过长按按键保存照片到指定文件夹,按日期时间组合文件名保存。
进入今日天气——》创建定时器每隔10分钟获取一次天气数据。
进入WIFI声波配网——》显示声波配网小程序码,通过微信扫一扫,进入小程序配网。配网部分使用例程代码,在代码中配网成功后保存WIFI配置,自动联网,并在LCD屏上显示配网信息。

2、临时线程首先等待WIFI连接成功——》执行NTP网络服务进行RTC时间同步——》执行创建MQTT网络云连接服务上传信息——》线程结束退出。

3、按键和GPIO扫描线程。使用的是Multi_button软件包,初始化创建了一个邮箱,专门发送按键信息。线程内循环扫描操作按键IO、开关门IO、门铃按键,并发送邮箱数据。

4、NTP服务时间同步使用例程线程。

5、MQTT使用ONENET_MQTT软件包内例程线程。

部分代码:
主用户菜单线程
  1. ////////////////////////////////////////////////////////////
  2. rt_event_t      wificonn_event = RT_NULL;
  3. #define     WIFI_CONN_OK        (1<<0)

  4. //temp Thread
  5. static void UserTempApp(void *arg)
  6. {
  7.     char mqtt_cmd[]={"onenet_mqtt_init"};
  8.     char ntp_cmd[]={"ntp_sync"};
  9.     //等待WIFI连接
  10.     rt_event_recv(wificonn_event, WIFI_CONN_OK, RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, RT_WAITING_FOREVER, RT_NULL);
  11.    
  12.     //创建时间同步,天气获取,网络云mqtt连接
  13.     msh_exec(mqtt_cmd, strlen(mqtt_cmd));       //exec mqtt
  14.     msh_exec(ntp_cmd, strlen(ntp_cmd));         //exec ntp
  15.     rt_kprintf("ntp and mqtt running......................\n");
  16. }


  17. #define     MENU_ITEM_NUM       5
  18. extern uint8_t     g_CurMenuIndex;
  19. extern uint8_t     g_CurMenuItem;


  20. extern uint8_t  MainFunInit(void);
  21. extern uint8_t  MainFunLoop(void);
  22. extern uint8_t  DoorVedioFunInit(void);
  23. extern uint8_t  DoorVedioFunLoop(void);
  24. extern uint8_t  WeatherFunInit(void);
  25. extern uint8_t  WeatherFunLoop(void);
  26. extern uint8_t  DoorReportFunInit(void);
  27. extern uint8_t  DoorReportFunLoop(void);
  28. extern uint8_t  WifiCfgFunInit(void);
  29. extern uint8_t  WifiCfgFunLoop(void);

  30. typedef struct MenuFunCB
  31. {
  32.     uint8_t  (*MenuItemInit)(void);
  33.     uint8_t  (*MenuItemFun)(void);
  34. }MenuFunCB;

  35. MenuFunCB MenuFun[MENU_ITEM_NUM]=
  36. {
  37.     {MainFunInit,MainFunLoop},
  38.     {DoorVedioFunInit,DoorVedioFunLoop},
  39.     {WeatherFunInit,WeatherFunLoop},
  40.     {DoorReportFunInit,DoorReportFunLoop},
  41.     {WifiCfgFunInit,WifiCfgFunLoop},

  42. };

  43. static uint8_t  _menu_state;
  44. //User Main Thread
  45. static void UserApp(void *arg)
  46. {

  47.     lcd_clear(BLUE);
  48.     lcd_set_font(&Font_CH24X24);
  49.     lcd_set_font_color(RED,BLUE);
  50.     lcd_disp_str_at(66,4,"RT-Thread");
  51.     lcd_disp_str_at(24,28,"应用创新设计大赛");
  52.     lcd_disp_str_at(108,52,"By WoodData");
  53.     lcd_set_font(&Font_CH48X48);
  54.     lcd_set_font_color(RED,WHITE);
  55.     lcd_disp_str_at(24,80,"智能门铃");

  56.     lcd_set_font(&Font_CH24X24);
  57.     lcd_set_font_color(RED,WHITE);
  58.     lcd_disp_str_at(12,200,"21IC");
  59.     lcd_set_font_color(BLUE,WHITE);
  60.     lcd_disp_str_at(60,200,"电子网技术论坛");
  61.     lcd_set_font(&Font_ASCII16X8);
  62.     lcd_set_font_color(RED,WHITE);
  63.     lcd_disp_str_at(40,224,"https://bbs.21ic.com");

  64.     lcd_show_qrcode(87,130,4,2,"https://bbs.21ic.com",2);

  65. //////////////////
  66.     key_init(); //创建按键扫描线程,及按键信息邮箱

  67. //////////////////
  68.     wificonn_event = rt_event_create("wifi_conn_event", RT_IPC_FLAG_FIFO);
  69. extern void user_callback_register(void);
  70.     user_callback_register();

  71. ///////////////////
  72.     rt_thread_t tid = RT_NULL;
  73.      /* Create background ticks thread */
  74.     tid = rt_thread_create("UserTemp", UserTempApp, RT_NULL, 1024, 11, 10);
  75.     if(tid != RT_NULL)
  76.     {
  77.         rt_thread_startup(tid);
  78.     }

  79. //////////////////
  80.     char wifistr[] = {"wifi"};
  81.     int fd = 0;
  82.     //检测WIFI连接是否配置
  83.     fd = open(WIFI_SETTING_FN,O_RDONLY);  //WIFI_SETTING_FN = "/sd/wificonnectcfg.json"
  84.     if(fd >= 0)
  85.     {
  86.         close(fd);
  87.         msh_exec(wifistr, strlen(wifistr));     //exec wifi link     
  88.         rt_kprintf("wifi auto connect.\n");
  89.         g_CurMenuItem = 0;
  90.         g_CurMenuIndex = 0;
  91.     }else
  92.     {
  93.         rt_kprintf("Open wificonnectcfg.json failed!!!\n");
  94.         g_CurMenuItem = 4;
  95.         g_CurMenuIndex = 0;
  96.     }
  97.    
  98.     _menu_state = 0;
  99.     rt_kprintf("Key Scan Thread..............................\n");
  100.     rt_thread_mdelay(3000);

  101.     while(1)
  102.     {
  103.         if(g_CurMenuItem < MENU_ITEM_NUM)
  104.         {
  105.             if(_menu_state == 0)
  106.             {
  107.                 if(MenuFun[g_CurMenuItem].MenuItemInit() == 0)
  108.                 {
  109.                     _menu_state = 1;
  110.                 }
  111.             }else
  112.             {
  113.                 if(MenuFun[g_CurMenuItem].MenuItemFun() == 0)
  114.                 {
  115.                     _menu_state = 0;
  116.                 }
  117.             }
  118.             
  119.         }        
  120.     }
  121. }
菜单绘制代码


  1. #include "time.h"
  2. #include "rtthread.h"
  3. #include <dfs.h>
  4. #include <dfs_fs.h>

  5. #if     1

  6. #include "tjpgd.h"
  7. #include "voice_config.h"
  8. #include "lcd_font.h"
  9. #include "key.h"



  10. uint8_t     g_CurMenuIndex;
  11. uint8_t     g_CurMenuItem;

  12. void WifiCfgDraw(uint16_t index);
  13. void MainPageDraw(uint16_t key);

  14. extern void UserGetCurTime(struct tm *tm_new);

  15. //////////////////////////////////////////////////////////////////////
  16. void MainPageDraw(uint16_t key)
  17. {
  18.     if(key&0x8000)
  19.     {
  20.         lcd_fill(0,0,240,48,BLUE);
  21.         lcd_fill(0,48,240,240,GBLUE);

  22.         lcd_set_font(&Font_CH48X48);
  23.         lcd_set_font_color(RED,BLUE);
  24.         lcd_disp_str_at(24,0,"智能门铃");  

  25.         lcd_set_color(WHITE,BLACK);
  26.         lcd_draw_line(0,47,240,47);
  27.     }

  28.     lcd_set_font(&Font_CH32X32);
  29.     if(key&0x0001)
  30.     {
  31.         lcd_fill(0,48,240,80,BLUE);
  32.         lcd_set_font_color(BRED,BLUE);
  33.         lcd_disp_str_at(0,48,"视频监控");
  34.       
  35.     }else
  36.     {
  37.         lcd_fill(0,48,240,80,GBLUE);
  38.         lcd_set_font_color(BRED,GBLUE);
  39.         lcd_disp_str_at(0,48,"视频监控");  
  40.     }

  41.     if(key&0x0002)
  42.     {
  43.         lcd_fill(0,80,240,112,BLUE);
  44.         lcd_set_font_color(BRED,BLUE);
  45.         lcd_disp_str_at(0,80,"今日天气");         
  46.     }else
  47.     {
  48.         lcd_fill(0,80,240,112,GBLUE);
  49.         lcd_set_font_color(BRED,GBLUE);
  50.         lcd_disp_str_at(0,80,"今日天气");  
  51.     }

  52.     if(key&0x0004)
  53.     {
  54.         lcd_fill(0,112,240,144,BLUE);
  55.         lcd_set_font_color(BRED,BLUE);
  56.         lcd_disp_str_at(0,112,"开关门记录");         
  57.     }else
  58.     {
  59.         lcd_fill(0,112,240,144,GBLUE);
  60.         lcd_set_font_color(BRED,GBLUE);
  61.         lcd_disp_str_at(0,112,"开关门记录");  
  62.     }  

  63.     if(key&0x0008)
  64.     {
  65.         lcd_fill(0,144,240,176,BLUE);
  66.         lcd_set_font_color(BRED,BLUE);
  67.         lcd_disp_str_at(0,144,"WIFI声波配网");         
  68.     }else
  69.     {
  70.         lcd_fill(0,144,240,176,GBLUE);
  71.         lcd_set_font_color(BRED,GBLUE);
  72.         lcd_disp_str_at(0,144,"WIFI声波配网");  
  73.     }
  74. }

  75. uint8_t  MainFunInit(void )
  76. {
  77.     MainPageDraw(0x8001);

  78.     return 0;
  79. }

  80. uint8_t  MainFunLoop(void )
  81. {
  82.     uint32_t  keyvalue;

  83.         if(rt_mb_recv(key_mailbox,&keyvalue,RT_WAITING_FOREVER) == RT_EOK)
  84.         {
  85.             rt_kprintf("Key mailbox recv %0X.\n",keyvalue);
  86.             switch((keyvalue &0xffff0000)>>16)
  87.             {
  88.                 case    0x0:    //key_m
  89.                 switch (keyvalue&0xffff)
  90.                 {
  91.                 case SINGLE_CLICK:
  92.                     switch(g_CurMenuIndex)
  93.                     {
  94.                         case    0:
  95.                         g_CurMenuIndex = 0;
  96.                         g_CurMenuItem  = 1;
  97.                         break;
  98.                         case    1:
  99.                         g_CurMenuIndex = 0;
  100.                         g_CurMenuItem  = 2;
  101.                         break;
  102.                         case    2:
  103.                         g_CurMenuIndex = 0;
  104.                         g_CurMenuItem  = 3;
  105.                         break;
  106.                         case    3:
  107.                         g_CurMenuIndex = 0;
  108.                         g_CurMenuItem  = 4;
  109.                         break;

  110.                     }               
  111.                     return 0;               
  112.                 default:
  113.                     break;
  114.                 }
  115.                 break;
  116.                
  117.                 case    0x1:    //key_up
  118.                 switch (keyvalue&0xffff)
  119.                 {
  120.                 case SINGLE_CLICK:
  121.                     if(g_CurMenuIndex )   g_CurMenuIndex --;   
  122.                     else    g_CurMenuIndex = 3;                                    
  123.                     MainPageDraw(0x0001<<g_CurMenuIndex);
  124.                     rt_kprintf("index %u.\n",g_CurMenuIndex);                              
  125.                     break;               
  126.                 default:
  127.                     break;
  128.                 }
  129.                 break;

  130.                 case    0x2:    //key_down
  131.                 switch (keyvalue&0xffff)
  132.                 {
  133.                 case SINGLE_CLICK:
  134.                     g_CurMenuIndex++;  
  135.                     if(g_CurMenuIndex == 4)   g_CurMenuIndex = 0;                    
  136.                     MainPageDraw(0x0001<<g_CurMenuIndex);
  137.                     rt_kprintf("index %u.\n",g_CurMenuIndex);                           
  138.                     break;               
  139.                 default:
  140.                     break;
  141.                 }

  142.                 break;



  143.                 case    0x5:    //门铃键
  144.                 switch (keyvalue&0xffff)
  145.                 {
  146.                 case SINGLE_CLICK:                              
  147.                     break;               
  148.                 default:
  149.                     break;
  150.                 }
  151.                 break;
  152.                 case    0x6:    //开关门

  153.                 break;
  154.             }
  155.         }

  156.     return 1;
  157. }

  158. /////////////////////////////////////////////////////
  159. extern void show_photo_test(void);
  160. extern void stop_photo(void);
  161. extern void save_photo(void);
  162. uint8_t  DoorVedioFunInit(void)
  163. {
  164.     lcd_fill(0,0,240,48,BLUE);
  165.     lcd_fill(0,48,240,240,GBLUE);

  166.     lcd_set_font(&Font_CH48X48);
  167.     lcd_set_font_color(RED,BLUE);
  168.     lcd_disp_str_at(0,0,"视频监控");

  169.     lcd_set_color(WHITE,BLACK);
  170.     lcd_draw_line(0,47,240,47);

  171.     show_photo_test();  
  172.     return 0;
  173. }

  174. uint8_t  DoorVedioFunLoop(void)
  175. {
  176.     uint32_t  keyvalue;

  177.         if(rt_mb_recv(key_mailbox,&keyvalue,RT_WAITING_FOREVER) == RT_EOK)
  178.         {
  179.             rt_kprintf("Key mailbox recv %0X.\n",keyvalue);
  180.             switch((keyvalue &0xffff0000)>>16)
  181.             {
  182.                 case    0x0:    //key_m
  183.                 switch (keyvalue&0xffff)
  184.                 {
  185.                 case SINGLE_CLICK:
  186.                     g_CurMenuIndex = 0;
  187.                     g_CurMenuItem  = 0;
  188.                     stop_photo();                  
  189.                     return 0;
  190.                 case LONG_RRESS_START:
  191.                     save_photo(); //Save jpg file
  192.                     break;              
  193.                 default:
  194.                     break;
  195.                 }
  196.                 break;
  197.                 case    0x1:    //key_up
  198.                 switch (keyvalue&0xffff)
  199.                 {
  200.                 case SINGLE_CLICK:                        
  201.                     break;               
  202.                 default:
  203.                     break;
  204.                 }

  205.                 break;
  206.                 case    0x2:    //key_down
  207.                 switch (keyvalue&0xffff)
  208.                 {
  209.                 case SINGLE_CLICK:                           
  210.                     break;               
  211.                 default:
  212.                     break;
  213.                 }

  214.                 break;


  215.                 case    0x5:    //门铃键
  216.                 switch (keyvalue&0xffff)
  217.                 {
  218.                 case SINGLE_CLICK:                              
  219.                     break;               
  220.                 default:
  221.                     break;
  222.                 }
  223.                 break;
  224.                 case    0x6:    //开关门

  225.                 break;
  226.             }
  227.         }
  228.     return 1;
  229. }

  230. /////////////////////////////////////////////////////
  231. static void weather_timer_10min(void * para)
  232. {
  233.     char argv[] = {"weather guangzhou"};   
  234.     msh_exec(argv, strlen(argv));     //exec wifi link
  235. }

  236. static rt_timer_t   weather_timer;

  237. uint8_t  WeatherFunInit(void)
  238. {
  239.     char argv[] = {"weather guangzhou"};

  240.     lcd_fill(0,0,240,48,BLUE);
  241.     lcd_fill(0,48,240,240,GBLUE);

  242.     lcd_set_font(&Font_CH48X48);
  243.     lcd_set_font_color(RED,BLUE);
  244.     lcd_disp_str_at(0,0,"今日天气");

  245.     lcd_set_color(WHITE,BLACK);
  246.     lcd_draw_line(0,47,240,47);

  247.     weather_timer  = rt_timer_create("weather timer",weather_timer_10min,RT_NULL, 10*60*RT_TICK_PER_SECOND,
  248.                                     RT_TIMER_FLAG_PERIODIC | RT_TIMER_FLAG_SOFT_TIMER );
  249.     if(weather_timer != RT_NULL)
  250.     {
  251.         rt_timer_start(weather_timer);
  252.     }else
  253.     {
  254.         rt_kprintf("weather timer fail!!!\n");
  255.     }
  256.    
  257.     msh_exec(argv, strlen(argv));     //exec wifi link

  258.     return 0;
  259. }

  260. uint8_t  WeatherFunLoop(void)
  261. {
  262.     uint32_t  keyvalue;

  263.         if(rt_mb_recv(key_mailbox,&keyvalue,RT_WAITING_FOREVER) == RT_EOK)
  264.         {
  265.             rt_kprintf("Key mailbox recv %0X.\n",keyvalue);
  266.             switch((keyvalue &0xffff0000)>>16)
  267.             {
  268.                 case    0x0:    //key_m
  269.                 switch (keyvalue&0xffff)
  270.                 {
  271.                 case SINGLE_CLICK:
  272.                     g_CurMenuIndex = 0;
  273.                     g_CurMenuItem  = 0;   
  274.                     if(weather_timer != RT_NULL)
  275.                     {
  276.                         rt_timer_delete(weather_timer);
  277.                     }                       
  278.                     return 0;               
  279.                 default:
  280.                     break;
  281.                 }
  282.                 break;
  283.                 case    0x1:    //key_up
  284.                 switch (keyvalue&0xffff)
  285.                 {
  286.                 case SINGLE_CLICK:                        
  287.                     break;               
  288.                 default:
  289.                     break;
  290.                 }

  291.                 break;
  292.                 case    0x2:    //key_down
  293.                 switch (keyvalue&0xffff)
  294.                 {
  295.                 case SINGLE_CLICK:                           
  296.                     break;               
  297.                 default:
  298.                     break;
  299.                 }

  300.                 break;


  301.                 case    0x5:    //门铃键
  302.                 switch (keyvalue&0xffff)
  303.                 {
  304.                 case SINGLE_CLICK:                              
  305.                     break;               
  306.                 default:
  307.                     break;
  308.                 }
  309.                 break;
  310.                 case    0x6:    //开关门

  311.                 break;
  312.             }
  313.         }
  314.     return 1;
  315. }

  316. /////////////////////////////////////////////////////
  317. uint8_t  DoorReportFunInit(void)
  318. {
  319.     lcd_fill(0,0,240,48,BLUE);
  320.     lcd_fill(0,48,240,240,GBLUE);

  321.     lcd_set_font(&Font_CH48X48);
  322.     lcd_set_font_color(RED,BLUE);
  323.     lcd_disp_str_at(0,0,"开关门记录");

  324.     lcd_set_color(WHITE,BLACK);
  325.     lcd_draw_line(0,47,240,47);
  326.     return 0;
  327. }
  328. uint8_t  DoorReportFunLoop(void)
  329. {
  330.     uint32_t  keyvalue;

  331.         if(rt_mb_recv(key_mailbox,&keyvalue,RT_WAITING_FOREVER) == RT_EOK)
  332.         {
  333.             rt_kprintf("Key mailbox recv %0X.\n",keyvalue);
  334.             switch((keyvalue &0xffff0000)>>16)
  335.             {
  336.                 case    0x0:    //key_m
  337.                 switch (keyvalue&0xffff)
  338.                 {
  339.                 case SINGLE_CLICK:
  340.                     g_CurMenuIndex = 0;
  341.                     g_CurMenuItem  = 0;  
  342.                        
  343.                     return 0;               
  344.                 default:
  345.                     break;
  346.                 }
  347.                 break;
  348.                 case    0x1:    //key_up
  349.                 switch (keyvalue&0xffff)
  350.                 {
  351.                 case SINGLE_CLICK:                        
  352.                     break;               
  353.                 default:
  354.                     break;
  355.                 }

  356.                 break;
  357.                 case    0x2:    //key_down
  358.                 switch (keyvalue&0xffff)
  359.                 {
  360.                 case SINGLE_CLICK:                           
  361.                     break;               
  362.                 default:
  363.                     break;
  364.                 }

  365.                 break;


  366.                 case    0x5:    //门铃键
  367.                 switch (keyvalue&0xffff)
  368.                 {
  369.                 case SINGLE_CLICK:                              
  370.                     break;               
  371.                 default:
  372.                     break;
  373.                 }
  374.                 break;
  375.                 case    0x6:    //开关门

  376.                 break;
  377.             }
  378.         }
  379.     return 1;
  380. }

  381. ///////////////////////////////////////////////////////
  382. void WifiCfgDraw(uint16_t index)
  383. {
  384.     if(index&0x8000)
  385.     {
  386.         lcd_fill(0,0,240,48,BLUE);
  387.         lcd_fill(0,48,240,240,GBLUE);

  388.         lcd_set_font(&Font_CH40X40);
  389.         lcd_set_font_color(RED,BLUE);
  390.         lcd_disp_str_at(0,0,"WIFI声波配网");

  391.         lcd_set_color(WHITE,BLACK);
  392.         lcd_draw_line(0,47,240,47);
  393.     }

  394.     if(index&0x0001)
  395.     {        
  396.         lcd_set_font(&Font_CH16X16);
  397.         lcd_set_font_color(BRED,GBLUE);
  398.         lcd_disp_str_at(((240-16*7)>>1), 50 ,"打开微信扫一扫");
  399.         Decode_Jpg("/sd/voice_wifi.jpg",48,80);
  400.     }   

  401. }

  402. uint8_t  WifiCfgFunInit(void)
  403. {
  404.     WifiCfgDraw(0x8001);
  405.     voice_config(0,NULL);
  406.     return 0;
  407. }

  408. uint8_t  WifiCfgFunLoop(void)
  409. {
  410.     uint32_t  keyvalue;

  411.         if(rt_mb_recv(key_mailbox,&keyvalue,RT_WAITING_FOREVER) == RT_EOK)
  412.         {
  413.             rt_kprintf("Key mailbox recv %0X.\n",keyvalue);
  414.             switch((keyvalue &0xffff0000)>>16)
  415.             {
  416.                 case    0x0:    //key_m
  417.                 switch (keyvalue&0xffff)
  418.                 {
  419.                 case SINGLE_CLICK:

  420.                     g_CurMenuIndex = 0;
  421.                     g_CurMenuItem  = 0;  
  422.                     voice_config_stop();
  423.                     rt_thread_mdelay(1000);                        
  424.                     return 0;               
  425.                 default:
  426.                     break;
  427.                 }
  428.                 break;
  429.                 case    0x1:    //key_up
  430.                 switch (keyvalue&0xffff)
  431.                 {
  432.                 case SINGLE_CLICK:                        
  433.                     break;               
  434.                 default:
  435.                     break;
  436.                 }

  437.                 break;
  438.                 case    0x2:    //key_down
  439.                 switch (keyvalue&0xffff)
  440.                 {
  441.                 case SINGLE_CLICK:                           
  442.                     break;               
  443.                 default:
  444.                     break;
  445.                 }

  446.                 break;


  447.                 case    0x5:    //门铃键
  448.                 switch (keyvalue&0xffff)
  449.                 {
  450.                 case SINGLE_CLICK:                              
  451.                     break;               
  452.                 default:
  453.                     break;
  454.                 }
  455.                 break;
  456.                 case    0x6:    //开关门

  457.                 break;
  458.             }
  459.         }
  460.         
  461.     return 1;
  462. }

  463. ////////////////////////////////////////////////






  464. #endif



按键扫描

  1. #include <rtthread.h>
  2. #include <stdint.h>
  3. #include <rtdevice.h>


  4. #if     1

  5. #include "key.h"


  6. #define KEY_MID         (13)
  7. #define KEY_UP          (28)
  8. #define KEY_DOWN        (19)
  9. #define KEY_LEFT        (12)
  10. #define KEY_RIGHT       (25)

  11. rt_mailbox_t  key_mailbox = RT_NULL;

  12. typedef enum
  13. {
  14.     KEY_M = 0,      //Middle
  15.     KEY_U,          //Up
  16.     KEY_D,          //Down
  17.     KEY_L,          //Left
  18.     KEY_R,          //Right
  19.     KEY_NUM         //key count
  20. } user_button_t;

  21. static struct button user_button[KEY_NUM];

  22. uint32_t    KeyValue;

  23. static void btn_0_cb(void *btn)
  24. {
  25.     rt_kprintf("btn_0_cb\n");
  26.     KeyValue = get_button_event((struct button *)btn);

  27.     switch(KeyValue)
  28.     {
  29.     case PRESS_DOWN:
  30.         rt_kprintf("button press down\n");
  31.     break;

  32.     case PRESS_UP:
  33.         rt_kprintf("button press up\n");
  34.     break;

  35.     case PRESS_REPEAT:
  36.         rt_kprintf("button press repeat\n");
  37.     break;

  38.     case SINGLE_CLICK:
  39.         rt_kprintf("button single click\n");
  40.     break;

  41.     case DOUBLE_CLICK:
  42.         rt_kprintf("button double click\n");
  43.     break;

  44.     case LONG_RRESS_START:
  45.         rt_kprintf("button long press start\n");
  46.     break;

  47.     case LONG_PRESS_HOLD:
  48.         rt_kprintf("button long press hold\n");
  49.     break;
  50.     }
  51.     rt_mb_send(key_mailbox,KeyValue);
  52. }

  53. static void btn_1_cb(void *btn)
  54. {
  55.     rt_kprintf("btn_1_cb\n");
  56.     KeyValue = get_button_event((struct button *)btn);
  57.     KeyValue |= 0x010000;
  58.     rt_mb_send(key_mailbox,KeyValue);
  59. }

  60. static void btn_2_cb(void *btn)
  61. {
  62.     rt_kprintf("btn_2_cb\n");
  63.     KeyValue = get_button_event((struct button *)btn);
  64.     KeyValue |= 0x020000;
  65.     rt_mb_send(key_mailbox,KeyValue);
  66. }

  67. static void btn_3_cb(void *btn)
  68. {
  69.     rt_kprintf("btn_3_cb\n");
  70.     KeyValue = get_button_event((struct button *)btn);
  71.     KeyValue |= 0x030000;
  72.     rt_mb_send(key_mailbox,KeyValue);
  73. }

  74. static void btn_4_cb(void *btn)
  75. {
  76.     rt_kprintf("btn_4_cb\n");
  77.     KeyValue = get_button_event((struct button *)btn);
  78.     KeyValue |= 0x040000;
  79.     rt_mb_send(key_mailbox,KeyValue);
  80. }

  81. ////////////////////////////////////////////////////
  82. //Key Read Value
  83. static uint8_t key_mid_read(void)
  84. {
  85.     return rt_pin_read(KEY_MID);
  86. }

  87. static uint8_t key_up_read(void)
  88. {
  89.     return rt_pin_read(KEY_UP);
  90. }

  91. static uint8_t key_down_read(void)
  92. {
  93.     return rt_pin_read(KEY_DOWN);
  94. }

  95. static uint8_t key_left_read(void)
  96. {
  97.     return rt_pin_read(KEY_LEFT);
  98. }

  99. static uint8_t key_right_read(void)
  100. {
  101.     return rt_pin_read(KEY_RIGHT);
  102. }

  103. //Key Scan Thread
  104. static void button_scan(void *arg)
  105. {
  106.     while(1)
  107.     {
  108.         /* 5ms */
  109.         rt_thread_delay(RT_TICK_PER_SECOND/200);
  110.         button_ticks();
  111.     }
  112. }


  113. int key_init(void)
  114. {
  115.     int i;
  116.     rt_thread_t tid = RT_NULL;

  117.     rt_pin_mode(KEY_MID, PIN_MODE_INPUT_PULLUP); /* set KEY pin mode to input */
  118.     rt_pin_mode(KEY_UP, PIN_MODE_INPUT_PULLUP); /* set KEY pin mode to input */
  119.     rt_pin_mode(KEY_DOWN, PIN_MODE_INPUT_PULLUP); /* set KEY pin mode to input */
  120.     rt_pin_mode(KEY_LEFT, PIN_MODE_INPUT_PULLUP); /* set KEY pin mode to input */
  121.     rt_pin_mode(KEY_RIGHT, PIN_MODE_INPUT_PULLUP); /* set KEY pin mode to input */


  122.     //创建按键信息邮箱
  123.     key_mailbox = rt_mb_create("KeyMail",16*4,RT_IPC_FLAG_FIFO);

  124.     /* Create background ticks thread */
  125.     tid = rt_thread_create("KeyScan", button_scan, RT_NULL, 512, 15, 10);
  126.     if(tid != RT_NULL)
  127.     {
  128.         rt_thread_startup(tid);
  129.     }

  130.     /* low level drive */
  131.     button_init  (&user_button[KEY_M], key_mid_read, PIN_LOW);
  132.     button_attach(&user_button[KEY_M], PRESS_DOWN,       btn_0_cb);
  133.     button_attach(&user_button[KEY_M], PRESS_UP,         btn_0_cb);
  134.     button_attach(&user_button[KEY_M], PRESS_REPEAT,     btn_0_cb);
  135.     button_attach(&user_button[KEY_M], SINGLE_CLICK,     btn_0_cb);
  136.     button_attach(&user_button[KEY_M], DOUBLE_CLICK,     btn_0_cb);
  137.     button_attach(&user_button[KEY_M], LONG_RRESS_START, btn_0_cb);
  138.     button_attach(&user_button[KEY_M], LONG_PRESS_HOLD,  btn_0_cb);
  139.     button_start (&user_button[KEY_M]);


  140.     button_init  (&user_button[KEY_U], key_up_read, PIN_LOW);
  141.     button_attach(&user_button[KEY_U], PRESS_DOWN,       btn_1_cb);
  142.     button_attach(&user_button[KEY_U], PRESS_UP,         btn_1_cb);
  143.     button_attach(&user_button[KEY_U], PRESS_REPEAT,     btn_1_cb);
  144.     button_attach(&user_button[KEY_U], SINGLE_CLICK,     btn_1_cb);
  145.     button_attach(&user_button[KEY_U], DOUBLE_CLICK,     btn_1_cb);
  146.     button_attach(&user_button[KEY_U], LONG_RRESS_START, btn_1_cb);
  147.     button_attach(&user_button[KEY_U], LONG_PRESS_HOLD,  btn_1_cb);
  148.     button_start (&user_button[KEY_U]);

  149.     button_init  (&user_button[KEY_D], key_down_read, PIN_LOW);
  150.     button_attach(&user_button[KEY_D], PRESS_DOWN,       btn_2_cb);
  151.     button_attach(&user_button[KEY_D], PRESS_UP,         btn_2_cb);
  152.     button_attach(&user_button[KEY_D], PRESS_REPEAT,     btn_2_cb);
  153.     button_attach(&user_button[KEY_D], SINGLE_CLICK,     btn_2_cb);
  154.     button_attach(&user_button[KEY_D], DOUBLE_CLICK,     btn_2_cb);
  155.     button_attach(&user_button[KEY_D], LONG_RRESS_START, btn_2_cb);
  156.     button_attach(&user_button[KEY_D], LONG_PRESS_HOLD,  btn_2_cb);
  157.     button_start (&user_button[KEY_D]);

  158.     button_init  (&user_button[KEY_L], key_left_read, PIN_LOW);
  159.     button_attach(&user_button[KEY_L], PRESS_DOWN,       btn_3_cb);
  160.     button_attach(&user_button[KEY_L], PRESS_UP,         btn_3_cb);
  161.     button_attach(&user_button[KEY_L], PRESS_REPEAT,     btn_3_cb);
  162.     button_attach(&user_button[KEY_L], SINGLE_CLICK,     btn_3_cb);
  163.     button_attach(&user_button[KEY_L], DOUBLE_CLICK,     btn_3_cb);
  164.     button_attach(&user_button[KEY_L], LONG_RRESS_START, btn_3_cb);
  165.     button_attach(&user_button[KEY_L], LONG_PRESS_HOLD,  btn_3_cb);
  166.     button_start (&user_button[KEY_L]);

  167.     button_init  (&user_button[KEY_R], key_right_read, PIN_LOW);
  168.     button_attach(&user_button[KEY_R], PRESS_DOWN,       btn_4_cb);
  169.     button_attach(&user_button[KEY_R], PRESS_UP,         btn_4_cb);
  170.     button_attach(&user_button[KEY_R], PRESS_REPEAT,     btn_4_cb);
  171.     button_attach(&user_button[KEY_R], SINGLE_CLICK,     btn_4_cb);
  172.     button_attach(&user_button[KEY_R], DOUBLE_CLICK,     btn_4_cb);
  173.     button_attach(&user_button[KEY_R], LONG_RRESS_START, btn_4_cb);
  174.     button_attach(&user_button[KEY_R], LONG_PRESS_HOLD,  btn_4_cb);
  175.     button_start (&user_button[KEY_R]);

  176.     return 0;
  177. }

  178. #endif

天气获取代码
  1. /*
  2. * File      : httpclient.c
  3. *
  4. * Copyright (c) 2006-2018, RT-Thread Development Team
  5. *
  6. * SPDX-License-Identifier: Apache-2.0
  7. *
  8. * Change Logs:
  9. * Date             Author      Notes
  10. * 2018-07-20     flybreak     first version
  11. * 2018-09-05     flybreak     Upgrade API to webclient latest version
  12. */

  13. #include <rtthread.h>
  14. #include <rtdevice.h>
  15. #include <board.h>
  16. #include <dfs.h>
  17. #include <dfs_fs.h>

  18. #include <webclient.h>  /* 浣跨敤 HTTP 鍗忚涓庢湇鍔″櫒閫氫俊闇€瑕佸寘鍚澶存枃锟?? */
  19. #include <sys/socket.h> /* 浣跨敤BSD socket锛岄渶瑕佸寘鍚玸ocket.h澶存枃锟?? */
  20. #include <netdb.h>
  21. #include <cJSON.h>
  22. #include "shell.h"
  23. #include <finsh.h>



  24. #if     1
  25. #include "lcd_font.h"
  26. #include "tjpgd.h"

  27. #define GET_HEADER_BUFSZ        1024        //澶撮儴澶у皬
  28. #define GET_RESP_BUFSZ          1024        //鍝嶅簲缂撳啿鍖哄ぇ
  29. #define GET_URL_LEN_MAX         256         //缃戝潃鏈€澶ч暱
  30. #define GET_URI                 "http://api.seniverse.com/v3/weather/now.json?key=%s&location=%s&language=en&unit=c" //蹇冪煡澶╂皵 API
  31. #define AREA_NAME               "guangzhou" //骞垮窞 ID
  32. #define XINZHI_API_KEY          "SaFaa9knM7IHfV5kl"     //蹇冪煡澶╂皵璁よ瘉 pravite key

  33. /* 澶╂皵鏁版嵁瑙f瀽 */
  34. void weather_data_parse(rt_uint8_t *data)
  35. {
  36.     cJSON *root = RT_NULL, *object = RT_NULL, *item = RT_NULL;
  37.     cJSON *arrayItem = RT_NULL,*subobject = RT_NULL;
  38.     char str[32];

  39.     /* set the background color and foreground color */
  40.     lcd_fill(0,48,240,240,GBLUE);   
  41.     lcd_set_font_color(RED, GBLUE);
  42.    

  43.     root = cJSON_Parse((const char *)data);
  44.     if (!root)
  45.     {
  46.         rt_kprintf("\nNo memory for cJSON root!\n");
  47.         return;
  48.     }
  49.     if((arrayItem =  cJSON_GetObjectItem(root, "results")) != RT_NULL)
  50.     {
  51.         //int size = cJSON_GetArraySize(arrayItem);     //鑾峰彇鏁扮粍涓璞′釜 3
  52.         if((object = cJSON_GetArrayItem(arrayItem,0)) != RT_NULL)//鑾峰彇鐖跺璞″唴
  53.                 {
  54.             /* 鍖归厤瀛愬1 */
  55.                         if((subobject = cJSON_GetObjectItem(object,"location")) != RT_NULL)
  56.                         {
  57.                 item = cJSON_GetObjectItem(subobject, "name");
  58.                 rt_kprintf("\ncityName:%s \n", item->valuestring);

  59.                 lcd_set_font(&Font_CH40X40);
  60.                 lcd_disp_str_at(20, 48, "广州");

  61.             }
  62.             /* 鍖归厤瀛愬2 */
  63.             if((subobject = cJSON_GetObjectItem(object,"now")) != RT_NULL)
  64.                         {
  65.                 lcd_set_font(&Font_CH32X32);
  66.                 item = cJSON_GetObjectItem(subobject, "text");
  67.                 rt_kprintf("weather:%s \n", item->valuestring);
  68.                 lcd_disp_str_at(0, 168, item->valuestring);

  69.                 item = cJSON_GetObjectItem(subobject, "code");
  70.                 rt_kprintf("code:%s \n", item->valuestring);
  71.                 rt_snprintf(str,32,"/sd/weather120/%s.jpg",item->valuestring);
  72.                 Decode_Jpg(str,120,48);

  73.                 lcd_set_font(&Font_CH40X40);
  74.                 item = cJSON_GetObjectItem(subobject, "temperature");
  75.                 rt_kprintf("temperature:%s \n", item->valuestring);
  76.                 rt_snprintf(str,32,"%s℃",item->valuestring);
  77.                 lcd_disp_str_at(20, 128, str);

  78.             }
  79.             /* 鍖归厤瀛愬3 */
  80.             if((subobject = cJSON_GetObjectItem(object,"last_update")) != RT_NULL)
  81.                         {
  82.                 lcd_set_font(&Font_CH16X16);
  83.                 lcd_disp_str_at(0, 200, "更新时间:");

  84.                 rt_kprintf("time:%s \n", subobject->valuestring);
  85.                 rt_memcpy(str,subobject->valuestring,19);
  86.                 str[10] = 0x20;
  87.                 str[19] = 0;
  88.                 lcd_set_font(&Font_CH24X24);
  89.                 lcd_disp_str_at(0, 216, str);
  90.             }
  91.         }
  92.     }

  93.     if (root != RT_NULL)
  94.         cJSON_Delete(root);
  95. }

  96. void weather(int argc, char **argv)
  97. {
  98.     rt_uint8_t *buffer = RT_NULL;
  99.     int resp_status;
  100.     struct webclient_session *session = RT_NULL;
  101.     char *weather_url = RT_NULL;
  102.     int content_length = -1, bytes_read = 0;
  103.     int content_pos = 0;

  104.     /*  weather_url 鍒嗛厤绌洪棿 */
  105.     weather_url = rt_calloc(1, GET_URL_LEN_MAX);
  106.     if (weather_url == RT_NULL)
  107.     {
  108.         rt_kprintf("No memory for weather_url!\n");
  109.         goto __exit;
  110.     }

  111.     /* 鎷兼帴 GET 缃戝潃 */   
  112.     if(argc > 1)
  113.     {
  114.         rt_snprintf(weather_url, GET_URL_LEN_MAX, GET_URI,XINZHI_API_KEY, argv[1]);   
  115.     }else
  116.     {
  117.         rt_snprintf(weather_url, GET_URL_LEN_MAX, GET_URI,XINZHI_API_KEY, AREA_NAME);        
  118.     }
  119.     rt_kprintf(weather_url);

  120.     /* 鍒涘缓浼氳瘽骞朵笖璁剧疆鍝嶅簲鐨勫ぇ */
  121.     session = webclient_session_create(GET_HEADER_BUFSZ);
  122.     if (session == RT_NULL)
  123.     {
  124.         rt_kprintf("No memory for get header!\n");
  125.         goto __exit;
  126.     }

  127.     /* 锟?? GET 璇锋眰浣跨敤榛樿鐨勫ご */
  128.     if ((resp_status = webclient_get(session, weather_url)) != 200)
  129.     {
  130.         rt_kprintf("webclient GET request failed, response(%d) error.\n", resp_status);

  131.         lcd_set_font_color(RED, GBLUE);
  132.         lcd_set_font(&Font_CH40X40);
  133.         lcd_disp_str_at(0, 100, " WIFI未连接 ");
  134.         lcd_disp_str_at(0, 140, "请先连接WIFI");
  135.         goto __exit;
  136.     }

  137.     /* 鍒嗛厤鐢ㄤ簬瀛樻斁鎺ユ敹鏁版嵁鐨勭紦 */
  138.     buffer = rt_calloc(1, GET_RESP_BUFSZ);
  139.     if (buffer == RT_NULL)
  140.     {
  141.         rt_kprintf("No memory for data receive buffer!\n");
  142.         goto __exit;
  143.     }

  144.     content_length = webclient_content_length_get(session);
  145.     if (content_length < 0)
  146.     {
  147.         /* 杩斿洖鐨勬暟鎹槸鍒嗗潡浼犺緭. */
  148.         do
  149.         {
  150.             bytes_read = webclient_read(session, buffer, GET_RESP_BUFSZ);
  151.             if (bytes_read <= 0)
  152.             {
  153.                 break;
  154.             }
  155.         }while (1);
  156.     }
  157.     else
  158.     {
  159.         do
  160.         {
  161.             bytes_read = webclient_read(session, buffer,
  162.                                         content_length - content_pos > GET_RESP_BUFSZ ?
  163.                                         GET_RESP_BUFSZ : content_length - content_pos);
  164.             if (bytes_read <= 0)
  165.             {
  166.                 break;
  167.             }
  168.             content_pos += bytes_read;
  169.         }while (content_pos < content_length);
  170.     }

  171.     /* 澶╂皵鏁版嵁瑙f瀽 */
  172.     weather_data_parse(buffer);

  173. __exit:
  174.     /* 閲婃斁缃戝潃绌洪棿 */
  175.     if (weather_url != RT_NULL)
  176.         rt_free(weather_url);
  177.     /* 鍏抽棴浼氳瘽 */
  178.     if (session != RT_NULL)
  179.         webclient_close(session);
  180.     /* 閲婃斁缂撳啿鍖虹┖ */
  181.     if (buffer != RT_NULL)
  182.         rt_free(buffer);
  183. }

  184. MSH_CMD_EXPORT(weather, Get weather by webclient);

  185. #endif

视屏监控
  1. /*
  2. 本例程实现摄像头拍摄图片解码后显示到 LCD 屏上
  3. */
  4. #include <time.h>
  5. #include <string.h>
  6. #include "rtthread.h"
  7. #include "include.h"

  8. #include "app_demo_softap.h"
  9. #include "video_transfer.h"

  10. #include <sys/socket.h>
  11. #include "netdb.h"
  12. #include "lwip/netif.h"

  13. //添加图片解码的头文件
  14. #include "lcd_font.h"
  15. #include "tjpgd.h"

  16. //添加文件操作使用需要的头文�?
  17. #include <dfs_posix.h>

  18. static char* boundary_data = RT_NULL;
  19. static   rt_thread_t  photo_tid1 = RT_NULL;
  20. static const char resp_header[] =
  21. "HTTP/1.1 200 OK\r\n"
  22. "Content-Type: multipart/x-mixed-replace; boundary=------Boundary-------\r\n\r\n";


  23. void UserGetCurTime(struct tm *tm_new)
  24. {
  25.     time_t now;
  26.     struct tm *p_tm;
  27.     /* get current time */
  28.     now = time(RT_NULL);
  29.     /* lock scheduler. */
  30.     rt_enter_critical();
  31.     /* converts calendar time time into local time. */
  32.     p_tm = localtime(&now);
  33.     /* copy the statically located variable */
  34.      memcpy(tm_new, p_tm, sizeof(struct tm));
  35.     /* unlock scheduler. */
  36.     rt_exit_critical();
  37. }

  38. #if 0
  39. static void hexdump(const rt_uint8_t *p, rt_size_t len)
  40. {
  41.     unsigned char *buf = (unsigned char*)p;
  42.     int i, j;
  43.    
  44.     rt_kprintf("Dump 0x%.8x %dBytes\n", (int)p, len);
  45.     rt_kprintf("Offset    0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F\n");

  46.     for (i=0; i<len; i+=16)
  47.     {
  48.         rt_kprintf("%08X: ", i+(int)p);

  49.         for (j=0; j<16; j++)
  50.         {
  51.             if (i+j < len)
  52.             {
  53.                 rt_kprintf("%02X ", buf[i+j]);
  54.             }
  55.             else
  56.             {
  57.                 rt_kprintf("   ");
  58.             }
  59.         }
  60.         rt_kprintf(" ");

  61.         for (j=0; j<16; j++)
  62.         {
  63.             if (i+j < len)
  64.             {
  65.                 rt_kprintf("%c", ((unsigned int)((buf[i+j]) - ' ') < 127u - ' ') ? buf[i+j] : '.');
  66.             }
  67.         }
  68.         rt_kprintf("\n");
  69.     }
  70. }
  71. #endif


  72. // 创建 mjpeg 会话的结构体
  73. static struct mjpeg_session
  74. {
  75.     int sock;
  76.     int connected;
  77.     char* buf;
  78.     int total_len;
  79.     int last_frame_id;
  80.     int recv_frame_flag;
  81.     rt_tick_t old_tick;
  82.     rt_event_t event;
  83.     TVIDEO_SETUP_DESC_ST setup;
  84. };
  85. //初始�?
  86. static struct mjpeg_session session = {0};

  87. static void camera_start(void);


  88. //定义一帧图片的大小
  89. #define SEND_FRAME_EVENT             (1 << 0)
  90. #define SEND_FRAME_COMPLETE         (1 << 1)
  91. #define CLIENT_CONNECT          (1 << 2)
  92. #define PORT                    (5000)

  93. static void get_ip(char* buf)
  94. {
  95.     rt_ubase_t index;
  96.     struct netif * netif;

  97.     rt_enter_critical();
  98.     netif = netif_list;

  99.     while(netif != RT_NULL)
  100.     {
  101.         if(netif->flags & NETIF_FLAG_LINK_UP)
  102.         {
  103.             rt_kprintf("ip address: %s\n", ipaddr_ntoa(&(netif->ip_addr)));
  104.             memcpy(buf, ipaddr_ntoa(&(netif->ip_addr)), 16);
  105.         }
  106.         netif = netif->next;
  107.     }
  108.     rt_exit_critical();
  109. }

  110. static void tcpserv(void *parameter)
  111. {
  112.     char *recv_data;                    
  113.     socklen_t sin_size;
  114.     struct sockaddr_in server_addr, client_addr;
  115.     int ret;
  116.     char ip[20] = {0};

  117.     if((session.sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
  118.     {
  119.         rt_kprintf("socket error\n");
  120.         goto __exit;
  121.     }

  122.     server_addr.sin_family = AF_INET;
  123.     server_addr.sin_port = htons(PORT);
  124.     server_addr.sin_addr.s_addr = INADDR_ANY;
  125.     rt_memset(&(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero));

  126.     if(bind(session.sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1)
  127.     {
  128.         rt_kprintf("unable to bind\n");
  129.         goto __exit;
  130.     }

  131.     if(listen(session.sock, 5) == -1)
  132.     {
  133.         rt_kprintf("listen error\n");
  134.         goto __exit;
  135.     }

  136.     get_ip(ip);
  137.     rt_kprintf("\nTCPServer Waiting for client on %s:%d...\n", ip, PORT);
  138.     session.connected = -1;

  139.     while(1)
  140.     {
  141.         sin_size = sizeof(struct sockaddr_in);
  142.         session.connected = accept(session.sock, (struct sockaddr *)&client_addr, &sin_size);

  143.         if(session.connected < 0)
  144.         {
  145.             rt_kprintf("accept connection failed! errno = %d\n", errno);
  146.             goto __exit;
  147.         }

  148.         rt_kprintf("I got a connection from (%s , %d)\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));

  149.         send(session.connected, resp_header, strlen(resp_header), 0);

  150.                 rt_event_send(session.event, CLIENT_CONNECT);
  151.     }

  152. __exit:
  153.     if(session.sock >= 0)
  154.     {
  155.         closesocket(session.sock);
  156.         session.sock = -1;
  157.     }
  158.         rt_kprintf("exit tcp server thread\n");
  159.     return ;
  160. }



  161. static void start_cb(void)
  162. {
  163.     rt_kprintf("start cb\n");
  164. }

  165. static void stop_cb(void)
  166. {
  167.     rt_kprintf("stop cb\n");
  168. }

  169. static void pkt_header_cb(TV_HDR_PARAM_PTR param)
  170. {
  171.     HDR_PTR elem_tvhdr = (HDR_PTR)param->ptk_ptr;

  172.     elem_tvhdr->id = (UINT8)param->frame_id;
  173.     elem_tvhdr->is_eof = param->is_eof;
  174.     elem_tvhdr->pkt_cnt = param->frame_len;
  175.     elem_tvhdr->size = 0;
  176. }

  177. static int tvideo_capture_cb(UINT8 *data, UINT32 pos, UINT32 len, UINT8 is_stop)
  178. {
  179.     rt_err_t ret = 0;
  180.         int temp = 0;

  181.     session.total_len = 0;
  182.     session.buf = data;
  183.     session.total_len += len;

  184.     rt_event_send(session.event, SEND_FRAME_EVENT);
  185.     return len;
  186. }

  187. static rt_uint8_t is_start = 0;
  188. static void camera_start(void)
  189. {
  190.     if(is_start == 1)
  191.     {
  192.         rt_kprintf("camera is already start\n");
  193.         return;
  194.     }

  195.     session.setup.send_type = TVIDEO_SND_INTF;
  196.     session.setup.send_func = tvideo_capture_cb;
  197.     session.setup.start_cb = NULL;
  198.     session.setup.end_cb = NULL;

  199.     session.setup.pkt_header_size = sizeof(HDR_ST);
  200.     session.setup.add_pkt_header = pkt_header_cb;

  201.     video_transfer_init(&session.setup);

  202.     is_start = 1;
  203. }

  204. static int start_flag = false;
  205. static int save_file_flag = false;

  206. static void showphoto_thread(void* param)
  207. {
  208.     rt_thread_t tid1;
  209.     rt_err_t   err;
  210.     uint32_t   evt;
  211.     int ret;
  212.     uint8_t  connect_ok = 0;

  213.     boundary_data = rt_malloc(1024);
  214.         if(boundary_data == RT_NULL)
  215.         {
  216.                 rt_kprintf("malloc boundary_data failed\n");
  217.                 goto __exit;
  218.         }

  219.     session.event = rt_event_create("vt_event", RT_IPC_FLAG_FIFO);

  220.     tid1 = rt_thread_create("tcpsrv", tcpserv, RT_NULL, 1024*4, 10, 10);
  221.     if(tid1 != RT_NULL)
  222.     {
  223.         rt_thread_startup(tid1);
  224.     }   
  225.     camera_start();

  226.     while(1)
  227.     {
  228.         tvideo_capture(1);
  229.         rt_event_recv(session.event, SEND_FRAME_EVENT, RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, RT_WAITING_FOREVER, &evt);
  230.         
  231.         if(connect_ok == 0)
  232.         {
  233.             err =   rt_event_recv(session.event, CLIENT_CONNECT, RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, RT_WAITING_NO, &evt);
  234.             if(err == RT_EOK)
  235.             {
  236.                 connect_ok = 1;
  237.             }
  238.         }
  239.         if((connect_ok) &&(session.connected >= 0))
  240.         {            
  241.             // rt_kprintf("send data\n");
  242.             rt_memset(boundary_data, 0x0, 1024);
  243.             ret = rt_sprintf(boundary_data, "------Boundary-------\r\nContent-Type: image/jpeg\r\nContent-Length: %d\r\n\r\n", session.total_len);
  244.             // rt_kprintf("pic len : %d\n", session.total_len);
  245.             ret = send(session.connected, boundary_data, ret, 0);
  246.             // hexdump(session.buf, 16);
  247.             ret = send(session.connected, session.buf, session.total_len, 0);
  248.             if(ret <= 0)
  249.             {
  250.                 if(session.connected >= 0) closesocket(session.connected);
  251.                 session.connected = -1;
  252.             }
  253.             session.old_tick = rt_tick_get();
  254.             session.total_len = 0;
  255.         }

  256.         if(start_flag)
  257.         {
  258.             ret = mjpeg_decoder_jpeg(session.buf,40,120);
  259.             rt_kprintf("mjpeg_dec res = %d\n", ret);
  260.         }

  261.         if(save_file_flag)
  262.         {
  263.             //save *.jpg file
  264.             char file_name[128] = {0};        
  265.             char timestr[64]={0};   
  266.             int fd, res;
  267.             struct tm tm_new;

  268.             UserGetCurTime(&tm_new);
  269.             rt_sprintf(timestr, "%d_%d_%d-%d_%d_%d",tm_new.tm_year+1900,
  270.                                                         tm_new.tm_mon+1,
  271.                                                         tm_new.tm_mday,
  272.                                                         tm_new.tm_hour,
  273.                                                         tm_new.tm_min,
  274.                                                         tm_new.tm_sec);
  275.             rt_sprintf(file_name, "/sd/video/%s.jpg",timestr);
  276.             rt_kprintf("filename = %s \n", file_name);
  277.             fd = open(file_name, O_WRONLY | O_CREAT);
  278.             if (fd >= 0)
  279.             {
  280.                 write(fd, session.buf, session.total_len);
  281.                 close(fd);
  282.                 rt_kprintf("save %s ok!!!\n", file_name);
  283.                 lcd_set_font(&Font_CH16X16);
  284.                 lcd_set_font_color(BRED,GBLUE);
  285.                 lcd_disp_str_at(0,64,"Save OK  ");
  286.             }
  287.             else
  288.             {
  289.                 rt_kprintf("save pic failed!!!\n");
  290.                 lcd_set_font(&Font_CH16X16);
  291.                 lcd_set_font_color(BRED,GBLUE);
  292.                 lcd_disp_str_at(0,64,"Save Fail");
  293.             }
  294.             save_file_flag = false;
  295.         }
  296.         tvideo_capture(0);

  297.         //if(session.connected < 0)    break;
  298.     }  
  299.     rt_kprintf("showphoto_thread exit out!\n");  
  300.     //video_transfer_deinit();

  301. __exit:
  302.         if(session.buf != RT_NULL) rt_free(session.buf);
  303.         if(boundary_data != RT_NULL) rt_free(boundary_data);
  304.     is_start = 0;
  305.     photo_tid1 = RT_NULL;
  306.     return;   

  307. }
  308. void start_photo(void)
  309. {
  310.     char str[64] = {0};
  311.     char ip[20] = {0};

  312.     start_flag = true;
  313.     get_ip(ip);
  314.     rt_snprintf(str,64,"http://%s:%d",ip,PORT);

  315.     lcd_set_font(&Font_CH16X16);
  316.     lcd_set_font_color(BRED,GBLUE);
  317.     lcd_disp_str_at(0,48,&str[7]);

  318.     lcd_show_qrcode(168,48,4,2,str,2);  //qr

  319. }
  320. void stop_photo(void)
  321. {
  322.     start_flag = false;
  323. }
  324. void save_photo(void)
  325. {
  326.     save_file_flag = true;
  327. }
  328. MSH_CMD_EXPORT(start_photo,start_photo);
  329. MSH_CMD_EXPORT(stop_photo, stop_photo);
  330. MSH_CMD_EXPORT(save_photo, save_photo);


  331. void show_photo_test(void)
  332. {
  333.     if(photo_tid1 == RT_NULL)
  334.     {
  335.         photo_tid1 = rt_thread_create("showphoto_thread", showphoto_thread, RT_NULL, 1024*4, 10, 10);
  336.         if(photo_tid1 != RT_NULL)
  337.             rt_thread_startup(photo_tid1);        
  338.     }
  339.     start_photo();
  340. }

  341. MSH_CMD_EXPORT(show_photo_test,show camera photo);








本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
 楼主| WoodData 发表于 2020-6-14 15:02 | 显示全部楼层


终于搞定了LCD和网页同时显示了。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
ly87802541 发表于 2020-6-17 13:24 | 显示全部楼层
很牛X,可视门铃鸭
hu9jj 发表于 2020-6-18 19:15 | 显示全部楼层
好思路,学习了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

127

主题

4784

帖子

28

粉丝
快速回复 在线客服 返回列表 返回顶部