GPSフリップドット時計
UNO

概要

ArduinoにGPSセンサとフリップドットディスプレイをつないで、デジタル時計を作成します。

作るもの

フリップドットディスプレイを利用してデジタル時計を作成します。時刻はGPSセンサから取得します。

用意するもの

以下のものを用意します。

  • Arduino Uno
  • フリップドットディスプレイ(ALFAZETA社のXY5を利用)
  • RS-485トランシーバ(LTC485CN8を利用)
  • GPSセンサ(GT-720Fを利用。ちょっと古いみたいです)
  • (PC)
  • (USBケーブル)
  • (ブレッドボード)
  • (ジャンプワイヤ)

利用機器

フリップドットディスプレイとGPSセンサを利用します。

フリップドットディスプレイを利用した実験はこちらのページを参照してください。

GPSセンサは、GT-720Fを利用します。GT-720Fを利用した簡単な実験はこちらのページを参照してください。

基本的な考え方

状況把握

GPSセンサから時刻情報(時・分・秒)を取得します。

機器操作

取得した時刻をフリップドットディスプレイに表示します。

設計

ハードウェアの設計

フリップドットディスプレイ(XY5)とGPSセンサ(GT-720F)とをArduinoに接続します。

XY5 LTC485CN8のピン番号 Arduinoのピン番号 GPSセンサ
VCC(24V) - - -
GND - - -
- 8(VCC) 5V POWER
- 5(GND) GND GND
+485 6(A) - -
-485 7(B) - -
- 4(DI) 1(TX) -
- 2(RE) 5V -
- 3(DE) 5V -
- - 0(RX) 6

XY5からデータを受信する必要がないので、Arduinoの0番とLTC485CN8の1番は使用せず、LTC485CNの2番(RE)と3番(DE)は5V固定にしています。

プログラムの設計

GPSセンサから時刻の取得

GPSセンサの出力する情報から時刻情報を取得します。今回は、GT-720Fが出力する情報のうち、$GPMRCから時刻情報を取得します。$GPMRCのフォーマットの概略は以下の通りです。$GPRMCの次の情報が時刻情報です。以下の例では、22時50分14秒を表しています。ただし、日本標準時(JST)ではなく協定世界時(UTC)です。このため、JSTにするには、9時間足す必要があります。

$GPRMC,225014.002,A,3500.0000,N,13900.0000,E,000.0,000.0,190811,,,D*6F

デジタル時計

以下のように数字を表示するようにしました。コロンは秒を砂時計風に表示します。

スケッチ

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#define TIME_DIFFERENCE     (9)
#define FONT_WIDTH_1        (4)
#define FONT_WIDTH          (6)
#define DISPLAY_WIDTH       (28)
 
#define XY5_HEADER          (0x80)
#define XY5_WRITE_COMMAND   (0x83)
#define XY5_ENDBYTE         (0x8f)
#define XY5_ADDRESS         (0x01)
 
 
uint8_t xy5Buffer[DISPLAY_WIDTH];
 
const uint8_t fontData[][FONT_WIDTH] = {
  {0x7f, 0x7f, 0x41, 0x41, 0x7f, 0x7f}, // 0
  {0x00, 0x00, 0x42, 0x7f, 0x7f, 0x40}, // 1
  {0x79, 0x79, 0x49, 0x49, 0x4f, 0x4f}, // 2
  {0x41, 0x49, 0x49, 0x49, 0x7f, 0x7f}, // 3
  {0x1f, 0x1f, 0x10, 0x7f, 0x7f, 0x10}, // 4
  {0x4f, 0x4f, 0x49, 0x49, 0x79, 0x79}, // 5
  {0x7f, 0x7f, 0x49, 0x49, 0x79, 0x79}, // 6
  {0x01, 0x01, 0x71, 0x7d, 0x0f, 0x03}, // 7
  {0x7f, 0x7f, 0x49, 0x49, 0x7f, 0x7f}, // 8
  {0x4f, 0x4f, 0x49, 0x49, 0x7f, 0x7f}, // 9
  {0x42, 0x7f, 0x7f, 0x40, 0x00, 0x00}, // extra 1
};
 
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
}
 
void loop() {
  // put your main code here, to run repeatedly:
  long time;
 
  if ((time = getTimeFromGPS()) >= 0) {
    printTime(time);
  }
}
 
void clearBuffer() {
  for (int i = 0; i < DISPLAY_WIDTH; i++) {
    xy5Buffer[i] = 0;
  }
}
 
void writeANumberToBuffer(int xAxis, int c) {
  for (int i = 0; i < FONT_WIDTH; i++) {
    xy5Buffer[xAxis++] = fontData[c][i];
  }
}
 
void flushBuffer(int address) {
  Serial.write(XY5_HEADER);
  Serial.write(XY5_WRITE_COMMAND);
  Serial.write(address);
 
  for (int i = 0; i < DISPLAY_WIDTH; i++) {
    Serial.write(xy5Buffer[i]);
  }
 
  Serial.write(XY5_ENDBYTE);
}
 
void printTime(long time) {
  int xAxis[] = {22, 15, 5};  // where to print digits
  long localTime;
 
  clearBuffer();
 
  // GMT to local time and make it a 12-hour clock
  localTime = (time + TIME_DIFFERENCE * 10000L + 240000L) % 240000L;
  if (localTime >= 120000L) {
    localTime -= 120000L;
  }
 
  // colon
  if (time % 2) {
    xy5Buffer[12] = xy5Buffer[13] = 0x7f;
    xy5Buffer[12] = xy5Buffer[13] &= ~(1 << (6 - ((time / 10) % 10)));
  }
   
  localTime /= 10;
 
  // hour and minute
  for (int i = 0; i < 3; i++) {
    localTime /= 10;
    writeANumberToBuffer(xAxis[i], localTime % 10);
  }
 
  // leading 1
  if (localTime / 10) {
    for (int i = 0; i < FONT_WIDTH_1; i++) {
      xy5Buffer[i] = fontData[10][i];
    }
  }
 
  flushBuffer(XY5_ADDRESS);
}
 
long getTimeFromGPS() {
  char gpsData[80];
  int position = 0;
 
  // get GPS data
  while (1) {
    if (Serial.available()) {
      gpsData[position] = Serial.read();
      if (gpsData[position] == '\n') {
        gpsData[position - 1] = '\0';
        position = 0;
        break;
      } else {
        position++;
      }
    }
  }
 
  // get time
  if (strcmp(strtok(gpsData, ","), "$GPRMC") == 0) {
    return atol(strtok(NULL, "."));
  } else {
    return -1;
  }
}

バージョン

Hardware:Arduino Uno
Software:Arduino 1.8.1

最終更新日

July 11, 2021

inserted by FC2 system