先前在海鲜市场买了一个M5Core-Ink,准备折腾一下,准备整个天气和基金的涨跌显示。
0、准备工作
需要按照官方的要求安装相关驱动以及开发工具。Arduino IDE 环境搭建 - M5Core-Ink,链接在这里,按照上面进行配置就行了,期间可能需要魔法,可以参看之前的博客。配置的地方在File -> Preferences –> Network这里配置。
1、开始编码
先去GitHub上找找有没有类似的项目,直接搜索coreink能找到一些项目,因为自己之前也没怎么写过,所以找了一个CoreInk-Weather进行改写。期间也看了一下其他的,因为这个不能显示中文,所以还参看了M5COREINK_CLOCK这个项目。之前获得天气的api不能用,所以换了一个之前自己用的,其他的就没啥了。代码也不是很复杂,搞搞就能显示了。下面是代码:
#include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
#include <Preferences.h>
#include "M5CoreInk.h"
#include "esp_adc_cal.h"
#include "images/cloudy.c"
#include "images/rainy.c"
#include "images/rainyandcloudy.c"
#include "images/snow.c"
#include "images/sunny.c"
#include "images/sunnyandcloudy.c"
#include "font/efontEnableCn.h"
#include "font/efont.h"
#include "font/efontM5StackCoreInk.h" //https://github.com/tanakamasayuki/efont
Ink_Sprite weatherSprite(&M5.M5Ink);
Ink_Sprite fundSprite(&M5.M5Ink); //创建 M5Ink实例
Ink_Sprite temperatureSprite(&M5.M5Ink);
// 天气接口
const char* endpoint = "http://www.nmc.cn/rest/weather?stationid=58238";
uint8_t hour = 0 ,minutes = 0;
RTC_TimeTypeDef RTCtime;
Preferences preferences;
void setup() {
M5.begin(); //Initialize CoreInk. 初始化 CoreInk
if( !M5.M5Ink.isInit()){ //check if the initialization is successful. 检查初始化是否成功
Serial.printf("Ink Init faild");
while (1) delay(100);
}
M5.M5Ink.clear(); //clear the screen. 清屏
Serial.begin(115200);
WiFi.begin("DDNT","1234567890");
//weatherSprite.creatSprite(0,0,200,200);
//fundSprite.creatSprite(0,0,200,200);
//temperatureSprite.creatSprite(0,0,200,200);
weatherSprite.creatSprite(0,0,120,105);
temperatureSprite.creatSprite(120,0,80,105);
fundSprite.creatSprite(0,105,200,64);
while (WiFi.status() != WL_CONNECTED) {
delay(2500);
Serial.println("Connecting to WiFi..");
}
Serial.println("Connected to the WiFi network");
//drawWeather();
//drawFund();
//WiFi.disconnect();
M5.update();
}
void flushTimePage()
{
Serial.printf("update page....");
while(1)
{
M5.rtc.GetTime(&RTCtime);
if( minutes != RTCtime.Minutes )
{
minutes = RTCtime.Minutes;
while (WiFi.status() != WL_CONNECTED) {
WiFi.reconnect();
delay(2500);
}
drawWeather();
drawFund();
if( hour != RTCtime.Hours){
hour = RTCtime.Hours;
weatherSprite.clear( CLEAR_DRAWBUFF | CLEAR_LASTBUFF );
temperatureSprite.clear( CLEAR_DRAWBUFF | CLEAR_LASTBUFF );
}
fundSprite.clear( CLEAR_DRAWBUFF | CLEAR_LASTBUFF );
if(WiFi.status() == WL_CONNECTED){
WiFi.disconnect();
}
Serial.println ("ShutDown");
M5.shutdown(48); //original 58 -> 53
//it only is reached when the USB is connected
Serial.println ("USB Power");
delay(45*1000); // original 55 ->50
Serial.println ("Restart");
ESP.restart();
}
M5.update();
if( M5.BtnPWR.wasPressed())
{
digitalWrite(LED_EXT_PIN,LOW);
saveBool("clock_suspend",false);
M5.shutdown();
}
if( M5.BtnMID.wasPressed()){
M5.M5Ink.clear(); //clear the screen. 清屏
};
if( M5.BtnDOWN.wasPressed()) break;
}
weatherSprite.clear( CLEAR_DRAWBUFF | CLEAR_LASTBUFF );
fundSprite.clear( CLEAR_DRAWBUFF | CLEAR_LASTBUFF );
temperatureSprite.clear( CLEAR_DRAWBUFF | CLEAR_LASTBUFF );
}
void loop() {
flushTimePage();
if( M5.BtnPWR.wasPressed())
{
Serial.printf("Btn %d was pressed \r\n",BUTTON_EXT_PIN);
digitalWrite(LED_EXT_PIN,LOW);
M5.shutdown();
}
M5.update();
}
void saveBool(String key, bool value){
preferences.begin("M5CoreInk", false);
preferences.putBool(key.c_str(), value);
preferences.end();
}
bool loadBool(String key) {
preferences.begin("M5CoreInk", false);
bool keyvalue =preferences.getBool(key.c_str(),false);
preferences.end();
return keyvalue;
}
float getBatVoltage()
{
analogSetPinAttenuation(35,ADC_11db);
esp_adc_cal_characteristics_t *adc_chars = (esp_adc_cal_characteristics_t *)calloc(1, sizeof(esp_adc_cal_characteristics_t));
esp_adc_cal_characterize(ADC_UNIT_1, ADC_ATTEN_DB_11, ADC_WIDTH_BIT_12, 3600, adc_chars);
uint16_t ADCValue = analogRead(35);
uint32_t BatVolmV = esp_adc_cal_raw_to_voltage(ADCValue,adc_chars);
float BatVol = float(BatVolmV) * 25.1 / 5.1 / 1000;
return BatVol;
}
void drawWeather() {
Serial.println("start drawWeather");
DynamicJsonDocument weatherdata(20000);
if ((WiFi.status() == WL_CONNECTED)) {
HTTPClient http;
http.begin(endpoint);
int httpCode = http.GET();
if (httpCode > 0) {
String jsonString = http.getString();
deserializeJson(weatherdata, jsonString);
} else {
Serial.println("Error on HTTP request");
}
http.end();
}
String weather = weatherdata["data"]["real"]["weather"]["info"];
if (weather.indexOf("雨") != -1) {
if (weather.indexOf("多云") != -1) {
weatherSprite.drawBuff(5,5,108,96,rainyandcloudy);
} else {
weatherSprite.drawBuff(5,5,108,96,rainy);
}
} else if (weather.indexOf("晴") != -1) {
if (weather.indexOf("多云") != -1) {
weatherSprite.drawBuff(5,5,108,96,sunnyandcloudy);
} else {
weatherSprite.drawBuff(5,5,108,96,sunny);
}
} else if (weather.indexOf("雪") != -1) {
weatherSprite.drawBuff(5,5,108,96,snow);
} else if (weather.indexOf("多云") != -1) {
weatherSprite.drawBuff(5,5,108,96,sunnyandcloudy);
}else{
weatherSprite.drawBuff(5,5,108,96,sunny);
}
weatherSprite.pushSprite();
String maxTemperature = weatherdata["data"]["real"]["weather"]["temperature"]; //温度
String minTemperature = weatherdata["data"]["real"]["weather"]["feelst"]; // 体感温度
String humidity = weatherdata["data"]["real"]["weather"]["humidity"]; // 湿度
String wind = weatherdata["data"]["real"]["wind"]["power"]; // 风速
float f=getBatVoltage();
String tmp = "天气:"+ weather ;
printEfont(&temperatureSprite, const_cast<char*>(tmp.c_str()), 0, 10 + 16*0);
tmp = "温度:" + maxTemperature;
printEfont(&temperatureSprite, const_cast<char*>(tmp.c_str()), 0, 10 + 16*1);
tmp = "体感:" + minTemperature;
printEfont(&temperatureSprite, const_cast<char*>(tmp.c_str()), 0, 10 +16*2);
tmp = "湿度:" + humidity;
printEfont(&temperatureSprite, const_cast<char*>(tmp.c_str()), 0, 10 +16*3);
tmp = "风速:" + wind;
printEfont(&temperatureSprite, const_cast<char*>(tmp.c_str()), 0, 10 +16*4);
char s[10];
String dy = dtostrf(f,1,2,s);
tmp = "电压:" + dy;
printEfont(&temperatureSprite, const_cast<char*>(tmp.c_str()), 0, 10 +16*5);
temperatureSprite.pushSprite();
}
void drawFund() {
// http://fundgz.1234567.com.cn/js/007380.js
Serial.println("start drawFund");
String prefix = "http://fundgz.1234567.com.cn/js/";
String code ="007380";
String postfix =".js";
String url = prefix + code + postfix;
const char* fundUrl = url.c_str();
Serial.println(fundUrl);
DynamicJsonDocument funddata(1000);
if ((WiFi.status() == WL_CONNECTED)) {
HTTPClient http;
http.begin(fundUrl);
int httpCode = http.GET();
if(httpCode > 0) {
String jsonString = http.getString();
jsonString.replace("jsonpgz(","");
jsonString.replace(");","");
deserializeJson(funddata, jsonString);
}else{
Serial.println("Error on HTTP request");
}
http.end();
}
String fundcode = funddata["fundcode"] ;
String name = funddata["name"];
String gszzl = funddata["gszzl"];
String tmp = fundcode + " | " + gszzl;
printEfont(&fundSprite, const_cast<char*>(tmp.c_str()), 0, 0);
printEfont(&fundSprite, const_cast<char*>(name.c_str()), 0, 0 + 16*1);
code = "000217";
url = prefix + code + postfix;
const char* fundUrl1 = url.c_str();
Serial.println(fundUrl1);
if ((WiFi.status() == WL_CONNECTED)) {
HTTPClient http;
http.begin(fundUrl1);
int httpCode = http.GET();
if(httpCode > 0) {
String jsonString = http.getString();
jsonString.replace("jsonpgz(","");
jsonString.replace(");","");
deserializeJson(funddata, jsonString);
}else{
Serial.println("Error on HTTP request");
}
http.end();
}
String fundcode1 = funddata["fundcode"];
String name1 = funddata["name"];
String gszzl1 = funddata["gszzl"];
String tmp1 = fundcode1 + " | " + gszzl1;
printEfont(&fundSprite, const_cast<char*>(tmp1.c_str()), 0, 0 + 16 * 2);
printEfont(&fundSprite, const_cast<char*>(name1.c_str()), 0, 0 + 16 * 3);
fundSprite.pushSprite();
}
2、难点坑点
问题1: 中文显示用了efont 这个项目,但是他的中文太大了,空间不够。
解决方案: 把之前文件里的efontEnableCn清空,然后自己用什么字,加什么字。
问题2: 之前联网是用的自己手机开的热点,想用电脑开热点,但是开的是5G的,根本搜不到。连不上网就没啥意思了。
解决方案: 参看这个链接我的联想笔记本电脑打开热点只有5G,我想改为2.4G怎么办,系统是win10的
你可以试试把无线网卡的频段改成有线2.4G试试。
- 右键右下角网络图标,选择“打开网络共享中心”。
- 选择左侧“更改适配器设置”。
- 在“WLAN”上右键,选择“属性”’。
- 在弹出的窗口上点击右侧“配置”。
- 标签栏选择“高级”。
- 拖动滚动条,可以看到“首选频带”,更改为首选2.4G频带。
3、成果展示
参考链接
efont
CoreInk-Weather
weather-icons
M5COREINK_CLOCK
我的联想笔记本电脑打开热点只有5G,我想改为2.4G怎么办,系统是win10的