display

作者: 全村滴希望 | 来源:发表于2019-12-24 20:50 被阅读0次
#include <ArduinoJson.h>
#include <ESP8266WiFi.h>
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Max72xxPanel.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClientSecureBearSSL.h>
#include <WiFiUdp.h>
#include <TimeLib.h>

int pinCS = D4; // Attach CS to this pin, DIN to MOSI and CLK to SCK (cf http://arduino.cc/en/Reference/SPI )
/**
 * ESP8266 Pin
 * D4 -> CS    -> CS
 * D5 -> HSCLK -> CLK
 * D7 -> HMOSI -> DIN
 * 3V -> VCC
 * G  -> GND
 */
int numberOfHorizontalDisplays = 4;
int numberOfVerticalDisplays = 1;
#define _DISPLAY_ROTATE 1

Max72xxPanel matrix = Max72xxPanel(pinCS, numberOfHorizontalDisplays, numberOfVerticalDisplays);

#ifndef STASSID
#define STASSID "█████████████████"
#define STAPSK  "█████████"
#endif

const char* ssid = "fyx";
const char* password = "20000402";

WiFiUDP Udp;
const int NTP_PACKET_SIZE = 48;     // NTP time is in the first 48 bytes of the message
byte packetBuffer[NTP_PACKET_SIZE]; // Buffer for I / O packets
unsigned int localPort = 8888; // Local port for listening UDP packets
static const char ntpServerName[] = "ntp.sjtu.edu.cn"; // NTP server, Shanghai Jiaotong University
const int timeZone = 8;                                // Time zone, Beijing time is + 8
time_t preDisplayTime = 0; // Last clock display time
String display_content = "00:00";
int days = 0;
int change_flag = 0;  //display time when flag is 0, display days when flag is 1


// 3x5 char maps
uint16_t numMap3x5[] = {
    32319,  //0
    10209,  //1
    24253, //2
    22207,  //3
    28831,  //4
    30391,  //5
    32439,  //6
    16927,  //7
    32447,  //8
    30399  //9
};
// 4x5 char maps
uint32_t numMap4x5[] = {
    476718,  //0
    10209,  //1
    315049, //2
    579246,  //3
    478178,  //4
    972470,  //5
    480418,  //6
    544408,  //7
    349866,  //8
    415406  //9
};


unsigned long api_mtbs = 20000; //mean time between api requests
unsigned long api_lasttime = 20000;   //last time api request has been done

#define PIXEL_SHOW HIGH
#define PIXEL_HIDE LOW

void _drawPixel(Max72xxPanel display, uint8_t x, uint8_t y, uint8_t pixel)
{
  display.drawPixel(x, y, pixel);
}

void _drawLine(Max72xxPanel display, uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, uint8_t pixel)
{
  display.drawLine(x1, y1, x2, y2, pixel);
}

void _drawPixelHorizontalMirror(Max72xxPanel display, uint8_t x, uint8_t y, uint8_t pixel)
{
  display.drawPixel(x, y, pixel);
  display.drawPixel(7-x, y, pixel);
}

void _fillHeart(Max72xxPanel display, uint8_t pixel)
{
    _drawPixelHorizontalMirror(display, 1, 2, pixel);
    _drawPixelHorizontalMirror(display, 1, 3, pixel);
    _drawPixelHorizontalMirror(display, 2, 2, pixel);
    _drawPixelHorizontalMirror(display, 2, 3, pixel);
    _drawPixelHorizontalMirror(display, 2, 4, pixel);
    _drawPixelHorizontalMirror(display, 3, 3, pixel);
    _drawPixelHorizontalMirror(display, 3, 4, pixel);
    _drawPixelHorizontalMirror(display, 3, 5, pixel);
}

void drawHeart(Max72xxPanel display, int heart_fill)
{
    display.fillRect(0, 0, 8, 8, PIXEL_HIDE);
    _drawPixelHorizontalMirror(display, 3, 2, PIXEL_SHOW);
    _drawPixelHorizontalMirror(display, 2, 1, PIXEL_SHOW);
    _drawPixelHorizontalMirror(display, 1, 1, PIXEL_SHOW);
    _drawPixelHorizontalMirror(display, 0, 2, PIXEL_SHOW);
    _drawPixelHorizontalMirror(display, 0, 3, PIXEL_SHOW);
    _drawPixelHorizontalMirror(display, 1, 4, PIXEL_SHOW);
    _drawPixelHorizontalMirror(display, 2, 5, PIXEL_SHOW);
    _drawPixelHorizontalMirror(display, 3, 6, PIXEL_SHOW);
    if (heart_fill == 1) {
      _fillHeart(display, PIXEL_SHOW);
    }
    else {
      _fillHeart(display, PIXEL_HIDE);
    }

}

void drawSplashtop(Max72xxPanel display)
{
  // F
  _drawLine(display, 8, 1, 8, 5, PIXEL_SHOW);
  _drawLine(display, 9, 1, 10, 1, PIXEL_SHOW);
  _drawLine(display, 9, 3, 10, 3, PIXEL_SHOW);

  // O
  _drawLine(display, 12, 1, 12, 5, PIXEL_SHOW);
  _drawLine(display, 13, 1, 14, 1, PIXEL_SHOW);
  _drawLine(display, 13, 5, 14, 5, PIXEL_SHOW);
  _drawLine(display, 14, 2, 14, 4, PIXEL_SHOW);

  //R
  _drawLine(display, 16, 1, 16, 5, PIXEL_SHOW);
  _drawLine(display, 17, 1, 18, 1, PIXEL_SHOW);
  _drawPixel(display, 18, 2, PIXEL_SHOW);
  _drawPixel(display, 17, 3, PIXEL_SHOW);
  _drawLine(display, 18, 4, 18, 5, PIXEL_SHOW);

  // F
  _drawLine(display, 21, 1, 21, 5, PIXEL_SHOW);
  _drawLine(display, 22, 1, 23, 1, PIXEL_SHOW);
  _drawLine(display, 22, 3, 23, 3, PIXEL_SHOW);

  // Y
  _drawLine(display, 25, 1, 25, 3, PIXEL_SHOW);
  _drawLine(display, 27, 1, 27, 3, PIXEL_SHOW);
  _drawLine(display, 26, 4, 26, 5, PIXEL_SHOW);

  // X
  _drawLine(display, 29, 1, 29, 2, PIXEL_SHOW);
  _drawLine(display, 29, 4, 29, 5, PIXEL_SHOW);
  _drawLine(display, 31, 1, 31, 2, PIXEL_SHOW);
  _drawLine(display, 31, 4, 31, 5, PIXEL_SHOW);
  _drawPixel(display, 30, 3, PIXEL_SHOW);

  display.write();

  // Y
  //_drawLine(display, 21, 1, 21, 3, PIXEL_SHOW);
  //_drawLine(display, 23, 1, 23, 3, PIXEL_SHOW);
  //_drawLine(display, 22, 4, 22, 5, PIXEL_SHOW);

  // O
  //_drawLine(display, 25, 1, 25, 5, PIXEL_SHOW);
  //_drawLine(display, 26, 1, 27, 1, PIXEL_SHOW);
  //_drawLine(display, 26, 5, 27, 5, PIXEL_SHOW);
  //_drawLine(display, 27, 2, 27, 4, PIXEL_SHOW);

  // U
  //_drawLine(display, 29, 1, 29, 5, PIXEL_SHOW);
  //_drawLine(display, 31, 1, 31, 5, PIXEL_SHOW);
  //_drawPixel(display, 30, 5, PIXEL_SHOW);

  // W
  //_drawLine(display, 17, 1, 17, 2, PIXEL_SHOW);
  //_drawLine(display, 18, 3, 18, 4, PIXEL_SHOW);
  //_drawPixel(display, 19, 5, PIXEL_SHOW);
  //_drawLine(display, 20, 2, 20, 4, PIXEL_SHOW);
  //_drawPixel(display, 21, 5, PIXEL_SHOW);
  //_drawLine(display, 22, 3, 22, 4, PIXEL_SHOW);
  //_drawLine(display, 23, 1, 23, 2, PIXEL_SHOW);

  // W
  //_drawLine(display, 25, 1, 25, 2, PIXEL_SHOW);
  //_drawLine(display, 26, 3, 26, 4, PIXEL_SHOW);
  //_drawPixel(display, 27, 5, PIXEL_SHOW);
  //_drawLine(display, 28, 2, 28, 4, PIXEL_SHOW);
  //_drawPixel(display, 29, 5, PIXEL_SHOW);
  //_drawLine(display, 30, 3, 30, 4, PIXEL_SHOW);
  //_drawLine(display, 31, 1, 31, 2, PIXEL_SHOW);
}

void drawMapValue3x5(Max72xxPanel display, uint8_t x, uint8_t y, uint32_t val)
{
    for (uint8_t i = 0; i < 20; i++)
    {
        if ((val >> i) & 1 == 1) {
            display.drawPixel(x + (3 - i / 5) - 1, y + (4 - i % 5), PIXEL_SHOW);
        }
    }
}

void drawMapValue4x5(Max72xxPanel display, uint8_t x, uint8_t y, uint32_t val)
{
    for (uint8_t i = 0; i < 20; i++)
    {
        if ((val >> i) & 1 == 1) {
            display.drawPixel(x + (4 - i / 5) - 1, y + (4 - i % 5), PIXEL_SHOW);
        }
    }
}

int calculatDays(int year_start, int month_start, int day_start, int year_end, int month_end, int day_end){
  int y2, m2, d2;
  int y1, m1, d1;
  
  m1 = (month_start + 9) % 12;
  y1 = year_start - m1/10;
  d1 = 365*y1 + y1/4 - y1/100 + y1/400 + (m1*306 + 5)/10 + (day_start - 1);
  
  m2 = (month_end + 9) % 12;
  y2 = year_end - m2/10;
  d2 = 365*y2 + y2/4 - y2/100 + y2/400 + (m2*306 + 5)/10 + (day_end - 1);

 return (d2 - d1);
}

void changeDisplay(){
  if (change_flag == 0) {
    int days = calculatDays(2000, 4, 2, year(), month(), day());
    display_content = days;
    display_content = display_content + "   D";
    change_flag = 1;
  }
  else{
    display_content = displayTimeFormat(hour(), minute());
    change_flag = 0;
  }
}

String displayTimeFormat(int hour, int minute){
  if (hour>=0 && hour<=9) {
    display_content = "0";
    display_content = display_content + hour;
  }
  else{
    display_content = hour;
  }

  display_content = display_content + ":";

  if (minute>=0 && minute<=9) {
    display_content = display_content + "0";
    display_content = display_content + minute;
  }
  else{
    display_content = display_content + minute;
  }
  
  return display_content;
}

void refreshTime(){
  if (timeStatus() != timeNotSet){
    if (now() != preDisplayTime){
      preDisplayTime = now();
      display_content = displayTimeFormat(hour(), minute());
    }
  }
}

time_t getNtpTime()
{
    IPAddress ntpServerIP;

    while (Udp.parsePacket() > 0);
    Serial.println("Transmit NTP Request");
    WiFi.hostByName(ntpServerName, ntpServerIP);
    Serial.print(ntpServerName);
    Serial.print(": ");
    Serial.println(ntpServerIP);
    sendNTPpacket(ntpServerIP);
    uint32_t beginWait = millis();
    while (millis() - beginWait < 1500){
        int size = Udp.parsePacket();
        if (size >= NTP_PACKET_SIZE){
            Serial.println("Receive NTP Response");
            Udp.read(packetBuffer, NTP_PACKET_SIZE);
            unsigned long secsSince1900;
            secsSince1900 = (unsigned long)packetBuffer[40] << 24;
            secsSince1900 |= (unsigned long)packetBuffer[41] << 16;
            secsSince1900 |= (unsigned long)packetBuffer[42] << 8;
            secsSince1900 |= (unsigned long)packetBuffer[43];
            Serial.println(secsSince1900);
            Serial.println(secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR);
            return secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR;
        }
    }
    Serial.println("No NTP Response :-(");
    return 0; 
}


void sendNTPpacket(IPAddress &address)
{
    memset(packetBuffer, 0, NTP_PACKET_SIZE);
    packetBuffer[0] = 0b11100011; // LI, Version, Mode
    packetBuffer[1] = 0;          // Stratum, or type of clock
    packetBuffer[2] = 6;          // Polling Interval
    packetBuffer[3] = 0xEC;       // Peer Clock Precision
    // 8 bytes of zero for Root Delay & Root Dispersion
    packetBuffer[12] = 49;
    packetBuffer[13] = 0x4E;
    packetBuffer[14] = 49;
    packetBuffer[15] = 52;
    Udp.beginPacket(address, 123);
    Udp.write(packetBuffer, NTP_PACKET_SIZE);
    Udp.endPacket();
}

void setup() {
    SPI.begin();
    SPI.setFrequency(10000000); // Here is 10Mhz
    matrix.setIntensity(2); // Set brightness between 0 and 15
    for (int i = 0; i< numberOfHorizontalDisplays;  i++)
        matrix.setRotation(i,_DISPLAY_ROTATE);
    matrix.fillScreen(PIXEL_HIDE);
    drawHeart(matrix, 1);
    drawSplashtop(matrix);
    
    WiFi.mode(WIFI_STA);
    wifi_fpm_set_sleep_type(LIGHT_SLEEP_T);
    WiFi.begin(ssid, password);

    Serial.begin(115200);
    Serial.println();
    Serial.printf("Flash: %d\n", ESP.getFlashChipRealSize());
    Serial.print("Connecting");
    int processbar = 0;
    while (WiFi.status() != WL_CONNECTED) {
        delay(100);
        Serial.print(".");
        drawHeart(matrix, processbar % 2);
        matrix.drawPixel(8 + (processbar % 24), 7, (processbar / 24) % 2 == 0 ? PIXEL_SHOW : PIXEL_HIDE);
        matrix.write();
        processbar++;
    }

    Serial.println();

    Serial.print("Connected to wifi. My address:");
    IPAddress myAddress = WiFi.localIP();
    Serial.println(myAddress);

    WiFi.setSleepMode(WIFI_LIGHT_SLEEP, 1000);
    matrix.fillScreen(PIXEL_HIDE);
    drawHeart(matrix, 1);
    drawSplashtop(matrix);
    Udp.begin(localPort);
    setSyncProvider(getNtpTime);
    setSyncInterval(300);     //Synchronize every 300 seconds
    display_content = displayTimeFormat(hour(), minute());
}

void loop() {
    // because of unsigned long, when overflow, it will be huge number
    unsigned long duration = millis() - api_lasttime;
    if (duration >= api_mtbs)
    {
        api_lasttime = millis();
        if (WiFi.status() != WL_CONNECTED) {
            Serial.println("WiFi Disconnected");
            ESP.restart();
        }
        changeDisplay();
    }
    matrix.fillScreen(PIXEL_HIDE);
    
    //Progress bar countdown
    int x = 9;
    drawHeart(matrix, 1);
    Serial.println("[duration]:" + duration);
    uint32_t waitBarLen = 20 - (duration / float(api_mtbs) * 20);
    if (waitBarLen > 20) waitBarLen = 20;
    for (uint8_t waitBar = 0; waitBar < waitBarLen; waitBar++)
    {
      _drawPixel(matrix, 9 + waitBar, 6, PIXEL_SHOW);
      _drawPixel(matrix, 9 + waitBar, 7, PIXEL_SHOW);
    }

    //show contents
    if (change_flag == 0) {
      refreshTime();
    }
    Serial.println("[display_content]:" + display_content);
    for (int i=0; i<display_content.length(); i++) {
        if (display_content[i] >= '0' && display_content[i] <= '9')
        {
            drawMapValue3x5(matrix, x, 0, numMap3x5[display_content[i] - '0']);
            x += 4;
        } else if (display_content[i] == ':') {
            matrix.drawPixel(x, 2, PIXEL_SHOW);
            matrix.drawPixel(x, 4, PIXEL_SHOW);
            x += 2;
        } else if (display_content[i] == ' ') {
            x += 1;
        } else {
            //matrix.drawChar(x, 0, display_content[i], PIXEL_SHOW, PIXEL_HIDE, 1);
            matrix.drawLine(x, 0, x, 4, PIXEL_SHOW);
            matrix.drawLine(x+1, 0, x+2, 0,PIXEL_SHOW);
            matrix.drawLine(x+1, 4, x+2, 4,PIXEL_SHOW);
            matrix.drawLine(x+3, 1, x+3, 3, PIXEL_SHOW);
            x+=5;
        }
    }
    matrix.write(); // Send bitmap to display
    delay(1000);
}

相关文章

网友评论

      本文标题:display

      本文链接:https://www.haomeiwen.com/subject/dcafoctx.html