一个由Arduino驱动的数字时钟详解

描述

  本文要介绍的是一个由Arduino驱动的数字时钟,同时也是一个非常有趣的四冲程发动机模拟器,通过小时和分钟处的数字模拟汽车发动机的活塞运动。

  介绍

  由Arduino驱动的“四冲程数字时钟”是一个有趣的数字时钟内燃机模拟器。小时和分钟数字代表活塞移动并具有精确的RPM控制(100到800),RPM由显示屏中心的两列显示。

  另一个有趣的视觉信息是气缸的点火顺序“1-3-4-2”。当活塞在压缩循环中位于气缸顶部时,火花开始。该项目可以作为学习管理点阵像素和引入简单动画功能的一个很好的练习。

  四冲程内燃机

  该项目中使用的发动机型号是四冲程循环的I4(直列四缸)。四冲程内燃机分为四个步骤(进气-压缩-燃烧-排气),其中一步如下图所示:

模拟器

  注意:更多内燃机的基本信息可以在维基百科上找到。

  时钟

  在这个项目中,小时和分钟的数字模拟了活塞的运动,并且所有气缸的火花在正确的时间突出显示。

  精确计算旋转以表示实际速度,并通过旋转电位计在100至800RPM(每分钟转数)之间调整该值。

模拟器

  材料清单

  ArduinoUNOR3

  LED点阵与MAX7219

  DS1307RTC(实时时钟)

  旋转电位器-10KOhms

  面包板

  打印模板

  跳线

模拟器

  3D打印文件:

模拟器

  示意图:

模拟器

  本文所用到代码:

#include // LED 矩阵库 - MAX72XX
#include // DS1307RTC 库 - Arduino UNO 的引脚:A4 (SDA), A5 (SCL)
#include // 实时时钟库
#include // 时间库
#include

// 全局变量
字节 hh, mm ;                               // 小时,分钟
字节uH,uM,dH,dM ;                      // 单位小时,单位分钟,青少年小时,青少年分钟
字节p  =  0 ;                                // 绘图模式(数字位置:上/下)
int RPM  =  0 , lastRPM  =  0 , pinRPM  =  0 ;      // RPM,RPM 的最后值,RPM 的模拟引脚
字节序列 =  1 ;                              // 开始火序列

/*
用于连接 MAX72XX的 Arduino  引脚号(带 MAX72XX 控制器的 LED 阵列)
  引脚5连接到 DataIn ( DIN )
  引脚6连接到负载( CS )
  引脚7连接到 CLK ( CLK )
*/

LedControl lc  = LedControl ( 5 , 7 , 6 , 2 ) ;   // LedControl ( int DIN, int CLK, int CS, int numDevices )


// 数字数组 - ( 0到9 ) - 大小 5x3

字节数[ 10 ] [ 3 ]  =  {

  { 0xF8, 0x88, 0xF8 } , // 0
  { 0x00, 0xF8, 0x40 } , // 1
  { 0xE8, 0xA8, 0xB8 } , // 2
  { 0xF8, 0xA8, 0x88 } , // 3
  { 0x78, 0x20, 0xE0 } , // 4
  { 0xB8, 0xA8, 0xE8 } , // 5
  { 0xB8, 0xA8, 0xF8 } , // 6
  { 0xC0, 0xB8, 0x80 } , // 7
  { 0xF8, 0xA8, 0xF8 } , // 8
  { 0xF8, 0xA0, 0xE0 } , // 9

};


无效设置() {

  setSyncProvider(RTC.get);              // Function to read RTC (Real Time Clock)
  setSyncInterval(60);                   // Set the number of seconds between re-sync
  //setTime(8, 19, 30, 10, 02, 2018);     // Set the Time and Date (hour, minute, second, day, month, year)
  //RTC.set(now());                       // Set the RTC time

  // Setup of Display "0"
  lc.shutdown(0, false);                // Wakeup Display "0"
  lc.setIntensity(0, 4);                // Set the Brightness of Display (0 to 15)
  lc.clearDisplay(0);                   // Clear Display "0"

  // Setup of Display "1"
  lc.shutdown(1, false);                // Wakeup Display "1"
  lc.setIntensity(1, 4);                // Set the Brightness of Display (0 to 15)
  lc.clearDisplay(1);                   // Clear Display "1"

}


void loop() {

  hh = hour();
  mm = minute();

  uH = hh % 10;
  dH = hh / 10;

  uM = mm % 10;
  dM = mm / 10;


  // Plot Hours

  for (byte k = 0; k < 3; k++) {

    lc.setRow(0, k + 5, num[dH][k] >> (p + 2));
    lc.setRow(0, k + 1, num[uH][k] >> (3 - p));

  }


  // Plot Minutes

  for (byte k = 0; k < 3; k++) {

    lc.setRow(1, k + 4, num[dM][k] >> (3 - p));
    lc.setRow(1, k , num[uM][k] >> (p + 2));

  }


  // Plot Fire Sequence: 1-3-4-2 (4 cyl: 1-3-4-2 or 1-2-4-3 or 1-4-3-2)

  if (seq == 1) {                               // Fire Cyl #1
    lc.setLed(0, 6, 0, true);
  }

  if (seq == 2) {                               // Fire Cyl #3
    lc.setLed(1, 5, 0, true);
  }

  if (seq == 3) {                               // Fire Cyl #4
    lc.setLed(1, 1, 0, true);
  }

  if (seq == 4) {                               // Fire Cyl #2
    lc.setLed(0, 2, 0, true);
  }

  seq = seq % 4 + 1;


  // RPM reading

  RPM = analogRead(pinRPM);                     // Potentiometer reading

  RPM = map(RPM, 0, 1023, 1, 9);

  if (RPM <= 8) {
    lc.setLed(1, 7, 8 - RPM, true);
    lc.setLed(0, 0, 8 - RPM, true);
    delay(300 / RPM);                           // Speed setup by potentiometer (100 - 800 RPM)

    if (lastRPM != RPM) {
      lc.setRow(0, 0, 0);
      lc.setRow ( 1 , 7 , 0 ) ;
      最后转数 =转数;
    }

  }

  p  = !p ;                                        // 切换数字位置(上 x 下)


}

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分