帕米 发表于 2014-4-4 12:19:32

Arduino ATmega328P 裸奔的小钟

本帖最后由 弘毅 于 2016-9-7 21:04 编辑

都在极客工坊逛了快半年了,没注册过用户,更没发过帖子.是不是太说不过去了.

昨天注册了, 各位前辈们请拍板砖吧!

http://i1068.photobucket.com/albums/u448/pamisisi/IMAG0001_zpsc7d52780.jpg
花费了近两个小时才焊上

http://i1068.photobucket.com/albums/u448/pamisisi/MyClock_zps03d7fa86.png

http://v.youku.com/v_show/id_XNjk0MjYyMDg0.html

arduino 库 DigSegTime 下载(这是我第一次写 arduino 库)
https://github.com/pamisisi/arduino-DigSegTime/archive/master.zip

(为啥我不能直接上传png的图片, 也不能上链接呢,)


// myClock.ino

/* 4位数码管引脚
1   a   f   2   3   b
12 11 109   8   7

D4 D5 D6 D7 D8 D9
2   9 10 11 12 13

28 27 26 25 24 23
A5 A4 A3 A2 A1 A0

1   2   3   4   5   6
e   d   dp c   g   4
*/

#include <EEPROM.h>
#include <DigSegTime.h>
#include <DS1302.h>
#include <IRremote.h>
#include <OneWire.h>
#include <DallasTemperature.h>

/***************************************************/
/* 数码管引脚 首个参数 true 代表共阳, false 代表共阴      */
/***************************************************/
DigSegTime dst(false, 4,7,8,A0, 5,9,A2,A4,A5,6,A1,A3);

/***************************************************/
/* DS1302引脚                                       */
/***************************************************/
DS1302 rtc(10, 11, 12);

/***************************************************/
/* DS18B20引脚                                    */
/***************************************************/
OneWire oneWire(2);
DallasTemperature sensors(&oneWire);

/***************************************************/
/* IR引脚                                           */
/***************************************************/
IRrecv irrecv(3);
decode_results results;

/***************************************************/
/* 临时变量                                        */
/***************************************************/
// 系统运行时间
unsigned long timer, mils;
// 一秒标记
boolean oneSec;
// 临时的秒从 DS1302 读取 一分钟读取一次 用于刷新时间
uint8_t tmpSec;
// 数码管亮度&数码管亮度EEPROM地址
uint8_t dstBrightness = 1, dstBrightness_add = 0;
// 温度
uint8_t temperatures;
// date & time
int rtc_year;
byte rtc_month, rtc_date, rtc_day, rtc_hour, rtc_min, rtc_sec;

// 好复杂的组合菜单 一项伟大的工程
uint8_t menu, clockModel = 1, clockModel_add = 1, setting = 1;
const uint8_t menuShowClock = 0, menuShowTemperature = 1, menuShowSetting = 2;
const uint8_t settingShowModel = 1, settingDstBrightness = 2, settingDSyear =3,
settingDSmonth = 4, settingDSdate = 5, settingDSday = 6, settingDShour = 7,
settingDSmin = 8, settingDSsec = 9;

// 我开机啦
void setup() {
// Serial.begin(9600);
// 从 EEPROM 读取亮度
dstBrightness = EEPROM.read(dstBrightness_add);
// 如果EEPROM 亮度值大于10 代表着 不是本程序想要的值
if(dstBrightness > 10){
    // 写个1 再保存吧
    dstBrightness = 1;
    EEPROM.write(dstBrightness_add,dstBrightness);
}
// 设置数码管亮度 (1 to 10);
dst.brightness(dstBrightness);

// 从 EEPROM 读取时钟模式
clockModel = EEPROM.read(clockModel_add);
if(clockModel > 10){
    clockModel = 1;
    EEPROM.write(clockModel_add, clockModel);
}

// 读取 DS1302 时间
Time t =rtc.time();
//Serial.println(t.yr);

// 当年为 2000 时,代表着DS1302还没有设置过时间喔 设置本程序的出厂日期吧!
if(t.yr == 2000){
    rtc.writeProtect(false);                // 写保护 关
    rtc.halt(false);                              // 时间停止 关
    Time t(2014, 3, 7, 00, 38, 00, Time::kWednesday);
    rtc.time(t);
    rtc.writeProtect(true);                        // 写保护 开
}
//t =rtc.time();
//Serial.println(t.yr);

irrecv.enableIRIn();                        //开启红外
timer=millis();
}

// 我拼命的干活
void loop() {

dst.scan();                        // 我拼命的扫描
scanIR();                        // 没事你可以玩玩遥控器上的扫雷,命中就从此发生

mils=millis();

// 你是想要显示时间呢,还是显示度度呢, 还是想要设置我
switch (menu) {
case menuShowClock:
    showClock();
    break;
case menuShowTemperature:
    showTemperature();
    break;
case menuShowSetting:
    showSetting();
    break;
}
}

// 时间其时有很多种花样的 1 HH:MM , 2 时间+度度 (交替显示),3, 只显示分:秒 (用于检验DS1302过快或者快慢)
void showClock() {
if(mils - timer >= 500) {
    timer = mils;
    oneSec = !oneSec;
    switch (clockModel) {
    case 1:                        // 只有时间
      if(oneSec) {
      if(tmpSec == 0 || tmpSec >= 59){
          Time t =rtc.time();
          tmpSec = t.sec;
          dst.printTime(t.hr, t.min);
      }
      tmpSec++;
      dst.printDp(0);                // 灭掉点点
      }
      else{
      dst.printDp(2);                // 点点亮
      }
      break;
    case 2:                // 时间 + 温度
      if(oneSec) {
      if(tmpSec == 0 || tmpSec > 8){ // 每8秒后显示一下温度
          Time t =rtc.time();
          rtc_hour = t.hr;
          rtc_min = t.min;
          tmpSec = 1;
          //获取温度
          sensors.requestTemperatures();
          temperatures = sensors.getTempCByIndex(0);
          //显示温度
          dst.printTime(temperatures,"C ");
          dst.printDp(1);
      }
      else{
          dst.printTime(rtc_hour, rtc_min);
      }
      dst.printDp(2);
      tmpSec++;
      }
      else{
      dst.printDp(0);
      }
      break;
    case 3:      // MM:SS
      if(oneSec) {
      Time t =rtc.time();
      dst.printTime(t.min, t.sec);
      dst.printDp(0);
      }
      else{
      dst.printDp(2);
      }
      break;

    }
}
}
// 显示温度 3秒后 自动回到时间模式
void showTemperature() {
if(mils - timer >= 1000) {
    timer = mils;
    if(tmpSec == 0){
      sensors.requestTemperatures();
      temperatures = sensors.getTempCByIndex(0);
      dst.printHr(temperatures);
      dst.printMin("C ");
      dst.printDp(1);
    }
    tmpSec++;
    if(tmpSec >= 3) {
      menu = menuShowClock;
      tmpSec = 0;
    }

}
}

// 设置
void showSetting() {
// 500 ms 时
if(mils - timer >= 500) {
    timer = mils;
    oneSec = !oneSec;
    // 1秒时
    if(oneSec) {
      switch (setting) {
      case settingShowModel:
      dst.printTime("C-", clockModel);
      break;
      case settingDstBrightness:
      dst.printTime("B-", dstBrightness);
      break;
      case settingDSyear:
      dst.print(rtc_year);
      break;
      case settingDSmonth:
      dst.printTime(rtc_month, rtc_date);
      dst.printDp(1);
      break;
      case settingDSdate:
      dst.printTime(rtc_month, rtc_date);
      dst.printDp(1);
      break;
      case settingDSday:
      dst.printTime("D-", rtc_day);
      dst.printDp(0);
      break;
      case settingDShour:
      dst.printTime(rtc_hour, rtc_min);
      dst.printDp(2);
      break;
      case settingDSmin:
      dst.printTime(rtc_hour, rtc_min);
      dst.printDp(2);
      break;
      case settingDSsec:
      dst.printTime(rtc_min,rtc_sec);
      dst.printDp(3);
      break;
      }
      // 500 ms 时
    }
    else {
      switch (setting) {
      case settingShowModel:
      dst.printTime("C-", "");
      break;
      case settingDstBrightness:
      dst.print("B-");
      break;
      case settingDSyear:
      dst.printTime("", "");
      break;
      case settingDSmonth:
      dst.printTime("", rtc_date);
      break;
      case settingDSdate:
      dst.printTime(rtc_month, "");
      break;
      case settingDSday:
      dst.printTime("D-", "");
      break;
      case settingDShour:
      dst.printTime("", rtc_min);
      break;
      case settingDSmin:
      dst.printTime(rtc_hour, "");
      break;
      case settingDSsec:
      dst.printTime(rtc_min, "");
      break;
      }
    }
}
}

// 红外判断
void scanIR() {
if (irrecv.decode(&results)) {
    //Serial.println(results.value,HEX);
    switch (results.value) {
    case 0xFF629D:      // CH 进入菜单红外编码
      if(++menu >= 3) menu = 0;
      // 进入调时模式
      if(menu == 2){
      Time t =rtc.time();
      rtc_year = t.yr;
      rtc_month = t.mon;
      rtc_date = t.date;
      rtc_day = t.day;
      rtc_hour = t.hr;
      rtc_min = t.min;
      rtc_sec = t.sec;
      }
      dst.print("    ");
      dst.printDp(0);
      tmpSec = 0;
      break;
    case 0xFF02FD:      // >>| 下一项 红外编码
      switch (menu) {
      case menuShowSetting:
      if(++setting == 10){
          setting = 1;
          menu = 0;
          tmpSec = 0;
          rtc.writeProtect(false);
          rtc.year(rtc_year);
          rtc.month(rtc_month);
          rtc.date(rtc_date);
          rtc.hour(rtc_hour);
          rtc.minutes(rtc_min);
          rtc.seconds(rtc_sec);
          switch (rtc_day) {
          case 1:
            rtc.day(Time::kSunday);
            break;
          case 2:
            rtc.day(Time::kMonday);
            break;
          case 3:
            rtc.day(Time::kTuesday);
            break;
          case 4:
            rtc.day(Time::kWednesday);
            break;
          case 5:
            rtc.day(Time::kThursday);
            break;
          case 6:
            rtc.day(Time::kFriday);
            break;
          case 7:
            rtc.day(Time::kSaturday);
            break;
          }
          rtc.halt(false);
          rtc.writeProtect(true);

      }
      break;
      }
      break;
    case 0xFF22DD:      // |<< 上一项 红外编码
      switch (menu) {
      case menuShowSetting:
      if(--setting == 0) setting = 9;
      break;
      }
      break;

    case 0xFFA857:      // + 红外编码
      switch (menu) {
      case menuShowSetting:
      switch (setting) {
      case settingShowModel:
          clockModel++;
          if(clockModel > 3)
            clockModel = 1;
          EEPROM.write(clockModel_add,clockModel);
          break;
      case settingDstBrightness:
          dstBrightness++;
          if(dstBrightness > 10) {
            dstBrightness = 1;
          }
          dst.brightness(dstBrightness);
          EEPROM.write(dstBrightness_add,dstBrightness);
          break;
      case settingDSyear:
          if(++rtc_year > 2090) rtc_year = 2014;
          break;
      case settingDSmonth:
          if(++rtc_month > 12) rtc_month = 1;
          break;
      case settingDSdate:
          if(++rtc_date > 31) rtc_date = 1;
          break;
      case settingDSday:
          if(++rtc_day > 7) rtc_day = 1;
          break;
      case settingDShour:
          if(++rtc_hour > 23) rtc_hour = 0;
          break;
      case settingDSmin:
          if(++rtc_min > 59) rtc_min = 0;
          break;
      case settingDSsec:
          if(++rtc_sec > 59) rtc_sec = 0;
          break;
      }
      break;
      }
      break;
    case 0xFFE01F:      // - 红外编码
      switch (menu) {
      case menuShowSetting:
      switch (setting) {
      case settingShowModel:
          clockModel--;
          if(clockModel == 0)
            clockModel = 3;
          EEPROM.write(clockModel_add,clockModel);
          break;
      case settingDstBrightness:
          dstBrightness--;
          if(dstBrightness == 0) {
            dstBrightness = 10;
          }
          dst.brightness(dstBrightness);
          EEPROM.write(dstBrightness_add,dstBrightness);
          break;
      case settingDSyear:
          if(--rtc_year < 2014) rtc_year = 2090;
          break;
      case settingDSmonth:
          if(--rtc_month < 1) rtc_month = 12;
          break;
      case settingDSdate:
          if(--rtc_date < 1) rtc_date = 31;
          break;
      case settingDSday:
          if(--rtc_day < 1) rtc_day = 7;
          break;
      case settingDShour:
          if(--rtc_hour == 255) rtc_hour = 23;
          break;
      case settingDSmin:
          if(--rtc_min == 255) rtc_min = 59;
          break;
      case settingDSsec:
          if(--rtc_sec == 255) rtc_sec = 59;
          break;
      }
      break;
      }
      break;
    }
    irrecv.resume(); // Receive the next value
}
}

JosephLeung 发表于 2014-4-4 15:35:24

{:soso_e179:}

362442340 发表于 2014-4-4 15:37:12

谢谢分享啦。。。。

白菜虫虫 发表于 2014-4-4 16:17:51

贴片飞线,这手工真心不错。
话说锂电池是充电的吗?充电用的是IC吗

沧海笑1122 发表于 2014-4-4 16:33:12

代码注释很霸气,可见功底深厚,赞一个。

HWL0541 发表于 2014-4-11 14:28:13

好友创意啊。顶楼主:)

问题不大 发表于 2014-4-23 10:05:28

{:soso_e179:}

wetnt 发表于 2014-4-24 12:38:05

如果能够把焊接过程也拍摄出来,就更棒了!对大家有很大帮助啊!

504835618 发表于 2014-5-31 20:30:27

做的很好,能共享下DigSegTime.h库吗?

504835618 发表于 2014-5-31 20:46:43

我的编译出错In file included from led_clk.ino:19:
E:\arduino-1.0.1-windows\arduino-1.0.1\libraries\DS1302/DS1302.h:31:22: error: WProgram.h: No such file or directory
led_clk.ino: In function 'void setup()':
led_clk:97: error: 'class DS1302' has no member named 'writeProtect'
led_clk:99: error: 'kWednesday' is not a member of 'Time'
led_clk:101: error: 'class DS1302' has no member named 'writeProtect'
led_clk.ino: In function 'void scanIR()':
led_clk:318: error: 'class DS1302' has no member named 'writeProtect'
led_clk:327: error: 'kSunday' is not a member of 'Time'
led_clk:330: error: 'kMonday' is not a member of 'Time'
led_clk:333: error: 'kTuesday' is not a member of 'Time'
led_clk:336: error: 'kWednesday' is not a member of 'Time'
led_clk:339: error: 'kThursday' is not a member of 'Time'

504835618 发表于 2014-6-12 21:48:45

蒂张图是什么软件?

greeng 发表于 2014-6-21 09:46:39

没看懂裸奔钟是神马,求科普资料

hongling1122 发表于 2014-6-25 22:25:04

非常不错,感谢;

vision2000 发表于 2014-10-28 14:36:28

谢谢分享啦。。。。

ghcl 发表于 2014-11-9 13:31:10

挺好的。也要做一个。
页: [1] 2
查看完整版本: Arduino ATmega328P 裸奔的小钟