三星9位段码VFD_ESP8266主控时钟
最终效果
还是不出的哈哈哈,电路分为两块,VFD显示部分以及ESP8266主控部分。
硬件介绍
显示屏
图片均来自淘宝,因为已经没有VFD变压器提供了,所以我使用了没有变压器的VFD驱动电路。
VFD驱动
VFD驱动我使用了专用驱动IC-PT6312,需为此IC提供负高压(-20V以上)以驱动VFD栅极,以及提供灯丝的交变电压。
VFD电源电路
经过我不懈的努力在网上找到了,一个无变压器产生负压以及灯丝交变电压的电路:网站,有能用的当然是买过来啦,一块钱可以接受。
“本电路采用廉价的音频功放集成电路,通过文氏电路自激震荡,低压下能输出符合驱动灯丝要求的交流电源;同时利用高集成度的高频boost-bust驱动电路产生负高压驱动栅极,电路非常简单,无需调试,即可生成驱动VFD的三路电压,通过改变采样电路分压电阻,能适配不同电压要求的VFD屏。整套电路成本非常低,不用采用变压器,能达到93%的驱动效率,适合推动绝大多数负高压的VFD电路。”
——来自作者描述
VFD显示屏部分电路图
因为使用ESP8266作为主控,IO不多,PT6312正好可以控制4个LED,以及按键检测,于是直接将这些集成到VFD显示板上了。
ESP8266主控板
电路好像没啥特色哈哈哈,就不多讲啦。这里使用ETA6093的原因是我本来想使用电池的,但这个系统耗电量还是挺大的,接电池不能工作很久(就几小时),钰泰ETA6093三合一SOC电源管理芯片,支持1A开关充电,1A同步升压,充放电效率高。SOT23-5小型封装,集成度,外围少。搭配USB-C接口使用,可以做C口充放电功能。
代码介绍
写代码当然是Ctrl+C,Ctrl+V啦,能不用自己写的就一点也不自己写,这里使用ArduinoIDE编写ESP8266代码,以前一直不怎么喜欢Arduino(真香),疯狂使用别人的库就行啦,哈哈哈。
大量代码参考自(拷贝自)单片机菜鸟哥的ESP8266 Arduino教程
NTP网络校时代码则来自B站的一位大神的开源项目代码。
主要实现功能
这里偷懒直接截图一下我写的使用说明:
配网
这里使用的是SmartConfig配网,可以在乐鑫官网下载安卓或者苹果对应的配网软件ESP-TOUCH进行配网(配置连接的WiFi信息)。
当然有兴趣的话,我推荐使用单片机菜鸟哥的ESP8266 Arduino教程里的wifimanager配网。
全部源码
很乱哈哈哈,就随便写写的,也没怎么整理,可以看到我原来使用的是红外控制,后来发现PT63212可是外接按键,就使用了按键控制了。
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <time.h>
#include <NTPClient.h>
//#include <IRremoteESP8266.h> //ESP8266红外控制库
//#include <IRrecv.h>
//#include <IRutils.h>
#include <RtcDS3231.h>
// #include "DHTesp.h"
#include <Wire.h>
#include <AHT10.h>
#include <Ticker.h> // Ticker can periodically call a function
#include <EEPROM.h>
#include <SPI.h>
#define DS3231_SDA 5
#define DS3231_SCL 4
#define ESP8266_LED 2
#define VFD_POWER 16
#define VFD_STB 15 // Pin cs (SPI)
#define VFD_STB_H() digitalWrite(VFD_STB, HIGH)
#define VFD_STB_L() digitalWrite(VFD_STB, LOW)
#define ESP8266_LED_OFF() digitalWrite(ESP8266_LED, HIGH)
#define ESP8266_LED_ON() digitalWrite(ESP8266_LED, LOW)
#define VFD_POWER_ON() digitalWrite(VFD_POWER, HIGH)
#define VFD_POWER_OFF() digitalWrite(VFD_POWER, LOW)
#define MODE 0x05 // VFD Dan set ( 9 digit*13 segment)
#define LIGHT 0x05 // VFD Brightness settings (0x00-0x07)
#define ON 0x08 // Open Display
#define OFF 0x00 // Off Display
uint8_t DisplayCache[9] = {0x00}; //'-' =0x40
uint8_t vfdmap[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f};
uint8_t VFD_LED_Cmd = 0x0F; //VFD LED灯命令
uint8_t VFD_LED_ONFlag = 0x01; //VFD LED允许点亮
uint8_t DisplayMode = 0x00; //显示温湿度或时间
uint8_t KEYMode = 0x00; //按键功能模式
uint8_t VFD_LIGHT_Mode = 0x02; //亮度等级
uint8_t VFD_LIGHT = LIGHT; //亮度等级
uint16_t BAT_V_Value = 0;//电池电压
uint8_t LowPowerFlag = 0; //低电量
uint8_t LowPowerLED = 0; //低电量指示灯
//共阴极数码管0到f的短编码:
//0x3f,0x06,0x5b,0x4f, //0~3
//0x66,0x6d,0x7d,0x07, //4~7
//0x7f,0x6f,0x77,0x7c, //8~b
//0x39,0x5e,0x79,0x71 //c~f
void VFD_Init(void);
void VFD_Display(void);
void VFD_Display_Test(void);
void VFD_LED_ON(void);
void VFD_LED_OFF(void);
uint8_t SPIRead_PT6312(uint8_t dat);
//#define MAX 22
//#define RECV_PIN 12 //定义红外接收模块输出口接数字引脚12
AHT10 myAHT10(AHT10_ADDRESS_0X38);
uint8_t AHT10ReadStatus = 0;
uint8_t AHT10ErrorFlag = 0;
IRrecv irrecv(RECV_PIN);
//decode_results results;
Car mp3编码
//unsigned long rremote_code[MAX] = {
// 0xFFA25D, 0xFF629D, 0xFFE21D, //1 2 3
// 0xFF22DD, 0xFF02FD, 0xFFC23D, //4 5 6
// 0xFFE01F, 0xFFA857, 0xFF906F, //7 8 9
// 0xFF6897, 0xFF9867, 0xFFB04F, // * 0 #
// 0xFF30CF, 0xFF18E7, 0xFF7A85, // NC ↑ NC
// 0xFF10EF, 0xFF38C7, 0xFF5AA5, // ← OK →
// 0xFF42BD, 0xFF4AB5, 0xFF52AD, // NC ↓ NC
// 0xFFFFFFFFFFFFFFFF //长按
//};
Car mp3对应的字符串
//String rremote_string[MAX] = {
// "CH-", "CH", "CH+",
// "PREV", "NEXT", "PLAY/PAUSE",
// "VOL-", "VOL+", "EQ",
// "0", "100+", "200+",
// "1", "2", "3",
// "4", "5", "6",
// "7", "8", "9",
// "longPress"
//};
//void SPI.transfer(uint8_t dat)
//{
// uint8_t i;
// for (i = 0; i < 8; i++)
// {
// VFD_CLK_L();
// if (dat & 0x01)
// {
// VFD_DIN_H();
// }
// else
// {
// VFD_DIN_L();
// }
// dat >>= 1;
// VFD_CLK_H();
// }
//}
void SendCSToPT6312(void)
{
VFD_STB_H();
VFD_STB_L();
}
uint8_t SPIRead_PT6312(uint8_t dat)
{
uint8_t data = 0x00;
SendCSToPT6312();
SPI.transfer(dat);
delayMicroseconds(1);//延时1us
data = SPI.transfer(0xF0);
VFD_STB_H();
return data;
}
void VFD_Init(void)
{
uint8_t i;
pinMode(VFD_STB, OUTPUT);
digitalWrite(VFD_STB, HIGH);
SendCSToPT6312();
SPI.transfer(MODE); // 段位设置
SendCSToPT6312();
SPI.transfer(0x40); // 设定数据
SendCSToPT6312();
SPI.transfer(0xc0); // Set Address
for (i = 0; i < 9; i++)
{
SPI.transfer(0x00); // Transfer display data low byte
SPI.transfer(0x00); // High byte data transmission display
}
SendCSToPT6312();
SPI.transfer(0x80 | ON | VFD_LIGHT); // Display Control
VFD_STB_H();
}
void VFD_Display_Test(void)
{
uint8_t i;
SendCSToPT6312();
SPI.transfer(0x40); // 设定数据
SendCSToPT6312();
SPI.transfer(0xc0); // Set Address //设置起始地址 0x00
for (i = 0; i < 9; i++) //发送数据
{
SPI.transfer(vfdmap[i]); // Transfer display data low byte //前8位
SPI.transfer(0x03); // High byte data transmission display //后8位
}
SendCSToPT6312();
SPI.transfer(0x80 | ON | VFD_LIGHT); // Display Control //显示控制
VFD_STB_H();
}
void VFD_LED_ON(uint8_t ledx)
{
if (VFD_LED_ONFlag)
{
// 打开LED显示
SendCSToPT6312();
SPI.transfer(0x41); // 设定LED
switch (ledx)
{
case 1:
VFD_LED_Cmd &= 0xFE;
break;
case 2:
VFD_LED_Cmd &= 0xFD;
break;
case 3:
VFD_LED_Cmd &= 0xFB;
break;
case 4:
VFD_LED_Cmd &= 0xF7;
break;
default:
VFD_LED_Cmd = ledx;
break;
}
SPI.transfer(VFD_LED_Cmd); //
VFD_STB_H();
}
}
void VFD_LED_Send(uint8_t cmd)
{
SendCSToPT6312();
SPI.transfer(0x41); // 设定LED
SPI.transfer(cmd);
VFD_STB_H();
}
void VFD_LED_OFF(uint8_t ledx)
{
// 关闭LED显示
SendCSToPT6312();
SPI.transfer(0x41); // 设定LED
switch (ledx)
{
case 1:
VFD_LED_Cmd |= 0x01;
break;
case 2:
VFD_LED_Cmd |= 0x02;
break;
case 3:
VFD_LED_Cmd |= 0x04;
break;
case 4:
VFD_LED_Cmd |= 0x08;
break;
default:
VFD_LED_Cmd = ledx;
break;
}
SPI.transfer(VFD_LED_Cmd);
VFD_STB_H();
}
void VFD_Display(void)
{
uint8_t i;
uint8_t *p = DisplayCache;
SendCSToPT6312();
SPI.transfer(0x40); // 设定数据
SendCSToPT6312();
SPI.transfer(0xc0);
for (i = 0; i < 9; i++)
{
SPI.transfer(*p++);
SPI.transfer(0x00);
}
SendCSToPT6312();
SPI.transfer(0x80 | ON | VFD_LIGHT);
VFD_STB_H();
}
void VFD_DisplayX(uint8_t x)
{
uint8_t i;
uint8_t *p = DisplayCache;
SendCSToPT6312();
SPI.transfer(0x40); // 设定数据
SendCSToPT6312();
SPI.transfer(0xc0);
for (i = 0; i < 9; i++)
{
SPI.transfer(*p++);
SPI.transfer(x);
}
SendCSToPT6312();
SPI.transfer(0x80 | ON | VFD_LIGHT);
VFD_STB_H();
}
void VFD_Display_Numb(uint8_t numb, uint8_t x, uint8_t len)
{
for (uint8_t i = 0; i < len; i++)
{
DisplayCache[x--] = vfdmap[numb % 10];
numb /= 10;
}
}
#define DEFAULT_STASSID "Xiaomi_Home_HE"
#define DEFAULT_STAPSW "1472683690"
struct wificonfig_type
{
char stassid[64];
char stapsw[64];
};
wificonfig_type wificonfig;
unsigned long epoch = 0;
uint8_t Second_temp = 0;
time_t t;
tm *tt;
char ch[21] = {0};
WiFiUDP ntpUDP;
// DHTesp dht11;
// You can specify the time server pool and the offset (in seconds, can be
// changed later with setTimeOffset() ). Additionaly you can specify the
// update interval (in milliseconds, can be changed using setUpdateInterval() ).
NTPClient timeClient(ntpUDP, "time1.aliyun.com", 3600 * 8, 60000 * 30);
RtcDS3231<TwoWire> Rtc(Wire);
/*
保存参数到EEPROM
*/
void wifisaveConfig()
{
Serial.println("Save config!");
Serial.print("stassid:");
Serial.println(wificonfig.stassid);
Serial.print("stapsw:");
Serial.println(wificonfig.stapsw);
EEPROM.begin(1024);
uint8_t *p = (uint8_t*)(&wificonfig);
for (int i = 0; i < sizeof(wificonfig); i++)
{
EEPROM.write(i, *(p + i));
}
EEPROM.commit();//保存更改的数据
}
/*
从EEPROM加载参数
*/
void wifiloadConfig()
{
EEPROM.begin(1024);
uint8_t *p = (uint8_t*)(&wificonfig);
for (int i = 0; i < sizeof(wificonfig); i++)
{
*(p + i) = EEPROM.read(i);
}
EEPROM.commit();//保存更改的数据
Serial.println("-----Read config-----");
Serial.print("stassid:");
Serial.println(wificonfig.stassid);
Serial.print("stapsw:");
Serial.println(wificonfig.stapsw);
}
uint8_t smartConfig(void)
{
uint8_t i = 0, count = 0;
WiFi.mode(WIFI_STA);
Serial.println("\r\nWait for Smartconfig");
VFD_LED_ON(3); //LED3亮 表示正在自动配网
for (i = 0; i < 9; i++)
DisplayCache[i] = 0x00;
delay(2000);
// 等待配网
WiFi.beginSmartConfig();
while (1)
{
Serial.print(".");
if (i >= 9)
{
for (i = 0; i < 9; i++)
DisplayCache[i] = 0x00;
i = 0;
}
DisplayCache[i] = 0x80;
VFD_DisplayX(0x03); //VFD显示
i++;
delay(500);
if (WiFi.smartConfigDone())
{
Serial.println("SmartConfig Success");
Serial.printf("SSID:%s\r\n", WiFi.SSID().c_str());
Serial.printf("PSW:%s\r\n", WiFi.psk().c_str());
// Serial.println(WiFi.smartConfigDone());
strcpy(wificonfig.stassid, WiFi.SSID().c_str());
strcpy(wificonfig.stapsw, WiFi.psk().c_str());
// WiFi.setAutoConnect(true); // 设置自动连接
break;
}
count++;
if (count >= 80) //40S
{
VFD_LED_OFF(3); //LED3灭 表示正在自动配网结束
Serial.println(WiFi.smartConfigDone());
return 1; //联网失败
}
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
VFD_LED_OFF(3); //LED3灭 表示正在自动配网结束
return 0; //联网成功
}
Ticker myTicker1; //建立一个需要定时调度的对象
//Ticker myTicker2; //建立一个需要定时调度的对象
//Ticker myTicker3; //建立一个需要定时调度的对象
Ticker myTicker4; //建立一个需要定时调度的对象
uint8_t TimeDisplay_Flag = 0; //时间是否刷新显示
uint8_t T_H_Display_Flag = 0; //温湿度是否刷新显示
uint8_t TimeShowMode = 1; //时间显示模式
uint8_t Daytemp = 0xFF; //时间天数缓存
uint8_t KEYScanFlag = 0; //按键扫描
uint8_t ADCGETFlag = 0; //ADC电压获取
uint8_t ADCGETCount = 0; //ADC电压获取次数
void tickerHandle1() //0.5到时间时需要执行的任务
{
// Serial.println(millis()); //打印当前时间
static uint8_t times_num1 = 0;
static uint8_t times_num2 = 0;
TimeDisplay_Flag = 1;
if (++times_num1 >= 5)
{
times_num1 = 0;
T_H_Display_Flag = 1;
}
if (++times_num2 >= 3)
{
LowPowerLED ^= 0x01; //取反
times_num2 = 0;
}
}
//void tickerHandle2() //10s到时间时需要执行的任务
//{
// TimeShowMode = 0x01; //
// myTicker2.detach(); //停止当前任务
//}
//void tickerHandle3() //1s到时间时需要执行的任务
//{
// AHT10ReadDataFlag = 1; //
//}
void tickerHandle4() //20ms到时间时需要执行的任务
{
KEYScanFlag = 1; //
ADCGETFlag = 1;
}
void NTP_TimeCheck(void) //NTP网络对时校准DS3231
{
if (WiFi.status() == WL_CONNECTED)
{
timeClient.begin();
Rtc.Begin();
timeClient.update();
epoch = timeClient.getEpochTime();
t = epoch;
tt = localtime(&t);
RtcDateTime compiled = RtcDateTime(tt->tm_year + 1900, tt->tm_mon + 1, tt->tm_mday, tt->tm_hour, tt->tm_min, tt->tm_sec);
Serial.println();
strftime(ch, sizeof(ch) - 1, "%Y-%m-%d %H:%M:%S", tt); //年-月-日 时-分-秒
Serial.println(ch);
printDateTime(compiled);
Serial.println();
if (!Rtc.GetIsRunning())
{
Serial.println("RTC was not actively running, starting now");
Rtc.SetIsRunning(true);
}
RtcDateTime now = Rtc.GetDateTime();
if (now < compiled)
{
Serial.println("RTC is older than compile time! (Updating DateTime)");
Rtc.SetDateTime(compiled);
}
else if (now > compiled)
{
Serial.println("RTC is newer than compile time. (this is expected)");
Rtc.SetDateTime(compiled);
}
else if (now == compiled)
{
Serial.println("RTC is the same as compile time! (not expected but all is fine)");
}
Rtc.Enable32kHzPin(false);
Rtc.SetSquareWavePin(DS3231SquareWavePin_ModeNone);
timeClient.end();
}
}
uint8_t WIFI_Connect(uint8_t configflag)
{
uint8_t time_count = 0, i = 0;
uint8_t configflagtemp=configflag;
WiFi.mode(WIFI_STA);
// WiFi.setAutoConnect(true); // 设置自动连接
WiFi.setAutoReconnect(true);//设置断开连接后重连
WiFi.begin(wificonfig.stassid, wificonfig.stapsw);
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
if (i >= 9)
{
for (i = 0; i < 9; i++)
DisplayCache[i] = 0x00;
i = 0;
}
DisplayCache[i] = 0x80;
VFD_DisplayX(0x02); //VFD显示
i++;
if (++time_count == 16) //超过8s未连接成功,启动自动配网
{
if(configflagtemp)
{
if (smartConfig()) //自动配网失败
{
return 1;
}
else //自动配网成功
{
wifisaveConfig();
ESP.restart(); //复位
break;
}
}
else
{
return 1;//联网失败
}
}
}
WiFi.setSleepMode(WIFI_MODEM_SLEEP); //
return 0;
}
void setup()
{
uint8_t time_out = 0;
// put your setup code here, to run once:
Serial.begin(115200);
// strcpy(wificonfig.stassid, DEFAULT_STASSID);
// strcpy(wificonfig.stapsw, DEFAULT_STAPSW);
// wifisaveConfig();
wifiloadConfig();
// dht11.setup(2, DHTesp::DHT11); // Connect DHT sensor to GPIO 2
pinMode(VFD_POWER, OUTPUT);
VFD_POWER_ON(); //开启显示电源
pinMode(ESP8266_LED, OUTPUT);
ESP8266_LED_OFF();//关闭LED
delay(500);
SPI.begin();
SPI.setBitOrder(LSBFIRST);
// SPI.setClockDivider(SPI_CLOCK_DIV32);
VFD_Init(); //VFD初始化
VFD_DisplayX(0x02); //VFD显示
// Wire.begin(DS3231_SDA, DS3231_SCL); // due to limited pins, use pin 0 and 2 for SDA, SCL
while (myAHT10.begin(DS3231_SDA, DS3231_SCL) != true)
{
Serial.println(F("AHT10 not connected or fail to load calibration coefficient")); //(F()) save string to flash & keeps dynamic memory free
time_out++;
delay(1000);
if (time_out >= 6)
{
AHT10ErrorFlag = 1;
break;
}
}
if (!AHT10ErrorFlag)
{
Serial.println(F("AHT10 OK"));
}
myAHT10.setNormalMode();
if (WIFI_Connect(0)) //联网失败
{
// VFD_LED_ON(2); //LED2亮 表示不联网
VFD_LED_Cmd &= 0xFD;
VFD_LED_Cmd |= 0x08;
VFD_LED_Send(VFD_LED_Cmd); //LED2亮 LED4灭 表示不联网
}
else
{
// VFD_LED_ON(4); //LED4亮
VFD_LED_Cmd &= 0xF7;
VFD_LED_Cmd |= 0x02;
VFD_LED_Send(VFD_LED_Cmd); //LED4亮 LED2灭 表示不联网
NTP_TimeCheck(); //NTP对时
}
WiFi.setAutoReconnect(false);//设置断开连接后不重连
// //WiFi.disconnect(); //断开连接,但仍然处于无线终端模式,只是清除了SSID和密码
WiFi.disconnect(true);//断开连接,直接关闭无线终端模式
// VFD_LED_ON(2); //LED2亮 表示不联网
VFD_LED_Cmd &= 0xFD;
VFD_LED_Cmd |= 0x08;
VFD_LED_Send(VFD_LED_Cmd); //LED2亮 LED4灭 表示不联网
myTicker1.attach_ms(500, tickerHandle1); //初始化调度任务,每0.5秒执行一次tickerHandle1()
// myTicker3.attach(2, tickerHandle3); //初始化调度任务,每2秒执行一次tickerHandle3()
myTicker4.attach_ms(50, tickerHandle4); //初始化调度任务,每50ms执行一次tickerHandle4()
}
void loop()
{
static bool time_valid_flag = true;
static bool time_valid_flag_temp = true;
static uint8_t wifi_connect_flag = 0;
static uint8_t KEYMode_temp = 0xFF;
static uint8_t VFD_LIGHT_Mode_temp = 0xFF;
uint8_t KEY_value = 0x00;
uint8_t time_out = 0x00;
float humidity = 0.0F;
float temperature = 0.0F;
uint16_t u16_humidity = 0;
int16_t i16_temperature = 0;
static uint32_t u32_adc_value = 0;
static uint8_t LowPowerFlagtemp = 0xFF;
static uint8_t LowPowercount = 0;
if (VFD_LIGHT_Mode_temp != VFD_LIGHT_Mode)
{
VFD_LIGHT_Mode_temp = VFD_LIGHT_Mode;
switch (VFD_LIGHT_Mode_temp)
{
case 0:
VFD_LIGHT = 0x02;
break;
case 1:
VFD_LIGHT = 0x04;
break;
case 2:
VFD_LIGHT = 0x07;
break;
}
SendCSToPT6312();
SPI.transfer(0x80 | ON | VFD_LIGHT); // Display Control
VFD_STB_H();
}
if (ADCGETFlag)
{
ADCGETFlag = 0;
// Serial.println(analogRead(A0)/102.4); //打印输出ADC引脚上电压
u32_adc_value += analogRead(A0);
ADCGETCount++;
if (ADCGETCount >= 50)
{
u32_adc_value /= ADCGETCount;
u32_adc_value *= 1000;//100
BAT_V_Value = u32_adc_value / 1024;
u32_adc_value = 0;
ADCGETCount = 0;
// Serial.println(BAT_V_Value); //打印输出ADC引脚上电压
if (BAT_V_Value <= 370)
{
LowPowercount++;
}
else
{
LowPowercount = 0;
LowPowerFlag = 0;
}
if(LowPowercount>=6)//联系测得6次较低
{
LowPowercount=0;
LowPowerFlag = 1;
}
}
}
if (LowPowerFlagtemp != LowPowerFlag)
{
LowPowerFlagtemp = LowPowerFlag;
if (!LowPowerFlagtemp)
{
ESP8266_LED_OFF();
VFD_POWER_ON(); //开启显示电源
delay(500);
VFD_Init(); //VFD初始化
VFD_DisplayX(0x02); //VFD显示
VFD_LED_ON(VFD_LED_Cmd); //点亮LED
}
else
{
if (WiFi.status() == WL_CONNECTED)//已联网
{
WiFi.setAutoReconnect(false);//设置断开连接后不重连
WiFi.disconnect(true);//断开连接,直接关闭无线终端模式
VFD_LED_Cmd &= 0xFD;
VFD_LED_Cmd |= 0x08;
VFD_LED_Send(VFD_LED_Cmd); //LED2亮 LED4灭 表示不联网
}
VFD_POWER_OFF(); //关闭显示电源
Serial.println(F("LOWPower!"));
}
}
if (LowPowerFlagtemp)
{
if (LowPowerLED)
{
ESP8266_LED_ON();
}
else
{
ESP8266_LED_OFF();
}
}
else
{
if (KEYMode_temp != KEYMode)
{
KEYMode_temp = KEYMode;
if (KEYMode_temp)
{
ESP8266_LED_ON();
}
else
{
ESP8266_LED_OFF();
}
}
if (KEYScanFlag)
{
KEYScanFlag = 0;
KEY_value = SPIRead_PT6312(0x43);
KEY_value &= 0x0F;
// Serial.print(KEY_value, HEX);
// Serial.println();
if (KEY_value != 0x0F)
{
time_out = 0x00;
if (!KEYMode)
{
switch (KEY_value)
{
case 0x07://KEY4 日期显示
TimeShowMode ^= 0x01; //取反
Daytemp = 0xFF; //立即刷新显示
Second_temp = 0xFF; //立即刷新显示
break;
case 0x0B://KEY3 温湿度显示
if (!AHT10ErrorFlag)
{
DisplayMode ^= 0x01; //取反
T_H_Display_Flag = 1; //立即刷新显示
}
break;
case 0x0D://KEY2 指示灯开关
VFD_LED_ONFlag ^= 0x01; //取反
if (VFD_LED_ONFlag)
{
VFD_LED_ON(VFD_LED_Cmd); //点亮LED
}
else
{
VFD_LED_Send(0x0F); //熄灭全部LED
}
break;
case 0x0E://KEY1 按键模式切换
KEYMode = 0x01;
break;
}
}
else
{
switch (KEY_value)
{
case 0x07://KEY4
VFD_LIGHT_Mode++;
if (VFD_LIGHT_Mode >= 3)
{
VFD_LIGHT_Mode = 0;
}
break;
case 0x0B://KEY3
wifi_connect_flag = 1; //启动联网
break;
case 0x0D://KEY2
if (WiFi.status() == WL_CONNECTED)//已联网
{
WiFi.setAutoReconnect(false);//设置断开连接后不重连
WiFi.disconnect(true);//断开连接,直接关闭无线终端模式
VFD_LED_Cmd &= 0xFD;
VFD_LED_Cmd |= 0x08;
VFD_LED_Send(VFD_LED_Cmd); //LED2亮 LED4灭 表示不联网
}
break;
case 0x0E://KEY1
KEYMode = 0x00;
break;
}
}
do {
delay(10);
KEY_value = SPIRead_PT6312(0x43);
KEY_value &= 0x0F;
if (++time_out >= 20)
break;
} while (KEY_value != 0x0F);
}
}
if (!DisplayMode)
{
if (TimeDisplay_Flag)
{
time_valid_flag = Rtc.IsDateTimeValid();
if (time_valid_flag != time_valid_flag_temp)
{
time_valid_flag_temp = time_valid_flag;
if (!time_valid_flag_temp)
{
if (Rtc.LastError() != 0)
{
// we have a communications error
// see https://www.arduino.cc/en/Reference/WireEndTransmission for
// what the number means
Serial.print("RTC communications error = ");
Serial.println(Rtc.LastError());
}
else
{
// Common Cuases:
// 1) the battery on the device is low or even missing and the power line was disconnected
Serial.println("RTC lost confidence in the DateTime!");
}
VFD_LED_ON(1); //LED1亮 时间数据失效
}
else
{
VFD_LED_OFF(1); //LED1灭 时间数据有效
}
}
RtcDateTime now = Rtc.GetDateTime();
if (TimeShowMode)
{
if (Second_temp != now.Second())
{
// Serial.println(timeClient.getFormattedTime());
// Serial.println(epoch);
// Serial.println(tt->tm_sec);
VFD_Display_Numb(now.Second(), 8, 2);
DisplayCache[0] = 0x40; //'-' =0x40
VFD_Display_Numb(now.Minute(), 5, 2);
DisplayCache[3] = 0x40; //'-' =0x40
VFD_Display_Numb(now.Hour(), 2, 2);
DisplayCache[6] = 0x40; //'-' =0x40
VFD_Display();
Daytemp = 255;
// strftime(ch, sizeof(ch) - 1, "%Y-%m-%d %H:%M:%S", tt); //年-月-日 时-分-秒
// Serial.println(ch);
// printDateTime(now);
// Serial.println();
Second_temp = now.Second();
// delay(1000);
}
}
else
{
if (Daytemp != now.Day())
{
VFD_Display_Numb(now.Day(), 8, 2);
DisplayCache[6] = 0x40; //'-' =0x40
VFD_Display_Numb(now.Month(), 5, 2);
DisplayCache[3] = 0x40; //'-' =0x40
VFD_Display_Numb(now.DayOfWeek(), 2, 2);
DisplayCache[0] = 0x40; //'-' =0x40
VFD_Display();
Daytemp = now.Day();
}
}
TimeDisplay_Flag = 0;
}
}
else//显示温湿度
{
if (T_H_Display_Flag)
{
T_H_Display_Flag = 0;
temperature = myAHT10.readTemperature(AHT10_FORCE_READ_DATA);
humidity = myAHT10.readHumidity(AHT10_USE_READ_DATA);//myAHT10.readTemperature(AHT10_FORCE_READ_DATA)
Serial.println();
Serial.print(F("Temperature: ")); Serial.print(temperature); Serial.println(F(" +-0.3C")); //by default "AHT10_FORCE_READ_DATA"
Serial.print(F("Humidity...: ")); Serial.print(humidity); Serial.println(F(" +-2%")); //by default "AHT10_FORCE_READ_DATA"
u16_humidity = humidity * 10;
i16_temperature = temperature * 10;
if (i16_temperature < 0)
{
DisplayCache[0] = 0x40; //'-' =0x40
i16_temperature = -i16_temperature;
}
else
{
DisplayCache[0] = 0x00; //'-' =0x40
}
VFD_Display_Numb(i16_temperature / 10, 2, 2); //温度整数部分
DisplayCache[2] |= 0x80; //加入小数点
VFD_Display_Numb(i16_temperature % 10, 3, 1); //温度小数部分
DisplayCache[4] = 0x39; //加入‘C’
VFD_Display_Numb(u16_humidity / 10, 6, 2); //温度整数部分
DisplayCache[6] |= 0x80; //加入小数点
VFD_Display_Numb(u16_humidity % 10, 7, 1); //温度小数部分
DisplayCache[8] = 0x76; //加入‘H’
VFD_Display();
}
}
// put your main code here, to run repeatedly:
// timeClient.update();
// epoch = timeClient.getEpochTime();
// t = epoch;
// tt = localtime(&t);
// if (AHT10ReadDataFlag)
// {
// AHT10ReadDataFlag = 0;
/* DEMO - 1, every temperature or humidity call will read 6 bytes over I2C, total 12 bytes */
// Serial.println(F("DEMO 1: read 12-bytes, show 255 if communication error is occurred"));
// Serial.print(F("Temperature: ")); Serial.print(myAHT10.readTemperature()); Serial.println(F(" +-0.3C")); //by default "AHT10_FORCE_READ_DATA"
// Serial.print(F("Humidity...: ")); Serial.print(myAHT10.readHumidity()); Serial.println(F(" +-2%")); //by default "AHT10_FORCE_READ_DATA"
// /* DEMO - 2, temperature call will read 6 bytes via I2C, humidity will use same 6 bytes */
// Serial.println(F("DEMO 2: read 6 byte, show 255 if communication error is occurred"));
// Serial.print(F("Temperature: ")); Serial.print(myAHT10.readTemperature(AHT10_FORCE_READ_DATA)); Serial.println(F(" +-0.3C"));
// Serial.print(F("Humidity...: ")); Serial.print(myAHT10.readHumidity(AHT10_USE_READ_DATA)); Serial.println(F(" +-2%"));
// /* DEMO - 3, same as demo2 but different call procedure */
// Serial.println(F("DEMO 3: read 6-bytes, show 255 if communication error is occurred"));
//
// AHT10ReadStatus = myAHT10.readRawData(); //read 6 bytes from AHT10 over I2C
//
// if (AHT10ReadStatus != AHT10_ERROR)
// {
// Serial.print(F("Temperature: ")); Serial.print(myAHT10.readTemperature(AHT10_USE_READ_DATA)); Serial.println(F(" +-0.3C"));
// Serial.print(F("Humidity...: ")); Serial.print(myAHT10.readHumidity(AHT10_USE_READ_DATA)); Serial.println(F(" +-2%"));
// }
// else
// {
// Serial.print(F("Failed to read - reset: "));
// Serial.println(myAHT10.softReset()); //reset 1-success, 0-failed
// }
// }
// if (irrecv.decode(&results))
// {
// //打印字符串
// String codeString = getRremoteString(results.value);
// if ((codeString.length() != 0))
// {
// Serial.println(codeString);
// if (codeString == "EQ")
// {
// if (TimeShowMode)
// {
// TimeShowMode = 0;
// myTicker2.attach(10, tickerHandle2);
// }
// }
// // else if(codeString=="VOL+")
// // {
// // DisplayMode ^=0x01;//取反
// // T_H_Display_Flag=1;//立即刷新显示
// // }
// else if (codeString == "PLAY/PAUSE")
// {
// wifi_connect_flag = 1; //启动联网
// }
// else if (codeString == "CH")
// {
// NTP_TimeCheck(); //NTP对时
// }
// else if (codeString == "CH-")
// {
// digitalWrite(16, LOW); //关闭显示电源
// }
// else if (codeString == "CH+")
// {
// digitalWrite(16, HIGH); //开启显示电源
// VFD_Init(); //VFD初始化
// delay(100); //等待100MS
// VFD_LED_ON(VFD_LED_Cmd); //点亮LED
// }
// else if (codeString == "NEXT")
// {
// VFD_LED_ONFlag ^= 0x01; //取反
// if (VFD_LED_ONFlag)
// {
// VFD_LED_ON(VFD_LED_Cmd); //点亮LED
// }
// else
// {
// VFD_LED_Send(0x0F); //熄灭全部LED
// }
// }
// }
// irrecv.resume(); // 接收下一个值
// }
if (wifi_connect_flag)
{
wifi_connect_flag = 0;
if (WiFi.status() != WL_CONNECTED)//未联网
{
if (WIFI_Connect(1)) //联网失败
{
// VFD_LED_ON(2); //LED2亮 表示不联网
VFD_LED_Cmd &= 0xFD;
VFD_LED_Cmd |= 0x08;
VFD_LED_Send(VFD_LED_Cmd); //LED2亮 LED4灭 表示不联网
}
else
{
// VFD_LED_OFF(2); //LED2灭 表示联网
// VFD_LED_ON(4); //LED4亮
VFD_LED_Cmd &= 0xF7;
VFD_LED_Cmd |= 0x02;
VFD_LED_Send(VFD_LED_Cmd); //LED4亮 LED2灭 表示不联网
NTP_TimeCheck(); //NTP对时
}
}
else//已经联网
{
VFD_LED_OFF(2); //LED2灭 表示联网
NTP_TimeCheck(); //NTP对时
}
}
}
}
/**
解析红外编码并返回对应的字符串
*/
//String getRremoteString(unsigned long code)
//{
// String rremotestring = "";
// int i = 0;
// for (i = 0; i < MAX - 1; i++)
// {
// if (code == rremote_code[i])
// {
// break;
// }
// }
// // 过滤掉长按
// if (i == MAX - 1)
// return "";
// else
// return rremote_string[i];
// return rremote_string[i];
//}
#define countof(a) (sizeof(a) / sizeof(a[0]))
void printDateTime(const RtcDateTime &dt)
{
char datestring[25];
snprintf_P(datestring,
countof(datestring),
PSTR("%02u/%02u/%04u %02u:%02u:%02u %02u"),
dt.Month(),
dt.Day(),
dt.Year(),
dt.Hour(),
dt.Minute(),
dt.Second(),
dt.DayOfWeek());
Serial.print(datestring);
}
制作过程
焊接好的控制板与显示板:
待焊接ESP-12F主控及VFD显示屏的PCB板和几个做好的:
相关资料
资料内容:链接