Controlar Windows con un control remoto de TV o cómo transmitir señales a través de un puerto serie

Decidí que quiero cambiar el volumen de las pistas de sonido y audio en una computadora portátil con Windows desde un control remoto por infrarrojos. Arduino uno, un montón de cables con una placa de prueba, un sensor de infrarrojos, una computadora portátil y, de hecho, un control remoto de infrarrojos.





Hay una idea, hay hierro, pero la teoría es poco convincente. ¿Cómo puedo hacer que mi computadora comprenda las señales infrarrojas del control remoto y tome las medidas necesarias? Decidí usar un arduino para recibir señales de control remoto a través del sensor de infrarrojos en la placa y enviar mensajes a la computadora portátil a través de USB. Esto requirió al menos algún conocimiento de cómo funciona todo.





Se decidió investigar.





Introduciendo Arduino al control remoto

Para recibir una señal del mando a distancia por infrarrojos se requiere un receptor, el cual conectaremos al arduino a través de un protoboard según el siguiente esquema:





Codificación de señales NEC
Codificación de señales NEC

Para que arduino entienda por qué protocolo y con qué comando se transmite la señal, existe la biblioteca IRremote, que en las nuevas versiones del IDE de Arduino se puede agregar desde las bibliotecas estándar.





La propia biblioteca





(/ ). 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/





, , . : - .





Esta combinación (códigos remotos + virtuales) tiene el potencial de controlar diferentes partes del sistema operativo. Por ejemplo, puede asignar programas a los botones o hacer algo como un controlador con el control remoto. Pero lo más conveniente, en mi opinión, es la gestión de medios.








All Articles