Страница 1 из 1

IR приёмник и передатчик на Arduino

Добавлено: Пт окт 03, 2014 10:52 am
sergejey
Давно собирался и вчера наконец сделал небольшой проектик -- приёмник и передатчик IR-сигналов, для управления техникой.

Проект состоит из двух частей:
1. IR-приёмник, который предназначен для получения кодов с кнопок имеющегося пульта.
2. IR-передатчик, задача которого, получив команду по радио-каналу, воспроизвести зашитый код, соответствующий этой команде.

Итак, часть I. Приёмник.

Подключение готового IR-модуля:
Изображение

(как вариант, брать просто элемент приёмника и подключать его через сопротивление, но у меня был готовый модуль, так что я просто его подсоединил как на схеме)

Для прошивки Aruino нам понадобится подключить библиотеку IR Remote
Код скетча для ArduinoSPOILER_SHOW
#include <IRremote.h>

int RECV_PIN = 4;

IRrecv irrecv(RECV_PIN);

decode_results results;

void setup()
{
Serial.begin(9600);
irrecv.enableIRIn(); // Start the receiver
}

void loop() {
if (irrecv.decode(&results)) {

if (results.decode_type == UNKNOWN) {
Serial.print("Unknown encoding: ");
}
else if (results.decode_type == NEC) {
Serial.print("Decoded NEC: ");
}
else if (results.decode_type == SONY) {
Serial.print("Decoded SONY: ");
}
else if (results.decode_type == RC5) {
Serial.print("Decoded RC5: ");
}
else if (results.decode_type == RC6) {
Serial.print("Decoded RC6: ");
}
else if (results.decode_type == PANASONIC) {
Serial.print("Decoded PANASONIC - Address: ");
Serial.print(results.panasonicAddress,HEX);
Serial.print(" Value: ");
}
else if (results.decode_type == LG) {
Serial.print("Decoded LG: ");
}
else if (results.decode_type == JVC) {
Serial.print("Decoded JVC: ");
}


Serial.print(results.value, HEX);

Serial.print(" Bits: ");

Serial.println(results.bits);

irrecv.resume(); // Receive the next value
}
}
В итоге мы получили небольшое устройство, которое выводит в консоль тип протокола и посылаемый пультом код нажатой кнопки.

Часть II. Передатчик.

Назначение передатчика -- воспроизвести зашитый код. Передатчик по радио-каналу получает команду на отправку IR-сигнала, код которого под определённым номером зашивается в сам передатчик. Не совсем универсально, но передавать протокол и код по радио я уже не стал. Для радио-обмена используются модули приёма-передачи на 433Mhz, работающие по этому протоколу/

Схема:
Изображение
Код скетча для ArduinoSPOILER_SHOW
#include <EEPROM.h> //Needed to access the eeprom read write functions
#include <IRremote.h>
#include <VirtualWire.h>
#include <EasyTransferVirtualWire.h>

#define PIN_LED (13) // INDICATOR
#define PIN_RF (7)
#define CLASS_IR (25) // control class command

String inData;
unsigned int unique_device_id = 0;

long int uptime = 0;
long int old_uptime = 0;
IRsend irsend;
unsigned int packet_received_id = 0;

EasyTransferVirtualWire ET;

struct SEND_DATA_STRUCTURE {
//put your variable definitions here for the data you want to send
//THIS MUST BE EXACTLY THE SAME ON THE OTHER ARDUINO
//Struct can'e be bigger then 26 bytes for VirtualWire version
unsigned int device_id;
unsigned int destination_id;
unsigned int packet_id;
byte command;
int data;
};

//give a name to the group of data
SEND_DATA_STRUCTURE mydata;

//This function will write a 2 byte integer to the eeprom at the specified address and address + 1
void EEPROMWriteInt(int p_address, unsigned int p_value)
{
byte lowByte = ((p_value >> 0) & 0xFF);
byte highByte = ((p_value >> 8) & 0xFF);

EEPROM.write(p_address, lowByte);
EEPROM.write(p_address + 1, highByte);
}

//This function will read a 2 byte integer from the eeprom at the specified address and address + 1
unsigned int EEPROMReadInt(int p_address)
{
byte lowByte = EEPROM.read(p_address);
byte highByte = EEPROM.read(p_address + 1);

return ((lowByte << 0) & 0xFF) + ((highByte << 8) & 0xFF00);
}

void blinking(int count) {
for(int i=0;i<count;i++) {
digitalWrite(PIN_LED, HIGH);
delay(200);
digitalWrite(PIN_LED, LOW);
delay(200);
}
}

void irCommand(int type, int command, int bits) {
Serial.print("Sending IR command: ");
Serial.println(command);
for (int i = 0; i < 3; i++) {
if (type==NEC) {
irsend.sendNEC(command, bits);
}
if (type==SONY) {
irsend.sendSony(command, bits);
}
if (type==RC5) {
irsend.sendRC5(command, bits);
}
if (type==RC6) {
irsend.sendRC6(command, bits);
}
if (type==SAMSUNG) {
irsend.sendSAMSUNG(command, bits);
}
if (type==DISH) {
irsend.sendDISH(command, bits);
}
if (type==SHARP) {
irsend.sendSharp(command, bits);
}
if (type==PANASONIC) {
irsend.sendPanasonic(command, bits);
}
if (type==JVC) {
irsend.sendJVC(command, bits,1);
}
delay(40);
}
}

void setup()
{
randomSeed(analogRead(0));
pinMode(PIN_LED, OUTPUT);


Serial.begin(9600); // Debugging only

ET.begin(details(mydata));
// Initialise the IO and ISR
vw_set_rx_pin(PIN_RF);
vw_setup(2000); // Bits per sec
vw_rx_start(); // Start the receiver PLL running


// Device ID
Serial.print("Getting Device ID... ");
unique_device_id=EEPROMReadInt(0);
if (unique_device_id<10000 || unique_device_id>60000 || unique_device_id==26807) {
Serial.print("N/A, updating... ");
unique_device_id=random(10000, 60000);
EEPROMWriteInt(0, unique_device_id);
}
Serial.println(unique_device_id);


}

void loop()
{
uptime=round(millis()/1000);
if (uptime!=old_uptime) {
Serial.print("Up: ");
Serial.println(uptime);
old_uptime=uptime;
}

//begin easy transfer
if (ET.receiveData()) {
Serial.print("Got packet for device ");
Serial.print(mydata.destination_id);
Serial.print(" packet ");
Serial.print(mydata.packet_id);
Serial.print(" command ");
Serial.print(mydata.command);
Serial.print(" data ");
Serial.println(mydata.data);

if ((mydata.destination_id==unique_device_id) && (mydata.packet_id!=packet_received_id) && mydata.command==CLASS_IR) {

Serial.print("Got RF command: ");
Serial.print(mydata.command);
Serial.print(" data: ");
Serial.println(mydata.data);
packet_received_id=(int)mydata.packet_id;
if (mydata.data==1) {
irCommand(RC5,0xA0,12); //up
}
if (mydata.data==2) {
irCommand(RC5,0xA1,12); //down
}
if (mydata.data==3) {
irCommand(RC5,0x8C,12); //off
}
} else {
Serial.println("Ignoring packet.");
}
}

if (Serial.available()) {
char c=Serial.read();
if (c == '\n' || c == ';')
{
Serial.println(inData);
int commandProcessed=0;
if (inData.equals("blink")) {
Serial.println("BLINKING!");
blinking(3);
commandProcessed=1;
}
if (inData.equals("up")) {
irCommand(RC5,0xA0,12);
commandProcessed=1;
}
if (inData.equals("down")) {
irCommand(RC5,0xA1,12);
commandProcessed=1;
}
if (inData.equals("off")) {
irCommand(RC5,0x8C,12);
commandProcessed=1;
}
inData="";
Serial.flush();
} else {
inData += (c);
}
}
}
В скетч зашиты три команды Up, Down, Off -- это три кнопки на пульте (управление вытяжкой кухонной). Ресивер запускает эти команды либо при получении радио-пакета с командой (25) и соотв номером (1,2,3), либо через консоль при получении команды "up;", "on;", "off;"

Собственно, всё. На основе вышеописанного можно легко делать свои устройства с применением IR-пультов.