Wemos D1 Mini MX7219 NTP时钟-如何将变量传递给Parola效果

时间:2018-06-19 12:02:36

标签: arduino iot esp8266 electronics

我想做的是使用Wemos D1 Mini v3创建一个简单的NTP时钟,该时钟将在64x8 MAX7219屏幕(2个加入的32x8屏幕)上显示工作日,日期和时间。

我在网上发现a sketch确实可以做到这一点,但是它使用滚动效果来更新屏幕,我想将其更改为其他效果。然后我发现了MD Parola库,它具有我要使用的效果(称为PA_OPENING_CURSOR)。附带说明一下,我正在使用最新的MD_ParolaMD_MAX72xx库(它们大约在一个月前更新)。

我想要得到的结果是:

  • 显示工作日(例如星期四)
  • 将PA_OPENING_CURSOR效果切换为日期(例如12/05/2019)
  • 切换到时间(例如19:57)(再次具有PA_OPENING_CURSOR效果)
  • 重复

通过使用初始草图并将其与Parola库示例合并,我设法到达了下面的草图(从原始草图更改并进行了评论,以便我可以更好地理解代码和所采取的每个步骤-新手警报),但由于不知道如何将所需的变量传递给产生切换效果的代码,我陷入了停滞状态。如您所见,该草图当前显示工作日/日期/时间(星期一/ 2345/21 Jan / 17:21:59),但它们的值仅是硬编码(静态)的,因此不会从NTP服务器上拉出。 Arduino IDE的串行监视器向我显示NTP时间已从NTP服务器正确提取。

到目前为止,我的代码是:

/*
NTP CLOCK and DATE Scroller
*/


//___________________________________________________________LIBRARIES USED
#include <MD_Parola.h>
#include <MD_MAX72xx.h>
#include <SPI.h>
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <ESP8266WebServer.h>
#include <TimeLib.h>

//___________________________________________________________PINS DEFINITIONS
#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
#define MAX_DEVICES 8
#define CLK_PIN   D5 // or SCK
#define DATA_PIN  D7 // or MOSI
#define CS_PIN    D4 // or SS

//___________________________________________________________ARBITRARY PINS DEFINITIONS
MD_Parola p = MD_Parola(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);


//___________________________________________________________USER CONTROL (POTENTIOMETER)
#define USE_UI_CONTROL 0 // set to 1 if we are implementing the user interface pot

#if USE_UI_CONTROL
#define SPEED_IN  A0
uint8_t frameDelay = 25;  // default frame delay value
#endif

//___________________________________________________________SPEED DEFINITION
#define SPEED_TIME  25  // Lower number means faster speed
#define PAUSE_TIME  2000

//___________________________________________________________DEBUGGING
#define  DEBUG  1 // Change to 1/0 to turn on/off debug statements to the serial output

#if  DEBUG
#define PRINT(s, x) { Serial.print(F(s)); Serial.print(x); }
#define PRINTS(x) Serial.print(F(x))
#define PRINTX(x) Serial.println(x, HEX)
#else
#define PRINT(s, x)
#define PRINTS(x)
#define PRINTX(x)
#endif

//___________________________________________________________WEB SERVER SETUP
ESP8266WebServer server(80);
const char ssid[] = "My_SSID_here";  //  your network SSID (name)
const char pass[] = "My_Password_here";       // your network password

//___________________________________________________________NTP SERVER and TIMEZONE
static const char ntpServerName[] = "3.uk.pool.ntp.org";
const float timeZone = 1.0;     // UK Standard Time

WiFiUDP Udp;
unsigned int localPort = 8888;  // local port to listen for UDP packets
time_t getNtpTime();
void sendNTPpacket(IPAddress &address);
static boolean isLongFormat = false;

String myTime;
String myDate;

//___________________________________________________________TIME AND DATE FUNCTION
void timeDisplay() {
  // Populate myTime String
  myTime = hour();

  if (hour() < 10) {
    myTime = "0" + myTime;
  }

  if (minute() < 10) {
    myTime = myTime + " : 0" + minute();
  }
  else {
    myTime = myTime + " : " + minute();
  }

  myTime = (" " + myTime + " ");
  PRINT("\nMyTime: ", myTime);

  int myTime_len = myTime.length() + 1;
  char myTime_charArray[myTime_len];
  myTime.toCharArray(myTime_charArray, myTime_len);

  PRINT("\nMyTime_charArray: ", myTime_charArray );

}

void dateDisplay() {
  // Populate myDate String
  myDate = myDate + "  " + day() + " " + monthShortStr(month()) + " " + year() ;
  myDate = (" " + myDate + " ");
  PRINT("\nMyDate: " , myDate);


  // covert from string/float to char array
  int myDate_len = myDate.length() + 1;
  char myDate_charArray[myDate_len];
  myDate.toCharArray(myDate_charArray, myDate_len);

  PRINT("\nMyDate_charArray: ", myDate_charArray);

}

//___________________________________________________________DEFINE THE TEXT TO DISPLAY
// Global variables
uint8_t  curText;
char  *pc[] =
{
  "Monday",
  "17 Jan 2345",
  "21 : 59",

};

//___________________________________________________________DEFINE THE TEXT EFFECT
uint8_t  inFX, outFX;
textEffect_t  effect[] =
{
  PA_OPENING_CURSOR,
};

//___________________________________________________________USER CONTROL ACTIONS (IF USED)
#if USE_UI_CONTROL
void doUI(void)
{
  // set the speed if it has changed
  {
    int16_t speed = map(analogRead(SPEED_IN), 0, 1023, 0, 250);

    if (speed != (int16_t)p.getSpeed())
    {
      p.setSpeed(speed);
      p.setPause(speed);
      frameDelay = speed;
      PRINT("\nChanged speed to ", p.getSpeed());
    }
  }
}
#endif // USE_UI_CONTROL

//___________________________________________________________void setup
void setup()
{
  p.begin();

#if  DEBUG
  Serial.begin(115200);
  delay(1000);
#endif

  Serial.begin(115200);
  PRINTS("\nLet's see if this thing will EVER work...");
  PRINTS("\n ");
  delay(1000);

  PRINT("\nConnecting to the WiFi Network named > ", ssid);

  WiFi.begin(ssid, pass);
  delay(1000);

  PRINTS("\n ");
  PRINTS("\nConnection established successfully");
  PRINTS("\n ");
  PRINT("\nThe IP address assigned to your device by your WiFi router is ", WiFi.localIP());
  PRINTS("\n ");
  PRINTS("\nStarting UDP...");
  PRINTS("\n ");
  Udp.begin(localPort);
  PRINT("\nLocal port: ", Udp.localPort());
  PRINTS("\n ");
  PRINTS("\nWaiting for synchronisation...");
  PRINTS("\n ");
  PRINTS("\n ");
  setSyncProvider(getNtpTime);
  setSyncInterval(120);  // NTP re-sync interval in seconds

#if USE_UI_CONTROL
  pinMode(SPEED_IN, INPUT);
  doUI();
#endif // USE_UI_CONTROL

  p.begin();
  p.setInvert(false);
  p.displayText(pc[curText], PA_CENTER, SPEED_TIME, PAUSE_TIME, effect[inFX], effect[outFX]);

}

//___________________________________________________________NTP CODE
const int NTP_PACKET_SIZE = 48; // NTP time is in the first 48 bytes of message
byte packetBuffer[NTP_PACKET_SIZE]; //buffer to hold incoming & outgoing packets

time_t getNtpTime()
{
  IPAddress ntpServerIP; // NTP server's ip address

  while (Udp.parsePacket() > 0) ; // discard any previously received packets
  Serial.println("Transmited request to the NTP server:");
  WiFi.hostByName(ntpServerName, ntpServerIP);
  Serial.print(" "); 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(" ");
      Serial.println("The NTP server responded successfully");
      Udp.read(packetBuffer, NTP_PACKET_SIZE);  // read packet into the buffer
      unsigned long secsSince1900;
      // convert four bytes starting at location 40 to a long integer
      secsSince1900 =  (unsigned long)packetBuffer[40] << 24;
      secsSince1900 |= (unsigned long)packetBuffer[41] << 16;
      secsSince1900 |= (unsigned long)packetBuffer[42] << 8;
      secsSince1900 |= (unsigned long)packetBuffer[43];
      return secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR;
    }
  }
  Serial.println("No NTP Response :-(");
  return 0; // return 0 if unable to get the time
}

// send an NTP request to the time server at the given address
void sendNTPpacket(IPAddress &address)
{
  // set all bytes in the buffer to 0
  memset(packetBuffer, 0, NTP_PACKET_SIZE);
  // Initialize values needed to form NTP request
  // (see URL above for details on the packets)
  packetBuffer[0] = 0b11100011;   // LI, Version, Mode
  packetBuffer[1] = 0;     // Stratum, or type of clock
  packetBuffer[2] = 30;     // 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;
  // all NTP fields have been given values, now
  // you can send a packet requesting a timestamp:
  Udp.beginPacket(address, 123); //NTP requests are to port 123
  Udp.write(packetBuffer, NTP_PACKET_SIZE);
  Udp.endPacket();
}


//___________________________________________________________void loop
void loop()
{

#if  DEBUG
#define PRINT(s, x) { Serial.print(F(s)); Serial.print(x); }
#define PRINTS(x) Serial.print(F(x))
#define PRINTD(x) Serial.println(x, DEC)

#else
#define PRINT(s, x)
#define PRINTS(x)
#define PRINTD(x)

#endif


#if USE_UI_CONTROL
  doUI();
#endif // USE_UI_CONTROL

  if (p.displayAnimate()) // animates and returns true when an animation is completed
  {
    // Set the display for the next string.
    curText = (++curText) % ARRAY_SIZE(pc);
    p.setTextBuffer(pc[curText]);

    // When we have gone back to the first string, set a new exit effect
    // and when we have done all those set a new entry effect.
    if (curText == 0)
    {
      outFX = (++outFX) % ARRAY_SIZE(effect);
      if (outFX == 0)
        p.setTextEffect(effect[inFX], effect[outFX]);
    }

    // Tell Parola we have a new animation
    p.displayReset();
  }
}

您能指导我如何实现这一目标吗?我是Arduino编程的新手,这对我来说已经太复杂了。我了解我已经很接近实现自己想要的目标,但是我凭有限的知识无法弄清楚。

谢谢。

0 个答案:

没有答案