基于 ESP8266-12F 墨水屏天气时钟模块驱动记录
前言
偶然看上一块开源的 4.2 英寸墨水屏天气时钟 PCB,但其不提供源码,那就考虑自己 DIY 固件了。由于首次接触 8266 ,在制作的过程中,遇到了一些小问题。就想着把其中涉及的一些模块驱动方法做个整理,含各模块驱动源码。
一、内容概述
- SHT20 温湿度传感器驱动
- 联网获取室外温度和天气
- 联网获取网络时间
- 网络连接状态提示
- 电源电压检测与板载 LED
二、代码分析
1.温湿度传感器 SHT20
由于硬件电路已固定,使用 Arduino 框架编程时。原本的sht20的驱动库因为接口A4,A5为固定接口无法继续使用。参考sht20的数据手册,在网上找到了一个软件 IIC 的库 ,通过写入对应的地址和命令,自行驱动 sht20,当然,得到的数据还需要以一定的公式转换为实际的温湿度,可参考数据手册。具体的温湿度获取代码如下所示:
#include "brzo_i2c.h"
#define dev_addr 0x40
#define T_code 0xF3
#define RH_code 0xF5
#define add_w 0x80
#define add_r 0x81
#define user_code_w 0xE6
#define user_code_r 0xE7
#define RST_code 0xFE
unsigned char trig_T[2]={T_code};
unsigned char trig_RH[2]={RH_code};
unsigned char ReadBuf[2];
char sda = 13;
char scl = 14;
void sht20Init(void)
{
brzo_i2c_setup(sda,scl,500);
}
float sht20GetTemp(void)
{
sht20Init();
brzo_i2c_start_transaction(dev_addr,100);
brzo_i2c_write(trig_T,1,true);
brzo_i2c_end_transaction();
delay(85);
brzo_i2c_start_transaction(dev_addr,100);
brzo_i2c_read (ReadBuf,2 ,true);
brzo_i2c_end_transaction();
uint temp =(ReadBuf[0]<<8)|ReadBuf[1];
float res = (temp*175.72)/65536-46.85;
return res;
}
float sht20GetHumi(void)
{
brzo_i2c_start_transaction(dev_addr,100);
brzo_i2c_write(trig_RH,1,true);
brzo_i2c_end_transaction();
delay(29);
brzo_i2c_start_transaction(dev_addr,100);
brzo_i2c_read (ReadBuf,2 ,true);
brzo_i2c_end_transaction();
uint temp =(ReadBuf[0]<<8)|ReadBuf[1];
float res = (temp*125)/65536-6;
return res;
}
2.获取心知天气
考虑到初学者,具体说明一下吧。首先,需要注册一个心知天气的登陆账号,然后申请一个私钥 reqUserKey ,配合自己想要获取信息的城市,构建出完整的网址。其次,利用 Arduino 库方法就能够轻松地获取天气信息了。参考代码如下:
#include <ESP8266_Seniverse.h>
WeatherNow WN;
void initWeather()
{
const char* reqUserKey = "你的私钥";
const char* reqLocation = "beijing";
const char* reqUnit = "c";
WN.config(reqUserKey, reqLocation, reqUnit);
}
void getWeatherData()
{
if(WN.update())
{
Serial.println(F("======Weahter Info======"));
Serial.print("服务器响应码: ");
Serial.println(WN.getServerCode());
Serial.print(F("天气 "));
Serial.print(WN.getWeatherText());
Serial.print(F(" "));
Serial.println(WN.getWeatherCode());
Serial.print(F("温度: "));
Serial.println(WN.getDegree());
Serial.print(F("最近更新: "));
Serial.println(WN.getLastUpdate());
Serial.println(F("========================"));
Out_Temp = int(WN.getDegree());
Out_weather = int(WN.getWeatherCode());
}
}
3.获取网络时间
这部分的原理是:通过苏宁授时网址,得到网络时间的相关Json信息,然后通过解析相关信息,得到具体的网络时间。参考代码如下:
#include <ESP8266HTTPClient.h>
HTTPClient http;
String GetUrl;
String response;
String ymd;
String hms;
void internetTimeInit(void)
{
GetUrl = "http://quan.suning.com/getSysTime.do";
http.setTimeout(5000);
http.begin(GetUrl);
}
void getRealTime(void)
{
const size_t cap = JSON_OBJECT_SIZE(2)+30;
DynamicJsonDocument doc(cap);
int httpCode = http.GET();
if (httpCode > 0){
Serial.printf("[HTTP] GET... code: %d\n", httpCode);
if (httpCode == HTTP_CODE_OK) {
response = http.getString();
deserializeJson(doc,response);
ymd = (doc["sysTime2"].as<String>()).substring(0,10);
hms = (doc["sysTime2"].as<String>()).substring(11,19);
}
}
http.end();
}
4.获取网络连接状态
为了判断时钟的实时联网状态,需要进行网络连接状态的获取。这部分是利用 WiFi 库函数实现的,具体可以参考Google;CF是网络连接标志位,相关判断代码如下:
#include <ESP8266WiFi.h>
void internetState(void)
{
if(WiFi.status()==3){
CF = 1;
}
}
5.电压检测与板载 LED
ESP8266-12F 的 ADC 接口对应 Arduino 中的 A0 口,ADC 的输入电压是 0-1V。板载 LED 的接口连接到了 GPIO2,其余的就没什么好说的了。
6.墨水屏驱动
微雪 4.2 寸屏的官方资料提供了一些例程,但是不够详细。并且部分代码写的过于复杂,如数据的显示。微雪的方法是将数据拆分成百位、十位等,然后再通过字符变量写入RAM,我对此进行了改进,通过引入 C 库函数 c_str 将字符串转换成字符,可以直接用字符串的方式写入变量。此处记录一下我的改进方法,对比官方的看看效果,参考代码如下:
6.1 官方代码
char time_string[] = {'0', '0', ':', '0', '0', '\0'};
time_string[0] = time_now_s / 60 / 10 + '0';
time_string[1] = time_now_s / 60 % 10 + '0';
time_string[3] = time_now_s % 60 / 10 + '0';
time_string[4] = time_now_s % 60 % 10 + '0';
paint.SetWidth(32);
paint.SetHeight(96);
paint.SetRotate(ROTATE_270);
paint.Clear(UNCOLORED);
paint.DrawStringAt(0, 4, time_string, &Font24, COLORED);
epd.SetFrameMemory(paint.GetImage(), 80, 72, paint.GetWidth(), paint.GetHeight());
epd.DisplayFrame();
6.2 改进代码
String T_str = "Room-T: "+ String(Room_Temp) + " C";
paint.Clear(UNCOLORED);
paint.DrawStringAt(0, 0, T_str.c_str(), &Font12, COLORED);
epd.SetPartialWindow(paint.GetImage(), 2*STEP, 18*STEP, paint.GetWidth(), paint.GetHeight());
epd.DisplayFrame();
# 总结
主要对制作墨水屏天气时钟的部分模块驱动方法做了一些简要记录,算是完整项目的总结吧,希望能够帮到有需要的伙伴。
|