蛍光表示管プロジェクト 6桁表示に74HC595を組み込む話

なんとか完成に近づいております、蛍光管表示プロジェクト
前回までは、ESR-WROOM-02のポート数が少なかったために、6桁中5桁しか表示出来ませんでした。

ですので、今回74HC595を組み込みました!

Serial to Parallel Shifting-Out with a 74HC595

74HC595は… 3入力を加えると、8桁出るってモノですw

配線は…

出力は Q1〜Q6までを蛍光表示管のQ1〜Q6に合わせました。
入力は SHCP DS STCPをESR-WROOM-02の空きポート 4 5 16

このチップの動作を簡単に説明しようと思ったけど…
本来の使い方出ない方法だと思うので参考にならないとも居ますが簡単に書いておきますと

DSに 1(0b00000001)を入力 Q6が点灯
DSに 2(0b00000010)を入力 Q5が点灯
DSに 4(0b00000100)を入力 Q4が点灯
DSに 8(0b00001000)を入力 Q3が点灯
DSに16(0b00010000)を入力 Q2が点灯
DSに32(0b00100000)を入力 Q1が点灯
と、ご想像通り、入力数値のビット部分が表示されるってモノです。

無事に、6桁を表示されましたっと

対象部分のソースを抽出しますと

#define ST_CP 4
#define SH_CP 5
#define DS  16

void setup() {
...
  pinMode(ST_CP, OUTPUT);
  pinMode(SH_CP, OUTPUT);
  pinMode(DS, OUTPUT);
...
}

void writeNumber(int pin, int num) {
  digitalWrite(SH_CP, LOW) ;
  shiftOut(DS, ST_CP, MSBFIRST, pow(2, pin)) ;
  digitalWrite(SH_CP, HIGH) ;
  writeNumber(num);
  delay(1);
}

こんな所ですね、
writeNumber部分は対象の数字を出力しております

  shiftOut(DS, ST_CP, MSBFIRST, pow(2, pin)) ;

この部分が実際にチップに投げている部分です。
pow(2,pin)の部分が少しトリッキーな部分ですね。
powは乗です。2のpin番号(1-6)乗としていますので、先の入力計算をしています。

ざっくり今回はチップを使って、出力ポートの節約をしました。
6ポート必要な部分を3ポートで出来るならスゴく便利ですね。
2チップとか使えば… もっと節約が出来るようです。

残りの作業を考えますと
・ケースの作成
・ESR-WROOM-02を評価ボードからチップに移行
・電源をUSBから、蛍光表示管の18Vからの提供に変更
残件もう少しあるねw

現在の最新のソースを上げておきますと

#include <ESP8266WiFi.h>
#include <WiFiUdp.h>

char ssid[] = "........";  //  your network SSID (name)
char pass[] = "...";       // your network password

#define PIN_A 13
#define PIN_B 0
#define PIN_C 2
#define PIN_D 15

#define ST_CP 4
#define SH_CP 5
#define DS  16

long timeZoneOffset = 9 * 3600L;

WiFiUDP udp;
const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message
byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets

unsigned long unixtime = 0L;
long lastUpdate = 0L;
unsigned long lastNtpAccessTime = 0L;
unsigned long ntpAccessDelay =  15 *  60L;
IPAddress timeServerIP; // time.nist.gov NTP server address
const char* ntpServerName = "time.nist.gov";
unsigned int localPort = 2390;      // local port to listen for UDP packets

void setup() {

  Serial.begin(115200);

  pinMode(PIN_A, OUTPUT);
  pinMode(PIN_B, OUTPUT);
  pinMode(PIN_C, OUTPUT);
  pinMode(PIN_D, OUTPUT);

  pinMode(ST_CP, OUTPUT);
  pinMode(SH_CP, OUTPUT);
  pinMode(DS, OUTPUT);

  WiFi.begin(ssid, pass);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");

  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

  Serial.println("Starting UDP");
  udp.begin(localPort);

  while (unixtime == 0) {
    unixtime =   getNtpTime();
  }
  lastNtpAccessTime = unixtime;
  Serial.println();

  printTimestamp(unixtime);
  Serial.print('(');
  printTimestamp((lastNtpAccessTime + ntpAccessDelay) );
  Serial.print(')');

}

unsigned long getNtpTime() {
  //get a random server from the pool
  WiFi.hostByName(ntpServerName, timeServerIP);

  sendNTPpacket(timeServerIP); // send an NTP packet to a time server
  // wait to see if a reply is available
  delay(1000);

  int cb = udp.parsePacket();
  if (!cb) {
    Serial.println("no packet yet");
  }
  else {
    Serial.print("packet received, length=");
    Serial.println(cb);
    // We've received a packet, read the data from it
    udp.read(packetBuffer, NTP_PACKET_SIZE); // read the packet into the buffer

    //the timestamp starts at byte 40 of the received packet and is four bytes,
    // or two words, long. First, esxtract the two words:

    unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
    unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
    unsigned long secsSince1900 = highWord << 16 | lowWord;

    // Unix time starts on Jan 1 1970. In seconds, that's 2208988800:
    const unsigned long seventyYears = 2208988800UL;
    // subtract seventy years:
    unsigned long epoch = secsSince1900 - seventyYears;
    // print Unix time:

    unixtime = epoch;
  }
  return unixtime;
}


void loop() {

  writeNumber(1, getSecound() % 10);
  writeNumber(2, getSecound() / 10L);

  writeNumber(3, getMinute() % 10);
  writeNumber(4, getMinute() / 10L);

  writeNumber(5, getHour() % 10);
  writeNumber(6, getHour() / 10L);

  if ((millis() - lastUpdate) >= 1000) {
    unixtime += 1;
    lastUpdate = millis();
  }

  if (( unixtime - lastNtpAccessTime) >= ntpAccessDelay) {
    unixtime =   getNtpTime();
    lastNtpAccessTime = unixtime;

    printTimestamp(lastNtpAccessTime);
    Serial.print('(');
    printTimestamp((lastNtpAccessTime + ntpAccessDelay) );
    Serial.print(')');

  }
}
unsigned long getUnixTime() {
  return unixtime + timeZoneOffset;
}

long getSecound() {
  long secound = getUnixTime()  % 60L ;
  return secound;
}
long getMinute() {
  long minute = (getUnixTime() / 60L) % 60L;
  return minute;
}

long getHour() {
  long hour = ((getUnixTime() / (60L * 60L))) % 24L;
  return hour;
}
void printTimestamp(unsigned long time) {

  Serial.print(((time / (60L * 60L))  + 9) % 24L);
  Serial.print(":");
  Serial.print((time / 60L) % 60L);
  Serial.print(":");
  Serial.print( time  % 60L );
}
void writeNumber(int pin, int num) {
  digitalWrite(SH_CP, LOW) ;
  shiftOut(DS, ST_CP, MSBFIRST, pow(2, pin)) ;
  digitalWrite(SH_CP, HIGH) ;
  writeNumber(num);
  delay(1);
}
void writeNumber(int num) {
  switch (num) {
    case 0 :
      digitalWrite(PIN_A, LOW);
      digitalWrite(PIN_B, LOW);
      digitalWrite(PIN_C, LOW);
      digitalWrite(PIN_D, LOW);
      return ;
    case 1 :
      digitalWrite(PIN_A, HIGH);
      digitalWrite(PIN_B, LOW);
      digitalWrite(PIN_C, LOW);
      digitalWrite(PIN_D, LOW);
      return ;
    case 2 :
      digitalWrite(PIN_A, LOW);
      digitalWrite(PIN_B, HIGH);
      digitalWrite(PIN_C, LOW);
      digitalWrite(PIN_D, LOW);
      return ;
    case 3 :
      digitalWrite(PIN_A, HIGH);
      digitalWrite(PIN_B, HIGH);
      digitalWrite(PIN_C, LOW);
      digitalWrite(PIN_D, LOW);
      return ;
    case 4 :
      digitalWrite(PIN_A, LOW);
      digitalWrite(PIN_B, LOW);
      digitalWrite(PIN_C, HIGH);
      digitalWrite(PIN_D, LOW);
      return ;
    case 5 :
      digitalWrite(PIN_A, HIGH);
      digitalWrite(PIN_B, LOW);
      digitalWrite(PIN_C, HIGH);
      digitalWrite(PIN_D, LOW);
      return ;
    case 6 :
      digitalWrite(PIN_A, LOW);
      digitalWrite(PIN_B, HIGH);
      digitalWrite(PIN_C, HIGH);
      digitalWrite(PIN_D, LOW);
      return ;
    case 7 :
      digitalWrite(PIN_A, HIGH);
      digitalWrite(PIN_B, HIGH);
      digitalWrite(PIN_C, HIGH);
      digitalWrite(PIN_D, LOW);
      return ;
    case 8 :
      digitalWrite(PIN_A, LOW);
      digitalWrite(PIN_B, LOW);
      digitalWrite(PIN_C, LOW);
      digitalWrite(PIN_D, HIGH);
      return ;
    case 9 :
      digitalWrite(PIN_A, HIGH);
      digitalWrite(PIN_B, LOW);
      digitalWrite(PIN_C, LOW);
      digitalWrite(PIN_D, HIGH);
      return ;
  }

  return ;
}
void resetNumber() {
  digitalWrite(PIN_A, HIGH);
  digitalWrite(PIN_B, HIGH);
  digitalWrite(PIN_C, HIGH);
  digitalWrite(PIN_D, HIGH);
}

// send an NTP request to the time server at the given address
unsigned long sendNTPpacket(IPAddress& address) {
  Serial.println("sending NTP packet...");
  // 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] = 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;

  // 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();
}