查看: 2669|回复: 2

[经验] 红外遥控计时程序(附带OLED字体更改教程)

[复制链接]
  • TA的每日心情
    开心
    2018-11-1 22:10
  • 签到天数: 3 天

    [LV.2]偶尔看看I

    发表于 2017-8-22 22:07 | 显示全部楼层 |阅读模式
    本帖最后由 诚哥崽 于 2017-8-26 15:01 编辑

    ----经过2个月的学习,初步掌握了arduino各个传感器和效应器的使用方法,制作了一个红外遥控计时程序,现在和大家分享一下
    视频
        先给大家看一下完成后的效果。

    P70816-154833.jpg
    准备
      如果感兴趣可以继续跟着我动手做哦!
       Arduino uno *1
       OLED 0.92寸*1
       红外接收器*1
       遥控器*1
       蜂鸣器*1
       杜邦线*N
       Arduino IDE软件   uno扩展板*1(可选)


    接线
    OLED 0.92寸⇲
            D0=13  D1=11 RES=5V DC=9 CS=10(SPI接口)
    红外接收器
            IO 3
    蜂鸣器
            IO 5
    QQ截图20170822213207.png

    程序
    程序一共143行,占uno存储空间90%(OLED的程序很大)
    [kenrobot_code]#include"IRremote.h"  //预加载红外遥控库
    #include "U8glib.h"   //预加载OLED显示屏控制库
    U8GLIB_SSD1306_128X64 u8g(13, 11, 10, 9);   //D0=13  D1=11 RES=5V DC=9 CS=10
    int RECV_PIN = 3;     //红外接收器所在引脚为3
    int speakerPin = 5;   //蜂鸣器连接5号管脚
    IRrecv irrecv(RECV_PIN);  
    decode_results results;  //储存编码结果
    int Internaltime;
    long IR;


    //音乐程序⇩
    int length = 15; // the number of notes
    char notes[] = "ccggaagffeeddc "; // a space represents a rest
    int beats[] = { 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 4 };
    int tempo = 300;

    void playTone(int tone, int duration) {
      for (long i = 0; i < duration * 1000L; i += tone * 2) {
        digitalWrite(speakerPin, HIGH);
        delayMicroseconds(tone);
        digitalWrite(speakerPin, LOW);
        delayMicroseconds(tone);
      }
    }

    void playNote(char note, int duration) {
      char names[] = { 'c', 'd', 'e', 'f', 'g', 'a', 'b', 'C' };
      int tones[] = { 1915, 1700, 1519, 1432, 1275, 1136, 1014, 956 };

    for (int i = 0; i < 8; i++) {
        if (names == note) {
          playTone(tones, duration);
        }
      }
    }
    //音乐程序⇧

    void setup() {
      pinMode(speakerPin, OUTPUT);  
      irrecv.enableIRIn();        //初始化红外解码
      u8g.firstPage();
      do
      {
        start();                        //运行start函数
      } while (u8g.nextPage());
      delay(500);
    }

    void start() {
      u8g.setFont(u8g_font_gdr11r);          // 设定字体
      u8g.drawStr(30, 30, "Welcome");        //定位、输入
      u8g.setFont(u8g_font_tpss);            //设定字体
      u8g.drawStr(20, 50, "Timingprogram V1.2");
    }

    void work() {
      u8g.setFont(u8g_font_profont22);
      u8g.drawStr(0, 30, "Set the time");
      u8g.setFont(u8g_font_tpssb);
      u8g.setPrintPos(40, 55);
      u8g.print(Internaltime);
      u8g.drawStr(50, 55, "min");
    }

    void work2() {
      u8g.setFont(u8g_font_fur11);
      u8g.drawStr(20, 30, "Set the time");
      u8g.setFont(u8g_font_tpssb);
      u8g.setPrintPos(40, 55);
      u8g.print(Internaltime);
      u8g.drawStr(90, 55, "S");
    }

    void song() {
      for (int i = 0; i < length; i++) {
        if (notes == ' ') {
          delay(beats * tempo); // rest
        } else {
          playNote(notes, beats * tempo);
        }
      }
    }
    void loop() {
      if (irrecv.decode(&results)) {         //如果接收到红外信号
        IR = results.value;                  
        if (IR == 16761405) {                //如果接收到确定指令
          Internaltime = Internaltime * 60;  //把分钟单位换成秒
          for (; Internaltime > 0; Internaltime--) {
            u8g.firstPage();
            do
            {
              work2();                        //运行work2函数
            } while (u8g.nextPage());
            delay(1000);
          }
          irrecv.resume();                     //接收下一个红外指令
          for(int i=2;i>0;i--){                //重复提醒音乐2次
           song();
          }
        }
        else {
          IR = results.value;
          switch (IR) {
            case 16724175:   //接收到1
              Internaltime = Internaltime + 1; //内部时间,分钟为单位
              break;
            case 16718055:  //接受到2,下面以此类推
              Internaltime = Internaltime + 2;
              break;
            case 16743045:
              Internaltime = Internaltime + 3;
              break;
            case 16716015:
              Internaltime = Internaltime + 4;
              break;
            case 16726215:
              Internaltime = Internaltime + 5;
              break;
            case 16734885:
              Internaltime = Internaltime + 6;
              break;
            case 16728765:
              Internaltime = Internaltime + 7;
              break;
            case 16730805:
              Internaltime = Internaltime + 8;
              break;
            case 16732845:
              Internaltime = Internaltime + 9;
              break;
            case 16748655:
              Internaltime = 0;
              break;
          }

          u8g.firstPage();
          do
          {
            work();                        //运行work函数
          } while (u8g.nextPage());
          irrecv.resume();
        }
      }
    }
    [/kenrobot_code]

    注意
    • 红外遥控器的型号不一致会导致程序无法正常运行,可以通过预先记录各个按键所对于的信号,再进行编程。
       QQ截图20170822220006.png 示例程序
    [kenrobot_code]#include"IRremote.h"
    int RECV_PIN=3;
    long a;
    IRrecv irrecv(RECV_PIN);
    decode_results results;
    void setup() {
    Serial.begin(9600);
    irrecv.enableIRIn();
    }

    void loop() {
    if(irrecv.decode(&results))
    {
      a=results.value;
      Serial.println(a);
      irrecv.resume();
    }
    }[/kenrobot_code]
    • 我使用的OLED是SPI接口,如果你是用的是IIC接口,可以通过更改程序第四行使得程序正常运行。
              示例:U8GLIB_SH1106_128X64 u8g(4, 5, 6, 7); // SW SPI Com: SCK = 4, MOSI = 5, CS = 6, A0 = 7 (new blue HalTec OLED)            
             QQ截图20170822211101.png
    • 蜂鸣器分为有源蜂鸣器和无源蜂鸣器,我使用的是无源5V蜂鸣器,如使用有源蜂鸣器,请更改音乐程序
    字体
    • 可以通过更改u8g.setFont()以到达更改字体的目的

           QQ截图20170822215115.png
    • u8g函数库包含有多种字体,可以到  https://github.com/olikraus/u8glib/wiki/fontsize 进行查看
    QQ截图20170822215546.png
    • 示例:把红色方框内的代码输入到u8g.setFont()的括号内即可修改字体
    QQ截图20170822215620.png
    完成
    • 编译可能需要较多的时间,请耐心等待...
           QQ截图20170822215930.png

    如果觉得对你有所帮助的话可以打赏一下我哦(~ ̄▽ ̄)~
  • TA的每日心情
    慵懒
    2017-8-24 18:09
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2017-8-24 16:02 | 显示全部楼层
    大神!感觉oled好复杂控制
  • TA的每日心情
    开心
    2018-11-1 22:10
  • 签到天数: 3 天

    [LV.2]偶尔看看I

     楼主| 发表于 2017-8-22 22:10 | 显示全部楼层
    第一次再Arduino中文社区发技术贴,请大家多多指教(*^▽^*)
    如果觉得对你有所帮助的话可以打赏一下我哦(~ ̄▽ ̄)~
    您需要登录后才可以回帖 登录 | 立即注册  

    本版积分规则

    热门推荐

    基于arduino的delta并联机械手
    基于arduino的delta并联机
    delta并联机械手现在广泛应用于工业,因为资金有限,用舵机做的,底座这些也是
    哪位大神知道怎么用这个16*16的led
    哪位大神知道怎么用这个16
    不知道这里的引脚A,B,C,D,DI,CLK,LAT有什么用啊
    【Arduino】108种传感器模块系列实验(42)---PM2.5韩国粉尘模块
    【Arduino】108种传感器模
    37款传感器与模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是
    求各位大佬帮帮新人
    求各位大佬帮帮新人
    void setup() { // put your setup code here, to run once: #include delay(50
    Arduino MEGA 与UNO 通过nRF24L模块通讯
    Arduino MEGA 与UNO 通过n
    之前在深水宝很“实惠”的店铺买了一些原件,随手砍了esp8266以及nRF24L*3 因为缺
    Copyright   ©2015-2016  Arduino中文社区  Powered by©Discuz!   ( 蜀ICP备14017632号-3 )
    快速回复 返回顶部 返回列表