数码之家

 找回密码
 立即注册
搜索
查看: 6416|回复: 54

[Arduino] 墨迹空气果AirNutFun ESP8266主板开源软硬件

[复制链接]
发表于 2021-11-11 20:22:06 | 显示全部楼层 |阅读模式

爱科技、爱创意、爱折腾、爱极致,我们都是技术控

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

x
本帖最后由 胡奚曷 于 2021-11-12 18:20 编辑

1.前言
鉴于空气果AirNutFun没有热度了,这里特地开源一下软件和硬件希望能帮助有需要的人,主要是害怕商家涨价,抱歉没有及时开源
接上个帖子:10块包邮的墨迹空气果fun换主板,ESP8266接入blinker APP,联网对时显示天气
https://www.mydigit.cn/thread-280524-1-1.html
(出处: 数码之家)

2.功能
1.实现时间显示,基于DS3231,7天对时一次,单击按键对时,上电对时,时区为东八区
2.实现天气显示,每2小时更新一次
3.实现自带触摸功能,单击显示日期3s
4.双击按键启用、关闭wifi
5.可以显示WiFi强度
6.背光亮度0~100调整
7.定时采集PM2.5,0~100分钟可调
8.采集PM2.5时ogo闪烁
9.app上可以显示温度、湿度、PM2.5和曲线,可以设定亮度和PM2.5定时
10.长按3s可以重新配网,配网使用web
11.支持web OTA

3.代码文件结构
未命名1636625676.png
4.代码
AirNutFun.ino
  1. #include "Blwifi.h"
  2. #include "Task.h"
  3. #include "Display.h"
  4. #include "SHT20.h"

  5. void setup()
  6. {
  7.   Serial.begin(9600);

  8.   Display_Init();
  9.   Blwifi_Init();
  10.   Task_Creat(500, Display_DateTime_Task500ms);
  11.   Task_Creat(100, Blwifi_Ds3231_Task100ms);
  12.   Task_Creat(100, SHT20_Task);
  13. }

  14. void loop()
  15. {
  16.   Blwifi_Loop();
  17.   Task_Loop();
  18.   Display_Loop();
  19. }
复制代码
ANF_Lcd.c
  1. /**
  2. * @file ANF_Lcd.C
  3. * [url=home.php?mod=space&uid=650075]@brief[/url] Airnut fun LCD Display User Interface
  4. * [url=home.php?mod=space&uid=2115719]@author[/url] Hu Xihe
  5. * [url=home.php?mod=space&uid=1360894]@copyright[/url] All rights reserved.
  6. */
  7. #include "ANF_Lcd.h"

  8. /**
  9. *  @brief LCD display RAM
  10. */
  11. unsigned char LCD_Ram[16] =
  12. {
  13.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  14. };

  15. /**
  16.   *  @brief LCD Temperature 8-Seg.
  17.   *  @param[in]  addr: slave address
  18.   *              data: as byte
  19.   *  @param[out]  none.
  20.   *  @return none.
  21.   */
  22. static void IIC_WriteByte(unsigned char addr, unsigned char data)
  23. {
  24.     unsigned char buffer[1];
  25.     buffer[0] = data;
  26.     IIC_WriteData(addr, buffer, 1);   
  27. }

  28. /**
  29.   *  @brief LCD Temperature 8-Seg.
  30.   *  @param[in]  ind1: index of ram1
  31.   *              ind2: index of ram2
  32.   *              num: value 0~9, 10 = ' ', 11 = '-'
  33.   *  @param[out]  none.
  34.   *  @return none.
  35.   */
  36. static void Temp_Seg8(unsigned char ind1, unsigned char ind2, unsigned char num)
  37. {
  38.     const unsigned char seg1[]=
  39.     {
  40.         0x0F, 0x00, 0x0D, 0x09, 0x02, 0x0B, 0x0F, 0x01, 0x0F,0x0B
  41.     };
  42.     const unsigned char seg2[]=
  43.     {
  44.         0x50, 0x50, 0x30, 0x70, 0x70, 0x60, 0x60, 0x50, 0x70, 0x70
  45.     };
  46.    
  47.     if(ind1 < 16 && ind2 < 16)
  48.     {
  49.         LCD_Ram[ind1] &= ~(seg1[8]);
  50.         LCD_Ram[ind2] &= ~(seg2[8]);
  51.         
  52.         if(num < 10)
  53.         {
  54.             LCD_Ram[ind1] |= seg1[num];
  55.             LCD_Ram[ind2] |= seg2[num];  
  56.         }
  57.         else if(num == 11) // display '-'
  58.         {
  59.             LCD_Ram[ind2] = 0x20;
  60.         }
  61.     }
  62. }

  63. /**
  64.   *  @brief Pm25 and Humidity 8-Seg.
  65.   *  @param[in]  ind1: index of ram1
  66.   *              ind2: index of ram2
  67.   *              num: value 0~9, 10 = ' '
  68.   *  @param[out]  none.
  69.   *  @return none.
  70.   */
  71. static void Pm25_Seg8(unsigned char ind1, unsigned char ind2, unsigned char num)
  72. {
  73.     const unsigned char seg1[]=
  74.     {
  75.         0xF0, 0x00, 0xD0, 0x90, 0x20, 0xB0, 0xF0, 0x10, 0xF0, 0xB0
  76.     };
  77.     const unsigned char seg2[]=
  78.     {
  79.         0x05, 0x05, 0x03, 0x07, 0x07, 0x06, 0x06, 0x05, 0x07, 0x07
  80.     };
  81.    
  82.     if(ind1 < 16 && ind2 < 16)
  83.     {
  84.         LCD_Ram[ind1] &= ~(seg1[8]);
  85.         LCD_Ram[ind2] &= ~(seg2[8]);
  86.         
  87.         if(num < 10)
  88.         {
  89.             LCD_Ram[ind1] |= seg1[num];
  90.             LCD_Ram[ind2] |= seg2[num];  
  91.         }
  92.     }
  93. }

  94. /**
  95.   *  @brief time hour 8-Seg.
  96.   *  @param[in]  ind1: index of ram1
  97.   *              ind2: index of ram2
  98.   *              num: value 0~9, 10 = ' '
  99.   *  @param[out]  none.
  100.   *  @return none.
  101.   */
  102. static void TimeHour_Seg8H(unsigned char ind1, unsigned char ind2, unsigned char num)
  103. {
  104.     const unsigned char seg1[]=
  105.     {
  106.         0xF0, 0x00, 0xB0, 0x90, 0x40, 0xD0, 0xF0, 0x80, 0xF0, 0xD0
  107.     };
  108.     const unsigned char seg2[]=
  109.     {
  110.         0x05, 0x05, 0x06, 0x07, 0x07, 0x03, 0x03, 0x05, 0x07, 0x07
  111.     };
  112.    
  113.     if(ind1 < 16 && ind2 < 16)
  114.     {
  115.         LCD_Ram[ind1] &= ~(seg1[8]);
  116.         LCD_Ram[ind2] &= ~(seg2[8]);
  117.         
  118.         if(num < 10)
  119.         {
  120.             LCD_Ram[ind1] |= seg1[num];
  121.             LCD_Ram[ind2] |= seg2[num];  
  122.         }
  123.     }
  124. }

  125. /**
  126.   *  @brief time hour 8-Seg.
  127.   *  @param[in]  ind1: index of ram1
  128.   *              ind2: index of ram2
  129.   *              num: value 0~9, 10 = ' '
  130.   *  @param[out]  none.
  131.   *  @return none.
  132.   */
  133. static void TimeHour_Seg8L(unsigned char ind1, unsigned char ind2, unsigned char num)
  134. {
  135.     const unsigned char seg1[]=
  136.     {
  137.         0xF0, 0x00, 0xB0, 0x90, 0x40, 0xD0, 0xF0, 0x80, 0xF0, 0xD0
  138.     };
  139.     const unsigned char seg2[]=
  140.     {
  141.         0x50, 0x50, 0x60, 0x70, 0x70, 0x30, 0x30, 0x50, 0x70, 0x70
  142.     };
  143.    
  144.     if(ind1 < 16 && ind2 < 16)
  145.     {
  146.         LCD_Ram[ind1] &= ~(seg1[8]);
  147.         LCD_Ram[ind2] &= ~(seg2[8]);
  148.         
  149.         if(num < 10)
  150.         {
  151.             LCD_Ram[ind1] |= seg1[num];
  152.             LCD_Ram[ind2] |= seg2[num];  
  153.         }
  154.     }
  155. }

  156. /**
  157.   *  @brief time minute 8-Seg.
  158.   *  @param[in]  ind1: index of ram1
  159.   *              ind2: index of ram2
  160.   *              num: value 0~9, 10 = ' '
  161.   *  @param[out]  none.
  162.   *  @return none.
  163.   */
  164. static void TimeMinute_Seg8(unsigned char ind1, unsigned char ind2, unsigned char num)
  165. {
  166.     const unsigned char seg1[]=
  167.     {
  168.         0x0F, 0x00, 0x0B, 0x09, 0x04, 0x0D, 0x0F, 0x08, 0x0F, 0x0D
  169.     };
  170.     const unsigned char seg2[]=
  171.     {
  172.         0x50, 0x50, 0x60, 0x70, 0x70, 0x30, 0x30, 0x50, 0x70, 0x70
  173.     };
  174.    
  175.     if(ind1 < 16 && ind2 < 16)
  176.     {
  177.         LCD_Ram[ind1] &= ~(seg1[8]);
  178.         LCD_Ram[ind2] &= ~(seg2[8]);
  179.         
  180.         if(num < 10)
  181.         {
  182.             LCD_Ram[ind1] |= seg1[num];
  183.             LCD_Ram[ind2] |= seg2[num];  
  184.         }
  185.     }
  186. }

  187. /**
  188.   *  @brief LCD airnut logo set.
  189.   *  @param[in]  st:0-NotDisplay 1-Display.
  190.   *  @param[out]  none.
  191.   *  @return none.
  192.   */
  193. void ANF_LcdAirNutLogo(unsigned char st)
  194. {
  195.     if(st == 0)
  196.         LCD_Ram[3] &= 0xF7;
  197.     else
  198.         LCD_Ram[3] |= 0x08;
  199. }

  200. /**
  201.   *  @brief LCD wifi logo set.
  202.   *  @param[in]  num as WIFI_DEF.
  203.   *  @param[out]  none.
  204.   *  @return none.
  205.   */
  206. void ANF_LcdWifi(WIFI_DEF num)
  207. {
  208.     unsigned char data[WIFI_COUNT] =
  209.     {
  210.         0x00,0x80,0xC0,0xE0,0xF0
  211.     };
  212.    
  213.     if(num < WIFI_COUNT)
  214.     {
  215.         LCD_Ram[1] &= 0x0F;
  216.         LCD_Ram[1] |= data[num];   
  217.     }
  218. }

  219. /**
  220.   *  @brief LCD separate line set.
  221.   *  @param[in]  st:0-NotDisplay 1-Display.
  222.   *  @param[out]  none.
  223.   *  @return none.
  224.   */
  225. void ANF_LcdSeparateLine(unsigned char st)
  226. {
  227.     if(st == 0)
  228.         LCD_Ram[4] &= 0xF7;
  229.     else
  230.         LCD_Ram[4] |= 0x08;
  231. }

  232. /**
  233.   *  @brief LCD battery set.
  234.   *  @param[in]  num as BATTERY_DEF.
  235.   *  @param[out]  none.
  236.   *  @return none.
  237.   */
  238. void ANF_LcdBattery(BATTERY_DEF num)
  239. {
  240.     unsigned char data[BAT_COUNT] =
  241.     {
  242.         0x00,0x08,0x09,0x0B,0x0F
  243.     };
  244.    
  245.     if(num < BAT_COUNT)
  246.     {
  247.         LCD_Ram[1] &= 0xF0;
  248.         LCD_Ram[1] |= data[num];   
  249.     }
  250. }

  251. /**
  252.   *  @brief LCD Time point set.
  253.   *  @param[in]  st:0-NotDisplay 1-Display.
  254.   *  @param[out]  none.
  255.   *  @return none.
  256.   */
  257. void ANF_LcdTimePoint(unsigned char st)
  258. {
  259.     if(st == 0)
  260.         LCD_Ram[15] &= 0x7F;
  261.     else
  262.         LCD_Ram[15] |= 0x80;   
  263. }

  264. /**
  265.   *  @brief LCD Time set.
  266.   *  @param[in]  hour, minute.
  267.   *  @param[out]  none.
  268.   *  @return none.
  269.   */
  270. void ANF_LcdTimeNumber(unsigned char hour, unsigned char minute)
  271. {
  272.     if(hour > 99)
  273.         hour = 99;
  274. #if 0
  275.     if(hour < 10)
  276.     {
  277.         TimeHour_Seg8H(2, 3, 10);
  278.         TimeHour_Seg8L(3, 15, (unsigned char)hour);
  279.     }
  280.     else
  281. #endif
  282.     {
  283.         TimeHour_Seg8H(2, 3, (unsigned char)(hour / 10));
  284.         TimeHour_Seg8L(3, 15, (unsigned char)(hour % 10));
  285.     }

  286.     if(minute > 99)
  287.         minute = 99;
  288. #if 0
  289.     if(minute < 10)
  290.     {
  291.         TimeMinute_Seg8(15, 14, 10);
  292.         TimeMinute_Seg8(14, 13, (unsigned char)minute);
  293.     }
  294.     else
  295. #endif
  296.     {
  297.         TimeMinute_Seg8(15, 14, (unsigned char)(minute / 10));
  298.         TimeMinute_Seg8(14, 13, (unsigned char)(minute % 10));
  299.     }
  300. }

  301. /**
  302.   *  @brief LCD PM2.5 Logo set.
  303.   *  @param[in]  st:0-NotDisplay 1-Display.
  304.   *  @param[out]  none.
  305.   *  @return none.
  306.   */
  307. void ANF_LcdPm25Logo(unsigned char st)
  308. {
  309.     if(st == 0)
  310.         LCD_Ram[10] &= 0xF7;
  311.     else
  312.         LCD_Ram[10] |= 0x08;   
  313. }

  314. /**
  315.   *  @brief LCD PM2.5 number set.
  316.   *  @param[in]  num:value
  317.   *  @param[out]  none.
  318.   *  @return none.
  319.   */
  320. void ANF_LcdPm25Number(short num)
  321. {
  322.     short tmp;
  323.     if(0 <= num)
  324.     {
  325.         if(num > 999)
  326.             num = 999;
  327.         if(num < 10)
  328.         {
  329.             Pm25_Seg8(8, 9, 10);
  330.             Pm25_Seg8(9, 10, 10);
  331.             Pm25_Seg8(10, 11, (unsigned char)num);
  332.         }
  333.         else if(num < 100)
  334.         {
  335.             Pm25_Seg8(8, 9, 10);
  336.             Pm25_Seg8(9, 10, (unsigned char)(num / 10));
  337.             Pm25_Seg8(10, 11, (unsigned char)(num % 10));
  338.         }
  339.         else
  340.         {
  341.             tmp = num;
  342.             Pm25_Seg8(8, 9, (unsigned char)(tmp / 100));
  343.             tmp %= 100;
  344.             Pm25_Seg8(9, 10, (unsigned char)(tmp / 10));
  345.             Pm25_Seg8(10, 11, (unsigned char)(tmp % 10));
  346.         }
  347.     }
  348. }

  349. /**
  350.   *  @brief LCD PM2.5 unit set.
  351.   *  @param[in]  st:0-NotDisplay 1-Display.
  352.   *  @param[out]  none.
  353.   *  @return none.
  354.   */
  355. void ANF_LcdPm25Unit(unsigned char st)
  356. {   
  357.     if(st == 0)
  358.         LCD_Ram[11] &= 0xF7;
  359.     else
  360.         LCD_Ram[11] |= 0x08;  
  361. }

  362. /**
  363.   *  @brief LCD Temperature Logo set.
  364.   *  @param[in]  st:0-NotDisplay 1-Display.
  365.   *  @param[out]  none.
  366.   *  @return none.
  367.   */
  368. void ANF_LcdTempLogo(unsigned char st)
  369. {
  370.     if(st == 0)
  371.         LCD_Ram[9] &= 0xF7;
  372.     else
  373.         LCD_Ram[9] |= 0x08;      
  374. }

  375. /**
  376.   *  @brief LCD Temperature number set.
  377.   *  @param[in]  num:value 10 factor of real value
  378.   *  @param[out]  none.
  379.   *  @return none.
  380.   */
  381. void ANF_LcdTempNumber(short num)
  382. {
  383.     short tmp;
  384.     if(num < 0)
  385.     {
  386.         Temp_Seg8(8, 7, 11);
  387.         
  388.         num = 0 - num;
  389.         if(num < 100)
  390.         {
  391.             Temp_Seg8(7, 6, (unsigned char)(num / 10));
  392.             Temp_Seg8(6, 5, (unsigned char)(num % 10));
  393.             LCD_Ram[6] |= 0x80;   
  394.         }
  395.         else
  396.         {
  397.             tmp = num / 10;
  398.             Temp_Seg8(7, 6, (unsigned char)(tmp / 10));
  399.             Temp_Seg8(6, 5, (unsigned char)(tmp % 10));
  400.             LCD_Ram[6] &= 0x7F;      
  401.         }
  402.     }
  403.     else
  404.     {
  405.         if(num < 100)
  406.         {
  407.             Temp_Seg8(8, 7, 10);
  408.             Temp_Seg8(7, 6, (unsigned char)num / 10);
  409.             Temp_Seg8(6, 5, (unsigned char)num % 10);
  410.             LCD_Ram[6] |= 0x80;   
  411.         }
  412.         else if(num < 1000)
  413.         {
  414.             tmp = num;
  415.             Temp_Seg8(8, 7, (unsigned char)(tmp / 100));
  416.             tmp %= 100;
  417.             Temp_Seg8(7, 6, (unsigned char)(tmp / 10));
  418.             Temp_Seg8(6, 5, (unsigned char)(tmp % 10));
  419.             LCD_Ram[6] |= 0x80;   
  420.         }
  421.         else
  422.         {
  423.             tmp = num / 10;
  424.             Temp_Seg8(8, 7, (unsigned char)(tmp / 100));
  425.             tmp %= 100;
  426.             Temp_Seg8(7, 6, (unsigned char)(tmp / 10));
  427.             Temp_Seg8(6, 5, (unsigned char)(tmp % 10));
  428.             LCD_Ram[6] &= 0x7F;      
  429.         }
  430.     }
  431. }

  432. /**
  433.   *  @brief LCD Temperature unit set.
  434.   *  @param[in]  st:0-NotDisplay 1-Display.
  435.   *  @param[out]  none.
  436.   *  @return none.
  437.   */
  438. void ANF_LcdTempUnit(unsigned char st)
  439. {
  440.     if(st == 0)
  441.         LCD_Ram[5] &= 0x7F;
  442.     else
  443.         LCD_Ram[5] |= 0x80;      
  444. }

  445. /**
  446.   *  @brief LCD Humidity Logo set.
  447.   *  @param[in]  st:0-NotDisplay 1-Display.
  448.   *  @param[out]  none.
  449.   *  @return none.
  450.   */
  451. void ANF_LcdHumidityLogo(unsigned char st)
  452. {
  453.     if(st == 0)
  454.         LCD_Ram[12] &= 0xF7;
  455.     else
  456.         LCD_Ram[12] |= 0x08;      
  457. }


  458. /**
  459.   *  @brief LCD Humidity number set.
  460.   *  @param[in]  num:value
  461.   *  @param[out]  none.
  462.   *  @return none.
  463.   */
  464. void ANF_LcdHumidityNumber(short num)
  465. {
  466.     if(0 <= num)
  467.     {
  468.         if(num > 99)
  469.             num = 99;
  470.         if(num < 10)
  471.         {
  472.             Pm25_Seg8(11, 12, 10);
  473.             Pm25_Seg8(12, 13, (unsigned char)num);
  474.         }
  475.         else
  476.         {
  477.             Pm25_Seg8(11, 12, (unsigned char)(num / 10));
  478.             Pm25_Seg8(12, 13, (unsigned char)(num % 10));
  479.         }
  480.     }
  481. }

  482. /**
  483.   *  @brief LCD Humidity unit set.
  484.   *  @param[in]  st:0-NotDisplay 1-Display.
  485.   *  @param[out]  none.
  486.   *  @return none.
  487.   */
  488. void ANF_LcdHumidityUnit(unsigned char st)
  489. {
  490.     if(st == 0)
  491.         LCD_Ram[13] &= 0xF7;
  492.     else
  493.         LCD_Ram[13] |= 0x08;      
  494. }

  495. /**
  496.   *  @brief LCD Weather set.
  497.   *  @param[in]  WEATHER_DEF.
  498.   *  @param[out]  none.
  499.   *  @return none.
  500.   */
  501. void ANF_LcdWeather(WEATHER_DEF st)
  502. {
  503.     if(st & WTHR_Sunny)
  504.         LCD_Ram[2] |= 0x08;
  505.     else
  506.         LCD_Ram[2] &= 0xF7;
  507.    
  508.     if(st & WTHR_Cloudy)
  509.         LCD_Ram[2] |= 0x04;
  510.     else
  511.         LCD_Ram[2] &= 0xFB;
  512.    
  513.     if(st & WTHR_Overcast)
  514.         LCD_Ram[2] |= 0x02;
  515.     else
  516.         LCD_Ram[2] &= 0xFD;
  517.    
  518.     if(st & WTHR_LightRain)
  519.         LCD_Ram[2] |= 0x01;
  520.     else
  521.         LCD_Ram[2] &= 0xFE;
  522.    
  523.     if(st & WTHR_ModerateRain)
  524.         LCD_Ram[4] |= 0x02;
  525.     else
  526.         LCD_Ram[4] &= 0xFD;
  527.    
  528.     if(st & WTHR_HeavyRain)
  529.         LCD_Ram[13] |= 0x80;
  530.     else
  531.         LCD_Ram[13] &= 0x7F;
  532.    
  533.     if(st & WTHR_Haze)
  534.         LCD_Ram[14] |= 0x80;
  535.     else
  536.         LCD_Ram[14] &= 0x7F;
  537.    
  538.     if(st & WTHR_Foggy)
  539.         LCD_Ram[4] |= 0x01;
  540.     else
  541.         LCD_Ram[4] &= 0xFE;
  542. }

  543. /**
  544.   *  @brief LCD Init.
  545.   *  @param[in] none.
  546.   *  @param[out]  none.
  547.   *  @return none.
  548.   */
  549. void ANF_LcdInit(void)
  550. {
  551.     IIC_WriteByte(0x7E,0x70);
  552.     IIC_WriteByte(0x7E,0xC0);
  553.     ANF_LcdClear();
  554.     ANF_LcdUpdate();
  555.     IIC_WriteByte(0x7E,0x8C);   
  556. }

  557. /**
  558.   *  @brief LCD update, IIC send data.
  559.   *  @param[in] none.
  560.   *  @param[out] none.
  561.   *  @return none.
  562.   */
  563. void ANF_LcdUpdate(void)
  564. {
  565.     IIC_WriteData(0x7E, LCD_Ram, 16);   
  566. }

  567. /**
  568.   *  @brief LCD clear.
  569.   *  @param[in] none.
  570.   *  @param[out]  none.
  571.   *  @return none.
  572.   */
  573. void ANF_LcdClear(void)
  574. {
  575.     int i;
  576.     for(i=0; i<16; i++)
  577.         LCD_Ram[i] = 0;     
  578. }

  579. /**
  580.   *  @brief LCD all display.
  581.   *  @param[in] none.
  582.   *  @param[out]  none.
  583.   *  @return none.
  584.   */
  585. void ANF_LcdAll(void)
  586. {
  587.     int i;
  588.     for(i=1; i<16; i++)
  589.         LCD_Ram[i] = 0xFF;      
  590. }
复制代码
ANF_Lcd.h
  1. /**
  2. * @file ANF_Lcd.h
  3. * @brief Airnut fun LCD Display User Interface
  4. * @author Hu Xihe
  5. * @copyright All rights reserved.
  6. */

  7. #ifndef __ANF_LCD_H__
  8. #define __ANF_LCD_H__
  9. #ifdef __cplusplus
  10. extern "C"{
  11. #endif

  12. /**
  13. *  @brief status type for weather
  14. */
  15. typedef enum
  16. {
  17.     WTHR_None           = 0x00,
  18.     WTHR_Sunny          = 0x01,
  19.     WTHR_Cloudy         = 0x02,
  20.     WTHR_Overcast       = 0x04,
  21.     WTHR_LightRain      = 0x08,
  22.     WTHR_ModerateRain   = 0x10,
  23.     WTHR_HeavyRain      = 0x20,
  24.     WTHR_Haze           = 0x40,
  25.     WTHR_Foggy          = 0x80,
  26.     WTHR_All            = 0xFF
  27. }WEATHER_DEF;

  28. /**
  29. *  @brief status type for battery
  30. */
  31. typedef enum
  32. {
  33.     BAT_None    = 0x00,
  34.     BAT_Zero    = 0x01,
  35.     BAT_Low     = 0x02,
  36.     BAT_Middle  = 0x03,
  37.     BAT_High    = 0x04,
  38.     BAT_COUNT
  39. }BATTERY_DEF;

  40. /**
  41. *  @brief status type for WIFI
  42. */
  43. typedef enum
  44. {
  45.     WIFI_None    = 0x00,
  46.     WIFI_Low     = 0x01,
  47.     WIFI_Middle  = 0x02,
  48.     WIFI_High    = 0x03,
  49.     WIFI_Full    = 0x04,
  50.     WIFI_COUNT
  51. }WIFI_DEF;

  52. /**
  53.   *  @brief IIC api
  54.   *  @param[in]  addr as slave address.
  55.   *              data[] as set value
  56.   *              length as data length
  57.   *  @param[out]  none.
  58.   *  @return none.
  59.   */
  60. extern void IIC_WriteData(unsigned char addr, unsigned char data[], unsigned char length);

  61. /**
  62.   *  @brief LCD airnut logo set.
  63.   *  @param[in]  st:0-NotDisplay 1-Display.
  64.   *  @param[out]  none.
  65.   *  @return none.
  66.   */
  67. void ANF_LcdAirNutLogo(unsigned char st);

  68. /**
  69.   *  @brief LCD wifi logo set.
  70.   *  @param[in]  num as WIFI_DEF.
  71.   *  @param[out]  none.
  72.   *  @return none.
  73.   */
  74. void ANF_LcdWifi(WIFI_DEF num);

  75. /**
  76.   *  @brief LCD separate line set.
  77.   *  @param[in]  st:0-NotDisplay 1-Display.
  78.   *  @param[out]  none.
  79.   *  @return none.
  80.   */
  81. void ANF_LcdSeparateLine(unsigned char st);

  82. /**
  83.   *  @brief LCD battery set.
  84.   *  @param[in]  BATTERY_DEF.
  85.   *  @param[out]  none.
  86.   *  @return none.
  87.   */
  88. void ANF_LcdBattery(BATTERY_DEF num);

  89. /**
  90.   *  @brief LCD Time point set.
  91.   *  @param[in]  st:0-NotDisplay 1-Display.
  92.   *  @param[out]  none.
  93.   *  @return none.
  94.   */
  95. void ANF_LcdTimePoint(unsigned char st);

  96. /**
  97.   *  @brief LCD Time set.
  98.   *  @param[in]  hour, minute.
  99.   *  @param[out]  none.
  100.   *  @return none.
  101.   */
  102. void ANF_LcdTimeNumber(unsigned char hour, unsigned char minute);

  103. /**
  104.   *  @brief LCD PM2.5 Logo set.
  105.   *  @param[in]  st:0-NotDisplay 1-Display.
  106.   *  @param[out]  none.
  107.   *  @return none.
  108.   */
  109. void ANF_LcdPm25Logo(unsigned char st);

  110. /**
  111.   *  @brief LCD PM2.5 number set.
  112.   *  @param[in]  num:value
  113.   *  @param[out]  none.
  114.   *  @return none.
  115.   */
  116. void ANF_LcdPm25Number(short num);

  117. /**
  118.   *  @brief LCD PM2.5 unit set.
  119.   *  @param[in]  st:0-NotDisplay 1-Display.
  120.   *  @param[out]  none.
  121.   *  @return none.
  122.   */
  123. void ANF_LcdPm25Unit(unsigned char st);

  124. /**
  125.   *  @brief LCD Temperature Logo set.
  126.   *  @param[in]  st:0-NotDisplay 1-Display.
  127.   *  @param[out]  none.
  128.   *  @return none.
  129.   */
  130. void ANF_LcdTempLogo(unsigned char st);

  131. /**
  132.   *  @brief LCD Temperature number set.
  133.   *  @param[in]  num:value
  134.   *  @param[out]  none.
  135.   *  @return none.
  136.   */
  137. void ANF_LcdTempNumber(short num);

  138. /**
  139.   *  @brief LCD Temperature unit set.
  140.   *  @param[in]  st:0-NotDisplay 1-Display.
  141.   *  @param[out]  none.
  142.   *  @return none.
  143.   */
  144. void ANF_LcdTempUnit(unsigned char st);

  145. /**
  146.   *  @brief LCD Humidity Logo set.
  147.   *  @param[in]  st:0-NotDisplay 1-Display.
  148.   *  @param[out]  none.
  149.   *  @return none.
  150.   */
  151. void ANF_LcdHumidityLogo(unsigned char st);

  152. /**
  153.   *  @brief LCD Humidity number set.
  154.   *  @param[in]  num:value
  155.   *  @param[out]  none.
  156.   *  @return none.
  157.   */
  158. void ANF_LcdHumidityNumber(short num);

  159. /**
  160.   *  @brief LCD Humidity unit set.
  161.   *  @param[in]  st:0-NotDisplay 1-Display.
  162.   *  @param[out]  none.
  163.   *  @return none.
  164.   */
  165. void ANF_LcdHumidityUnit(unsigned char st);

  166. /**
  167.   *  @brief LCD Weather set.
  168.   *  @param[in]  WEATHER_DEF.
  169.   *  @param[out]  none.
  170.   *  @return none.
  171.   */
  172. void ANF_LcdWeather(WEATHER_DEF st);

  173. /**
  174.   *  @brief LCD Init.
  175.   *  @param[in] none.
  176.   *  @param[out]  none.
  177.   *  @return none.
  178.   */
  179. void ANF_LcdInit(void);

  180. /**
  181.   *  @brief LCD update, IIC send data.
  182.   *  @param[in] none.
  183.   *  @param[out] none.
  184.   *  @return none.
  185.   */
  186. void ANF_LcdUpdate(void);

  187. /**
  188.   *  @brief LCD clear.
  189.   *  @param[in] none.
  190.   *  @param[out]  none.
  191.   *  @return none.
  192.   */
  193. void ANF_LcdClear(void);

  194. /**
  195.   *  @brief LCD all display.
  196.   *  @param[in] none.
  197.   *  @param[out]  none.
  198.   *  @return none.
  199.   */
  200. void ANF_LcdAll(void);

  201. #ifdef __cplusplus
  202. }

  203. #endif
  204. #endif /*end of __ANF_LCD_H__*/
复制代码
Blwifi.cpp
  1. /**
  2. * @file Blwifi.cpp
  3. * @brief wifi config
  4. * @author Hu Xihe
  5. * @copyright All rights reserved.
  6. */
  7. #define BLINKER_WIFI
  8. #define BLINKER_MIOT_OUTLET

  9. #include <WiFiManager.h>
  10. #include <Blinker.h>
  11. #include <ESP8266WebServer.h>
  12. #include <ESP8266mDNS.h>
  13. #include <ESP8266HTTPUpdateServer.h>
  14. #include <EEPROM.h>
  15. #include "GpioButton.h"
  16. #include "Blwifi.h"
  17. #include "Display.h"
  18. #include "DS3231SN.h"
  19. #include "ANF_Lcd.h"

  20. WiFiManager wifiManager;

  21. bool shouldSaveConfig=false;
  22. Settings wifiSettings;

  23. ESP8266WebServer httpServer(80);
  24. ESP8266HTTPUpdateServer httpUpdater;
  25. const char* host = "AirNutFunUpdate";

  26. // 定义按钮对象,指定按钮的GPIO口
  27. GpioButton myButton(RESET_WIFI_PIN);

  28. uint8_t setDs3231 = 0;
  29. /**
  30.   *  @brief set ds3231 by net time
  31.   *  @param[in]  none.
  32.   *  @param[out]  none.
  33.   *  @return none.
  34.   */
  35. static uint8_t Set_Ds3231(void)
  36. {
  37.   uint8_t ret;
  38.   if(0<= Blinker.hour() && Blinker.hour() < 24  && wifiSettings.UseWifi == WIFI_CONNECT)
  39.   {
  40.     Ds3231_SetDate(Blinker.year()%100, Blinker.month(), Blinker.mday());
  41.     Ds3231_SetTime(Blinker.hour(), Blinker.minute(), Blinker.second());
  42.     ret = 1;
  43.   }
  44.   else
  45.     ret = 0;
  46.   return ret;
  47. }

  48. /**
  49.   *  @brief to reset wifi information.
  50.   *  @param[in]  none.
  51.   *  @param[out]  none.
  52.   *  @return none.
  53.   */
  54. static void Wifi_Reset(void)
  55. {
  56.   Display_WifiFlash(3);

  57.   EEPROM.begin(4096);
  58.   EEPROM.get<Settings>(2448, wifiSettings);
  59.   wifiSettings.auth_key[0]='\0';
  60.   EEPROM.put<Settings>(2448, wifiSettings);
  61.   if (EEPROM.commit())
  62.   {
  63.     Serial.println(F("EEPROM successfully committed"));
  64.   }
  65.   else
  66.   {
  67.     Serial.println(F("ERROR! EEPROM commit failed"));
  68.   }
  69.   EEPROM.end();

  70.   wifiManager.resetSettings();
  71.   ESP.restart();
  72. }

  73. /**
  74.   *  @brief to set wifi saved infor.
  75.   *  @param[in]  st as WIFI_SET_ST.
  76.   *  @param[out]  none.
  77.   *  @return none.
  78.   */
  79. static void Wifi_OnOffSet(WIFI_SET_ST st)
  80. {
  81.     EEPROM.begin(4096);
  82.     EEPROM.get<Settings>(2448, wifiSettings);
  83.     wifiSettings.UseWifi = st;
  84.     EEPROM.put<Settings>(2448, wifiSettings);
  85.     if (EEPROM.commit())
  86.     {
  87.         Serial.println(F("EEPROM successfully committed"));
  88.     }
  89.     else
  90.     {
  91.         Serial.println(F("ERROR! EEPROM commit failed"));
  92.     }
  93.     EEPROM.end();
  94. }

  95. /**
  96.   *  @brief my button init.
  97.   *  @param[in]  none.
  98.   *  @param[out]  none.
  99.   *  @return none.
  100.   */
  101. static void MyButton_Init()
  102. {
  103.   // 绑定按钮事件处理
  104.   myButton.BindBtnPress([](){
  105.       Serial.println(F("Time sync."));
  106.       Set_Ds3231();
  107.   });

  108.   // 绑定按钮事件处理
  109.   myButton.BindBtnDblPress([](){
  110.     if(wifiSettings.UseWifi != WIFI_ST_OFF)
  111.     {
  112.         Serial.println(F("WiFi Off."));
  113.         Wifi_OnOffSet(WIFI_ST_OFF);
  114.         ESP.restart();
  115.     }
  116.     else
  117.     {
  118.         Serial.println(F("WiFi On."));
  119.         Wifi_OnOffSet(WIFI_WAIT_CONFIG);
  120.         ESP.restart();
  121.     }
  122.   });

  123.   // 绑定长按事件处理(长按判定为3000ms)
  124.   myButton.BindBtnLongPress([]()
  125.   {
  126.     Serial.println(F("WiFi resetSettings."));
  127.     Wifi_Reset();
  128.   }, 3000);
  129. }

  130. /**
  131.   *  @brief wifi save call back.
  132.   *  @param[in]  none.
  133.   *  @param[out]  none.
  134.   *  @return none.
  135.   */
  136. static void saveConfigCallback(void)
  137. {
  138.   Serial.println("Should save config");
  139.   shouldSaveConfig = true;
  140. }

  141. /**
  142.   *  @brief to check the author key.
  143.   *  @param[in]  key as char*
  144.   *              len as int.
  145.   *  @param[out]  none.
  146.   *  @return none.
  147.   */
  148. static bool chkAuthkey(char* key, int len)
  149. {
  150.   if (len != 12) return false;
  151.   for (int i=0;key[i]!=0;i++){
  152.     if (!isxdigit(key[i])) return false;
  153.   }
  154.   return true;
  155. }

  156. /**
  157.   *  @brief wifi config
  158.   *  @param[in]  none.
  159.   *  @param[out]  none.
  160.   *  @return none.
  161.   */
  162. static void Blwifi_Config(void)
  163. {
  164.   EEPROM.begin(4096);
  165.   if( wifiSettings.auth_key[0]=='\0'||wifiSettings.auth_key[0]==0xFF)
  166.   {
  167.     Display_WaitWifi();
  168.     WiFi.mode(WIFI_STA);
  169.     //wifiManager.setDebugOutput(true);
  170.    
  171.     wifiManager.resetSettings();

  172.     wifiManager.setAPStaticIPConfig(IPAddress(192,168,10,1), IPAddress(192,168,10,1), IPAddress(255, 255, 255, 0));
  173.      // 3分钟配网时间,如没有完成则退出配网.
  174.      // 例如原正常连接的WIFI路由掉线死机或不通电等情况, 通过配网超时后, 会重新进行连接原WIFI信号。 避免停在配网模式下等待
  175.     wifiManager.setConfigPortalTimeout(180);
  176.     //wifiManager.setConnectTimeout(240);

  177.     // 设置点击保存的回调
  178.     wifiManager.setSaveConfigCallback(saveConfigCallback);

  179.     WiFiManagerParameter custom_authkey("auth_key", "Authkey", wifiSettings.auth_key, 12);
  180.     wifiManager.addParameter(&custom_authkey);

  181.     //AP名称:ESP_AP 密码:12345678
  182.     if(!wifiManager.autoConnect("ESP_AP","12345678"))
  183.     {
  184.       Serial.println(F("Failed to connect. Reset and try again. . ."));
  185.       ESP.restart();
  186.       delay(5000);
  187.     }

  188.     Serial.println(F("Connected to Wifi."));
  189.     Serial.print(F("My IP:"));
  190.     Serial.println(WiFi.localIP());

  191.     // 保存自定义信息
  192.     if (shouldSaveConfig)
  193.     {
  194.       Serial.println(F("saving config..."));
  195.       //Serial.println(custom_authkey.getValue());
  196.       strncpy(wifiSettings.auth_key, custom_authkey.getValue(), 12);
  197.       wifiSettings.auth_key[12] = '\0';
  198.       strcpy(wifiSettings.ssid, wifiManager.getWiFiSSID().c_str());
  199.       wifiSettings.ssid[wifiManager.getWiFiSSID().length()]='\0';
  200.       
  201.       strcpy(wifiSettings.pswd, wifiManager.getWiFiPass().c_str());
  202.       wifiSettings.pswd[wifiManager.getWiFiPass().length()]='\0';
  203.       
  204.       if (!chkAuthkey(wifiSettings.auth_key, strlen(wifiSettings.auth_key)))
  205.       {
  206.         Serial.println(F("Authkey is wrong."));
  207.         Wifi_Reset();
  208.         delay(5000);
  209.       }

  210.       EEPROM.put<Settings>(2448, wifiSettings);
  211.       if (EEPROM.commit())
  212.       {
  213.         Serial.println(F("EEPROM successfully committed"));
  214.         EEPROM.end();
  215.         ESP.restart();
  216.       }
  217.       else
  218.       {
  219.         Serial.println(F("ERROR! EEPROM commit failed"));
  220.       }
  221.     }
  222.   }
  223.   EEPROM.end();
  224.   wifiSettings.auth_key[12] = '\0';
  225. }

  226. BlinkerNumber Temperature("num-tmp");
  227. BlinkerNumber Humidity("num-hum");
  228. BlinkerNumber PM25Number("num-pm25");
  229. BlinkerText IpText("txt-ip");
  230. BlinkerSlider BackLight("ran-light");
  231. BlinkerSlider Pm25UpdatePreiod("ran-pm25");

  232. #define WEATHER_UPDATE  2*60*60*10 /* unit 100ms */
  233. uint32_t weatherTime = 10*10;   /* unit 100ms */

  234. void BackLight_Callback(int32_t value)
  235. {
  236.   wifiSettings.backlight = value;

  237.   EEPROM.begin(4096);
  238.   
  239.   EEPROM.put<Settings>(2448, wifiSettings);
  240.   if (EEPROM.commit())
  241.   {
  242.   }
  243.   EEPROM.end();

  244.   Display_SetBacklight(wifiSettings.backlight);
  245.   BLINKER_LOG("back light set: ", wifiSettings.backlight);
  246. }

  247. void Pm25UpdatePreiod_Callback(int32_t value)
  248. {
  249.   wifiSettings.pm25period = value;  
  250.   EEPROM.begin(4096);
  251.   
  252.   EEPROM.put<Settings>(2448, wifiSettings);
  253.   if (EEPROM.commit())
  254.   {
  255.   }
  256.   EEPROM.end();
  257.   BLINKER_LOG("pm2.5 update period set: ", wifiSettings.pm25period);
  258. }

  259. void dataRead(const String & data)
  260. {
  261.     BLINKER_LOG("Blinker readString: ", data);

  262.     Blinker.vibrate();
  263.    
  264.     uint32_t BlinkerTime = millis();
  265.    
  266.     Blinker.print("millis", BlinkerTime);
  267. }


  268. void heartbeat()
  269. {  
  270.   Temperature.print(Dis_Temperature);
  271.   Humidity.print(Dis_Humidity);
  272.   PM25Number.print(Dis_Pm25);
  273.   IpText.print("http://" + WiFi.localIP().toString() + "/update");
  274.   BLINKER_LOG("heart beat temperature: ", Dis_Temperature);
  275.   BLINKER_LOG("heart beat humidity: ", Dis_Humidity);
  276.   BackLight.print(wifiSettings.backlight);
  277.   Pm25UpdatePreiod.print(wifiSettings.pm25period);
  278. }

  279. void dataStorage()
  280. {
  281.     Blinker.dataStorage("temp", Dis_Temperature);
  282.     Blinker.dataStorage("humi", Dis_Humidity);
  283.     Blinker.dataStorage("pm25", Dis_Pm25);
  284.     BLINKER_LOG("data Storage temperature: ", Dis_Humidity);
  285.     BLINKER_LOG("data Storage humidity: ", Dis_Humidity);
  286.     BLINKER_LOG("data Storage pm25: ", Dis_Pm25);

  287.     if(weatherTime == 0)
  288.     {
  289.       weatherTime = WEATHER_UPDATE;
  290.       Blinker.weather();
  291.     }
  292. }


  293. void weatherData(const String & data)
  294. {
  295.     BLINKER_LOG("weather: ", data);

  296.     DynamicJsonDocument jsonBuffer(1024);
  297.     DeserializationError error = deserializeJson(jsonBuffer, data);
  298.     JsonObject wth = jsonBuffer.as<JsonObject>();

  299.     Display_Weather(wth["weather"]);
  300. }

  301. void miotQuery(int32_t queryCode)
  302. {
  303.     BLINKER_LOG("MIOT Query codes: ", queryCode);

  304.     switch (queryCode)
  305.     {
  306.         case BLINKER_CMD_QUERY_ALL_NUMBER :
  307.             BLINKER_LOG("MIOT Query All");
  308.             BlinkerMIOT.temp(Dis_Temperature);
  309.             BlinkerMIOT.humi(Dis_Humidity);
  310.             BlinkerMIOT.pm25(Dis_Pm25);
  311.             BlinkerMIOT.print();
  312.             break;
  313.         default :
  314.             BlinkerMIOT.temp(Dis_Temperature);
  315.             BlinkerMIOT.humi(Dis_Humidity);
  316.             BlinkerMIOT.pm25(Dis_Pm25);
  317.             BlinkerMIOT.print();
  318.             break;
  319.     }
  320. }

  321. /**
  322.   *  @brief wifi init, read eeprom
  323.   *  @param[in]  none.
  324.   *  @param[out]  none.
  325.   *  @return none.
  326.   */
  327. void Blwifi_Init(void)
  328. {
  329.     MyButton_Init();
  330.         
  331.     EEPROM.begin(4096);
  332.     EEPROM.get<Settings>(2448, wifiSettings);

  333.     if(wifiSettings.UseWifi != WIFI_ST_OFF)
  334.         wifiSettings.UseWifi = WIFI_WAIT_CONFIG;
  335.     else
  336.         ANF_LcdWifi(WIFI_None);
  337.     EEPROM.end();
  338.     Display_SetBacklight(wifiSettings.backlight);
  339. }

  340. /**
  341.   *  @brief task every 100ms
  342.   *  @param[in]  none.
  343.   *  @param[out]  none.
  344.   *  @return none.
  345.   */
  346. void Blwifi_Ds3231_Task100ms(void)
  347. {
  348.   static uint32_t syncTime = 7*24*3600*10;
  349.   if(setDs3231 == 0)
  350.   {
  351.     setDs3231 = Set_Ds3231();
  352.   }
  353.   if(weatherTime > 0)
  354.   {
  355.     weatherTime--;
  356.   }
  357.   if(syncTime > 0)
  358.   {
  359.     syncTime--;
  360.   }
  361.   else
  362.   {
  363.     Set_Ds3231();
  364.     syncTime = 7*24*3600*10;
  365.   }
  366. }

  367. /**
  368.   *  @brief wifi loop
  369.   *  @param[in]  none.
  370.   *  @param[out]  none.
  371.   *  @return none.
  372.   */
  373. void Blwifi_Loop(void)
  374. {
  375.     switch(wifiSettings.UseWifi)
  376.     {
  377.         case WIFI_ST_OFF:
  378.         break;
  379.         case WIFI_WAIT_CONFIG:
  380.             Blwifi_Config();
  381.             wifiSettings.UseWifi = WIFI_WAIT_CONNECT;
  382.         break;
  383.         case WIFI_WAIT_CONNECT:
  384.             BLINKER_DEBUG.stream(Serial);
  385.             Blinker.setTimezone(8.0);

  386.             Blinker.begin(wifiSettings.auth_key, wifiSettings.ssid, wifiSettings.pswd);
  387.             Blinker.attachData(dataRead);
  388.             Blinker.attachHeartbeat(heartbeat);
  389.             Blinker.attachWeather(weatherData);
  390.             Blinker.attachDataStorage(dataStorage);
  391.             BackLight.attach(BackLight_Callback);
  392.             Pm25UpdatePreiod.attach(Pm25UpdatePreiod_Callback);   
  393.             BlinkerMIOT.attachQuery(miotQuery);
  394.         
  395.             MDNS.begin(host);
  396.             httpUpdater.setup(&httpServer);
  397.             httpServer.begin();
  398.             MDNS.addService("http", "tcp", 80);

  399.             wifiSettings.UseWifi = WIFI_CONNECT;
  400.         break;
  401.         case WIFI_CONNECT:
  402.             Blinker.run();
  403.             httpServer.handleClient();
  404.         break;
  405.     }
  406.     myButton.loop();
  407. }
复制代码
Blwifi.h
  1. /**
  2. * @file Blwifi.h
  3. * @brief wifi config
  4. * @author Hu Xihe
  5. * @copyright All rights reserved.
  6. */
  7. #ifndef __BLWIFI_H__
  8. #define __BLWIFI_H__

  9. #define RESET_WIFI_PIN   14

  10. typedef enum
  11. {
  12.     WIFI_ST_OFF,
  13.     WIFI_WAIT_CONFIG,
  14.     WIFI_WAIT_CONNECT,
  15.     WIFI_CONNECT
  16. }WIFI_SET_ST;

  17. struct Settings
  18. {
  19.   char auth_key[13];
  20.   char ssid[128];
  21.   char pswd[32];
  22.   WIFI_SET_ST UseWifi;
  23.   int backlight;
  24.   int pm25period;
  25. };
  26. extern Settings wifiSettings;

  27. /**
  28.   *  @brief wifi init, read eeprom
  29.   *  @param[in]  none.
  30.   *  @param[out]  none.
  31.   *  @return none.
  32.   */
  33. void Blwifi_Init(void);

  34. /**
  35.   *  @brief task every 100ms
  36.   *  @param[in]  none.
  37.   *  @param[out]  none.
  38.   *  @return none.
  39.   */
  40. void Blwifi_Ds3231_Task100ms(void);

  41. /**
  42.   *  @brief wifi loop
  43.   *  @param[in]  none.
  44.   *  @param[out]  none.
  45.   *  @return none.
  46.   */
  47. void Blwifi_Loop(void);

  48. #endif /*end of __BLWIFI_H__*/
复制代码
DS3231SN.c
  1. /**
  2. * @file DS3231SN.c
  3. * @brief DS3231 RTC
  4. * @author Hu Xihe
  5. * @copyright All rights reserved.
  6. */

  7. #include "DS3231SN.h"
  8. #include "IIC.h"

  9. /**
  10.   *  @brief ds3231 write command
  11.   *  @param[in]  addr as ds3231 register address
  12.   *                           dat as ds3231 command.
  13.   *  @param[out]  none.
  14.   *  @return none.
  15.   */
  16. static void DS3231_WriteByte(uint8_t addr,uint8_t dat)
  17. {
  18.     IIC_Start();
  19.     IIC_Send_Byte(DS3231_WriteAddress);
  20.     (void)IIC_Wait_Ack();
  21.     IIC_Send_Byte(addr);
  22.     (void)IIC_Wait_Ack();
  23.     IIC_Send_Byte(dat);
  24.     (void)IIC_Wait_Ack();
  25.     IIC_Stop();
  26. }
  27. /**
  28.   *  @brief ds3231 read current data
  29.   *  @param[in]  none.
  30.   *  @param[out]  none.
  31.   *  @return as uint8_t .
  32.   */
  33. static uint8_t DS3231_ReadCurrent(void)
  34. {
  35.     uint8_t read_dat;
  36.     IIC_Start();
  37.     IIC_Send_Byte(DS3231_ReadAddress);
  38.     (void)IIC_Wait_Ack();
  39.     read_dat=IIC_Read_Byte(1);
  40.     IIC_Stop();        
  41.     return read_dat;
  42. }
  43. /**
  44.   *  @brief ds3231 read Random data
  45.   *  @param[in]  random_addr as uint8_t.
  46.   *  @param[out]  none.
  47.   *  @return as uint8_t .
  48.   */
  49. static uint8_t DS3231_ReadRandom(uint8_t random_addr)
  50. {
  51.     IIC_Start();
  52.     IIC_Send_Byte(DS3231_WriteAddress);
  53.     (void)IIC_Wait_Ack();
  54.     IIC_Send_Byte(random_addr);
  55.     (void)IIC_Wait_Ack();
  56.     return (DS3231_ReadCurrent());               
  57. }
  58. /**
  59.   *  @brief BCD to byte
  60.   *  @param[in]  bcd as uint8_t.
  61.   *  @param[out]  none.
  62.   *  @return as uint8_t .
  63.   */
  64. static uint8_t BCD2Byte(uint8_t bcd)
  65. {
  66.     uint8_t ret = (bcd >> 4) * 10;
  67.     ret += (bcd & 0x0F);  
  68.     return ret;
  69. }

  70. /**
  71.   *  @brief BCD to byte
  72.   *  @param[in]  bcd as uint8_t.
  73.   *  @param[out]  none.
  74.   *  @return as uint8_t .
  75.   */
  76. static uint8_t Byte2BCD(uint8_t data)
  77. {
  78.     uint8_t ret = (data / 10) * 16;
  79.     ret += (data % 10);  
  80.     return ret;
  81. }

  82. /**
  83.   *  @brief ds3231 set time
  84.   *  @param[in]  hour as uint8_t
  85.   *                                 minute as uint8_t
  86.   *                                 second as uint8_t.
  87.   *  @param[out]  none.
  88.   *  @return none .
  89.   */
  90. void Ds3231_SetTime(uint8_t hour, uint8_t minute, uint8_t second)
  91. {
  92.     DS3231_WriteByte(DS3231_HOUR, Byte2BCD(hour));     
  93.     DS3231_WriteByte(DS3231_MINUTE, Byte2BCD(minute));      
  94.     DS3231_WriteByte(DS3231_SECOND, Byte2BCD(second));      
  95. }

  96. /**
  97.   *  @brief ds3231 set date
  98.   *  @param[in]  year as uint8_t
  99.   *                                 month as uint8_t
  100.   *                                 day as uint8_t.
  101.   *  @param[out]  none.
  102.   *  @return none .
  103.   */
  104. void Ds3231_SetDate(uint8_t year, uint8_t month, uint8_t day)
  105. {
  106.     DS3231_WriteByte(DS3231_YEAR,Byte2BCD(year));   
  107.     DS3231_WriteByte(DS3231_MONTH, Byte2BCD(month));  
  108.     DS3231_WriteByte(DS3231_DAY, Byte2BCD(day));      
  109. }

  110. /**
  111.   *  @brief ds3231 get time
  112.   *  @param[in]  none.
  113.   *  @param[out]  hour as uint8_t
  114.   *                                  minute as uint8_t
  115.   *                                  second as uint8_t.
  116.   *  @return none .
  117.   */
  118. void Ds3231_GetTime(uint8_t *hour, uint8_t *minute, uint8_t *second)
  119. {
  120.     *hour = BCD2Byte(DS3231_ReadRandom(DS3231_HOUR));     
  121.     *minute = BCD2Byte(DS3231_ReadRandom(DS3231_MINUTE));
  122.     *second = BCD2Byte(DS3231_ReadRandom(DS3231_SECOND));
  123. }

  124. /**
  125.   *  @brief ds3231 get date
  126.   *  @param[in]  none.
  127.   *  @param[out]  year as uint8_t
  128.   *                                  month as uint8_t
  129.   *                                  day as uint8_t.
  130.   *  @return none .
  131.   */
  132. void Ds3231_GetDate(uint8_t *year, uint8_t *month, uint8_t *day)
  133. {
  134.           *year = BCD2Byte(DS3231_ReadRandom(DS3231_YEAR));
  135.     *month = BCD2Byte(DS3231_ReadRandom(DS3231_MONTH));
  136.     *day = BCD2Byte(DS3231_ReadRandom(DS3231_DAY));
  137. }
复制代码
DS3231SN.h
  1. /**
  2. * @file DS3231SN.h
  3. * @brief DS3231 RTC
  4. * @author Hu Xihe
  5. * @copyright All rights reserved.
  6. */
  7. #ifndef __DS3231SN_H__
  8. #define __DS3231SN_H__
  9. #ifdef __cplusplus
  10. extern "C"{
  11. #endif

  12. #include <Arduino.h>

  13. #define DS3231_WriteAddress 0xD0    //器件写地址
  14. #define DS3231_ReadAddress  0xD1    //器件读地址
  15. #define DS3231_SECOND       0x00    //秒
  16. #define DS3231_MINUTE       0x01    //分
  17. #define DS3231_HOUR         0x02    //时
  18. #define DS3231_WEEK         0x03    //星期
  19. #define DS3231_DAY          0x04    //日
  20. #define DS3231_MONTH        0x05    //月
  21. #define DS3231_YEAR         0x06    //年

  22. #define DS3231_TEMPERATURE      0x0E    //温度
  23. #define DS3231_TEMP_CONVERT     0x20
  24. #define DS3231_TEMP_HIGH_uint8_t   0x11
  25. #define DS3231_TEMP_LOW_uint8_t    0x12

  26. /**
  27.   *  @brief ds3231 set time
  28.   *  @param[in]  hour as uint8_t
  29.   *                                 minute as uint8_t
  30.   *                                 second as uint8_t.
  31.   *  @param[out]  none.
  32.   *  @return none .
  33.   */
  34. void Ds3231_SetTime(uint8_t hour, uint8_t minute, uint8_t second);

  35. /**
  36.   *  @brief ds3231 set date
  37.   *  @param[in]  year as uint8_t
  38.   *                                 month as uint8_t
  39.   *                                 day as uint8_t.
  40.   *  @param[out]  none.
  41.   *  @return none .
  42.   */
  43. void Ds3231_SetDate(uint8_t year, uint8_t month, uint8_t day);

  44. /**
  45.   *  @brief ds3231 get time
  46.   *  @param[in]  none.
  47.   *  @param[out]  hour as uint8_t
  48.   *                                  minute as uint8_t
  49.   *                                  second as uint8_t.
  50.   *  @return none .
  51.   */
  52. void Ds3231_GetTime(uint8_t *hour, uint8_t *minute, uint8_t *second);

  53. /**
  54.   *  @brief ds3231 get date
  55.   *  @param[in]  none.
  56.   *  @param[out]  year as uint8_t
  57.   *                                  month as uint8_t
  58.   *                                  day as uint8_t.
  59.   *  @return none .
  60.   */
  61. void Ds3231_GetDate(uint8_t *year, uint8_t *month, uint8_t *day);

  62. #ifdef __cplusplus
  63. }

  64. #endif
  65. #endif /*end of __DS3231SN_H__*/
复制代码
Display.cpp
  1. /**
  2. * @file Display.cpp
  3. * @brief display task
  4. * @author Hu Xihe
  5. * @copyright All rights reserved.
  6. */
  7. #include "Display.h"
  8. #include "IIC.h"
  9. #include "ANF_Lcd.h"
  10. #include "DS3231SN.h"
  11. #include "GpioButton.h"
  12. #include "SHT20.h"
  13. #include "Blwifi.h"
  14. #include <ESP8266WiFi.h>

  15. uint8_t pm25Buffer[32];
  16. uint8_t pm25Index = 0;
  17. float Dis_Temperature = 0;
  18. float Dis_Humidity = 0;
  19. float Dis_Pm25 = 0;

  20. /**
  21.   *  @brief Display init
  22.   *  @param[in] none.
  23.   *  @param[out]  none.
  24.   *  @return none.
  25.   */
  26. void Display_Init(void)
  27. {
  28.         IIC_Init(12, 13);
  29.         ANF_LcdInit();
  30.         TouchButton_Init();
  31.         ANF_LcdAll();
  32.   ANF_LcdUpdate();
  33.         delay(100);

  34.   pinMode(BACK_LED_PIN, OUTPUT);
  35.   pinMode(PM25_POWER_PIN, OUTPUT);
  36.   digitalWrite(PM25_POWER_PIN, LOW);
  37.   analogWriteRange(100);
  38.   Display_SetBacklight(100);
  39.   ANF_LcdBattery(BAT_None);
  40.   ANF_LcdWeather(WTHR_None);
  41.         ANF_LcdUpdate();
  42. }

  43. /**
  44.   *  @brief set display after wifi init
  45.   *  @param[in] none.
  46.   *  @param[out]  none.
  47.   *  @return none.
  48.   */
  49. void Display_AfterWifiInit(void)
  50. {
  51.   ANF_LcdAll();
  52.   ANF_LcdBattery(BAT_None);
  53.   ANF_LcdWeather(WTHR_None);
  54.   Display_Time();
  55.   Display_TempHumidity();
  56. }

  57. /**
  58.   *  @brief only display wifi logo
  59.   *  @param[in] none.
  60.   *  @param[out]  none.
  61.   *  @return none.
  62.   */
  63. void Display_WaitWifi(void)
  64. {
  65.   ANF_LcdClear();
  66.   ANF_LcdWifi(WIFI_Full);
  67.   ANF_LcdUpdate();
  68. }
  69. /**
  70.   *  @brief Display time, value from ds3231
  71.   *  @param[in] none.
  72.   *  @param[out]  none.
  73.   *  @return none.
  74.   */
  75. void Display_Time(void)
  76. {
  77.         static uint8_t point = 0;
  78.         uint8_t gethour, getminute, getsencond;
  79.         Ds3231_GetTime(&gethour, &getminute, &getsencond);
  80.         ANF_LcdTimeNumber(gethour, getminute);
  81.         ANF_LcdTimePoint(point);
  82.         point = !point;
  83. }

  84. /**
  85.   *  @brief Display date, value from ds3231
  86.   *  @param[in] none.
  87.   *  @param[out]  none.
  88.   *  @return none.
  89.   */
  90. void Display_Date(void)
  91. {
  92.         uint8_t getyear, getmonth, getday;
  93.         Ds3231_GetDate(&getyear, &getmonth, &getday);
  94.         ANF_LcdTimeNumber(getmonth, getday);
  95.         ANF_LcdTimePoint(0);
  96. }

  97. /**
  98.   *  @brief Display temperature humidity, value from sht20
  99.   *  @param[in] none.
  100.   *  @param[out]  none.
  101.   *  @return none.
  102.   */
  103. void Display_TempHumidity(void)
  104. {
  105.   short tmp;
  106.   
  107.   tmp = SHT20_GetTemperature();
  108.   Dis_Temperature = (float)(tmp/10.0);
  109.   ANF_LcdTempNumber(tmp);
  110.   
  111.   tmp = SHT20_GetHumidity();
  112.   Dis_Humidity = (float)tmp;
  113.   ANF_LcdHumidityNumber(tmp);
  114. }

  115. /**
  116.   *  @brief set pwm value.
  117.   *  @param[in] value as int.
  118.   *  @param[out]  none.
  119.   *  @return none.
  120.   */
  121. void Display_SetBacklight(int value)
  122. {
  123.   analogWrite(BACK_LED_PIN, value);
  124. }

  125. /**
  126.   *  @brief display weather info.
  127.   *  @param[in] str as string.
  128.   *  @param[out]  none.
  129.   *  @return none.
  130.   */
  131. void Display_Weather(const String & str)
  132. {
  133.   WEATHER_DEF wthr = WTHR_None;
  134.   if(str == "晴") wthr = WTHR_Sunny;
  135.   else if(str == "多云") wthr = WTHR_Cloudy;
  136.   else if(str == "阴") wthr = WTHR_Overcast;
  137.   else if(str == "小雨") wthr = WTHR_LightRain;
  138.   else if(str == "中雨") wthr = WTHR_ModerateRain;
  139.   else if(str == "大雨") wthr = WTHR_HeavyRain;
  140.   else if(str == "霾") wthr = WTHR_Haze;
  141.   else if(str == "雾") wthr = WTHR_Foggy;

  142.   ANF_LcdWeather(wthr);
  143. }
  144. /**
  145.   *  @brief Wifi logo flash.
  146.   *  @param[in] times as uint8_t.
  147.   *  @param[out]  none.
  148.   *  @return none.
  149.   */
  150. void Display_WifiFlash(uint8_t times)
  151. {
  152.     uint8_t i;
  153.     for(i=0; i<times; i++)
  154.     {
  155.         ANF_LcdWifi(WIFI_None);
  156.         ANF_LcdUpdate();
  157.         delay(200);
  158.         ANF_LcdWifi(WIFI_Full);
  159.         ANF_LcdUpdate();
  160.         delay(200);
  161.     }
  162.         
  163. }

  164. uint16_t ShowDate = 0;

  165. GpioButton TouchButton(5);

  166. /**
  167.   *  @brief touch key init, press show date
  168.   *  @param[in] none.
  169.   *  @param[out]  none.
  170.   *  @return none.
  171.   */
  172. void TouchButton_Init()
  173. {
  174.   TouchButton.BindBtnPress([](){
  175.     if(ShowDate > 0)
  176.     {
  177.       ShowDate = 0;
  178.       Display_Time();
  179.     }
  180.     else
  181.     {
  182.       ShowDate = 6;
  183.       Display_Date();
  184.     }
  185.   });
  186. }

  187. /**
  188.   *  @brief show pm2.5 call by 500ms
  189.   *  @param[in] none.
  190.   *  @param[out]  none.
  191.   *  @return none.
  192.   */
  193. static void Display_Pm25(void)
  194. {
  195.   static uint32_t period = wifiSettings.pm25period*60*2;
  196.   static uint32_t sampTime = 0;
  197.   uint32_t setPeriod = wifiSettings.pm25period*60*2;

  198.   if(period < setPeriod)
  199.   {
  200.     period++;
  201.     digitalWrite(PM25_POWER_PIN, LOW);
  202.   }
  203.   else if(period == setPeriod)
  204.   {
  205.     digitalWrite(PM25_POWER_PIN, HIGH);
  206.     period++;
  207.     sampTime = PM25_SAMP_TIME;
  208.   }
  209.   else
  210.   {
  211.     if(sampTime > 0)
  212.     {
  213.       if(setPeriod > 0)
  214.       {
  215.         if(sampTime & 0x01)
  216.           ANF_LcdPm25Logo(1);
  217.         else
  218.           ANF_LcdPm25Logo(0);
  219.       }
  220.       else
  221.         ANF_LcdPm25Logo(1);

  222.       ANF_LcdPm25Number(Dis_Pm25);
  223.       sampTime--;
  224.     }
  225.     else
  226.     {
  227.       period = 0;
  228.     }
  229.   }
  230. }

  231. /**
  232.   *  @brief show date and time call by 500ms
  233.   *  @param[in] none.
  234.   *  @param[out]  none.
  235.   *  @return none.
  236.   */
  237. void Display_DateTime_Task500ms(void)
  238. {
  239.   if(ShowDate == 0)
  240.     Display_Time();  
  241.   else
  242.   {
  243.     Display_Date();
  244.     ShowDate--;
  245.   }

  246.   Display_TempHumidity();
  247.   Display_Pm25();

  248.   int rssi = WiFi.RSSI();
  249.   if(rssi <= 0 && rssi >= -50)
  250.     ANF_LcdWifi(WIFI_Full);
  251.   else if(rssi < -50 && rssi >= -70)
  252.     ANF_LcdWifi(WIFI_High);
  253.   else if(rssi < -70 && rssi >= -80)
  254.     ANF_LcdWifi(WIFI_Middle);
  255.   else if(rssi <-80  && rssi >= -100)
  256.     ANF_LcdWifi(WIFI_Low);
  257.   else
  258.     ANF_LcdWifi(WIFI_None);
  259.    
  260.   ANF_LcdUpdate();
  261.   ST20_StartSample();
  262. }

  263. typedef enum
  264. {
  265.   PM25_Head1,
  266.   PM25_Head2,
  267.   PM25_Length,
  268.   PM25_Data
  269. }PM25_ST;

  270. PM25_ST pm25St = PM25_Head1;
  271. /**
  272.   *  @brief serial of pm2.5 loop
  273.   *  @param[in] none.
  274.   *  @param[out]  none.
  275.   *  @return none.
  276.   */
  277. static void Display_PM25_Loop(void)
  278. {
  279.   static uint16_t dataLength = 0;
  280.   uint16_t sum, i, chksum;
  281.   if(digitalRead(PM25_POWER_PIN) == HIGH)
  282.   {
  283.     if(Serial.available() > 0)
  284.     {
  285.       switch(pm25St)
  286.       {
  287.         case PM25_Head1:
  288.           pm25Index = 0;
  289.           pm25Buffer[pm25Index] = Serial.read();
  290.           if(pm25Buffer[pm25Index] == 0x32)
  291.             pm25St = PM25_Head2;
  292.         break;
  293.         case PM25_Head2:
  294.           pm25Index = 1;
  295.           pm25Buffer[pm25Index] = Serial.read();
  296.           if(pm25Buffer[pm25Index] == 0x3D)
  297.             pm25St = PM25_Length;
  298.           else
  299.             pm25St = PM25_Head1;
  300.         break;
  301.         case PM25_Length:
  302.           pm25Index++;
  303.           pm25Buffer[pm25Index] = Serial.read();
  304.           if(pm25Index >= 3)
  305.           {
  306.             pm25Index = 4;
  307.             pm25St = PM25_Data;
  308.             dataLength = pm25Buffer[2] * 256 + pm25Buffer[3] + 4;
  309.           }
  310.         break;
  311.         case PM25_Data:
  312.           pm25Buffer[pm25Index] = Serial.read();
  313.           pm25Index++;
  314.           if(pm25Index >= dataLength)
  315.           {
  316.             sum = 0;
  317.             for(i=0; i<dataLength-2; i++)
  318.             {
  319.               sum += pm25Buffer[i];
  320.             }
  321.             chksum = pm25Buffer[dataLength-2]*256 + pm25Buffer[dataLength-1];
  322.             if(chksum == sum)
  323.               Dis_Pm25 = pm25Buffer[6]*256+pm25Buffer[7];
  324.             pm25St = PM25_Head1;
  325.           }
  326.         break;
  327.       }
  328.     }
  329.   }
  330.   else if(Serial.available() > 0)
  331.   {
  332.     Serial.flush();
  333.   }
  334. }

  335. /**
  336.   *  @brief key loop for touch key
  337.   *  @param[in] none.
  338.   *  @param[out]  none.
  339.   *  @return none.
  340.   */
  341. void Display_Loop(void)
  342. {
  343.         TouchButton.loop();
  344.   Display_PM25_Loop();
  345. }
复制代码
Display.h
  1. /**
  2. * @file Display.h
  3. * @brief display task
  4. * @author Hu Xihe
  5. * @copyright All rights reserved.
  6. */
  7. #ifndef __DISPLAY_H__
  8. #define __DISPLAY_H__

  9. #include <Arduino.h>

  10. extern float Dis_Temperature;
  11. extern float Dis_Humidity;
  12. extern float Dis_Pm25;
  13. #define BACK_LED_PIN    4
  14. #define PM25_POWER_PIN  16
  15. #define PM25_SAMP_TIME  60*2 /* uint: s */

  16. /**
  17.   *  @brief Display init
  18.   *  @param[in] none.
  19.   *  @param[out]  none.
  20.   *  @return none.
  21.   */
  22. void Display_Init(void);

  23. /**
  24.   *  @brief set display after wifi init
  25.   *  @param[in] none.
  26.   *  @param[out]  none.
  27.   *  @return none.
  28.   */
  29. void Display_AfterWifiInit(void);

  30. /**
  31.   *  @brief only display wifi logo
  32.   *  @param[in] none.
  33.   *  @param[out]  none.
  34.   *  @return none.
  35.   */
  36. void Display_WaitWifi(void);

  37. /**
  38.   *  @brief Display time, value from ds3231
  39.   *  @param[in] none.
  40.   *  @param[out]  none.
  41.   *  @return none.
  42.   */
  43. void Display_Time(void);

  44. /**
  45.   *  @brief Display date, value from ds3231
  46.   *  @param[in] none.
  47.   *  @param[out]  none.
  48.   *  @return none.
  49.   */
  50. void Display_Date(void);

  51. /**
  52.   *  @brief set pwm value.
  53.   *  @param[in] value as int.
  54.   *  @param[out]  none.
  55.   *  @return none.
  56.   */
  57. void Display_SetBacklight(int value);

  58. /**
  59.   *  @brief Display temperature humidity, value from sht20
  60.   *  @param[in] none.
  61.   *  @param[out]  none.
  62.   *  @return none.
  63.   */
  64. void Display_TempHumidity(void);

  65. /**
  66.   *  @brief display weather info.
  67.   *  @param[in] str as string.
  68.   *  @param[out]  none.
  69.   *  @return none.
  70.   */
  71. void Display_Weather(const String & str);

  72. /**
  73.   *  @brief Wifi logo flash.
  74.   *  @param[in] times as uint8_t.
  75.   *  @param[out]  none.
  76.   *  @return none.
  77.   */
  78. void Display_WifiFlash(uint8_t times);

  79. /**
  80.   *  @brief touch key init, press show date
  81.   *  @param[in] none.
  82.   *  @param[out]  none.
  83.   *  @return none.
  84.   */
  85. void TouchButton_Init();

  86. /**
  87.   *  @brief show date and time call by 500ms
  88.   *  @param[in] none.
  89.   *  @param[out]  none.
  90.   *  @return none.
  91.   */
  92. void Display_DateTime_Task500ms(void);

  93. /**
  94.   *  @brief key loop for touch key
  95.   *  @param[in] none.
  96.   *  @param[out]  none.
  97.   *  @return none.
  98.   */
  99. void Display_Loop(void);


  100. #endif /*end of __DISPLAY_H__*/
复制代码
GpioButton.h
  1. #ifndef _GPIO_BUTTON_H_
  2. #define _GPIO_BUTTON_H_
  3. #include <Arduino.h>

  4. #define DEF_ELIMINATING_JITTER_MS        20                // default eliminating jitter ms
  5. #define DEF_LONG_PRESS_WAIT_MS  1000                // default long press wait ms
  6. #define DEF_DB_PRESS_MS 300

  7. class GpioButton {
  8.     public:
  9.         GpioButton(uint8_t gpio_pin, void(*btn_press_event)()=nullptr) :
  10.             GpioPin(gpio_pin),
  11.             ButtonPressEvent(btn_press_event),
  12.             LongPressWaitMS(DEF_LONG_PRESS_WAIT_MS),
  13.             ButtonLongPressEvent(nullptr),
  14.             first_key_down_millis(0),
  15.             first_key_up_millis(0),
  16.             action_done(false),
  17.             last_gpio_state(HIGH) {
  18.                 pinMode(GpioPin, INPUT_PULLUP);
  19.                 digitalWrite(GpioPin, HIGH);
  20.         };
  21.         // bind click event CB function
  22.         void BindBtnPress(void(*btn_press_event)()) {
  23.                 ButtonPressEvent = btn_press_event;
  24.         };
  25.         // bind long key press CB function
  26.         bool BindBtnLongPress(void(*btn_long_press_event)(), uint16_t wait_ms=DEF_LONG_PRESS_WAIT_MS) {
  27.             if(wait_ms < DEF_LONG_PRESS_WAIT_MS) return false;
  28.             ButtonLongPressEvent = btn_long_press_event;
  29.             LongPressWaitMS = wait_ms;
  30.             return true;
  31.         };
  32.         // bind double click CB function
  33.         void BindBtnDblPress(void(*btn_dbl_press_event)()) {
  34.             ButtonDblPressEvent = btn_dbl_press_event;
  35.         };
  36.         // loop function
  37.         void loop(){
  38.             
  39.             uint8_t current_gpio_state = digitalRead(GpioPin);
  40.             uint32_t current_millis = millis();
  41.             
  42.             // gpio status no change
  43.             if(current_gpio_state == last_gpio_state) {
  44.                 if(current_gpio_state == LOW) {
  45.                     if(first_key_down_millis && !first_key_up_millis && (current_millis - first_key_down_millis > LongPressWaitMS)) {
  46.                         if(!action_done && ButtonLongPressEvent != nullptr) {
  47.                             ButtonLongPressEvent();
  48.                             action_done = true;
  49.                         }
  50.                     }
  51.                 }
  52.                 else {
  53.                     if(first_key_up_millis && (current_millis - first_key_up_millis > DEF_DB_PRESS_MS)) {
  54.                         if(!action_done && ButtonPressEvent != nullptr) {
  55.                             // Serial.println("Debug:Press Event.");
  56.                             ButtonPressEvent();
  57.                             action_done = true;
  58.                         }
  59.                     }
  60.                 }
  61.             }
  62.             // gpio status changed
  63.             else {
  64.                 if(current_millis - last_jitter_millis > DEF_ELIMINATING_JITTER_MS) {
  65.                     // key down
  66.                     if(current_gpio_state == LOW) {
  67.                         // is first keydown in cycle
  68.                         if(0 == first_key_down_millis) {
  69.                             first_key_down_millis = current_millis;
  70.                             first_key_up_millis = 0;
  71.                             action_done = false;
  72.                         }
  73.                         // is not first key down in cycle
  74.                         else {
  75.                             // has define double click CB function
  76.                             if(nullptr != ButtonDblPressEvent){
  77.                                 // key down mill - last key up mill > elimination jitter interval
  78.                                 if(        0 != first_key_up_millis // is release key in event cycle
  79.                                     && (current_millis - first_key_up_millis) > DEF_ELIMINATING_JITTER_MS) {        // skip eliminating jitter
  80.                                     // is double click?
  81.                                     if(        false == action_done // did in event cycle?
  82.                                         && current_millis - first_key_up_millis < DEF_DB_PRESS_MS) {        // and 2nd click is in interval
  83.                                         // call double click event function
  84.                                         // Serial.println("Debug:Double Press Event.");
  85.                                         ButtonDblPressEvent();
  86.                                         action_done = true;
  87.                                     }
  88.                                     
  89.                                 }
  90.                             }
  91.                         }
  92.                     }
  93.                     // key up
  94.                     else {
  95.                         if(!action_done && first_key_down_millis && first_key_up_millis == 0) {
  96.                             first_key_up_millis = current_millis;
  97.                         }
  98.                     }
  99.                     // Keep gpio status
  100.                     last_gpio_state = current_gpio_state;
  101.                     last_jitter_millis = current_millis;
  102.                 }
  103.             }
  104.             
  105.             if(action_done && current_gpio_state == HIGH) {
  106.                 // Serial.println("Event Reset.");
  107.                 first_key_down_millis = 0;
  108.                 first_key_up_millis = 0;
  109.                 action_done = false;
  110.             }
  111.         };
  112.     protected:
  113.         uint8_t GpioPin;                                                // gpio pin of key
  114.         void (*ButtonPressEvent)();       // Click Event CB function
  115.         uint16_t LongPressWaitMS;                            // Long press ms
  116.         void (*ButtonLongPressEvent)();                // Long press Event CB function
  117.         void (*ButtonDblPressEvent)();                // Double click Event CB function
  118.         uint32_t first_key_down_millis;
  119.         uint32_t first_key_up_millis;
  120.         bool action_done;
  121.         uint8_t last_gpio_state;
  122.         uint32_t last_jitter_millis;
  123. };

  124. #endif
复制代码
5.Blinker界面配置
  1. {¨version¨¨2.0.0¨¨config¨{¨headerColor¨¨transparent¨¨headerStyle¨¨dark¨¨background¨{¨img¨¨assets/img/headerbg.jpg¨¨isFull¨«}}¨dashboard¨|{¨type¨¨cha¨¨bg¨É¨sty¨¨line¨¨clr¨¨#FBA613¨¨sty1¨ßG¨clr1¨¨#076EEF¨¨sty2¨ßG¨clr2¨¨#595959¨¨cols¨Ñ¨rows¨Í¨key¨¨cha-oh6¨´x´É´y´Ï¨speech¨|÷¨t0¨¨温度¨¨key0¨¨temp¨¨lstyle¨Ê¨key1¨¨humi¨¨t1¨¨湿度¨¨key2¨¨pm25¨¨t2¨¨Pm25¨}{ßC¨num¨ßU¨室内温度¨¨ico¨¨fad fa-thermometer-three-quarters¨ßHßI¨min¨É¨max¨¢1c¨uni¨¨℃ ¨ßEÉßPÍßQËßR¨num-tmp¨´x´Í´y´ËßT|÷ßYÊ}{ßCßhßU¨室内湿度¨ßj¨fad fa-humidity¨ßH¨#389BEE¨ßlÉßmº0ßn´%´ßEÉßPÍßQËßR¨num-hum¨´x´Í´y´ÍßT|÷ßYÊ}{ßCßhßU¨室内PM25¨ßj¨fal fa-question¨ßHßsßlÉßm¢G7ßn¨ug/m3¨ßEÉßPÍßQÍßR¨num-pm25¨´x´É´y´ËßT|÷ßYÍ}{ßC¨ran¨ßU¨屏幕背光亮度¨ßHßsßmº0ßlÉßEÉßPÑßQËßR¨ran-light¨´x´É´y´¤CßT|÷}{ßCßyßU¨PM2.5采集周期¨ßHßsßmº0ßlÉßEÉßPÑßQËßR¨ran-pm25¨´x´É´y´¤EßT|÷}{ßC¨tex¨ßU¨IP:¨ßb¨固件升级地址¨¨size¨¤EßEÉßj¨fal fa-font¨ßPÑßQÊßR¨txt-ip¨´x´É´y´¤BßT|÷ßYÎ}÷¨actions¨|÷¨triggers¨|÷}
复制代码

5.软件和硬件
AirNutFun.rar (457.4 KB, 下载次数: 50)
未命名1636633041.png
未命名1636633055.png
6.注意事项
(a)PCB为1mm厚
(b)烧录的时候要短接GPIO 0到地,板上没有预留,建议用镊子捅
(c)运行到现在,遇到过一次温度显示56度,重启就好了
(d)帖子字数限制,删了一部分代码,附件里是全的


打赏

参与人数 5家元 +146 收起 理由
18063153801 + 8 謝謝分享
happysea72 + 12 優秀文章
abigbell + 20 謝謝分享
家睦 + 100
guangqu + 6

查看全部打赏

发表于 2021-11-11 20:49:17 | 显示全部楼层
先下为敬,支持一下
回复 支持 反对

使用道具 举报

发表于 2021-11-11 20:51:03 | 显示全部楼层
你们采集PM2.5数据有什么用?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-11-11 20:58:14 | 显示全部楼层
sdfwssf 发表于 2021-11-11 20:51
你们采集PM2.5数据有什么用?

看着自己欢乐就好
回复 支持 反对

使用道具 举报

发表于 2021-11-11 21:17:24 | 显示全部楼层
没上车 ,帮顶
回复 支持 反对

使用道具 举报

发表于 2021-11-12 09:45:12 | 显示全部楼层
还是不要发好,卖家太可恶了。坐地起价又任性。凉他半年先。
回复 支持 反对

使用道具 举报

发表于 2021-11-12 14:54:39 | 显示全部楼层
电池能不能用3V 的LDO代替?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-11-12 18:21:09 | 显示全部楼层
xiaodaishu 发表于 2021-11-12 14:54
电池能不能用3V 的LDO代替?

没有用上电池呀,电池需要充电电路,太麻烦了
回复 支持 反对

使用道具 举报

发表于 2021-11-13 04:42:30 | 显示全部楼层
胡奚曷 发表于 2021-11-12 18:21
没有用上电池呀,电池需要充电电路,太麻烦了

那个给时钟供电的电池能不能用3V的LDO代替?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-11-13 08:22:34 来自手机浏览器 | 显示全部楼层
xiaodaishu 发表于 2021-11-13 04:42
那个给时钟供电的电池能不能用3V的LDO代替?

可以,但是掉电不能保持时间了,没网的话也就没时间了
回复 支持 反对

使用道具 举报

发表于 2021-11-13 09:24:25 | 显示全部楼层
真大佬,没赶上车的路过看下。
回复 支持 反对

使用道具 举报

发表于 2021-11-13 09:26:49 | 显示全部楼层
我等小白什么都不懂,只想有烧好程序的成品板直接替换使用。
回复 支持 1 反对 0

使用道具 举报

发表于 2021-11-13 11:59:22 | 显示全部楼层
没赶上车 路过。:sweat:
回复 支持 反对

使用道具 举报

发表于 2021-11-13 22:35:37 | 显示全部楼层
谢谢分享。电池弄个4056小板外挂:lol:
回复 支持 反对

使用道具 举报

发表于 2021-11-14 10:47:25 | 显示全部楼层
20元了,还一直不发货。
回复 支持 反对

使用道具 举报

发表于 2021-11-24 16:08:26 | 显示全部楼层
DS3231有点贵啊,能不能用RX8025T,这玩意二手的贼便宜
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-11-24 19:21:56 | 显示全部楼层
duyes 发表于 2021-11-24 16:08
DS3231有点贵啊,能不能用RX8025T,这玩意二手的贼便宜

当年7毛一片买的,感觉很便宜了
回复 支持 反对

使用道具 举报

发表于 2021-11-27 00:01:19 | 显示全部楼层
胡奚曷 发表于 2021-11-24 19:21
当年7毛一片买的,感觉很便宜了

7毛一片简直是赚翻了!
回复 支持 反对

使用道具 举报

发表于 2021-11-29 14:16:06 | 显示全部楼层
需要配合app使用吗?
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

APP|手机版|小黑屋|关于我们|联系我们|法律条款|技术知识分享平台

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2024-6-3 21:40 , Processed in 0.468000 second(s), 15 queries , Redis On.

Powered by Discuz!

© 2006-2023 smzj.net

快速回复 返回顶部 返回列表