Arduino Based TV Remote: Control any TV or Set Up Box Channels with Alexa

Published  February 25, 2022   0
Arduino Based TV Remote with Alexa

Normally we are facing problems with the IR Remote sometimes it may not work and regularly we need to change the Batteries, so thought of replacing this IR Remote with Voice Assistant (Alexa). This is very helpful to all the people for changing the channels, for volume control, changing to channels directly by a single word (Alexa, change the channel to 4 on TV). By using this device we can save more time in searching for Remote, for buying the Batteries, by focusing Remote exactly to TV for changing, etc., for this no need of any external power supply, directly we can connect this device USB port of Set-Up Box.

Component Required for Alexa Based TV Remote 

Required Components for Arduino TV Remote

Project Used Hardware

  • ESP8266 Chip,
  • IR LED,
  • Optocoupler (PC817),
  • Transistor(BC547),
  • 1K Ohm Resistor,
  • AMS117-3.3,
  • Micro USB Connector

Project Used Software

  • Arduino,
  • Sinric Pro

Project Hardware Software Selection

Arduino TV Remote

I have selected ESP8266(ESP-01) Chip which is the smallest microcontroller that comes with default wifi connectivity and also we can design a small PCB using this ESP8266 Chip. The next main component is IR Transmitter to communicate with the set-up box, the next component is a transistor for switching purposes, next component is optocoupler, which is mainly used for isolating the two regions, here I have used it for safe switching and transferring of the signal. Next coming to the software section, Arduino IDE is the best user-friendly Environment for Arduino, and next, I have used Sinric Pro Skill to communicate with Alexa, as it is the default skill available in Alexa so, no need for any 3rd party Voice Assistant Applications. Finally, we can control the channels using Alexa via Sinric Pro Skill directly.

Circuit Diagram

 

Arduino TV Remote Circuit Diagram

This is the simple circuit diagram has designed for smart control of set-up box channels using Alexa, very simple design and power supply is given from Micro USB Port but for ESP Chip is capable of only 3.3V so, we have used AMS1117-3.3 Voltage Regulator.

We previously built many Alexa based project, you can check by following the link.

Code
#include <Arduino.h>

#ifdef ESP8266

       #include <ESP8266WiFi.h>

#endif

#ifdef ESP32  

       #include <WiFi.h>

#endif

#include "SinricPro.h"

#include "SinricProTV.h"

#include <IRremoteESP8266.h>

#include <IRsend.h>

#include <Arduino.h>

#include <IRremoteESP8266.h>

#include <IRrecv.h>

#include <IRutils.h>

decode_results results;

const uint16_t kIrLed = 2 ; //Pin you wish to send IR on

IRsend irsend(kIrLed);

#define WIFI_SSID         "GPONWIFI_1970"    //WIFI Name

#define WIFI_PASS         "123456123456"    // WIFI Password

#define APP_KEY           "6d29d25c-e4fc-4b10-8a9c-8837a00c7ecd"      //Sinric App Key, should look like "de0bxxxx-1x3x-4x3x-ax2x-5dabxxxxxxxx"

#define APP_SECRET        "19db7e4f-f787-4a20-be49-78dee5f65621-7beb3e43-1323-4bfd-b6d4-1d00829de6e0"   // Sinric App Secret, should look like "5f36xxxx-x3x7-4x3x-xexe-e86724a9xxxx-4c4axxxx-3x3x-x5xe-x9x3-333d65xxxxxx"

#define TV_ID             "610b8ed6bab19d4058190f9a"    // Sinric TV Device ID Should look like "5dc1564130xxxxxxxxxxxxxx"

#define TV_ID_2           "6107a515fc89cf405088cb37"    // Sinric TV Device ID Should look like "5dc1564130xxxxxxxxxxxxxx"

#define BAUD_RATE         115200

bool tvPowerState;

unsigned int tvVolume;

unsigned int tvChannel;

bool tvMuted;

String channel;

const char* channelNames[] = {

  "0", //(Alexa only reconises Netflix written like this, i believe its a Virgin Media thing. However saying "Change channel to Netflix on TV" works fine)

  "one",

  "two",

  "three",

  "four",

  "five",

  "six",

  "twenty two",

  "fourty seven",

  "one one nine",

  "one one eight",

  "Zee Telugu",

  "E TV",

  "Maa TV",

  "ETV Plus",

  "ETV Abhiruchi",

  "Zee Cinemalu",

  "Movies",

  "AP Local",

  "win six",

};

#define MAX_CHANNELS sizeof(channelNames) / sizeof(channelNames[0])  // just to determine how many channels are in channelNames array

// map channelNumbers used to convert channelName into channelNumber

// This map is initialized in "setupChannelNumbers()" function by using the "channelNames" array

std::map<String, unsigned int> channelNumbers;

void setupChannelNumbers() {

  for (unsigned int i=0; i < MAX_CHANNELS; i++) {

    channelNumbers[channelNames[i]] = i;

  }

}


// TV device callbacks


bool onAdjustVolume(const String &deviceId, int &volumeDelta, bool volumeDefault) {

  if (volumeDelta > 0) {irsend.sendNEC(0x8877D22D, 32);delay(250);irsend.sendNEC(0x8877D22D, 32);delay(250);irsend.sendNEC(0x8877D22D, 32);delay(250);irsend.sendNEC(0x8877D22D, 32);delay(250);irsend.sendNEC(0x8877D22D, 32);} //Insert IR for Volume Up here.

  if (volumeDelta < 0) {irsend.sendNEC(0x887738C7, 32);delay(250);irsend.sendNEC(0x887738C7, 32);delay(250);irsend.sendNEC(0x887738C7, 32);delay(250);irsend.sendNEC(0x887738C7, 32);delay(250);irsend.sendNEC(0x887738C7, 32);} //Insert IR for Volume Down here.

  tvVolume += volumeDelta;  // calcualte new absolute volume

  Serial.printf("Volume changed about %i to %i\r\n", volumeDelta, tvVolume);

  volumeDelta = tvVolume; // return new absolute volume

  return true;

}

bool onChangeChannel(const String &deviceId, String &channel) {

  tvChannel = channelNumbers[channel]; // save new channelNumber in tvChannel variable

  Serial.printf("Change channel blah to \"%s\" (channel number %d)\r\n", channel.c_str(), tvChannel);

  Serial.println(tvChannel);

  Serial.println(channel);

  if ((channel) == ("ETV")) {

    irsend.sendNEC(0x8877827D, 32);

    Serial.println("Hi....11");

    }// irsend.sendNEC(0x8877827D, 32); delay (250); irsend.sendNEC(0x8877827D, 32);} //Change IR sequence inside of {} for each channel.

  if (channel == "zee telugu") {

    irsend.sendNEC(0x887702FD, 32);

    Serial.println("Hi....22");

    }//irsend.sendNEC(0xFD00FF, 32); delay (250); irsend.sendNEC(0XFD807F, 32);}

  if ((channel) == ("TV")) {

    irsend.sendNEC(0x8877A25D, 32);

    Serial.println("Hi....33");

    }

  if (channel == "ETV Plus") {

    irsend.sendNEC(0x8877629D, 32);

    Serial.println("Hi....44");

  }

  if (channel == "ETV Abhiruchi") {

    irsend.sendNEC(0x887722DD, 32);

    Serial.println("Hi....55");

  }

  if (channel == "zee cinemalu") {

    irsend.sendNEC(0x8877827D, 32);

    delay(250);

    irsend.sendNEC(0x8877827D, 32);

    Serial.println("Hi....66");

  }

  if (channel == "movies") {

    irsend.sendNEC(0x887742BD, 32);

    delay(250);

    irsend.sendNEC(0x8877B24D, 32);

    delay(250);

    irsend.sendNEC(0x8877A25D, 32);

    Serial.println("Hi....77");

  }

  if (channel == "ap 24x7") {

    irsend.sendNEC(0x887742BD, 32);

    delay(250);

    irsend.sendNEC(0x887742BD, 32);

    delay(250);

    irsend.sendNEC(0x8877926D, 32);

    Serial.println("Hi....88");

  }

  if (channel == "win tv") {

    irsend.sendNEC(0x887742BD, 32);

    delay(250);

    irsend.sendNEC(0x887742BD, 32);

    delay(250);

    irsend.sendNEC(0x887712ED, 32);

    Serial.println("Hi....99");

  }

  return true;

}

bool onChangeChannelNumber(const String& deviceId, int channelNumber, String& channelName) {

  tvChannel = channelNumber; // update tvChannel to new channel number 

  if (tvChannel < 0) tvChannel = 0;

  if (tvChannel > MAX_CHANNELS-1) tvChannel = MAX_CHANNELS-1;   

  delay(250);

  channelName = channelNames[tvChannel]; // return the channelName

  Serial.print("channelNumber: ");

  Serial.println(channelNumber);

  Serial.print("channelName: ");

  Serial.println(channelName);

  if ((channelName) == "one") {

    irsend.sendNEC(0x8877827D, 32);

    Serial.println("Hi....11");

    }// irsend.sendNEC(0x8877827D, 32); delay (250); irsend.sendNEC(0x8877827D, 32);} //Change IR sequence inside of {} for each channel.

  if (channelNumber == 2) {

    irsend.sendNEC(0x8877827D, 32);

    Serial.println("Hi....22");

    }//irsend.sendNEC(0xFD00FF, 32); delay (250); irsend.sendNEC(0XFD807F, 32);}

  if ((channelNumber) == 3) {

    irsend.sendNEC(0x887702FD, 32);

    Serial.println("Hi....33");

    }   

  if (channelNumber == 4) {

    irsend.sendNEC(0x8877629D, 32);

    Serial.println("Hi....44");

  }

  if (channelNumber == 5) {

    irsend.sendNEC(0x8877A25D, 32);

    Serial.println("Hi....55");

  }

  if (channelNumber == 6) {

    irsend.sendNEC(0x887722DD, 32);

    delay(250);

    irsend.sendNEC(0x8877827D, 32);

    Serial.println("Hi....66");

  }

  if (channelNumber == 7) {

    irsend.sendNEC(0x887742BD, 32);

    delay(250);

    irsend.sendNEC(0x8877B24D, 32);

    delay(250);

    irsend.sendNEC(0x8877A25D, 32);

    Serial.println("Hi....77");

  }

  if (channelNumber == 8) {

    irsend.sendNEC(0x887742BD, 32);

    delay(250);

    irsend.sendNEC(0x887742BD, 32);

    delay(250);

    irsend.sendNEC(0x8877926D, 32);

    Serial.println("Hi....88");

  }

  if (channelNumber == 9) {

    irsend.sendNEC(0x887742BD, 32);

    delay(250);

    irsend.sendNEC(0x887742BD, 32);

    delay(250);

    irsend.sendNEC(0x887712ED, 32);

    Serial.println("Hi....99");

  }

  if (channelNumber == 22) {

    irsend.sendNEC(0x8877827D, 32);

    delay(250);

    irsend.sendNEC(0x8877827D, 32);

    Serial.println("Hi....22");

  }

  if (channelNumber == 47) {

    irsend.sendNEC(0x8877629D, 32);

    delay(250);

    irsend.sendNEC(0x887752AD, 32);

    Serial.println("Hi....47");

  }

  if (channelNumber == 119) {

    irsend.sendNEC(0x887742BD, 32);

    delay(250);

    irsend.sendNEC(0x887742BD, 32);

    delay(250);

    irsend.sendNEC(0x887712ED, 32);

    Serial.println("Hi....119");

  }

  if (channelNumber == 118) {

    irsend.sendNEC(0x887742BD, 32);

    delay(250);

    irsend.sendNEC(0x887742BD, 32);

    delay(250);

    irsend.sendNEC(0x8877926D, 32);

    Serial.println("Hi....118");

  }

  if (channelNumber == 104) {

    irsend.sendNEC(0x887742BD, 32);

    delay(250);

    irsend.sendNEC(0x8877B24D, 32);

    delay(250);

    irsend.sendNEC(0x8877629D, 32);

    Serial.println("Hi....104");

  }

  if (channelNumber == 103) {

    irsend.sendNEC(0x887742BD, 32);

    delay(250);

    irsend.sendNEC(0x8877B24D, 32);

    delay(250);

    irsend.sendNEC(0x887702FD, 32);

    Serial.println("Hi....103");

  }

  if (channelNumber == 102) {

    irsend.sendNEC(0x887742BD, 32);

    delay(250);

    irsend.sendNEC(0x8877B24D, 32);

    delay(250);

    irsend.sendNEC(0x8877827D, 32);

    Serial.println("Hi....103");

  }

  if (channelNumber == 105) {

    irsend.sendNEC(0x887742BD, 32);

    delay(250);

    irsend.sendNEC(0x8877B24D, 32);

    delay(250);

    irsend.sendNEC(0x8877A25D, 32);

    Serial.println("Hi....105");

  }

  if (channelNumber == 106) {

    irsend.sendNEC(0x887742BD, 32);

    delay(250);

    irsend.sendNEC(0x8877B24D, 32);

    delay(250);

    irsend.sendNEC(0x887722DD, 32);

    Serial.println("Hi....106");

  } 

  Serial.printf("Change to channel to %d (channel name \"%s\")\r\n", tvChannel, channelName.c_str());

  return true;

}

bool onMute(const String &deviceId, bool &mute) {

  if(deviceId=="TV_ID"){ 

  Serial.printf("TV volume is %s\r\n", mute?"muted":"unmuted");

  tvMuted = mute; // set tvMuted state

  if(mute){

        irsend.sendNEC(0x8877E21D, 32); //Insert Mute button IR for Mute

      }

       else{

        irsend.sendNEC(0x8877E21D, 32); //Insert Mute button IR for unmute (Normally the same as above)

        }

  }

  return true;

}

bool onSetVolume(const String &deviceId, int &volume) {

  Serial.printf("Volume set to:  %i\r\n", volume);

  tvVolume = volume; // update tvVolume

  return true;

}

// setup function for WiFi connection

void setupWiFi() {

  irsend.begin()

  Serial.printf("\r\n[Wifi]: Connecting");

  WiFi.begin(WIFI_SSID, WIFI_PASS);

  while (WiFi.status() != WL_CONNECTED) {

    Serial.printf(".");

    delay(250);

  }

  IPAddress localIP = WiFi.localIP();

  Serial.printf("connected!\r\n[WiFi]: IP-Address is %d.%d.%d.%d\r\n", localIP[0], localIP[1], localIP[2], localIP[3]);

}

void dump(decode_results *results) {

  // Dumps out the decode_results structure.

  // Call this after IRrecv::decode()

  uint16_t count = results->rawlen;

  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 == RC5X) {

    Serial.print("Decoded RC5X: ");

  } else if (results->decode_type == RC6) {

    Serial.print("Decoded RC6: ");

  } else if (results->decode_type == RCMM) {

    Serial.print("Decoded RCMM: ");

  } else if (results->decode_type == PANASONIC) {

    Serial.print("Decoded PANASONIC - Address: ");

    Serial.print(results->address, HEX);

    Serial.print(" Value: ");

  } else if (results->decode_type == LG) {

    Serial.print("Decoded LG: ");

  } else if (results->decode_type == JVC) {

    Serial.print("Decoded JVC: ");

  } else if (results->decode_type == AIWA_RC_T501) {

    Serial.print("Decoded AIWA RC T501: ");

  } else if (results->decode_type == WHYNTER) {

    Serial.print("Decoded Whynter: ");

  } else if (results->decode_type == NIKAI) {

    Serial.print("Decoded Nikai: ");

  }

  serialPrintUint64(results->value, 16);

  Serial.print(" (");

  Serial.print(results->bits, DEC);

  Serial.println(" bits)");

  Serial.print("Raw (");

  Serial.print(count, DEC);

  Serial.print("): {");

  for (uint16_t i = 1; i < count; i++) {

    if (i % 100 == 0)

      yield();  // Preemptive yield every 100th entry to feed the WDT.

    if (i & 1) {

      Serial.print(results->rawbuf[i] * kRawTick, DEC);

    } else {

      Serial.print(", ");

      Serial.print((uint32_t) results->rawbuf[i] * kRawTick, DEC);

    }

  }

  Serial.println("};");

}

// setup function for SinricPro

void setupSinricPro() {

  // add device to SinricPro

  SinricProTV& myTV = SinricPro[TV_ID];

  // set callback functions to device

  myTV.onAdjustVolume(onAdjustVolume);

  myTV.onChangeChannel(onChangeChannel);

  myTV.onChangeChannelNumber(onChangeChannelNumber);

  myTV.onMute(onMute);

  myTV.onSetVolume(onSetVolume);

  // setup SinricPro

  SinricPro.onConnected([](){ Serial.printf("Connected to SinricPro\r\n"); });

  SinricPro.onDisconnected([](){ Serial.printf("Disconnected from SinricPro\r\n"); });

  SinricPro.begin(APP_KEY, APP_SECRET);

}

// main setup function

void setup() {

  Serial.begin(BAUD_RATE); Serial.printf("\r\n\r\n");

  Serial.printf("%d channels configured\r\n", MAX_CHANNELS);

//  irrecv.enableIRIn();

  setupWiFi();

  setupSinricPro();

  setupChannelNumbers();

}

void loop() {

  SinricPro.handle();

}

Video

Have any question realated to this Article?

Ask Our Community Members