Code de recherche

Comment utiliser un Arduino comme télécommande de télévision

Comment utiliser un Arduino comme télécommande de télévision

Ce guide montre comment transformer un Arduino en télécommande universelle pour votre téléviseur, lecteur Blu-ray ou d'autres appareils contrôlés par infrarouge. Vous apprendrez à décoder les signaux de n'importe quelle télécommande, puis à transmettre ces codes en utilisant un Arduino et une LED infrarouge. Cela ouvre un monde de possibilités d'automatisation, allant d'un simple contrôle marche/arrêt à des séquences complexes impliquant plusieurs appareils.

Broches du récepteur IR sans fil VS1838B
Récepteur IR VS1838B broches
Décodage de toute télécommande noire ou blanche avec Arduino
Décodage de n'importe quelle télécommande noire ou blanche avec Arduino

Voici quelques idées de projets pour vous aider à commencer :

  • Créez un système de programmation d'allumage et d'extinction de la télévision.
  • Intégrez le contrôle de votre téléviseur dans un système de maison intelligente.
  • Créez une télécommande personnalisée avec des fonctions uniques.
  • Contrôlez votre système de divertissement avec des commandes vocales via un assistant vocal basé sur Arduino.

Matériel/Composants

  • Arduino Uno (ou carte compatible)
  • Module récepteur infrarouge (IR) (par exemple, TSOP1738, VS1838B)
  • LED infrarouge (IR) (par exemple, longueur d'onde de 940 nm)
  • Résistance (270-330 ohms pour la LED IR)
  • Fils de connexion
  • Plaque de prototypage (optionnelle)

Guide de câblage

Câblage_du_transmetteur_IR

Connectez le module récepteur IR comme suit (dans la vidéo à 02:45) :

  • VCC à Arduino 5V
  • GND à GND Arduino
  • Pin de signal vers la broche 11 de l'Arduino (peut être modifié dans le code)

Connectez la LED IR comme suit (dans la vidéo à 02:07) :

  • Une broche LED à la broche 3 de l'Arduino (à travers une résistance de 270-330 ohms)
  • Autre broche LED à GND Arduino

La résistance limite le courant vers la LED IR, la protégeant des dommages (dans la vidéo à 03:37).

Explication du code

Tout d'abord, installez la bibliothèque IRremote (dans la vidéo à 04:16). Cette bibliothèque gère les subtilités de l'envoi et de la réception des signaux infrarouges. Vous pouvez la trouver dans le gestionnaire de bibliothèques Arduino.

Les extraits de code fournis sont à titre de référence. La bibliothèque IRremote comprend un code d'exemple pour recevoir et envoyer des signaux IR. Les exemples peuvent être trouvés dans l'IDE Arduino : Fichier > Exemples > IRremote.

Code de réception

Ce extrait de code configure le récepteur sur la broche 11 (dans la vidéo à 04:50). Modifiez leRECV_PINsi vous utilisez un code PIN différent.


#include 
int RECV_PIN = 11;
IRrecv irrecv(RECV_PIN);
decode_results results;

Envoi du code

Ce code envoie le code IR brut capturé. Lerawle tableau stocke les temps de signal, et38représente la fréquence (en kHz). Vous devrez remplacer les données d'exemple par le code capturé depuis votre télécommande (dans la vidéo à 05:26).


irsend.sendRaw(raw, sizeof(raw) / sizeof(raw[0]), 38);

Lesizeof(raw) / sizeof(raw[0])calcule le nombre d'éléments dans lerawtableau (dans la vidéo à 06:18).

Projet/Démonstration en direct

La vidéo démontre comment capturer le code du bouton d'alimentation à partir d'une télécommande Samsung et ensuite utiliser l'Arduino pour allumer et éteindre la télévision (dans la vidéo à 08:29). Le processus implique de capturer le code en utilisant le croquis de réception, puis de coller ce code dans le croquis d'envoi. La démonstration montre comment l'Arduino imite avec succès la télécommande d'origine.

Chapitres

  • [00:00] Introduction et aperçu du projet
  • [00:41] Comprendre la télécommande infrarouge
  • [02:07] Composants matériels et câblage
  • [04:16] Installation de la bibliothèque IRremote
  • [05:26] Envoi de signaux IR avec Arduino
  • [06:46] Test de la transmission IR
  • Démonstration en direct avec un téléviseur Samsung
  • [09:27] Expansion du projet et idées supplémentaires

Images

Décodage de n'importe quelle télécommande noire ou télécommande blanche avec Arduino
Décodage de n'importe quelle télécommande noire ou télécommande blanche avec Arduino
Broches du récepteur IR VS1838B
Broches du récepteur IR VS1838B
ir_receiver_sl838
ir_receiver_sl838
remote
remote
IR_remote_transmitter_wiring
IR_remote_transmitter_wiring
140-You don't need this code. The example is already included in the library.
Langue: C++
#include <IRremote.h>
// Sketch from:
//https://gist.github.com/probonopd/5793692#file-sendandreceive-ino
 
// http://www.pjrc.com/teensy/td_libs_IRremote.html
// If one keypress results in multiple codes being output, then
// change in IRremoteInt.h:
// #define _GAP 50000
// Provided by Robojax.com on August 4, 2018
// Watch video instructions for this code:https://youtu.be/xA66hXYRx9I
 
int RECV_PIN = 11;
IRrecv irrecv(RECV_PIN);
decode_results results;
 
// Compare two tick values, returning 0 if newval is shorter,
// 1 if newval is equal, and 2 if newval is longer.
// Use a tolerance of 20%
int compare(unsigned int oldval, unsigned int newval) {
  if (newval < oldval * .8) {
    return 0;
  } 
  else if (oldval < newval * .8) {
    return 2;
  } 
  else {
    return 1;
  }
}
 
// Use FNV hash algorithm: http://isthe.com/chongo/tech/comp/fnv/#FNV-param
#define FNV_PRIME_32 16777619
#define FNV_BASIS_32 2166136261
 
/* Converts the raw code values into a 32-bit hash code.
 * Hopefully this code is unique for each button.
 */
unsigned long decodeHash(decode_results *results) {
  unsigned long hash = FNV_BASIS_32;
  for (int i = 1; i+2 < results->rawlen; i++) {
    int value =  compare(results->rawbuf[i], results->rawbuf[i+2]);
    // Add value into the hash
    hash = (hash * FNV_PRIME_32) ^ value;
  }
  return hash;
}
 
void setup()
{
  Serial.begin(9600);
  Serial.println("Robojax IR Capture");
  irrecv.enableIRIn(); // Start the receiver
}
 
int c = 1;
 
void dump(decode_results *results) {
  int count = results->rawlen;
  Serial.println(c);
  c++;
  Serial.println("Hash: ");
  unsigned long hash = decodeHash(results);
  Serial.println(hash, HEX);
  Serial.println("For IR Scope/IrScrutinizer: ");
  for (int i = 1; i < count; i++) {
 
    if ((i % 2) == 1) {
      Serial.print("+");
      Serial.print(results->rawbuf[i]*USECPERTICK, DEC);
    }
    else {
      Serial.print(-(int)results->rawbuf[i]*USECPERTICK, DEC);
    }
    Serial.print(" ");
  }
  Serial.println("-127976");
  Serial.println("For Arduino sketch: ");
  Serial.print("unsigned int raw[");
  Serial.print(count, DEC);
  Serial.print("] = {");
  for (int i = 1; i < count; i++) {
 
    if ((i % 2) == 1) {
      Serial.print(results->rawbuf[i]*USECPERTICK, DEC);
    }
    else {
      Serial.print((int)results->rawbuf[i]*USECPERTICK, DEC);
    }
    Serial.print(",");
  }
  Serial.print("};");
  Serial.println(""); 
  Serial.print("irsend.sendRaw(raw,");
  Serial.print(count, DEC);
  Serial.print(",38);");
  Serial.println(""); 
  Serial.println("");
}
 
 
#include <avr/interrupt.h>
#include <stdio.h>
#include <avr/pgmspace.h>
#include <stdint.h>
#include <avr/io.h>
#define IR_PORT PORTB
// #define IR_PIN PINB
// #define IR_DDR DDRB
// #define IR_BV _BV(1)
#define IR_OCR OCR1A
#define IR_TCCRnA TCCR1A
#define IR_TCCRnB TCCR1B
#define IR_TCNTn TCNT1
#define IR_TIFRn TIFR1
#define IR_TIMSKn TIMSK1
#define IR_TOIEn TOIE1
#define IR_ICRn ICR1
#define IR_OCRn OCR1A
#define IR_COMn0 COM1A0
#define IR_COMn1 COM1A1
#define PRONTO_IR_SOURCE 0 // Pronto code byte 0
#define PRONTO_FREQ_CODE 1 // Pronto code byte 1
#define PRONTO_SEQUENCE1_LENGTH 2 // Pronto code byte 2
#define PRONTO_SEQUENCE2_LENGTH 3 // Pronto code byte 3
#define PRONTO_CODE_START 4 // Pronto code byte 4
 
static const uint16_t *ir_code = NULL;
static uint16_t ir_cycle_count = 0;
static uint32_t ir_total_cycle_count = 0;
static uint8_t ir_seq_index = 0;
static uint8_t ir_led_state = 0;
 
void ir_on()
{
  IR_TCCRnA |= (1<<IR_COMn1) + (1<<IR_COMn0);
  ir_led_state = 1;
}
 
void ir_off()
{
  IR_TCCRnA &= ((~(1<<IR_COMn1)) & (~(1<<IR_COMn0)) );
  ir_led_state = 0;
}
 
void ir_toggle()
{
  if (ir_led_state)
    ir_off();
  else
    ir_on();
}
 
void ir_start(uint16_t *code)
{
  ir_code = code;
  // IR_PORT &= ~IR_BV; // Turn output off (atmega328 only)
  digitalWrite(9,LOW); // Turn output off
  // IR_DDR |= IR_BV; // Set it as output (atmega328 only)
  pinMode(9,OUTPUT); // Set it as output
  IR_TCCRnA = 0x00; // Reset the pwm
  IR_TCCRnB = 0x00;
  //printf_P(PSTR("FREQ CODE: %hd\r\n"), code[PRONTO_FREQ_CODE]);
  uint16_t top = ( (F_CPU/1000000.0) * code[PRONTO_FREQ_CODE] * 0.241246 ) - 1;
  //printf_P(PSTR("top: %hu\n\r"), top);
  IR_ICRn = top;
  IR_OCRn = top >> 1;
  IR_TCCRnA = (1<<WGM11);
  IR_TCCRnB = (1<<WGM13) | (1<<WGM12);
  IR_TCNTn = 0x0000;
  IR_TIFRn = 0x00;
  IR_TIMSKn = 1 << IR_TOIEn;
  ir_seq_index = PRONTO_CODE_START;
  ir_cycle_count = 0;
  ir_on();
  IR_TCCRnB |= (1<<CS10);
}
 
#define TOTAL_CYCLES 80000 // Turns off after this number of
// cycles. About 2 seconds.
// FIXME: Turn off after having sent all data
ISR(TIMER1_OVF_vect) {
  uint16_t sequenceIndexEnd;
  uint16_t repeatSequenceIndexStart;
  ir_total_cycle_count++;
  ir_cycle_count++;
 
  if (ir_cycle_count== ir_code[ir_seq_index]) {
    ir_toggle();
    ir_cycle_count = 0;
    ir_seq_index++;
    sequenceIndexEnd = PRONTO_CODE_START +
      (ir_code[PRONTO_SEQUENCE1_LENGTH]<<1) +
      (ir_code[PRONTO_SEQUENCE2_LENGTH]<<1);
 
    repeatSequenceIndexStart = PRONTO_CODE_START +
      (ir_code[PRONTO_SEQUENCE1_LENGTH]<<1);
 
    if (ir_seq_index >= sequenceIndexEnd ) {
      ir_seq_index = repeatSequenceIndexStart;
 
      if(ir_total_cycle_count>TOTAL_CYCLES) {
        ir_off();
        TCCR1B &= ~(1<<CS10);
      }
    }
  }
}
 
void ir_stop()
{
  IR_TCCRnA = 0x00; // Reset the pwm
  IR_TCCRnB = 0x00;
}
 
const uint16_t inputLength = 512;
 
 
 
void loop() {
  if (irrecv.decode(&results)) {
    dump(&results);
    irrecv.resume(); // Receive the next value
  }
 
  if ( Serial.available() > 0 )
  {
    static char input[inputLength];
    static uint16_t i;
    char c = Serial.read();
 
    if ( c != '\r' && c != '\n' && i < inputLength-1)
      input[i++] = c;
 
    else
    {
      input[i] = '\0';
      i = 0;
 
      uint16_t array[80];
      uint16_t j = 0;
 
      if ( !strncmp(input, "SEND", 4) )
      {
        char* p = input+4;
 
        while ( (p = strchr(p, ' ')) != NULL )
          array[j++] = strtol(p, &p, 16);
 
        ir_start(array);
        Serial.print("SENT ");
        for ( uint8_t i = 0; i < j; i++ )
        {
          Serial.print ("0x");
          Serial.print (array[i], HEX);
          Serial.print(" ");
        }
 
 
        Serial.println();
      }
    }
  }
}

Ce dont vous pourriez avoir besoin

Fichiers📁

Aucun fichier disponible.