• ArduinoIDE初步开发ESP8266时钟


    1.开发环境介绍

    1.1软件环境

    使用的是Arduino最新更新的IDE,当前我使用的版本是Arduino IDE 2.0.0-rc9-nightly版本,该软件使用的内核是vscode,个人认为与老版本的最大区别就是增加了代码提示功能,界面看着也很舒服,放一张图大家简单看一下吧:
    新版ArduinoIDE的界面
    因为使用的vscode的内核,可以汉化,但是汉化会有一点点bug,就是打开工程汉化之后,将工程关闭,再次打开,可能就会回到英文原版,简单说一下汉化的步骤:
    点击“File”:
    汉化步骤1
    展开有个“Preferences”,点击进入看到如下界面:
    汉化步骤2
    在“Language”处直接选择中文简体即可。
    这里说一下如果同样要开发ESP8266,这里“添加开发板管理器URLs”:
    8266开发配置
    链接:http://arduino.esp8266.com/stable/package_esp8266com_index.json
    Arduino开发的最出彩之处就是其可以导库,导库的方式与vscode下载插件的方式相同:
    新版IDE导库
    这里使用ArduinoIDE开发ESP8266一来是8266好上手,二来是想熟悉练习一下C++。
    CSDN的资源链接稍后上传
    百度网盘的下载链接:链接:https://pan.baidu.com/s/1jypbX5HAzwpVUyuA3ebWAA
    提取码:6789
    –来自百度网盘超级会员V4的分享

    1.2硬件环境

    ESP8266MOD(ESP-12F) 单片机或者说WIFI模块
    DHT11 温湿度传感器(单总线,精度不是很高但便宜够用)
    128*64OLED屏幕 共四个引脚IIC通讯
    目前就这三个,可能后续还要添加功能,会更新的,选用这几个模块优点在于Arduino开源程度很高,开源直接安装相应的开发软件库,尤其是OLED的u8g2库,开发起来简直不要太爽。
    ESP8266的电路原理图如下所示:
    电路原理图

    2.代码部分

    2.1任务调度框架

    通过最近一段时间的了解,ESP8266是可以使用FreeRTOS进行开发的,但是需要使用专门的MDK进行开发,据说可以使用ArduinoIDE进行开发,也有相关的库,但是下载后,发现不能正常使用,缺少开发环境,并且资料也并不多,如果有大佬路过知道应该如何使用,希望指正。
    需要使用的库是:

    #include "Ticker.h"
    
    • 1

    导入之后创建任务,并初始化:

    Ticker loop_1Hz,loop_2Hz;
    // schedule中断任务初始化
    void Schedule::init_Schedule(void){
      loop_1Hz.attach(1,loopTask_1Hz);
      loop_2Hz.attach_ms(500,loopTask_2Hz);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    这里我创建的两个任务一个是时钟,一个是LED灯,至于attach的用法网上的资料很多,这里我使用的是最简单的两种,而且这里的任务调度逻辑十分简单,可以理解成在单片机的定时器里面开了两个中断,一个以1hz执行一个以2hz执行,这里只需要在设定函数中初始化之后即可正常使用了:

    /* Schedule框架初始化 */
    mySchedule.init_Schedule();
    
    • 1
    • 2

    2.2单片机时钟

    之所以使用该方式进行时钟,是因为频繁的从服务器上获取时间会被限制,从而导致无法获取,因此本程序所使用的逻辑是单片机上电获取一次时间,之后每隔24小时再次获取时间用于校准,但是目前有个小问题就是校准的时候使用了一个while循环获取时间,频繁获取导致服务器限制我的获取,会使得系统卡死,需要稍加修改,这里把开机获取时间,获取之后使用1hz任务进行时钟运行的代码放到下面:
    上电获取时间:

    // 获取从网络读取的数据,初步只获取时间数据
    void HTTP::httpGetdata(void){
      httpCode = http.GET();
      while(getFlag == false && myWiFi.judgeState == true) //在WiFi连接成功的情况下,时间获取成功停止运行
      {
        if(httpCode > 0){
          Serial.printf("[HTTP] GET... code: %d\n", httpCode);
          if(httpCode == HTTP_CODE_OK){
            // 读取响应内容
            response = http.getString();
            Serial.println(response);
            timeData.date = response.substring(13,23);
            timeData.time = response.substring(24,32);
            Serial.println(timeData.date);
            Serial.println(timeData.time);
    
            //提出出来数字用于设定本地时钟
            timeData.year = timeData.date.substring(0,4).toInt();
            timeData.month = timeData.date.substring(6,7).toInt();
            timeData.day = timeData.date.substring(8,10).toInt();
    
            timeData.hour = timeData.time.substring(0,2).toInt();
            timeData.minute = timeData.time.substring(3,5).toInt();
            timeData.second = timeData.time.substring(6,8).toInt();
    
            timeData.alltime[3] = timeData.year;
            timeData.alltime[4] = timeData.month;
            timeData.alltime[5] = timeData.day;
            if(timeData.alltime[3] > 2000){
              getFlag = true;
              timeData.alltime[0] = timeData.hour;
              timeData.alltime[1] = timeData.minute;
              timeData.alltime[2] = timeData.second;
            }  
          }
        }
        else{
          Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
        }
        http.end();
        delay(1000);
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    这里把需要用到的库放置一下,尤其是提取字符串中的需要字段并转换成int形式需要注意:

    #include "string.h"
    #include "stdlib.h"
    #include "bits/stdc++.h"
    
    • 1
    • 2
    • 3

    获取之后单片机本地计时:

    // h是时间校准的固定时刻,输入0就是在每天0点时进行校准
    void HTTP::httpTimedata(const int h){
      // 从网络获取一次时间数据,然后将数值传递给本地时钟
      timeData.alltime[2]++;
      if(timeData.alltime[2] >= 60){
        timeData.alltime[2] = 0;
        timeData.alltime[1]++;
        timeData.sum_min++;   //计算累计运行多少分钟
        if(timeData.alltime[1] >= 60){
          timeData.alltime[1] = 0;
          timeData.sum_min = 0;
          timeData.sum_hour++;
          timeData.alltime[0]++;   //时
          if(timeData.alltime[0] >= 24){
            timeData.alltime[0] = 0;
            timeData.alltime[3]++;  //日
            /* 月需要考虑闰年 31天和30天这先不写 */
          }
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    这里把http.h放到下面:

    typedef struct _Date_time{
      String date;
      String time;
    
      int year;     //年
      int month;    //月
      int day;      //日
    
      int hour;     //小时  24小时
      int minute;   //分钟  60分钟
      int second;   //秒钟  60秒
    
      int sum_hour; //计算累计运行几个小时
      int sum_min; //计算累计运行分钟数
    
      int alltime[6];  //0是hour 1是min 2是sec 3是年 4是月 5是日
    }datetimeDefine;
    
    class HTTP{
      public:
        String response;      //返回函数
        datetimeDefine timeData;  //时间结构体
    
        HTTP();               //析构函数
        HTTP(const String getUrl);         //重载析构函数
        ~HTTP();
        void httpInit(void);        //初始化
        void httpGetdata(void);     //获取数据
    
        void httpTimedata(const int h);    //获取时间数据,由于经常访问时间会出问题 
      private:
        String   GetUrl = "http://quan.suning.com/getSysTime.do";
        int httpCode;
        bool getFlag = false;
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    2.3避坑u8g2

    因为刚开始使用u8g2库进行开发,所以有些不是很清楚,接下来说几个自己认为需要注意的事项:

    x,y轴坐标,这里y轴坐标计算从左下角开始,比如在第一行显示汉字,x=0,y=16
    u8g2.setCursor(x,y);
    u8g2.print("你好世界!");
    x,y轴坐标,这里y轴坐标计算从左下角开始,比如在第二行显示字母,x=0,y=32
    u8g2.drawStr(x,y,"Hello World!");
    
    • 1
    • 2
    • 3
    • 4
    • 5

    如果想同时显示汉字和字母,可以自己写,或者说采用进一步模块化处理:

    // 显示汉字
    // x,y轴坐标,这里y轴坐标计算从左下角开始,比如在第一行显示汉字,x=0,y=16
    // 汉字字符串
    void OLED::oledDisplayChinese(const uint8_t x,const uint8_t y,const String str){
      u8g2.setFont(u8g2_font_unifont_t_chinese1);	//设定显示汉字
      u8g2.setCursor(x,y);
      u8g2.print(str);
    }
    
    // 显示英文字符串
    // x,y轴坐标
    // 英文字符串
    void OLED::oledDisplayString(const uint8_t x,const uint8_t y,const char str[]){
      u8g2.setFont(u8g2_font_ncenB08_tr);		//设定显示除汉字之外的字符
      u8g2.drawStr(x,y,str);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    这样只需要输入需要显示的字符串,并输入坐标即可,个人认为方便了不少。

    2.4关于u8g2库导入汉字

    如果不自己进行操作,使用u8g2自带的字库,无法显示出来全部汉字,因此需要想法导入汉字,网上关于此的资料很多,操作并不复杂,哔哩哔哩也有相应的视频教程,这里不赘述,但是把常用的汉字放到下面,需要自取:

    的一是在不了有和人这中大为上个国我以要他时来用们生到作地于出就分对成会可主发瞭年动同工也能下过子说产种面而方后多定行学法所民得经十三之进着等部度家电力里如水化高自二理起小物现实瞭加量都两体制机当使点从业本去把性好应开它合还因由其些然前外天政四日那社义事平形相全表间样与关各重新线内数正心反瞭你明看原又么利比或但质气第向道命此变条只没结解惇问意建月公无系军很情者最立代想已通并提直题党程展五果料象员革位入常文总次品式活设及管特件长求老头基资边流路级少图山统接知较长将组见计别她手角期根论运农指几九区强放决西被干做必战先回则任取据处队南给色光门即保治北造百规热领七海地口东导器压志世金增争济阶油思术极交受联什认六共权收证改清已美再采转更单风切打白教速花带安场身车例真务具万每目至达走积示议声报斗完类八离华名确才科张信马节话米整空元况今集温传土许步群广石记需段研界拉林律叫且瞭究观越织装影算瞭低持音众书布复容儿须际商非验连断深难近矿千周委素技备半办青省列习响约支般史感劳便团往酸历市克何除消构府称太准精值号率族维划选标写存候毛亲快效斯院查江型眼王按格养易置派层片始却专状育厂京识适属圆包火住调满县局照参红细引听该铁价严首瞭底液官德调随病苏失尔死讲配女黄推显谈罪神艺呢席含企望密批营项防举球英氧势告李台落木帮轮破亚师围注远字材排供河态封另施减树溶怎止案言士均武固叶鱼波视仅费紧爱左章早朝害续轻服试食充兵源判护司足某练差致板田降黑犯负击范继兴似余坚曲输修的惇故城夫够送笔船占右财吃富春职觉汉画功巴跟虽杂飞检吸助升阳互初创抗考投坏策古径换未跑留钢曾端责站简述钱副尽帝射草冲承独令限阿宣环双请超微让控州良轴找否纪益依优顶础载倒房突坐粉敌略客袁冷胜绝析块剂测丝协重诉念陈仍罗盐友洋错苦夜刑移频逐靠混母短皮终聚汽村云哪既距卫停―烈央察烧行迅境若印洲刻括激孔搞甚室待核校散侵吧甲游久菜味旧模湖货损预阻毫普稳乙妈植息扩银语挥酒守拿序纸医缺雨吗针刘啊急唱误训愿审附获茶鲜粮斤瞭孩脱硫肥善龙演父渐血欢械掌歌沙著刚攻谓盾讨晚粒乱燃矛乎杀药宁鲁贵钟煤读班伯香介迫句丰培握兰担弦蛋沉假穿执答乐谁顺烟缩征脸喜松脚困异瞭免背星福买染井概慢怕磁倍祖皇促静补评―翻肉践尼衣宽扬棉希伤操垂秋宜氢套笔督振架亮末宪庆编牛触映雷销诗座居抓裂胞呼娘景威绿晶厚盟衡鸡孙延危胶还屋乡临陆顾掉呀灯岁措束耐剧玉赵跳哥季课凯胡额款绍卷齐瞭伟蒸殖永宗苗川炉岩弱零杨奏沿露杆探滑镇饭浓航怀赶库夺伊灵税了途灭赛归召鼓播盘裁险康唯录菌纯借糖盖横符私努堂域枪润幅哈竟熟虫泽脑壤碳欧遍侧寨敢彻虑斜薄庭都纳弹饲伸折麦湿暗荷瓦塞床筑恶户访塔奇透梁刀旋迹卡氯遇份毒泥退洗摆灰彩卖耗夏择忙铜献硬予繁圈雪函亦抽篇阵阴丁尺追堆雄迎泛爸楼避谋吨野猪旗累偏典馆索秦脂潮爷豆忽托瞭惊塑遗愈朱替纤粗倾尚痛楚谢奋购磨君池旁碎骨监捕弟暴割贯殊释词亡壁顿宝午尘闻揭炮残冬桥妇警综招吴付浮遭徐您摇谷赞箱隔订男吹乐园纷唐败宋玻巨耕坦荣闭湾键凡驻锅救恩剥凝碱齿截炼麻纺禁废盛版缓净睛昌婚涉筒嘴插岸朗庄瞭街藏姑贸腐奴啦惯乘伙恢匀纱扎辩耳彪臣亿璃抵脉秀萨俄网舞店喷纵寸汗挂洪着贺闪柬爆烯津稻墙软勇像滚厘蒙芳肯坡柱荡腿仪旅尾轧冰贡登黎削钻勒逃障氨郭峰币港伏轨亩毕擦莫刺浪秘援株健售股岛甘泡睡童铸汤阀休汇舍牧绕炸哲磷绩朋淡尖启陷柴呈徒颜泪稍忘泵蓝拖洞授镜辛壮锋贫虚弯摩泰幼廷尊窗纲弄隶疑氏宫姐震瑞怪尤琴循描膜违夹腰缘珠穷森枝竹沟催绳忆邦剩幸浆栏拥牙贮礼滤钠纹弹罢拍咱喊袖埃勤罚焦潜伍墨欲缝姓刊饱仿奖铝鬼瞭丽跨默挖链扫喝袋炭污幕诸弧励梅奶洁灾舟鉴苯讼抱毁率懂寒智埔寄届跃渡挑丹艰贝碰拔爹戴码梦芽熔赤渔哭敬颗奔藏铅熟仲虎稀妹乏珍申桌遵允隆螺仓魏锐晓氮兼隐碍赫拨忠肃缸牵抢博巧壳兄杜讯惇诚碧祥柯页巡矩悲灌龄伦票寻桂铺圣恐恰郑趣抬荒腾贴柔滴猛阔辆妻填撤储签闹扰紫砂递戏吊陶伐喂疗瞭瓶婆抚臂摸忍虾蜡邻胸巩挤偶弃槽劲乳邓吉仁烂砖租乌舰伴瓜浅丙暂燥橡柳迷暖牌纤秧胆详簧踏瓷谱呆宾糊洛辉愤竞隙怒粘乃绪肩籍敏涂熙皆侦悬掘享纠醒狂锁淀恨牲霸爬赏逆玩陵祝秒浙貌役彼悉鸭着趋凤晨畜辈秩卵署梯炎滩棋驱筛峡冒啥寿译浸泉帽迟硅疆贷漏稿冠嫩胁芯牢叛蚀奥鸣岭羊凭串塘绘酵融盆锡庙筹冻辅摄袭筋拒瞭僚旱钾鸟漆沈眉疏添棒穗硝韩逼扭侨凉挺碗栽炒杯患馏劝豪辽瞭勃鸿旦吏拜狗埋轮掩饮搬骂辞勾扣估蒋绒雾丈朵姆拟宇辑陕雕偿蓄崇剪倡厅咬驶薯刷斥番赋奉佛浇漫曼扇钙桃扶仔返瞭俗亏腔鞋棱覆框悄叔撞骗勘旺沸孤粘吐孟渠屈疾妙惜瞭仰狠胀谐抛霉桑岗嘛衰盗渗脏赖涌甜曹阅肌哩厉经纬毅昨伪症煮叹钉搭茎笼酷偷弓锥恒杰坑鼻翼纶叙狱逮罐络棚抑膨蔬寺骤穆冶枯册尸凸绅坯牺焰轰欣晋瘦御锭锦丧旬锻垄搜佛扑邀亭酯迈舒脆酶闲忧酚顽羽涨卸仗陪薄辟惩杭姚肚捉飘漂昆欺吾郎烷汁呵饰萧雅邮迁燕撒姻赴宴烦削债帐斑铃旨醇董饼雏姿拌傅腹妥揉贤拆歪葡胺丢浩徽昂垫挡览贪慰缴汪慌冯诺姜谊凶劣诬耀昏躺盈骑乔溪丛卢抹易闷咨刮驾缆悟摘饵掷颇幻柄惠惨佳仇腊窝涤剑瞧堡泼葱罩霍捞胎苍滨俩捅湘砍霞邵萄疯淮遂熊粪烘宿档戈驳嫂裕徙箭捐肠撑晒辨殿莲摊搅酱屏疫哀蔡堵沫皱畅叠阁莱敲辖钩痕坝巷饿祸丘玄溜曰逻彭尝卿妨艇吞韦怨矮歇郊禄捻漠粹颠宏冤肪饥呵仙押挨醛娃拾没佩勿吓讹侯恋夕锌篡戚淋蓬岂釉兆泊魂拘亡杠摧氟颂浑凌铀诱犁谴颁舶扯嘉萌犹滋焊舌匹媳肺掠酿烹疲驰鸦窄辱狭朴遣菲奸韧辣拳杆卧醉竭茅墓矣哎艳敦舆缔雇尿葬履契禽渣衬躲赔咸溉贼醋堤抖妃裤廉晴挽掀茫丑亥拦悠阐慧佐奇竖孝柜麟绣遥逝愁肖昭芬逢窑捷圜盲闸宙辐披账狼幽绸蜂慎餐酬誓惟叉弥址帜芝砌唉仆涛臭瞭翠盒劫慨炳阖寂椒倘拓畏喉巾颈垦拚兽蔽芦乾爽窃谭挣崩模褐传翅儒伞晃谬胚剖凑眠浊霜礁蔑抄闯洒碑蓉耶猜蹲壶唤澳锯郡玲绵纽梳掏吁锤鼠穴椅殷遮吵萍厌畜俱夸吕囊捧雌闽饶瞬郁哨凿朝俺浒茂肝勋盯籽耻菊滥稼戒奈帅鞭蚕镁询跌烤坛宅笛鄂蛮颤棍睁鼎岌降侍藩嚷匪岳糟缠迪泄卑氛堪萝盛碘缚悦澄甫攀屠溢拱晰携朽吟菱谦凹俊芒盼婶艘酰趁唇挫羞浴疼萎肴愚肿刨绞枢嫁慕舱铲苹豫谕迭潘顷翁榜匠欠茬畴胃沾踪弊哼鹏歧桐沃悼惑溃蔗荐潭孢露诊庸聪嫌厨庞祁钳肆梭赠崖篮颖甸藻捣且撕诏贞赐慈炕胖兹差琼锈汛卓棵馈挠灶婴蒂肤衫沥仑勉沪逸蜜浦嗓晕膏祭赢艾扮鹅怜蒲兔孕听孽挪淑谣惧廊缅俘骄膀陡宰诞峻恼腺猎涡夷愉魔铵葛贾似荫哟脊钞苛锰椭镶杏溴倚滞会氓捏斩傲匆僵卤烫衍榨拢裸屑咽坊舅渴翔邪拄窖猫砌钦媒脾勺柏栅噪昼耿扁辰秤得贩糕梁昙衷宦扔哇诈嘱藤卜冈悔廓皂拐氰杉玛矢寓瓣罕垮笋淘衔称恭喇帕桉秉帘铭蛇摔斋叭帆裸俭瘤篷砸肢辟脖瞪暑卜竿歼笙酮蕴哗瞎喀刃楔喘枚嵌挝厢粤甩拴膝恳腕娓熄锚忌愧哦荆圃骚丸蒜毯弗俯鹿梢屯瞭衙轿贱垒谅踢哑滔渥饷泳棕熬搁腈梨吻樱奠捆姨柏聘惕郓绑冀裹酥寡彦稠啡钝汝擅汰埔敞嘿逊栋谨咖鲤雀佣庵葫贿鳞拼搏谎塌仞腻戊怖坟禾刹嘻桔坎拇煽狮痒曾梗寇鹰烛哄莽雯胳龟亟糠泌坪傻什喻渊蚌跪巷涅钊譬蕊膛侮奕枕辫况扼郝寥凄厦腥钧耦蹄戮屁诵匈桩钓涵倦袍抒屿蹈忿敷虹聊嗣尉灿糙蹬嗯姬狡笨辜僧茨讽翰枉岐枣崭焚咕猴揽涝耍趟汹咋傍镀给爵虏劈璋踩瞅迄昔汞呱诡魄―祺嘲惶赃癌咐歉扳鄙庐聂便芡躯贬煌拧隋襄淤宠炊滇窖懒栓佑憾骆裙猖兜孵痼盥曝泣絮韵眷旷噢参栖盏鳌溅煎校榴暮琪淆陛巢哒吼槐唧其沛乞蜀蜇赚捍较幂尧咒耽叮褂焕煞雹搓釜铬拣募淹瑰链茄灼邹躬觉娇焉彰鹤琳沦畔惹庶毙皖邢禹渍绷窜翘淫笔陌膊鞑咳玫巫拂蕉澜赎绥锄囱赌颊缕寅躁稚庚荀氦魁珊蜕蛭酌逗闺蔓撇豌朕缉襟镍桅荧侄卒佃瞿娶饪耸乍靶痴靖扛筐韶嚣崔蓿岔氛娥剿霖喃搪雍裳撰豹骏慷

  • 相关阅读:
    经典模型——NiN&GoogLeNet
    利用三次样条插值调整鱼眼扭曲程度
    Flutter笔记:目录与文件存储以及在Flutter中的使用(下)
    腾讯云大数据ES Serverless
    【附源码】计算机毕业设计JAVA政府采购线上招投标平台
    2023年中职组“网络安全”赛项云南省竞赛任务书
    【药材识别】基于色差色温特征结合SVM实现药材炮制程度判断系统附GUI界面
    【Python深度学习】深度学习中框架和模型的区别
    Express框架
    保驾护航,嘉为蓝鲸助力某科技公司AD域故障恢复实记
  • 原文地址:https://blog.csdn.net/weixin_44080304/article/details/126396753