去年做了个基于oled屏幕的小电视,但是受限于技术力和屏幕尺寸限制,做出来的东西只能说是很不完善。
正好看到了vfd屏幕,很酷,决定做一个。
1 用u8g2库点亮vfd屏幕
1.1 u8g2库的安装
淘宝卖家给了个魔改过的u8g2库,我很不解,但是很好用(bushi
vfd屏u8g2库 – 天鹅绒房间 (qwqpap.xyz)
关于u8g2库的安装这里简略说明
解压放在你arduino ide 的\Arduino\libraries\下就可以。
1.2 u8g2库的使用方法
首先我们需要屏幕驱动的名字,然后创建对应的对象就可以啦。
对于本例而言,我们使用一块分辨率 256*50, 驱动为GP1287AI的vfd屏幕,故你的代码应该开头包含这样一段
#include <U8g2lib.h>
U8G2_GP1287AI_256X50_1_3W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 15, /* reset=*/ 2);
那么传递的参数就是自定义的接线了
比如此例中SCK线接的18 SDA接的23,而CS和RESET如上,是自定义的15和2,还得记得给灯丝使能一个高电平信号才能亮熬。
具体的线如图,接反了可能会干烂不少东西(
然后是初始化和输出一行文字
我们需要了解的是u8g2的坐标系是以左上角为0点,→为x,↓为y,字体会在虚拟光标坐标的右上角开始打印。
这是一个知识水平不太高的实例。
#include <U8g2lib.h>
U8G2_GP1287AI_256X50_1_3W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 15, /* reset=*/ 2);
void setup(void) {
u8g2.begin();//初始化u8g2库
u8g2.setContrast(255);//亮度设置 0-255
u8g2.enableUTF8Print();///使用utf8
}
void loop(void) {
u8g2.setFont(u8g2_font_wqy12_t_gb2312); //设置中文字体
//u8g2.firstPage();
do {
u8g2.setCursor(0, 20);//设置光标位置
u8g2.print("苟利国家生死以");//打印文本
u8g2.setCursor(0, 40);
u8g2.print("岂因祸福避趋之");
} while ( u8g2.nextPage() );
delay(2000);
}
所以可以用来做一些很酷的例子了。
对于本例而言,已经可以实现基本的功能了捏
1.3 u8g2库的各个函数
这个实在是太多了,我有空整理整理
2 获取天气预报
这里使用和风天气的api来获取数据,需要提前的和风天气注册一个账号获得你的私钥
当然,为了不自己搓解析json的数据,我们来调用有的库:ESP32_Heweather.h
非常感谢这个大佬的库,实在是方便啊啊啊
请在arduino ide里面安装,好像是有什么很重要的依赖来着qwq
2.1初始化和调用
#include <ESP32_Heweather.h>
#include <Wire.h>
#include "stdio.h"
const char* ssid = "Triority"; // WiFi名称
const char* password = "@"; // WiFi密码
String UserKey = "**********************************"; // 私钥 https://dev.heweather.com/docs/start/get-api-keyx
String Location = "1******"; // 城市代码 https://github.com/heweather/LocationList,表中的 Location_ID
String Unit = "m"; // 公制-m/英制-i
String Lang = "zh"; // 语言 英文-en/中文-zh
//注意,使用中文请务必确保使用u8g2的中文字体和utf8编码,不然会寄
float ROUND = 1; // 更新间隔<小时>空气质量API 1小时更新一次
WeatherNow weatherNow; // 建立weatherNow对象
WeatherForecast WeatherForecast;
AirQuality AirQuality;
//这个是连接wifi的函数捏
void ConnectWiFi(){
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
Serial.print("Connecting to ");
Serial.print(ssid);
int i = 0;
while (WiFi.status() != WL_CONNECTED && (i < 10)) {
delay(1000);
Serial.print('.');
i++;
}
if (i == 10) { // 10s失败
Serial.println("WiFi Connection Failed");
} else { // 成功
}
}
void setup(void) {
ConnectWiFi();
delay(2000); //连接wifi
weatherNow.config(UserKey, Location, Unit, Lang);
WeatherForecast.config(UserKey, Location, Unit, Lang);
AirQuality.config(UserKey, Location, Unit, Lang);
}
2.2 把天气打印在屏幕
当成功更新天气,weathernow.get()返回一个true的布尔值,根据这个我们可以这样来写
if(weatherNow.get()){
WeatherForecast.get();
AirQuality.get();
sprintf(line_1,"北京市 昌平区");
sprintf(line_2,"预报温度:%d°C 最低:%d°C",weatherNow.getTemp(),WeatherForecast.getTempMin(0));
sprintf(line_3,"当前天气:%s 明日:%s",weatherNow.getWeatherText(),WeatherForecast.getTextDay(1));
sprintf(line_4,"风力: %d 体感温度: %d°C",weatherNow.getWindScale(),weatherNow.getFeelLike());
sprintf(line_5,"降雨量: %3.1fmm 紫外强度: %d",weatherNow.getPrecip(),WeatherForecast.getUvIndex(0));
sprintf(line_6,"空气质量:%s",AirQuality.getCategory());
u8g2.setFont(u8g2_font_wqy12_t_gb2312); //设置中文字体
u8g2.firstPage();
do {
u8g2.setCursor(0, 10);
u8g2.print(line_1);
u8g2.setCursor(0,20);
u8g2.print(line_2);
u8g2.setCursor(0, 30);
u8g2.print(line_3);
u8g2.setCursor(0, 40);
u8g2.print(line_4);
u8g2.setCursor(0, 50);
u8g2.print(line_5);
u8g2.setCursor(150, 10);
u8g2.print(line_6);
} while ( u8g2.nextPage() );
delay(2000);
}
当然这样是顺便给做好了字符串直接用就可以用,写这个的时候本人还在昌平读书捏,所以这个是昌平的天气预报,改成你的城市就可以,用英文也是可以的 。
这样就完成了 天气信息的获取,需要其他数据可以去看那个库的说明。
3 从传感器获取数据
这里使用了SHT31温湿度传感器,气压传感器确实没有什么用,我就给扔了(其实是坏了)。这个传感器使用经典的iic协议和esp32进行通信,而esp32的iic接线如下,照着SDA和SCL接就可以啦。
iic协议的原理不再赘述,可以去找找视频康康
这里一样是懒狗操作,直接调库。使用了经典的Adafruit_SHT31.h这个库,在arduino ide就有,非常好用,这里给出一些初始化和使用的方法。
#include "stdio.h"
#include "Adafruit_SHT31.h"
Adafruit_SHT31 sht31 = Adafruit_SHT31();
void setup(){
if (! sht31.begin(0x44)) { // Set to 0x45 for alternate i2c addr
Serial.println("Couldn't find SHT31");
while (1) delay(1);
}
}
void loop(){
char a[50];
char b[50];
char c[50];
sprintf(a,"室内温度:%.2f°C",sht31.readTemperature());
sprintf(b,"你好");
sprintf(c,"室内湿度:%.2f °",sht31.readHumidity());
}
这里也是把数据提前和汉字拼在一起,然后往屏幕打印就好了
4 拼在一起,然后美化
#include <Arduino.h>
#include <U8g2lib.h>
#include <Wire.h>
//#include "DFRobot_BMP280.h"
#include "stdio.h"
#include "Adafruit_SHT31.h"
#include <ESP32_Heweather.h>
U8G2_GP1287AI_256X50_1_3W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 15, /* reset=*/ 2);
//DFRobot_BMP280 bmp280;
////typedef DFRobot_BMP280_IIC BMP; // ******** use abbreviations instead of full names ********
//BMP bmp280(&Wire, BMP::eSdoLow);
bool enableHeater = false;
uint8_t loopCnt = 0;
Adafruit_SHT31 sht31 = Adafruit_SHT31();
//const char* ssid = "@";
const char* ssid = "88888888888888"; // WiFi名称
//const char* password = "@"; // WiFi密码
const char* password = "888888888888";
String UserKey = "88888888888888888888"; // 私钥 https://dev.heweather.com/docs/start/get-api-keyx
String Location = "101010700"; // 城市代码 https://github.com/heweather/LocationList,表中的 Location_ID
String Unit = "m"; // 公制-m/英制-i
String Lang = "zh"; // 语言 英文-en/中文-zh
float ROUND = 1; // 更新间隔<小时>空气质量API 1小时更新一次
WeatherNow weatherNow; // 建立weatherNow对象
WeatherForecast WeatherForecast;
AirQuality AirQuality;
int qwq = 34;
char line_1[50];
char line_2[50];
char line_3[50];
char line_4[50];
char line_5[50];
char line_6[50];
// 连接WiFi
void ConnectWiFi(){
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
Serial.print("Connecting to ");
Serial.print(ssid);
int i = 0;
while (WiFi.status() != WL_CONNECTED && (i < 10)) {
delay(1000);
Serial.print('.');
i++;
}
if (i == 10) { // 10s失败
Serial.println("WiFi Connection Failed");
} else { // 成功
}
}
void ShowWeather(){
char a[50];
char b[50];
char c[50];
sprintf(a,"室内温度:%.2f°C",sht31.readTemperature());
sprintf(b,"have a good day");
sprintf(c,"室内湿度:%.2f °",sht31.readHumidity());
float t = sht31.readTemperature();
if(qwq>30){
if(weatherNow.get()){
WeatherForecast.get();
AirQuality.get();
sprintf(line_1,"北京市 昌平区");
sprintf(line_2,"预报温度:%d°C 最低:%d°C",weatherNow.getTemp(),WeatherForecast.getTempMin(0));
sprintf(line_3,"当前天气:%s 明日:%s",weatherNow.getWeatherText(),WeatherForecast.getTextDay(1));
sprintf(line_4,"风力: %d 体感温度: %d°C",weatherNow.getWindScale(),weatherNow.getFeelLike());
sprintf(line_5,"降雨量: %3.1fmm 紫外强度: %d",weatherNow.getPrecip(),WeatherForecast.getUvIndex(0));
sprintf(line_6,"空气质量:%s",AirQuality.getCategory());
u8g2.setFont(u8g2_font_wqy12_t_gb2312);
//u8g2.firstPage();
do {
u8g2.setCursor(0, 10);
u8g2.print(line_1);
u8g2.setCursor(0,20);
u8g2.print(line_2);
u8g2.setCursor(0, 30);
u8g2.print(line_3);
u8g2.setCursor(0, 40);
u8g2.print(line_4);
u8g2.setCursor(0, 50);
u8g2.print(line_5);
u8g2.setCursor(0, 60);
u8g2.print(line_6);
u8g2.setCursor(150, 11);
u8g2.print(line_6);
u8g2.setCursor(150, 30);
u8g2.print(a);
u8g2.setCursor(150, 50);
u8g2.print(c);
} while ( u8g2.nextPage() );
delay(2000);
qwq = 0;
}
else {
qwq = 30; // 更新失败
u8g2.setFont(u8g2_font_timR08_tr);
//u8g2.firstPage();
do {
u8g2.setCursor(0, 30);
u8g2.print("ERROR code");
u8g2.setCursor(0, 50);
u8g2.print(weatherNow.getServerCode());
}
while ( u8g2.nextPage() );
ConnectWiFi();
}
}
else{
u8g2.setFont(u8g2_font_wqy12_t_gb2312);
//u8g2.firstPage();
do {
u8g2.setCursor(0, 10);
u8g2.print(line_1);
u8g2.setCursor(0, 20);
u8g2.print(line_2);
u8g2.setCursor(0, 30);
u8g2.print(line_3);
u8g2.setCursor(0, 40);
u8g2.print(line_4);
u8g2.setCursor(0, 50);
u8g2.print(line_5);
u8g2.setCursor(0, 60);
u8g2.print(line_6);
u8g2.setCursor(150, 11);
u8g2.print(line_6);
u8g2.setCursor(150, 30);
u8g2.print(a);
u8g2.setCursor(150, 50);
u8g2.print(c);
} while ( u8g2.nextPage() );
delay(2000);
qwq = qwq + 1;}
}
void setup(void) {
u8g2.begin();
u8g2.setContrast(255);//亮度设置 0-255
u8g2.enableUTF8Print();///使用utf8
ConnectWiFi();
delay(2000); //连接wifi
weatherNow.config(UserKey, Location, Unit, Lang);
WeatherForecast.config(UserKey, Location, Unit, Lang);
AirQuality.config(UserKey, Location, Unit, Lang);
Serial.begin(9600);
//if (!bmp280.begin()) {
//Serial.println("Could not find a valid BMP280 sensor!");
//while (1);//别动,删了就挂壁
//}//sht31
// while (!Serial)
// delay(10); // will pause Zero, Leonardo, etc until serial console opens
Serial.println("SHT31 test");
if (! sht31.begin(0x44)) { // Set to 0x45 for alternate i2c addr
Serial.println("Couldn't find SHT31");
while (1) delay(1);
}
}
void loop(void) {
//u8g2.setFont(u8g2_font_wqy12_t_gb2312);
u8g2.setFont(u8g2_font_profont12_mf);
ShowWeather();
delay(3000);
}
特别提示
这个淘宝屏幕上面的裸露金属会带90v直流电压,无比小心,我要被电死咯,而且接触金属就会被烧烂,我的已经买新的了
qwq
woc好绚