网站首页
minecraft
资源共享
个人随笔
科技圈
杂七杂八
豆丁wiki
您的位置:首页 > 笔记 > Arduino+LCD1602制作电子时钟
Arduino+LCD1602制作电子时钟
2018-1-23    6939    0

迷恋各种arduino的电子钟,这次是一个基于1602显示加DS3231时钟模块的版本。

硬件:

Arduino UNO(特殊版带1602接口)一块

LCD1602显示模块一个

DS3231模块一个

杜邦线若干


接线:

1602:

因为板子特殊,留有直插口所以直接插上就行了。

板子如下:

TB2aPdgpm0jpuFjy0FlXXc0bpXa_!!1639117447.jpg

通过原理图查询得知它的接口就是自带1602库里面的标准接口,直接用就行,不用改引脚。

附上电路图,方便查阅:德飞莱LY-AVR-F1电路图.pdf


DS3231:

VCC —— VCC

GND —— GND

SCL —— SCL/A5

SDA —— SDA/A4


显示代码:

#include <Wire.h>
#include "ds3231_2.h"
#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2); 

#define BUFF_MAX 128

uint8_t time[8];
char recv[BUFF_MAX];
unsigned int recv_size = 0;
unsigned long prev, interval = 1000;

void setup()
{
    Serial.begin(9600);
    Wire.begin();
    DS3231_init(DS3231_INTCN);
    memset(recv, 0, BUFF_MAX);
    Serial.println("GET time");
    lcd.begin(16, 2);
    lcd.clear();
    
    Serial.println("Setting time");
    //parse_cmd("T302911604102014",16);
}

void loop()
{
    char in;
    char tempF[6]; 
    float temperature;
    char buff[BUFF_MAX];
    unsigned long now = millis();
    struct ts t;

    // show time once in a while
    if ((now - prev > interval) && (Serial.available() <= 0)) {
        DS3231_get(&t); //Get time
        parse_cmd("C",1);
        temperature = DS3231_get_treg(); //Get temperature
        dtostrf(temperature, 5, 1, tempF);

        lcd.clear();
        lcd.setCursor(0,0);
        
        lcd.print(t.mday);
        
        printMonth(t.mon);
        
        lcd.print(t.year);
        
        lcd.setCursor(0,1); //Go to second line of the LCD Screen
        lcd.print(t.hour);
        lcd.print(":");
        if(t.min<10)
        {
          lcd.print("0");
        }
        lcd.print(t.min);
        lcd.print(":");
        if(t.sec<10)
        {
          lcd.print("0");
        }
        lcd.print(t.sec);
        
        lcd.print(' ');
        lcd.print(tempF);
        lcd.print((char)223);
        lcd.print("C ");
        prev = now;
    }

    
    if (Serial.available() > 0) {
        in = Serial.read();

        if ((in == 10 || in == 13) && (recv_size > 0)) {
            parse_cmd(recv, recv_size);
            recv_size = 0;
            recv[0] = 0;
        } else if (in < 48 || in > 122) {;       // ignore ~[0-9A-Za-z]
        } else if (recv_size > BUFF_MAX - 2) {   // drop lines that are too long
            // drop
            recv_size = 0;
            recv[0] = 0;
        } else if (recv_size < BUFF_MAX - 2) {
            recv[recv_size] = in;
            recv[recv_size + 1] = 0;
            recv_size += 1;
        }

    }
}

void parse_cmd(char *cmd, int cmdsize)
{
    uint8_t i;
    uint8_t reg_val;
    char buff[BUFF_MAX];
    struct ts t;

    //snprintf(buff, BUFF_MAX, "cmd was '%s' %d\n", cmd, cmdsize);
    //Serial.print(buff);

    // TssmmhhWDDMMYYYY aka set time
    if (cmd[0] == 84 && cmdsize == 16) {
        //T355720619112011
        t.sec = inp2toi(cmd, 1);
        t.min = inp2toi(cmd, 3);
        t.hour = inp2toi(cmd, 5);
        t.wday = inp2toi(cmd, 7);
        t.mday = inp2toi(cmd, 8);
        t.mon = inp2toi(cmd, 10);
        t.year = inp2toi(cmd, 12) * 100 + inp2toi(cmd, 14);
        DS3231_set(t);
        Serial.println("OK");
    } else if (cmd[0] == 49 && cmdsize == 1) {  // "1" get alarm 1
        DS3231_get_a1(&buff[0], 59);
        Serial.println(buff);
    } else if (cmd[0] == 50 && cmdsize == 1) {  // "2" get alarm 1
        DS3231_get_a2(&buff[0], 59);
        Serial.println(buff);
    } else if (cmd[0] == 51 && cmdsize == 1) {  // "3" get aging register
        Serial.print("aging reg is ");
        Serial.println(DS3231_get_aging(), DEC);
    } else if (cmd[0] == 65 && cmdsize == 9) {  // "A" set alarm 1
        DS3231_set_creg(DS3231_INTCN | DS3231_A1IE);
        //ASSMMHHDD
        for (i = 0; i < 4; i++) {
            time[i] = (cmd[2 * i + 1] - 48) * 10 + cmd[2 * i + 2] - 48; // ss, mm, hh, dd
        }
        byte flags[5] = { 0, 0, 0, 0, 0 };
        DS3231_set_a1(time[0], time[1], time[2], time[3], flags);
        DS3231_get_a1(&buff[0], 59);
        Serial.println(buff);
    } else if (cmd[0] == 66 && cmdsize == 7) {  // "B" Set Alarm 2
        DS3231_set_creg(DS3231_INTCN | DS3231_A2IE);
        //BMMHHDD
        for (i = 0; i < 4; i++) {
            time[i] = (cmd[2 * i + 1] - 48) * 10 + cmd[2 * i + 2] - 48; // mm, hh, dd
        }
        byte flags[5] = { 0, 0, 0, 0 };
        DS3231_set_a2(time[0], time[1], time[2], flags);
        DS3231_get_a2(&buff[0], 59);
        Serial.println(buff);
    } else if (cmd[0] == 67 && cmdsize == 1) {  // "C" - get temperature register
        Serial.print("temperature reg is ");
        Serial.println(DS3231_get_treg(), DEC);
    } else if (cmd[0] == 68 && cmdsize == 1) {  // "D" - reset status register alarm flags
        reg_val = DS3231_get_sreg();
        reg_val &= B11111100;
        DS3231_set_sreg(reg_val);
    } else if (cmd[0] == 70 && cmdsize == 1) {  // "F" - custom fct
        reg_val = DS3231_get_addr(0x5);
        Serial.print("orig ");
        Serial.print(reg_val,DEC);
        Serial.print("month is ");
        Serial.println(bcdtodec(reg_val & 0x1F),DEC);
    } else if (cmd[0] == 71 && cmdsize == 1) {  // "G" - set aging status register
        DS3231_set_aging(0);
    } else if (cmd[0] == 83 && cmdsize == 1) {  // "S" - get status register
        Serial.print("status reg is ");
        Serial.println(DS3231_get_sreg(), DEC);
    } else {
        Serial.print("unknown command prefix ");
        Serial.println(cmd[0]);
        Serial.println(cmd[0], DEC);
    }
}

void printMonth(int month)
{
  switch(month)
  {
    case 1: lcd.print(" January ");break;
    case 2: lcd.print(" February ");break;
    case 3: lcd.print(" March ");break;
    case 4: lcd.print(" April ");break;
    case 5: lcd.print(" May ");break;
    case 6: lcd.print(" June ");break;
    case 7: lcd.print(" July ");break;
    case 8: lcd.print(" August ");break;
    case 9: lcd.print(" September ");break;
    case 10: lcd.print(" October ");break;
    case 11: lcd.print(" November ");break;
    case 12: lcd.print(" December ");break;
    default: lcd.print(" Error ");break;
  } 
}

用到的库文件:https://github.com/rodan/ds3231


串口调时间代码:

#include <DS3231test.h>
#include <Wire.h>

DS3231 Clock;
bool Century=false;
bool h12;
bool PM;
byte ADay, AHour, AMinute, ASecond, ABits;
bool ADy, A12h, Apm;

int year, month, date, DoW,week , hour, minute, second,temperature;

String comdata = "";
int numdata[7] = {0},  mark = 0;

void setup (void) 
{
  Serial.begin(9600);
 
  //Wire.begin(); 
  Serial.println("set_time :");
  Serial.println("year mouth day week hour minute second");
  Serial.println();
  Serial.println("week : 1 -> Sunday; 2 -> Monday; 3 -> Tuesday:  ....7 -> Saturday");
  Serial.println();
  Serial.println("for example :2014-5-20 Tue 0:33:30  ");
  Serial.println("set_time :");
  Serial.println("14 5 20 3 0 33 30");
  Serial.println();
}

void set_time()               //DS3231设置时间
{
 Wire.begin();
 Clock.setSecond(numdata[6]); //秒 
 Clock.setMinute(numdata[5]); //分
 Clock.setHour(numdata[4]);   //时 
 Clock.setDoW(numdata[3]);    //周
 Clock.setDate(numdata[2]);   //日
 Clock.setMonth(numdata[1]);  //月
 Clock.setYear(numdata[0]);   //年
}

void loop (void)
{
     int j = 0;
  while (Serial.available() > 0)    //检测串口是否有数据
  {
    comdata += char(Serial.read());
    delay(2);
    mark = 1;
    
  }

  if(mark == 1)  
  {
    Serial.println(comdata);             //串口打印检测到的数据
    for(int i = 0; i < comdata.length() ; i++)
    {
      if(comdata[i] == ' ')
      {
        j++;
      }
      else
      {
        numdata[j] = numdata[j] * 10 + (comdata[i] - '0');
      }
    }

    comdata = String("");
   Serial.print("set_time... ");
    set_time();
    Serial.println(" OK ");
    for(int i = 0; i < 7; i++)
    {
      numdata[i] = 0;
    }
    mark = 0;
  }

}

用到的库文件:http://image.geek-workshop.com/forum/201405/20/131459ouvueuv08gph0uqh.rar?_upd=DS3231.rar(注意库文件的重命名,两个都是,.h和.cpp都要修改,.cpp里还要修改对应的.h名称)

调时间说明:打开arduino 串口监视器

输入要设定日期以及时间
格式为(年+空格+月+空格+日+空格+星期+空格+时+空格+分+空格+秒)
设置中星期:01对应星期天;02对应星期一;03对应星期二;……07对应星期六
例如:现在是 2014年5月20日 星期二 13:35:00
那么在串口数据发送栏中输入   : 14 05 20 03 13 35 00


先烧录调时间的代码,完成后再烧录显示代码即可。

效果图:

IMG_20180121_224054-01.jpg


参考链接:

http://www.geek-workshop.com/thread-9841-1-1.html
http://educ8s.tv/arduino-project-real-time-clock-with-ds3231-module/


上一篇: D1 mini+OLED制作世界时钟
下一篇: 如何批量更改文件扩展名?
发表评论:
您的网名:
个人主页:
编辑内容: