veiner.eu
ÚVODMCP2221IR PŘIJÍMAČOVLÁDÁNÍ ZVUKUSCHÉMA ZAPOJENÍHARDWAREFIRMWARE
SOFTWARE

Dálkové ovládání PC - software

26.12.2018

Program, který je napsaný pro OS GNU/Linux, běží v terminálu a nevyžaduje (nepřijímá) žádné parametry. Zdrojový kód je možné si stáhnout. Kód se přeloží jednoduše, např. gcc -o remotePC remotePC.c.

Popis programu

Program na počátku testuje, zda existuje soubor /dev/ttyACM0 nebo ttyACM1. Jakmile je některý ze souborů detekován, zjišťuje se, jestli je přístupný pro čtení a zápis pro běžného uživatele (jestli má práva pro přístup k souboru skupina s ID různým od 0).

Následně se soubor otevře pro čtení a zápis a odešlou se dva byty s hodnotami 0xAA, 0x55. Dále se v cyklu čeká, až přijde 8mi znakový řetězec, který se porovnává s uloženými hodnotami. Jakmile je nalezena shoda, vykoná se předdefinovaná operace. Zároveň se v terminálu vypíše přijatý kód.

Kódy dálkového ovladače jsem do programu zapsal "napevno". Jistě by se daly programy v PICu i PC snadno upravit tak, aby se kódy z dálkového ovladače přenesly do PC, kde by si uživatel například v grafickém prostředí ke kódům přiřadil požadované akce. Nicméně je to zbytečná práce vzhledem k tomu, že využívám pouhých 7 kódů, které se nebudou měnit. Navíc případné přidání dalších kódů/akcí do programu je triviální záležitost.

Zdrojový kód

#include <fcntl.h>
#include <termios.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <errno.h>

#define PREFIX "/dev/"
#define _POSIX_SOURCE 1

int main()
{
  char devicename1[50];
  char devicename2[50];
  sprintf(devicename1,"%s%s",PREFIX,"ttyACM0");
  sprintf(devicename2,"%s%s",PREFIX,"ttyACM1");
  char *devicename;
  unsigned int BAUDRATE=B9600;

  unsigned long seconds=0;
  struct stat sts1,sts2,*sts;
  while (
    ((stat(devicename1,&sts1)==-1) && (errno==ENOENT)) &&
    ((stat(devicename2,&sts2)==-1) && (errno==ENOENT))
  )
  {
    printf("\nfiles %s;%s do not exist, %lu seconds",devicename1,devicename2,seconds);
    sleep(2);
    seconds+=2;
  }
  devicename=((stat(devicename1,&sts1)!=-1) ? devicename1 : devicename2);
  sts=((devicename==devicename1) ? &sts1 : &sts2);
  printf("\n\nfile %s exists (%lu seconds)\n\n",devicename,seconds);
  seconds=0;
  while ((sts->st_gid)==0)
  {
    printf("group ID of the %s file's group: %u, %lu seconds\n",devicename,sts->st_gid,seconds);
    sleep(2);
    seconds+=2;
    stat(devicename,sts);
  }
  printf("\ngroup ID of the %s file's group is not 0 (%lu seconds)\n\n\n",devicename,seconds);

  int fd,res;
  struct termios oldtio,newtio;
  char buf[20];

  if (!(fd=open(devicename,O_RDWR|O_NOCTTY)))
  {
    return(-1);
  }

  tcgetattr(fd,&oldtio);

  memset(&newtio,0,sizeof(newtio));
  newtio.c_cflag=BAUDRATE|CRTSCTS|CS8|CLOCAL|CREAD;
  newtio.c_iflag=IGNPAR;
  newtio.c_oflag=0;

  newtio.c_lflag=0;

  newtio.c_cc[VTIME]=0;
  newtio.c_cc[VMIN]=0;

  tcflush(fd,TCIFLUSH);
  tcsetattr(fd,TCSANOW,&newtio);

  tcflush(fd,TCIOFLUSH);

  unsigned char d[2]={0xAA,0x55};
  write(fd,d,2);
  printf("Sent: %02X%02X\n\n",d[0],d[1]);

  puts("waiting for data...\n\n");

  while (1)
  {
    res=read(fd,buf,8);
    if (res==8)
    {
      buf[res]='\0';
      printf("%s\n",buf);
      if (0==strcmp(buf,"00FFE01F"))
        system("pactl set-sink-volume 0 -10%");
      else if (0==strcmp(buf,"00FFA857"))
        system("pactl set-sink-volume 0 +10%");
      else if (0==strcmp(buf,"00FF906F"))
        system("pactl set-sink-mute 0 toggle");
      else if (0==strcmp(buf,"00FFA25D"))
        system("dbus-send --type=method_call --dest=org.mpris.MediaPlayer2.vlc
         /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Previous");
      else if (0==strcmp(buf,"00FFE21D"))
        system("dbus-send --type=method_call --dest=org.mpris.MediaPlayer2.vlc
         /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Next");
      else if (0==strcmp(buf,"00FFC23D"))
        system("dbus-send --type=method_call --dest=org.mpris.MediaPlayer2.vlc
         /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.PlayPause");
      else if (0==strcmp(buf,"00FF52AD"))
      {
        puts("Program will be terminated in a moment...\n");
        tcflush(fd,TCIOFLUSH);
        tcsetattr(fd,TCSANOW,&oldtio);
        close(fd);
        sleep(2);
        return 0;
      }
    }
    else
      tcflush(fd,TCIFLUSH);

    usleep(100000);
  }

  tcsetattr(fd,TCSANOW,&oldtio);
  close(fd);

  return 0;
}