三星9位段码VFD_ESP8266主控时钟实现

三星9位段码VFD_ESP8266主控时钟

最终效果

三星9位段码VFD_ESP8266主控时钟实现三星9位段码VFD_ESP8266主控时钟实现三星9位段码VFD_ESP8266主控时钟实现
还是不出的哈哈哈,电路分为两块,VFD显示部分以及ESP8266主控部分

硬件介绍

显示屏

三星9位段码VFD_ESP8266主控时钟实现三星9位段码VFD_ESP8266主控时钟实现图片均来自淘宝,因为已经没有VFD变压器提供了,所以我使用了没有变压器的VFD驱动电路

VFD驱动

VFD驱动我使用了专用驱动IC-PT6312,需为此IC提供负高压(-20V以上)以驱动VFD栅极,以及提供灯丝的交变电压。

VFD电源电路

经过我不懈的努力在网上找到了,一个无变压器产生负压以及灯丝交变电压的电路:网站,有能用的当然是买过来啦,一块钱可以接受。
“本电路采用廉价的音频功放集成电路,通过文氏电路自激震荡,低压下能输出符合驱动灯丝要求的交流电源;同时利用高集成度的高频boost-bust驱动电路产生负高压驱动栅极,电路非常简单,无需调试,即可生成驱动VFD的三路电压,通过改变采样电路分压电阻,能适配不同电压要求的VFD屏。整套电路成本非常低,不用采用变压器,能达到93%的驱动效率,适合推动绝大多数负高压的VFD电路。”
——来自作者描述

VFD显示屏部分电路图

三星9位段码VFD_ESP8266主控时钟实现因为使用ESP8266作为主控,IO不多,PT6312正好可以控制4个LED,以及按键检测,于是直接将这些集成到VFD显示板上了。
三星9位段码VFD_ESP8266主控时钟实现

ESP8266主控板

三星9位段码VFD_ESP8266主控时钟实现电路好像没啥特色哈哈哈,就不多讲啦。这里使用ETA6093的原因是我本来想使用电池的,但这个系统耗电量还是挺大的,接电池不能工作很久(就几小时),钰泰ETA6093三合一SOC电源管理芯片,支持1A开关充电,1A同步升压,充放电效率高。SOT23-5小型封装,集成度,外围少。搭配USB-C接口使用,可以做C口充放电功能。

代码介绍

写代码当然是Ctrl+CCtrl+V啦,能不用自己写的就一点也不自己写,这里使用ArduinoIDE编写ESP8266代码,以前一直不怎么喜欢Arduino(真香),疯狂使用别人的库就行啦,哈哈哈。
大量代码参考自(拷贝自)单片机菜鸟哥的ESP8266 Arduino教程
NTP网络校时代码则来自B站的一位大神的开源项目代码。

主要实现功能

这里偷懒直接截图一下我写的使用说明:
三星9位段码VFD_ESP8266主控时钟实现三星9位段码VFD_ESP8266主控时钟实现

配网

这里使用的是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);
}

制作过程

焊接好的控制板与显示板:
三星9位段码VFD_ESP8266主控时钟实现待焊接ESP-12F主控及VFD显示屏的PCB板和几个做好的:
三星9位段码VFD_ESP8266主控时钟实现

相关资料

资料内容:链接
三星9位段码VFD_ESP8266主控时钟实现

上一篇:ESP8266引脚的说明


下一篇:开源OA办公平台搭建教程:O2OA+Arduino实现物联网应用(一)