« 乱数発生関数で Tank Robot の動きに変化を付ける | Main | Added comments to my Tank Robot sketches »

08/11/2019

GPS Clock and display the time when posted to the post box

Img_20190810_153857Gps-watch-with-twelite
ポストボックスの蓋が開けられた際に、Twe-Liteを使って離れた場所にある書斎に信号を送り、投函されたという信号をLED点滅で表示する装置を以前に作った。
LEDの点滅ではわからない情報(例えば、何回投函された?何時投函された?)を表示させたいと思い、それぞれの目的に応じたものをNANOを用いて製作した。しかしNANOで作った前述の装置を見ると、使っているPINには重複が無いので、下記の①~⑤の内容を、1つのNANOで処理できると考え、これまで2個のNANOを使って表示していたものを纏めてみた。(写真は、壁のボードに各部品類を両面テープで貼り付けて設置している。)

①GPSによる時間捕捉
②4桁7セグメントを用いた時刻表示
③TWE-Liteからの投函信号
④8x8ドットマトリックスを用いた現在の投函数
⑤20x4LCDを用いた投函回数とその時刻表示(この表示器を用いれば、もう少し詳細なGPS時計としても表示出来る)

《使用した部品とポート間接続》
Arduino NANO --- 接続先
 Pin No.  
   A4  ---  SDA (20x4 LCD I2C 接続)
   A5  ---  SCL (20x4 LCD I2C 接続)
   D2  ---  TWE-Lite 受信後のフォトカプラより
   D3  --- RX (GPS)
   D4  --- TX (GPS)
   D6  ---  CLK (4桁7セグメント)
   D7  ---  DIO (4桁7セグメント)
   D10  ---  CS (8x8 ドットマトリックスディスプレイ)
   D11  ---  DIN (8x8 ドットマトリックスディスプレイ)
   D12  ---  NANO内部結線
   D13  ---  CLK (8x8 ドットマトリックスディスプレイ)

GPS: Cikuso  NEO-6M GPS module  GY-GPS6MV2

4桁7セグメントDisplay:
  KKHMF モジュールは12ピンの時計点付きの4位共通アノードデジタルチューブ(0.36インチ)の表示モジュール,
  ドライブチップはTM1637


TWI-Lite からの信号用フォトカプラ:

8x8ドットマトリックス:SODIAL(R) MAX7219

20x4 LCDディスプレイ:Aideepen  I2C HD44780コントローラ 
  Arduino対応(2004 LCD 5V blue)

《注記1》
これを記載した翌朝、新聞の投函があったので、表示装置を見ると・・・投函された際に表示する表記が想定していたのと違う!
表示の問題点が分かったので、2019/08/21 sketch(下記)を加筆修正した。また、Frizingを使って回路を記載した。しかし、LEDを1秒毎に点灯するためのデバイス(M34-1L)がないため、外観が同じものを流用して記述しているのでご容赦ください。

ダウンロード - gps20watch20with20twelite20sketch2020190821.fzz

注記2
Sketch の loop 内に if 文の範囲ミスが見つかったので2か所修正した。2019/08/28


《Sketch》
// GPS Clock and display the time when posted to the post box My Spice Cabinet
#include <Wire.h>
#include <TimeLib.h>     // include Arduino time library
#include <SoftwareSerial.h>  // include software serial library
#include <Adafruit_GFX.h>
#include <Max72xxPanel.h>
const int numberOfHorizontalDisplays = 1;
const int numberOfVerticalDisplays = 1;
const int pinCS = 10; // Cs - SS (Pin 10)
// Din - Mosi (Pin 11)
// Clk - Sck (Pin 13)
Max72xxPanel matrix = Max72xxPanel(pinCS, numberOfHorizontalDisplays, numberOfVerticalDisplays);

#include <TinyGPS++.h> // include TinyGPS++ library
TinyGPSPlus gps;
static const int TXPin = 4, RXPin = 3;   // TX -> D4, RX -> D3
SoftwareSerial Serial_GPS(TXPin, RXPin);
static const uint32_t GPSBaud = 9600;

#include <LiquidCrystal_I2C.h>
#define I2C_ADDR  0x27
LiquidCrystal_I2C lcd(I2C_ADDR, 20, 4);   // I2C: 0x27 20x4 LCD
// LCD(20x4) --- Arduino NANO (I2C connection)
// GND --- GND
// VCC --- 5V
// SDA --- A4
// SCL --- A5

#include "SevenSegmentTM1637.h"
#include "SevenSegmentExtended.h"
const byte PIN_CLK = 6;    // define CLK pin (any digital pin)
const byte PIN_DIO = 7;    // define DIO pin (any digital pin)
SevenSegmentExtended display(PIN_CLK, PIN_DIO);
int Satellites = 12;
int hours;
int minutes;
const int UTC_offset = 9;   // Tokyo Japan Time
#define time_offset 3600   // define a clock offset of 3600 seconds (@hour)

// variable definitions
char Time[] = "Time: 00:00:00";
char Date[] = "Date: 00_   _2000";
char visit[]  = "            ";  // changed 20190821
byte last_second, Second, Minute, Hour, Day, Month;
int Year;

char time_value[20];
#define PUSH_SHORT 100
int count = 2;   // counter from outside TWE-Lite
int icount = 0;   // number of switched on
int jcount = 0;   // column location on the display
int row = 0;
char c;
String s;
String visitor;
int count_low = 0;

void setup(void)
{
Serial.begin(9600);                 // added 20190821
Serial_GPS.begin(GPSBaud);   // initialize software serial
display.begin();                      // initializes the display
display.setBacklight(30);         // set the brightness to 30%
matrix.setIntensity( 1 );         // Adjust the 8x8 brightness (dark)0 << 15(bright)
matrix.setPosition( 0, 3, 0);
matrix.setRotation( 0, 3) ;      // rotation position
pinMode(count, INPUT_PULLUP);

c = char(icount + 48);
Serial.print("c = ");
Serial.println(c);
matrix.drawChar( 2, 1, c, HIGH, LOW, 1);
matrix.write();    // Send bitmap to display
delay( 50);

pinMode(Satellites, INPUT_PULLUP);
delay(100);

// set up the 20x4 LCD's number of columns and rows
lcd.begin(20, 4);
lcd.init();
lcd.backlight();
lcd.setCursor(2, 0);    // move LCD cursor to column 1, row 0 [upper left position (0, 0)]
lcd.print("GPS clock (UTC_ )");
lcd.setCursor(17, 0);
lcd.print(UTC_offset);

Wire.begin();
pinMode(count, INPUT_PULLUP); // switch on signal from TWE-Lite
String s;
}

void loop()
{
  matrix.fillScreen(LOW);
  while (Serial_GPS.available() > 0)
  {
    if (gps.encode(Serial_GPS.read()))
    {
// get time from GPS module
    if (gps.time.isValid())
    {
      Minute = gps.time.minute();
      Second = gps.time.second();
      Hour = gps.time.hour();
    }

// get date drom GPS module
    if (gps.date.isValid())
    {
      Day = gps.date.day();
      Month = gps.date.month();
      Year = gps.date.year();
    }

    if(last_second != gps.time.second()) // if the time has changed
    {
      last_second = gps.time.second();
// set current UTC time
      setTime(Hour, Minute, Second, Day, Month, Year);
// add the offset to get local time
      adjustTime(UTC_offset*time_offset);

// update time array
      Time[12] = second() / 10 + '0';
      Time[13] = second() % 10 + '0';
      Time[9] = minute() / 10 + '0';
      Time[10] = minute() % 10 + '0';
      Time[8] = char(58) ;
      Time[6] = hour() / 10 + '0';
      Time[7] = hour() % 10 + '0';

      hours = hour();
      minutes = minute();
// update date array
      Date[15] = (year() / 10) % 10 + '0';
      Date[16] = year() % 10 + '0';
      Date[8] = char(47) ;
      Date[9] = month() / 10 + '0';
      Date[10] = month() % 10 + '0';
      Date[11] = " ";
      Date[6] = day() / 10 + '0';
      Date[7] = day() % 10 + '0';

      if(jcount == 0)
      {
// print time & date to 20x4 LCD display
        print_wday(weekday());   // print day of the week
        print_wmonth(month());

        lcd.setCursor(0, 2);   // move cursor to column 0 row 2
        lcd.print(Time); // print time (HH:MM:SS)

        lcd.setCursor(0, 3);   // move cursor to column 0 row 3
        lcd.print(Date); // print date (DD-MM-YYYY)
        print_wmonth(month());
      }

      display.printTime(hours, minutes, true);   // overwrite to LCD display
    }
//  }  // deleted 20190827

// http://techblog.wp.xdomain.jp/2018/10/27/arduino_tactile_switch/
  if(digitalRead(count) == LOW){   // when switch on
  if(count_low <= PUSH_SHORT) count_low ++;
  }else{   // switch off state
    count_low = 0;
  }
  if(count_low == PUSH_SHORT){
    Serial.println("Pushed Button!");
    icount = icount + 1 ;
    if(icount == 1 )  lcd.clear();
    displayInfo();   // display the number of visitor and the time
    jcount = jcount + 1 ;
  }
 }  // added 20190827
 }
}

// function for displaying day of the week
void print_wday(byte wday)
{
  lcd.setCursor(5, 1);   // move cursor to column 5, row 1
  switch(wday)
  {
    case 1: lcd.print(" Sunday "); break;
    case 2: lcd.print(" Monday "); break;
    case 3: lcd.print(" Tuesday "); break;
    case 4: lcd.print("Wednesday"); break;
    case 5: lcd.print("Thursday "); break;
    case 6: lcd.print(" Friday "); break;
    default: lcd.print("Saturday ");
  }
}

// function for displaying month of year
void print_wmonth(byte wmonth)
{
  lcd.setCursor( 9, 3);   // move cursor to column 9, row 3
  switch(wmonth)
  {
    case 1: lcd.print("Jan"); break;
    case 2: lcd.print("Feb"); break;
    case 3: lcd.print("Mar"); break;
    case 4: lcd.print("Apr"); break;
    case 5: lcd.print("May"); break;
    case 6: lcd.print("Jun"); break;
    case 7: lcd.print("Jul"); break;
    case 8: lcd.print("Aug"); break;
    case 9: lcd.print("Sep"); break;
    case 10: lcd.print("Oct"); break;
    case 11: lcd.print("Nov"); break;
    default: lcd.print("Dec");
  }
}

void displayInfo()
{     // write information to 20x4 LCD Display and 8x8 matrix Display
  c = char(icount + 48);
  visit[0] = hour() / 10 + '0';
  visit[1] = hour() % 10 + '0';
  visit[2] = char(58) ;  // changed 20190821
  visit[3] = minute() / 10 + '0';
  visit[4] = minute() % 10 + '0';
  visit[5] = char(32);  // changed 20190821

  visit[6] = month() / 10 + '0';
  visit[7] = month() % 10 + '0';
  visit[8] = char(47) ;  // changed 20190821
  visit[9] = day() / 10 + '0';
  visit[10]= day() % 10 + '0';

  if( row == 4 ) row = 0;
  lcd.setCursor(0, row);  // changed 20190821
  lcd.print("Posted");      // changed 20190821
  lcd.setCursor(7, row);  // changed 20190821
  lcd.print( c );
  lcd.setCursor(9, row);  // changed 20190821
  lcd.print(visit);
  Serial.print("Posted ");  // changed 20190821
  Serial.print(visit);         // changed 20190821

  matrix.drawChar( 2, 1, c, HIGH, LOW, 1);
  matrix.write();   // Send bitmap to display
  delay(100);
  row = row + 1;
}

« 乱数発生関数で Tank Robot の動きに変化を付ける | Main | Added comments to my Tank Robot sketches »

Arduino」カテゴリの記事

Comments

Post a comment

Comments are moderated, and will not appear on this weblog until the author has approved them.

(Not displayed with comment.)

« 乱数発生関数で Tank Robot の動きに変化を付ける | Main | Added comments to my Tank Robot sketches »

September 2019
Sun Mon Tue Wed Thu Fri Sat
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          

Recent Trackbacks

無料ブログはココログ