风筝
发表于: 2024-12-19 16:15:22 | 显示全部楼层

在本篇帖子中,我们将探索红外技术的潜力以及如何将其与Arduino开发板一起使用。红外通信是电子设备中允许无线信息交换的常见功能。从遥控器到自动门,红外技术无处不在。了解红外通信的原理并学习如何使用它将会开辟广泛的可能性。本文将帮助您使用Arduino开发板发送和接收红外信号。我们将介绍红外通信的基础知识,包括不同的协议和代码,以及帮助您入门的实际示例。


什么是红外通信?

红外通信是一种常见、廉价且简单的无线通信技术。红外光与可见光非常相似,只是它的波长稍长。这意味着红外辐射对人眼是不可见的,使其适合数据交换。


红外通信仅限于短距离,并且需要直接视线。它也不能穿过墙壁。

IR-2Arduino-LEDandSensor-1200x750.jpg


由于红外的这些限制,很难跟踪通信。事实上,红外设备之间的通信通常是一对一的。因此,以这种方式传输的数据通常不加密。


当您使用红外无线控制时,红外光谱中的LED用于将数据传输到接收器。但我们周围有各种红外源。太阳、灯泡或任何其他产生热量的东西在红外光谱中都非常明亮。因此,红外接收器必须能够区分遥控器的信号和环境红外信号。为此,我们使用调制的红外信号。调制信号就像为数据分配一个模式以确保接收器可以识别它。


红外通信的常见调制是38kHz 调制。38kHz信号波的自然来源很少,因此使用该频率的红外发射器将与环境红外波不同。当您按下遥控器上的某个键时,红外发射器的LED将在几分之一秒内快速闪烁,将编码数据传输到接收器。

IR-2Arduino-How-It-Works.gif


通过红外传输的数据(除了其主频率38kHz 外)还有自己的协议。例如,NEC 协议(曾被日本家电制造商广泛使用)以以下格式传输数据。

IR-2Arduino-NEC-Protocol.jpg


到目前为止,我们已经了解了红外发射器和接收器以及如何在它们之间进行通信。现在,让我们看看如何使用这种方法在两个Arduino开发板之间进行通信并在它们之间发送和接收命令。


所需的组件

●    Arduino UNO R3开发板

●    38KHz红外接收器模块

●    红外发射器模块

●    公对母跳线


两个Arduino开发板之间的红外通信的硬件电路

如前所述,我们将使用Arduino搭建两个独立的电路。第一个电路使用38kHz红外传感器接收红外信号,并使用Arduino控制器解释输入信号。第二个电路包括一个红外发射器LED模块和一个Arduino控制器,用于将红外代码发送到接收器。


以下是这是发射器的电路:

IR-2Arduino-Transmitter-Wiring.jpg


以下是接收器的电路:

IR-2Arduino-Reciever-Wiring.jpg


红外发射器的Arduino代码

首先,下载IRremote库并安装。然后在Arduino IDE软件中复制并粘贴以下代码。


  1. /*
  2.   modified on AUG 23, 2023
  3. */

  4. #include <Arduino.h>

  5. #define DISABLE_CODE_FOR_RECEIVER // Disables restarting receiver after each send. Saves 450 bytes program memory and 269 bytes RAM if receiving functions are not used.
  6. //#define SEND_PWM_BY_TIMER         // Disable carrier PWM generation in software and use (restricted) hardware PWM.
  7. //#define USE_NO_SEND_PWM           // Use no carrier PWM, just simulate an active low receiver signal. Overrides SEND_PWM_BY_TIMER definition

  8. /*
  9.    This include defines the actual pin number for pins like IR_RECEIVE_PIN, IR_SEND_PIN for many different boards and architectures
  10. */
  11. #include "PinDefinitionsAndMore.h"
  12. #include <IRremote.hpp> // include the library

  13. void setup() {
  14.   pinMode(LED_BUILTIN, OUTPUT);
  15.   Serial.begin(115200);
  16.   pinMode(10, INPUT_PULLUP);
  17.   pinMode(11, INPUT_PULLUP);
  18.   pinMode(12, INPUT_PULLUP);

  19.   Serial.print(F("Send IR signals at pin ")); //Printouts the IR send pin used in the chip you want.
  20.   Serial.println(IR_SEND_PIN);

  21.   //    IrSender.begin(); // Start with IR_SEND_PIN as send pin and if NO_LED_FEEDBACK_CODE is NOT defined, enable feedback LED at default feedback LED pin
  22.   IrSender.begin(DISABLE_LED_FEEDBACK); // Start with IR_SEND_PIN as send pin and disable feedback LED at default feedback LED pin
  23. }

  24. /*
  25.    Set up the data to be sent.
  26.    For most protocols, the data is build up with a constant 8 (or 16 byte) address
  27.    and a variable 8 bit command.
  28.    There are exceptions like Sony and Denon, which have 5 bit address.
  29. */
  30. uint8_t saddress = 0;
  31. uint8_t sCommand = 0;
  32. uint8_t sRepeats = 0;

  33. void loop() {
  34.   if (digitalRead(10) == LOW)
  35.   {
  36.     saddress = 0x00;
  37.     sCommand = 0x10;
  38.     sRepeats = 1;
  39.   }
  40.   else if (digitalRead(11) == LOW)
  41.   {
  42.     saddress = 0x01;
  43.     sCommand = 0x20;
  44.     sRepeats = 1;
  45.   }
  46.   else if (digitalRead(12) == LOW)
  47.   {
  48.     saddress = 0x02;
  49.     sCommand = 0x30;
  50.     sRepeats = 1;
  51.   }
  52.   if (digitalRead(10) == LOW || digitalRead(11) == LOW || digitalRead(12) == LOW)
  53.   {
  54.     /*
  55.       Print current send values
  56.     */
  57.     Serial.println();
  58.     Serial.print(F("Send now: address=0x"));  Serial.print(saddress, HEX);
  59.     Serial.print(F("command=0x"));            Serial.print(sCommand, HEX);
  60.     Serial.print(F(", repeats="));            Serial.print(sRepeats);
  61.     Serial.println();

  62.     Serial.println(F("Send standard LG with 8 bit address"));
  63.     Serial.flush();
  64.     IrSender.sendLG(saddress, sCommand, sRepeats);
  65.   }


  66.   delay(1000);  // delay must be greater than 5 ms (RECORD_GAP_MICROS), otherwise the receiver sees it as one long signal
  67. }
复制代码

该代码读取Arduino引脚10、11和12的状态,如果其中任何一个连接到GND,它会传输一条包含不同命令和不同地址的消息。使用的协议是LG。通过更改sRepeats变量,您可以设置每次传输的消息重复次数。


传输的数据也可以在串口监视器中查看。为此,您需要在Arduino IDE软件中打开,然后将波特率设置为115200。


红外接收器的Arduino代码

在Arduino IDE软件中复制并粘贴以下代码。


  1. /*
  2.   modified on AUG 23, 2023
  3. */

  4. /*
  5. * Specify which protocol(s) should be used for decoding.
  6. * If no protocol is defined, all protocols (except Bang&Olufsen) are active.
  7. * This must be done before the #include <IRremote.hpp>
  8. */
  9. //#define DECODE_DENON        // Includes Sharp
  10. //#define DECODE_JVC
  11. //#define DECODE_KASEIKYO
  12. //#define DECODE_PANASONIC    // alias for DECODE_KASEIKYO
  13. #define DECODE_LG
  14. #define DECODE_NEC          // Includes Apple and Onkyo
  15. //#define DECODE_SAMSUNG
  16. //#define DECODE_SONY
  17. //#define DECODE_RC5
  18. //#define DECODE_RC6

  19. //#define DECODE_BOSEWAVE
  20. //#define DECODE_LEGO_PF
  21. //#define DECODE_MAGIQUEST
  22. //#define DECODE_WHYNTER
  23. //#define DECODE_FAST

  24. //#define DECODE_DISTANCE_WIDTH // Universal decoder for pulse distance width protocols
  25. //#define DECODE_HASH         // special decoder for all protocols

  26. //#define DECODE_BEO          // This protocol must always be enabled manually, i.e. it is NOT enabled if no protocol is defined. It prevents decoding of SONY!

  27. //#define DEBUG               // Activate this for lots of lovely debug output from the decoders.

  28. //#define RAW_BUFFER_LENGTH  180  // Default is 112 if DECODE_MAGIQUEST is enabled, otherwise 100.

  29. #include <Arduino.h>

  30. /*
  31. * This include defines the actual pin number for pins like IR_RECEIVE_PIN, IR_SEND_PIN for many different boards and architectures
  32. */
  33. #include "PinDefinitionsAndMore.h"
  34. #include <IRremote.hpp> // include the library

  35. void setup() {
  36.     Serial.begin(115200);

  37.     // Start the receiver and if not 3. parameter specified, take LED_BUILTIN pin from the internal boards definition as default feedback LED
  38.     IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK);

  39.     Serial.print(F("Ready to receive IR signals of protocols: "));
  40.     printActiveIRProtocols(&Serial);
  41.     Serial.println(F("at pin " STR(IR_RECEIVE_PIN))); //Printouts the IR receive pin used in the chip you want.
  42. }

  43. void loop() {
  44.     /*
  45.      * Check if received data is available and if yes, try to decode it.
  46.      * Decoded result is in the IrReceiver.decodedIRData structure.
  47.      */
  48.     if (IrReceiver.decode()) {

  49.         /*
  50.          * Print a short summary of received data
  51.          */
  52.         IrReceiver.printIRResultShort(&Serial);
  53.         IrReceiver.printIRSendUsage(&Serial);
  54.         if (IrReceiver.decodedIRData.protocol == UNKNOWN) {
  55.             Serial.println(F("Received noise or an unknown (or not yet enabled) protocol"));
  56.             // We have an unknown protocol here, print more info
  57.             IrReceiver.printIRResultRawFormatted(&Serial, true);
  58.         }
  59.         Serial.println();

  60.         /*
  61.          * !!!Important!!! Enable receiving of the next value,
  62.          * since receiving has stopped after the end of the current received data packet.
  63.          */
  64.         IrReceiver.resume(); // Enable receiving of the next value

  65.         /*
  66.          * Finally, check the received data and perform actions according to the received command
  67.          */
  68.         if (IrReceiver.decodedIRData.command == 0x10) {
  69.             // do something
  70.             Serial.println("received command 10");
  71.         } else if (IrReceiver.decodedIRData.command == 0x20) {
  72.             // do something else
  73.             Serial.println("received command 20");
  74.         } else if (IrReceiver.decodedIRData.command == 0x30) {
  75.             // do something else
  76.             Serial.println("received command 30");
  77.         }
  78.     }
  79. }
复制代码

在该代码中,Arduino开发板等待接收红外信号,如果接收到的数据格式正确,则根据其指令和地址在串口监视器上打印一条消息。


Arduino红外通信示例测试

对两个Arduino开发板进行编程后,确保发射器上的LED和红外接收器上的二极管彼此相对。现在,如果您将发射器板上的10、11或12引脚之一连接到GND,则相应的地址和命令将传输到接收器。


您可以在发射器和接收器的串行监视器上分别查看发送和接收的数据。在这里,我们通过将引脚10、11 或12连接到GND 来测试所有三种模式。如您所见,每个引脚对应的命令都已发送和接收。

IR-2Arduino-Receiver-SerialOut-1.jpg

跳转到指定楼层
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题 716 | 回复: 1504



手机版|

GMT+8, 2025-1-21 06:38 , Processed in 0.034355 second(s), 6 queries , Gzip On, MemCache On. Powered by Discuz! X3.5

YiBoard一板网 © 2015-2022 地址:河北省石家庄市长安区高营大街 ( 冀ICP备18020117号 )

快速回复 返回顶部 返回列表