Controlling Windows with a TV remote control or how to transmit signals through a serial port

I decided that I want to switch the volume of sound and audio tracks on a laptop under Windows from an infrared remote control. Arduino uno, a bunch of wires with a breadboard, an infrared sensor, a laptop and, in fact, an infrared remote control.





There is an idea, there is iron, but the theory is lame. How can I get my computer to understand the infrared signals of the remote control and take the required action? I decided to use an arduino to receive remote control signals through the infrared sensor on the breadboard and send messages to the laptop via USB. This required at least some knowledge of how it all works.





It was decided to investigate.





Introducing Arduino to the remote control

To receive a signal from the infrared remote control, you need a receiver, which we will connect to the arduino through a breadboard according to the following scheme:





signal coding according to NEC protocol
signal coding according to NEC protocol

In order for arduino to understand by what protocol and with what command the signal is transmitted, there is the IRremote library, which in new versions of the Arduino IDE can be added from the standard libraries.





The library itself





(/ ). 5 .





, , , IrReceiver.decodedIRData.decodedRawData. , . . , . , :





#include <IRremote.h>
int IR_RECEIVE_PIN = 2; //    2- 
long command;

void setup()
{
  Serial.begin(9600);
  IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK); 
}

void loop() {
  if (IrReceiver.decode()) //    
  {
    command = IrReceiver.decodedIRData.decodedRawData; /*     
    																											   */
    switch(command) //       
    {
      case 0xEA15FF00:
        Serial.write("D"); delay(120);
      break;

      case 0xB946FF00:
        Serial.write("U"); delay(120);
      break;

      case 0xBF40FF00:
        Serial.write("P"); delay(120);
      break;

      case 0xBC43FF00:
        Serial.write("N"); delay(120);
      break;

      case 0xBB44FF00:
        Serial.write("R"); delay(120);
      break;
    }
    
    IrReceiver.resume(); //   
  }
}
      
      



, , USB.





Windows

Windows, .





- . ++ Visual Studio Windows.h





, , SendInput :





 INPUT Input = { 0 };
 Input.type = INPUT_KEYBOARD;
 Input.ki.wVk = VK_VOLUME_UP; /*      , 
 																   */
 SendInput(1, &Input, sizeof(Input));
 ZeroMemory(&Input, sizeof(Input));
      
      



: (VK_VOLUME_UP, VK_VOLUME_DOWN); (VK_MEDIA_PLAY_PAUSE); "" (VK_MEDIA_NEXT_TRACK, VK_MEDIA_PREV_TRACK)





.





Serial port ?

USB, (Serial port), Windows COM , IBM PC. , , . Windows.h





#include <Windows.h>
#include <stdio.h>
#include <string.h>

int main(void)
{
    HANDLE Port;
    BOOL Status;
    DCB dcbSerialParams = { 0 };
    COMMTIMEOUTS timeouts = { 0 };
    DWORD dwEventMask;
    char ReadData;
    DWORD NoBytesRead;
    bool Esc = FALSE;

    Port = CreateFile(L"\\\\.\\COM3", GENERIC_READ, 0, NULL,  //   
    OPEN_EXISTING, 0, NULL);

    if (Port == INVALID_HANDLE_VALUE)
    {
        printf("\nError to Get the COM state\n");
        CloseHandle(Port);
    }
    else
    {
   
        printf("\nopening serial port is succesful\n");

    }

    dcbSerialParams.DCBlength = sizeof(dcbSerialParams);

    Status = GetCommState(Port, &dcbSerialParams); 			//    
    if (Status == FALSE)
    {
        printf("\n Error to Get the COM state \n");
        CloseHandle(Port);
    }

    dcbSerialParams.BaudRate = CBR_9600;									//   
    dcbSerialParams.ByteSize = 8;
    dcbSerialParams.StopBits = ONESTOPBIT;
    dcbSerialParams.Parity = NOPARITY;

    Status = SetCommState(Port, &dcbSerialParams);   
  
    if (Status == FALSE)
    {
        printf("\n Error to Setting DCB Structure \n ");
        CloseHandle(Port);
    }

    timeouts.ReadIntervalTimeout = 10;						/*     
   																								  (    ) */
   timeouts.ReadTotalTimeoutConstant = 200;				
    timeouts.ReadTotalTimeoutMultiplier = 2;

    if (SetCommTimeouts(Port, &timeouts) == FALSE)
    {
        printf("\n Error to Setting Timeouts");
        CloseHandle(Port);
    }

        while (Esc == FALSE)
        {
          
            Status = SetCommMask(Port, EV_RXCHAR);

            if (Status == FALSE)
            {
                printf("\nError to in Setting CommMask\n");
                CloseHandle(Port);
            }

            Status = WaitCommEvent(Port, &dwEventMask, NULL); 		/*    
          																												(   ) */
            if (Status == FALSE)
            {
                printf("\nError! in Setting WaitCommEvent () \n");
                CloseHandle(Port);
            }


            Status = ReadFile(Port, &ReadData, 3, &NoBytesRead, NULL); //   


            printf("\nNumber of bytes received = % d\n\n", sizeof(ReadData) - 1);

            switch (ReadData)																/*    
            																									    */
            {
                case 'U':
                {
                    INPUT Input = { 0 };
                    Input.type = INPUT_KEYBOARD;
                    Input.ki.wVk = VK_VOLUME_UP;
                    SendInput(1, &Input, sizeof(Input));
                    ZeroMemory(&Input, sizeof(Input));
                }
                break;

                case 'D':
                {
                    INPUT Input = { 0 };
                    Input.type = INPUT_KEYBOARD;
                    Input.ki.wVk = VK_VOLUME_DOWN;
                    SendInput(1, &Input, sizeof(Input));
                    ZeroMemory(&Input, sizeof(Input));
                }
                break;

                case 'P':
                {
                    INPUT Input = { 0 };
                    Input.type = INPUT_KEYBOARD;
                    Input.ki.wVk = VK_MEDIA_PLAY_PAUSE;
                    SendInput(1, &Input, sizeof(Input));
                    ZeroMemory(&Input, sizeof(Input));
                }
                break;

                case 'N':
                {
                    INPUT Input = { 0 };
                    Input.type = INPUT_KEYBOARD;
                    Input.ki.wVk = VK_MEDIA_NEXT_TRACK;
                    SendInput(1, &Input, sizeof(Input));
                    ZeroMemory(&Input, sizeof(Input));
                }
                break;

                case 'R':
                {
                    INPUT Input = { 0 };
                    Input.type = INPUT_KEYBOARD;
                    Input.ki.wVk = VK_MEDIA_PREV_TRACK;
                    SendInput(1, &Input, sizeof(Input));
                    ZeroMemory(&Input, sizeof(Input));
                }
                break;

                default:
                    printf("\n Error\n");
                    break;
            }
          

            PurgeComm(Port, PURGE_RXCLEAR);    //     

        }


    CloseHandle(Port);  /*      ,
    										        */

}


      
      



.





https://www.xanthium.in/Serial-Port-Programming-using-Win32-API





http://citforum.ru/hardware/articles/comports/





, , . : - .





This combination (remote + virtual codes) has the potential to control different parts of the OS. For example, you can assign programs to the buttons or make something like a controller out of the remote control. But the most convenient, in my opinion, is media management.








All Articles