ArduinoUNO实战-第二十二章-红外遥控实验

这篇具有很好参考价值的文章主要介绍了ArduinoUNO实战-第二十二章-红外遥控实验。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、参考

  • Arduino基础入门篇25—红外遥控
  • Arduino与红外遥控握手

二、目标

在日常生活中我们会接触到各式各样的遥控器,电视机、空调、机顶盒等都有专用的遥控器,很多智能手机也在软硬件上对红外遥控做了支持,可以集中遥控绝大部分家用电器。
当按下遥控器上某个按键,串口输出该按键的名称。

三、理论学习

红外遥控主要由红外发射和红外接收两部分组成。

红外发射和接收的信号其实都是一连串的二进制脉冲码,高低电平按照一定的时间规律变换来传递相应的信息。为了使其在无线传输过程中免受其他信号的干扰,通常都将信号调制在特定的载波频率上(38K红外载波信号),通过红外发射二极管发射出去,而红外接收端则要将信号进行解调处理,还原成二进制脉冲码进行处理。

红外接收头有三个引脚,如上图从左到右依次为VOUT、GND、VCC。红外遥控器发射的38K红外载波信号由遥控器里的编码芯片对其进行编码,具体编码方式和协议可在网上获取,这里不再展开。当按下遥控器按键时,遥控器发出红外载波信号,红外接收器接收到信号,程序对载波信号进行解码,通过数据码的不同来判断按下的是哪个键。

arduino红外发射与接收,# linux嵌入式,单片机,嵌入式硬件

  • 本实验采用红外接收头VS1838+红外遥控器。VS1838使用NEC码编码格式
  • NEC码格式:
    1、使用38kHz载波频率
    2、引导码间隔9ms+4.5ms
    3、使用16位客户代码
    4、使用8位数据代码和8位取反的数据代码
    下面的波形是从红外接收头上得到的波形:(调制信号转换为高低电平了)
    arduino红外发射与接收,# linux嵌入式,单片机,嵌入式硬件
    5、二进制0和1的表示方法
    arduino红外发射与接收,# linux嵌入式,单片机,嵌入式硬件

四、接线图

arduino红外发射与接收,# linux嵌入式,单片机,嵌入式硬件
红外接收头左侧VOUT连接开发板数字引脚11,GND和VCC分别连接开发板的GND和5V。

实验原理图如下图所示:

arduino红外发射与接收,# linux嵌入式,单片机,嵌入式硬件

实物连接图
arduino红外发射与接收,# linux嵌入式,单片机,嵌入式硬件
两种规格遥控
arduino红外发射与接收,# linux嵌入式,单片机,嵌入式硬件

五、代码

库安装

在IDE中点击「项目」—「加载库」—「管理库」,查找「IRremote」进行安装。
arduino红外发射与接收,# linux嵌入式,单片机,嵌入式硬件

测试按下按键通过窗口输出

我们演示右侧遥控器效果
arduino红外发射与接收,# linux嵌入式,单片机,嵌入式硬件

#include <IRremote.h>

int RECV_PIN = 11;//定义红外接收器的引脚为11

IRrecv irrecv(RECV_PIN);
long ir_item; // 解码之后的值
decode_results results;//注意这个数据类型

void setup()
{
  Serial.begin(9600);
  irrecv.enableIRIn(); // 初始化红外接收器
}

void loop() {
  if (irrecv.decode(&results)) {  //注意这里取解码结果的方法,传递的是变量指针。
    ir_item = results.value;
    print(results);
    irrecv.resume(); // 给红外传送指令,让其继续接收下一个值。同315M无线接收一个道理。
  }
}

void print(decode_results result)
{
  long value = results.value;
  int type = results.decode_type;
  String typeStr = "UNKNOWN";
  String typelist[14]={"UNKNOWN", "NEC", "SONY", "RC5", "RC6", "DISH", "SHARP", "PANASONIC", "JVC", "SANYO", "MITSUBISHI", "SAMSUNG", "LG", "WHYNTER"};
  if(type>=1 && type<=13){
    typeStr=typelist[type];
  }
  Serial.print(ir_item, HEX); //以16进制换行输出接收代码。注意取值方法【results.value】。
  Serial.print(" = ");
  Serial.print("IR TYPE:"+typeStr+"  ");
  Serial.print(" = ");
  if(value==0xFF38C7)
  {
    Serial.println("ok");
  }
  else if(value==0xFFA25D)
  {
    Serial.println("1");
  }
  else if(value==0xFF629D)
  {
    Serial.println("2");
  }
  else if(value==0xFFE21D)
  {
    Serial.println("3");
  }
  else if(value==0xFF22DD)
  {
    Serial.println("4");
  }
  else if(value==0xFF02FD)
  {
    Serial.println("5");
  }
  else if(value==0xFFC23D)
  {
    Serial.println("6");
  }
  else if(value==0xFFE01F)
  {
    Serial.println("7");
  }
  else if(value==0xFFA857)
  {
    Serial.println("8");
  }
  else if(value==0xFF906F)
  {
    Serial.println("9");
  }
  else if(value==0xFF9867)
  {
    Serial.println("0");
  }
  else if(value==0xFF6897)
  {
    Serial.println("*");
  }
  else if(value==0xFFB04F)
  {
    Serial.println("#");
  }
  else if(value==0xFF18E7)
  {
    Serial.println("up");
  }
  else if(value==0xFF4AB5)
  {
    Serial.println("down");
  }
  else if(value==0xFF10EF)
  {
    Serial.println("left");
  }
  else if(value==0xFF5AA5)
  {
    Serial.println("right");
  }
  else{
    Serial.println("unKnown");    
  }  
}

arduino红外发射与接收,# linux嵌入式,单片机,嵌入式硬件文章来源地址https://www.toymoban.com/news/detail-599866.html

结合之前LED显示温度试验,按下按键把按键值显示到第一行

#include <IRremote.h>

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

// #include <OneWire.h> //可以不引入,因为DallasTemperature.h中已经引入了OneWire.h
#include <DallasTemperature.h>

#define ONE_WIRE_BUS A0               //1-wire数据总线连接在IO4
OneWire oneWire(ONE_WIRE_BUS);       //声明
DallasTemperature sensors(&oneWire); //声明

LiquidCrystal_I2C lcd(0x27,16,2);  // set the LCD address to 0x27 for a 16 chars and 2 line display

int RECV_PIN = 11;//定义红外接收器的引脚为11

IRrecv irrecv(RECV_PIN);
long ir_item; // 解码之后的值
decode_results results;//注意这个数据类型

char lcdStr[16] = "hello, world!   ";
int index = 0;

void setup()
{
  Serial.begin(115200);
  irrecv.enableIRIn(); // 初始化红外接收器


  sensors.begin(); //初始化总线
  sensors.setWaitForConversion(false); //设置为非阻塞模式

  lcd.init();                      // initialize the lcd 
 
  // Print a message to the LCD.
  lcd.backlight();
  lcd.print(lcdStr);
}

void loop() {
  // 显示温度
  displayTemp();
  if (irrecv.decode(&results)) {  //注意这里取解码结果的方法,传递的是变量指针。
    ir_item = results.value;
    print(results);
    irrecv.resume(); // 给红外传送指令,让其继续接收下一个值。同315M无线接收一个道理。
  }
}

void print(decode_results result)
{
  long value = results.value;
  int type = results.decode_type;
  String typeStr = "UNKNOWN";
  String typelist[14]={"UNKNOWN", "NEC", "SONY", "RC5", "RC6", "DISH", "SHARP", "PANASONIC", "JVC", "SANYO", "MITSUBISHI", "SAMSUNG", "LG", "WHYNTER"};
  if(type>=1 && type<=13){
    typeStr=typelist[type];
  }
  Serial.print(ir_item, HEX); //以16进制换行输出接收代码。注意取值方法【results.value】。
  Serial.print(" = ");
  Serial.print("IR TYPE:"+typeStr+"  ");
  Serial.print(" = ");
  lcd.setCursor(0,0);
  if(value==0xFF38C7)
  {
    Serial.println("ok");
    displayValue(lcdStr,"ok",2);
  }
  else if(value==0xFFA25D)
  {
    Serial.println("1");
    displayValue(lcdStr,"1",1);
  }
  else if(value==0xFF629D)
  {
    Serial.println("2");
    displayValue(lcdStr,"2",1);
  }
  else if(value==0xFFE21D)
  {
    Serial.println("3");
    displayValue(lcdStr,"3",1);
  }
  else if(value==0xFF22DD)
  {
    Serial.println("4");
    displayValue(lcdStr,"4",1);
  }
  else if(value==0xFF02FD)
  {
    Serial.println("5");
    displayValue(lcdStr,"5",1);
  }
  else if(value==0xFFC23D)
  {
    Serial.println("6");
    displayValue(lcdStr,"6",1);
  }
  else if(value==0xFFE01F)
  {
    Serial.println("7");
    displayValue(lcdStr,"7",1);
  }
  else if(value==0xFFA857)
  {
    Serial.println("8");
    displayValue(lcdStr,"8",1);
  }
  else if(value==0xFF906F)
  {
    Serial.println("9");
    displayValue(lcdStr,"9",1);
  }
  else if(value==0xFF9867)
  {
    Serial.println("0");
    displayValue(lcdStr,"0",1);
  }
  else if(value==0xFF6897)
  {
    Serial.println("*");
    displayValue(lcdStr,"*",1);
  }
  else if(value==0xFFB04F)
  {
    Serial.println("#");
    displayValue(lcdStr,"#",1);
  }
  else if(value==0xFF18E7)
  {
    Serial.println("up");
    displayValue(lcdStr,"up",2);
  }
  else if(value==0xFF4AB5)
  {
    Serial.println("down");
    displayValue(lcdStr,"down",4);
  }
  else if(value==0xFF10EF)
  {
    Serial.println("left");
  }
  else if(value==0xFF5AA5)
  {
    Serial.println("right");
  }
  else{
    Serial.println("unKnown");    
  }  
}

// 将按键值显示在LED,并向右位移
void displayValue(char* buffer, char* value, int length)
{
  // LCD只能显示16位
  int size = 16;
  for(int i = size ; i > length ; i--)
	{
		buffer[i-1] = buffer[i-length-1] ;
	}
  memcpy(buffer, value, length);
  
  Serial.println(buffer);
  Serial.println(lcdStr);
  lcd.print(buffer);
}


unsigned long previousMillis = 0; //毫秒时间记录
const long interval = 1000;       //时间间隔
void displayTemp()
{
  //以下段落相当于每秒读取前次温度,并发起新一次温度转换
  unsigned long currentMillis = millis();         //读取当前时间
  if (currentMillis - previousMillis >= interval) //如果和前次时间大于等于时间间隔
  {
    previousMillis = currentMillis; //更新时间记录

    float tempC = sensors.getTempCByIndex(0); //获取索引号0的传感器摄氏温度数据
    if (tempC != DEVICE_DISCONNECTED_C)       //如果获取到的温度正常
    {
      Serial.print("\n当前温度是: ");
      Serial.print(tempC);
      Serial.println(" ℃");
      Serial.println(" ");

      String val = "temp:"+ String(tempC) + String("℃");
      
      lcd.setCursor(0,1);
      //lcd.print(val);
      // lcd.print((int)tempC/10);
      // lcd.print(".");
      // lcd.print((int)tempC%10);
      lcd.print("temp:");
      lcd.print(tempC);
      // 打印摄氏度
      lcd.print((char)223);
      lcd.print("C");
      
    }
    sensors.requestTemperatures(); //发起新的温度转换
  }
}

到了这里,关于ArduinoUNO实战-第二十二章-红外遥控实验的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 第二十二章 开发Productions - ObjectScript Productions - 生成警报

    如果发生警报事件,警报会在生产运行时向适用的用户发送通知。目的是提醒系统管理员或服务技术人员存在问题。可以通过电子邮件、文本寻呼机或其他机制发送警报。所有警报还会将消息写入 IRIS 事件日志,类型为警报。 生产警报机制的工作原理如下: 当为 Productions 创

    2024年02月07日
    浏览(63)
  • UNIX网络编程卷一 学习笔记 第二十二章 高级UDP套接字编程

    TCP是一个字节流协议,又使用滑动窗口,因此没有记录边界或发送者数据发送能力超过接收者接收能力之类的事情,但对于UDP,每个输入操作对应一个UDP数据报(一个记录),因此当收取的数据报大于引用的输入缓冲区时就有问题。 UDP是不可靠协议,但有些应用确实有理由使

    2024年02月12日
    浏览(34)
  • 第二章:25+ Python 数据操作教程(第二十二节如何从 R 调用或运行 python)持续更新

    本文介绍了如何从 R 调用或运行 python。这两种工具都有自己的优点和缺点。使用这两个工具中最好的包和功能并将其组合起来总是一个好主意。在数据科学领域,这些工具在使用方面拥有良好的市场份额。R 主要以数据分析、统计建模和可视化而闻名。而Python在深度学习和自

    2024年02月07日
    浏览(26)
  • STP和MTP(第二十二课)

    2、如何实现 1)在MSTP网络种,引入了域的概念,称为MST域 2)每一个MST域中包含一个或多个“生成树”称为“实例” 3)每个“实例生成树”都可以绑定vlan,实现vlan数据流的负载分担/负载均衡 4)默认情况下,所有的vlan都属于“实例树0:即:instance 0” 5)不同的“实例树”、

    2024年02月15日
    浏览(25)
  • 【从零开始学习JAVA | 第二十二篇】BigInteger

    目录  前言:  BigInterger: BigInteger常见的方法: 总结:         本篇我们将介绍BigInteger这个比较实用一点的API,这个API在我们实际写项目中都是很实用的API,因此大家应该对这个API有更加熟练的掌握。 在Java中,整数类型int和long的取值范围是有限的,超出该范围的整数无法

    2024年02月15日
    浏览(30)
  • Linux学习第二十二节-网卡IP设置

    1. 修改网卡IP地址 方式一:通过修改 网卡配置文件 修改 网卡配置文件位置: /etc/sysconfig/network-scripts/网卡名 #ifconfig   表示用于显示和设置网卡的参数 #ip addr   表示用于显示和设置网卡的参数   #systemctl restart network 表示重启网络 #ifup 网卡名 表示启动该网卡设备 #ifdown 网卡

    2024年02月17日
    浏览(29)
  • 【从零开始学习C++ | 第二十二篇】C++新增特性(下)

    目录 前言: 类型推导: constexpr: 初始化列表: 基于范围的for循环: 智能指针之unique ptr Lambda表达式: 总结:         本文我们将继续介绍   C++ 11 新增十大特性的剩余六个,如果没有看过介绍前四个特性的小伙伴的可以点进我C++的专栏就可以看到。 类型推导(

    2024年02月14日
    浏览(24)
  • 【Kubernetes】第二十二篇 - k8s 部署 MySQL 服务(secret、deployment、service)

    上一篇,介绍基于 k8s 项目部署流程设计; 本篇,介绍 MySQL 服务的部署; 部署 MySQL 可以为指定 node 添加污点,专门用于 mysql 部署(当前只有一个节点,不考虑); 为了保证mysql容器重启时数据不会丢失:创建 mysql 数据目录,用于存储 mysql 数据,实现 MySQL 数据的持久化;

    2024年02月03日
    浏览(36)
  • C++ 并发编程实战 第二章 线程管控

    线程通过构建 std::thread 对象而自动启动 ,该对象指明线程要运行的任务。 对应复杂的任务,可以使用函数对象。 一旦启动了线程,我们就需明确是要等待它结束(与之汇合 join() ),还是任由它独自运行(与之分离 detach() ) ❗❗❗ 同一个线程的 .join() 方法不能被重复调用

    2023年04月08日
    浏览(17)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包