工業製造
産業用モノのインターネット | 工業材料 | 機器のメンテナンスと修理 | 産業プログラミング |
home  MfgRobots >> 工業製造 >  >> Manufacturing Technology >> 製造プロセス

Arduino Nano 4×64 LEDマトリックス時計 - 新バージョン

コンポーネントと用品

Arduino Nano R3 × 1
LEDマトリックス (MAX7219 4-in-1モジュール) × 1
フォトレジスター (CdSセル) × 1
ブレッドボード (汎用) × 1
DS3231 RTCモジュール × 1

アプリとオンラインサービス

Arduino IDE

このプロジェクトについて

数メートル離れた部屋からでも時刻が読めるようなLEDマトリックス時計が欲しくて作りました。

4セルのディスプレイを安く入手したので、HacksterでArduino Nano用のプロジェクトを探しました。いくつか見つかりましたが、時・分・秒を同時に表示するには、一般的な5×7ピクセルフォントより小さな数字フォントが必要で、動作するプロジェクトはわずかでした。選択肢としてはMD_Parolaライブラリがありますが、シンプルな時計にはコードサイズが大きすぎます。Max72xxPanelライブラリも試しましたが、古くて他のライブラリを呼び出すため不向きでした。最終的に、他のライブラリの基盤となっている基本インターフェースライブラリMD_MAX72XXを直接使用することにしました。

このサイトのコメントを参考に、ハードウェア面とコードを見直しました。

「敬意」ボタンで関心を示していただき、ありがとうございます!

コード

旧版 - Arduino Nano ドットマトリックス時計

ライブラリの更新により旧コードは陳腐化しました。新版をお使いください。すべての接続はコード内に記述。小さなフォントを使うには MD_MAX72xx_font.cpp の数行を変更(コード内で説明)。

新版 (v2) - Arduino Nano ドットマトリックス時計

新しいライブラリに対応して更新。

/* Arduino Nano DS3231 clock with LED Matrix 4x(8x8) SPI
 * Version 2 - updated 15/05/2021
 * Arduino Nano 5V logic - 32kB prog. space
 * Tools: Board: Arduino Nano; Processor: ATmega328P (Old Bootloader)!!
 * LED Matrix 4x(8x8) SPI with connector on the right side (last module)
 * https://www.banggood.com/MAX7219-Dot-Matrix-Module-4-in-1-Display-For-Arduino-p-1072083.html
 *
 * CONNECTIONS:
 * >> LCD 4x64 -> Arduino Nano: (Hardware SPI使用)
 * 5V -> 5V pin
 * GND -> GND pin
 * CLK_PIN -> 13 // or SCK
 * DATA_PIN -> 11 // or MOSI
 * CS_PIN -> 10 // or SS
 *
 * >> DS3231 RTC -> Arduino Nano:
 * SDA (DAT) -> A4
 * SCL (CLK) -> A5
 *
 * Inspired by: 1) Arduino Clock by AnthoTRONICS (MD_parola不使用、コードサイズ削減)
 * 2) Simplest UNO Digital Clock Ever by plouc68000
 * 3) LEDDotMatrixClock.ino by Leonardo Sposina (Max72xxPanel.h不使用)
 * Small footprint code.
 *
 * project: 13558 bytes (44%); variables 372 bytes (17%)
 * Author: MVP https://www.hackster.io/M-V-P
 */
#include <SPI.h>
#include "DS3231.h"
#include "MD_MAX72xx_lib.h"

DS3231 rtc(SDA, SCL);
const byte LDR_PIN = A2;
#define MAX_DEVICES 4
#define CLK_PIN 13
#define DATA_PIN 11
#define CS_PIN 10
#define HARDWARE_TYPE MD_MAX72XX::FC16_HW  // お使いのハードウェアに合わせて変更
#define USE_NEW_FONT 1
#define BUF_SIZE 20
#define CHAR_SPACING 1

char buf[BUF_SIZE], secs[4];
uint8_t hh, mm, ss, dots;

// 3x5小さなフォント定義
uint8_t Font3x5[10][3] = {
  {248, 136, 248}, // 0
  {144, 248, 128}, // 1
  {200, 168, 184}, // 2
  {136, 168, 248}, // 3
  {112, 72, 224},  // 4
  {184, 168, 232}, // 5
  {248, 168, 232}, // 6
  {8, 232, 24},    // 7
  {248, 168, 248}, // 8
  {184, 168, 248}  // 9
};

char months[12][4] = {"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
char* wday;

MD_MAX72XX matrix = MD_MAX72XX(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);
const byte WAIT = 100;
const byte SPACER = 1;
byte FONT_WIDTH;
bool timeset = false;

void adjustClock(String data) {
  byte _day = data.substring(0,2).toInt();
  byte _month = data.substring(3,5).toInt();
  int _year = data.substring(6,10).toInt();
  byte _hour = data.substring(11,13).toInt();
  byte _min = data.substring(14,16).toInt();
  byte _sec = data.substring(17,19).toInt();
  rtc.setTime(_hour, _min, _sec);
  rtc.setDate(_day, _month, _year);
  Serial.println(F(">> Datetime successfully set!"));
  timeset = true;
}

byte ledintensitySelect(int light) {
  byte _value = 0;
  if (light >= 0 && light <= 127) _value = 12;
  else if (light >= 128 && light <= 319) _value = 3;
  else if (light >= 320 && light <= 512) _value = 0;
  return _value;
}

void printText(uint8_t modStart, uint8_t modEnd, char *pMsg) {
  uint8_t state = 0;
  uint8_t curLen;
  uint16_t showLen;
  uint8_t cBuf[FONT_WIDTH];
  int16_t col = ((modEnd + 1) * COL_SIZE) - 1;
  matrix.control(modStart, modEnd, MD_MAX72XX::UPDATE, MD_MAX72XX::OFF);
  
  do {
    switch(state) {
      case 0:
        if (*pMsg == '\0') {
          showLen = col - (modEnd * COL_SIZE);
          state = 2;
          break;
        }
        showLen = matrix.getChar(*pMsg++, sizeof(cBuf)/sizeof(cBuf[0]), cBuf);
        curLen = 0;
        state++;
      case 1:
        matrix.setColumn(col--, cBuf[curLen++]);
        if (curLen == showLen) {
          showLen = CHAR_SPACING;
          state = 2;
        }
        break;
      case 2:
        curLen = 0;
        state++;
      case 3:
        matrix.setColumn(col--, 0);
        curLen++;
        if (curLen == showLen) state = 0;
        break;
      default:
        col = -1;
    }
  } while (col >= (modStart * COL_SIZE));
  
  matrix.control(modStart, modEnd, MD_MAX72XX::UPDATE, MD_MAX72XX::ON);
}

void setup() {
  pinMode(LDR_PIN, INPUT_PULLUP);
  Serial.begin(9600);
  Serial.println(F(">> Arduino 32x8 LED Dot Matrix Clock!"));
  Serial.println(F(">> Use 
format to set clock's date and hour!")); rtc.begin(); matrix.begin(); matrix.clear(); FONT_WIDTH = 5 + SPACER; matrix.control(MD_MAX72XX::INTENSITY, 2); rtc.setDOW(); } void getDate() { String dts = rtc.getDateStr(); String dds = dts.substring(0,2); String mms = dts.substring(3,5); int mm = mms.toInt(); dds.concat(" "); dds.concat(String(months[mm-1])); dds.toCharArray(buf, sizeof(buf)); wday = rtc.getDOWStr(2); } void getHour() { String dts = rtc.getTimeStr(); String hhs = dts.substring(0,2); String mms = dts.substring(3,5); hh = hhs.toInt(); mm = mms.toInt(); ss = (dts.substring(6,8)).toInt(); if (hh >= 0 && hh < 10) dots = 7; else if (hh > 9 && hh < 20) dots = 11; else if (hh > 19 && hh < 25) dots = 13; if (hh % 10 == 1) dots -= 2; String outmsg = String(hh); outmsg.concat(char(124)); // 区切り文字(1カラム) outmsg.concat(dts.substring(3,5)); outmsg.toCharArray(buf, BUF_SIZE); } void showsec(uint8_t secs) { uint8_t secs1 = secs % 10; uint8_t secs2 = secs / 10; for (uint8_t k = 0; k < 3; k++) { matrix.setColumn(MAX_DEVICES*8 - 26 - k, Font3x5[secs2][k]); matrix.setColumn(MAX_DEVICES*8 - 30 - k, Font3x5[secs1][k]); } } void loop() { byte ledIntensity = ledintensitySelect(analogRead(LDR_PIN)); matrix.control(MD_MAX72XX::INTENSITY, ledIntensity); getHour(); printText(0, MAX_DEVICES-1, buf); matrix.setColumn(MAX_DEVICES*8 - dots, 0); unsigned long inst = millis(); while (ss < 53) { // 最初の53秒間は時刻表示 while (millis() - inst > 1000) { inst = millis(); ss++; showsec(ss); for (uint8_t i = 0; i < 2; i++) { matrix.setColumn(MAX_DEVICES*8 - dots, 36); // 点滅ドット delay(240); matrix.setColumn(MAX_DEVICES*8 - dots, 0); delay(240); } } } // 時刻を上スクロールで退場 for (uint8_t i = 0; i < 8; i++) { matrix.transform(MD_MAX72XX::TSU); delay(3 * WAIT); } // 日付表示 getDate(); printText(0, MAX_DEVICES-1, buf); delay(20 * WAIT); // 曜日表示(コメントアウト解除で有効) // printText(0, MAX_DEVICES-1, wday); // delay(20 * WAIT); // RTC内蔵センサーで室温推定表示 int temp = rtc.getTemp(); temp = temp - 1; // -1℃補正 String outmsg = String(temp); outmsg.concat(" C"); outmsg.toCharArray(buf, BUF_SIZE); printText(0, MAX_DEVICES-1, buf); delay(20 * WAIT); // シリアルモニターからの時刻設定 if (Serial.available() > 0 && timeset == false) { adjustClock(Serial.readString()); } }

回路図

Leonardo Sposina氏のプロジェクトに着想を得ていますが、#define CS_PIN(Matrix) <-> 10(Nano) の接続がポイントです。回路図はほぼすべてのマトリックスプロジェクトで共通です。ここではフォトレジスターの接続がオリジナルです。詳細は GitHubリポジトリ を参照してください。

製造プロセス

  1. Arduino で作るイスラム教礼拝時刻付きリアルタイムクロック
  2. Arduino Dueと3.2インチTFTで作る温度監視付きリアルタイムクロック
  3. ArduinoでBluetooth経由でLEDを制御 – シンプルDIYガイド
  4. Arduino MegaとNextion HMIで作る高機能ウェザーステーション
  5. PIRセンサー連動 インタラクティブLEDマトリクスドアディスプレイ - ホリデーグリーティング
  6. Arduino Nanoとジョイスティックで2軸ステッピングモーターを制御:Visuinoで簡単プログラミング
  7. Arduino Nanoで作る8×8 LEDマトリックスのフリップクロック - 自作リアルタイムクロック
  8. Arduino Unoで8×8 LEDマトリックスを制御:ステップバイステップガイド
  9. Arduino Nanoで作る携帯型ガイガーカウンター
  10. Arduinoで作る多チャネル・スマートバッテリー充電器:自動切替・電圧表示・近接センサー付き
  11. Arduinoリアルタイム気象時計 - OLEDに時刻/日付/温度を表示