VNC를 통한 라즈베리 원격 제어

|

VNC를 통한 라즈베리 원격 제어

VNC(Virtual Network Connection)를 이용하면 라즈베리파이를 원격에서 GUI 환경에서 쉽게 제어할 수 있습니다.


VNC 서버 설치

VNC(Virtual Network Connection) 서버는 다음 명령어를 이용해서 설치할 수 있습니다.

$ sudo apt-get update
$ sudo apt-get install tightvncserver


VNC 서버 실행

VNC 서버를 설치한 후, 다음 명령어를 이용해서 VNC 서버를 실행할 수 있습니다.

$ vncserver :1


VNC 서버에 접속

원격에서는 VNC 클라이언트를 설치해야 합니다. 다양한 VNC 프로그램들이 있으며, RealVNC 등을 사용할 수 있습니다.

접속할 때 IP 주소 뒤에 :1을 입력하면 화면 번호 ‘1’에 접속할 수 있습니다.


라즈베리파이 시작할 때 VNC 서버 자동 실행하기

다음 명령어를 이용해서 라즈베리파이를 시작할 때 VNC 서버를 자동으로 실행되도록 할 수 있습니다.

$ cd /home/pi
$ cd .config
$ mkdir autostart
$ cd autostart
$ nano tightvnc.desktop

그 후 tightvnc.desktop 내용에 다음을 입력합니다.

[Desktop Entry]
Type=Application
Name=TightVNC
Exec=vncserver :1
StartupNotify=false

라즈베리 파이 설정 쉽게 변경하기 (raspi-config)

|

Configuration Tool 다운로드

라즈베리파이에서는 raspi-config라는 프로그램을, 나노파이에서는 npi-config라는 프로그램을 이용해서 단말기의 설정을 쉽게 변경할 수 있습니다.

Image

raspi-config 프로그램은 다음과 같은 기능을 제공합니다.

  • pi 계정의 패스워드 변경
  • 네트워크 호스트 이름(Hostname) 변경
  • 부팅 옵션 변경
  • 언어 및 지역 설정
  • GPIO를 포함한 인터페이스(Interface) 설정
  • 오버클럭(Overclock)
  • 업데이트
  • 기타 설정


raspi-config 설치 및 실행

$ sudo apt-get install raspi-config

$ sudo raspi-config


npi-config 설치 및 실행

$ sudo apt-get install npi-config

$ sudo npi-config

네트워크(WiFI) 설정 방법

|

일반적으로 라즈베리파이는 GUI 환경이 있어서 GUI 상에서 설정을 하면 편리하지만, 나노파이(NanoPI) 또는 라즈베리파이의 non-GUI 버전을 사용할 경우에는 터미널 상에서 네트워크 세팅을 해주어야 합니다.

다음과 같이 파일을 설정하면 됩니다.

Interface 수정

/etc/network/interfaces 파일을 열어서 다음과 같이 수정해줍니다. 파일이 없다면 생성하시면 됩니다.

auto lo
iface lo inet loopback

auto wlan0

allow-hotplug wlan0
iface wlan0 inet dhcp
wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf
iface default inet dhcp


SSID 정보 입력

/etc/wpa_supplicant/wpa_supplicant.conf 파일을 다음과 같이 수정해줍니다.

ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev

update_config=1

network={
        ssid="snowdeer_AP"
        scan_ssid=1
        psk="password"
        key_mgmt=WPA-PSK
}

여기서 scan_ssid 항목은 공유기의 속성이 숨김으로 되어 있을 때 사용하는 옵션입니다.

설정 이후 재부팅을 하면 라즈베리파이는 자동으로 공유기에 접속되며 IP를 할당받습니다.

atoi(), itoa() 함수 사용법

|

문자열 변환 함수

atoi()itoa() 함수는 문자형과 정수형간 데이터를 변한하는 함수입니다. 두 함수는 stdlib.h에 선언되어 있습니다.


atoi()

atoi() 함수는 문자형을 정수형으로 변환합니다. 예를 들어 다음과 같은 코드 형태로 사용할 수 있습니다.

int a = atoi("123");


itoa()

itoa()는 반대로 숫자를 문자형으로 변환하는 함수입니다. 다만 itoa()는 표준 함수는 아닙니다. 플랫폼에 따라 쓸 수 없기도 합니다. 하지만 숫자를 문자로 바꾸는 것은 대부분의 언어에서는 아주 쉬운 일입니다. C++에서는 sprintf() 함수 등을 이용해서 쉽게 변경할 수 있습니다.


그 외

그 외에도 문자열을 double 형태나 long, long long 형태로 바꿔주는 함수들도 존재합니다.

double atof(const char* str);
long atol(const char* str);
long long atoll(const char* str);

연산자 오버로딩

|

연산자 오버로딩

연산자 오버로딩은 사용자가 직접 만든 클래스에 대해서도 이미 알려져 있는 연산자들(ex. +, -, *, / 등)을 쉽게 사용할 수 있게 해주는 기능입니다.

연산자 오버로딩은 클래스 작성자를 위한 기능은 아니며, 클래스를 사용하는 사람을 좀 더 편리하게 사용할 수 있도록 해주는 기능입니다.


연산자 오버로딩의 제약 사항

연산자 오버로딩은 다음과 같은 상황에서는 사용할 수 없습니다.

  • 새로운 연산자 기호를 적용할 수 없음.
  • 오버로딩할 수 없는 연산자도 있음. 대표적으로 ::, sizeof, 삼항 연산자 ?: 등은 오버로딩 못함.
  • 연산자의 인자의 개수는 변경 불가능. 예를 들어 ++는 한 개의 인자를 갖고, +는 두 개의 인자를 가짐.
  • 연산자의 우선 순위와 결합 규칙은 변경 안됨.
  • 내장 타입(기존에 이미 정의되어 있는 데이터 타입들. 예를 들어 int 등)에 대한 연산자 재정의 불가능.


연산자 오버로딩 구현 예제

단항 뺄셈, 덧셈 연산자 오버로딩

단항 뺄셈, 덧셈은 다음과 같은 연산입니다.

Point a(2, 3);
Point x = -a;
Point y = -(-a);

이 경우 단항 덧셈은 아무런 변화가 없는 연산이기 때문에 굳이 구현할 필요는 없고, 단항 뺄셈의 경우에만 구현을 해주면 됩니다.

class Point {
 public:
  Point(int _x, int _y) : x(_x), y(_y) {}

  // 단항 뺄셈
  const Point operator-() const;


  int getX() { return x; }
  int getY() { return y; }

 private:
  int x, y;
};

const Point Point::operator-() const {
  Point newPoint(*this);
  newPoint.x = -x;
  newPoint.y = -y;

  return newPoint;
}


증가, 감소 연산자의 오버로딩

증가, 감소 연산자는 다음과 같습니다.

Point a(2, 3);
a++;
++a;
a--;
--a;

++--의 위치에 따라 연산자 오버로딩이 다르게 적용됩니다. ++prefix로 붙는 경우에는 인자가 없고 postfix로 붙는 경우에는 int 타입의 더미(Dummy) 인자가 주어집니다. 그래서 증가, 감소 연산자 오버로딩을 지원하기 위해서는 함수 4개를 구현해주어야 합니다.

class Point {
 public:
  Point(int _x, int _y) : x(_x), y(_y) {}

  // 단항 뺄셈
  const Point operator-() const;

  // 증가, 감소 연산자
  Point &operator++();
  Point operator++(int);
  Point &operator--();
  Point operator--(int);

  int getX() { return x; }
  int getY() { return y; }

 private:
  int x, y;
};

Point &Point::operator++() {
  x += 1;
  y += 1;

  return *this;
}

Point Point::operator++(int) {
  Point newPoint(*this);
  x += 1;
  y += 1;

  return newPoint;
}

Point &Point::operator--() {
  x -= 1;
  y -= 1;

  return *this;
}

Point Point::operator--(int) {
  Point newPoint(*this);
  x -= 1;
  y -= 1;

  return newPoint;
}


사칙 연산자의 오버로딩

아무래도 가장 많이 사용하게 될 오버로딩일 것 같은데, +, -, *, /의 사칙 연산에 대한 오버로딩입니다.

Point a(2, 3);
Point b(5, 4);
Point c = a + b;

아래의 예제에서는 +에 대한 오버로딩만 구현했습니다.

class Point {
 public:
  Point(int _x, int _y) : x(_x), y(_y) {}

  // 단항 뺄셈
  const Point operator-() const;

  // 증가, 감소 연산자
  Point &operator++();
  Point operator++(int);
  Point &operator--();
  Point operator--(int);

  // 사칙 연산자
  Point operator+(Point &point);

  int getX() { return x; }
  int getY() { return y; }

 private:
  int x, y;
};

Point Point::operator+(Point& point) {
  Point newPoint(*this);

  newPoint.x += point.x;
  newPoint.y += point.y;

  return newPoint;
}


비트, 논리 연산자의 오버로딩

비트 연산자와 논리 연산자의 경우는 오버로딩하는 경우가 드물며, 특히 논리 연산자인 &&, ||의 오버로딩은 권장하지 않고 있습니다. 논리 연산자를 오버로딩할 경우 if 문과 같은 조건문 등에서 의도치 않은 결과가 발생하기도 합니다.


변환 연산자의 오버로딩

변환 연산자는 다음과 같이 데이터 타입의 변환을 의미합니다.

Point a(2, 3);
int intPoint = a;
string strPoint = a;
#include <string>

using namespace std;

class Point {
 public:
  Point(int _x, int _y) : x(_x), y(_y) {}

  // 단항 뺄셈
  const Point operator-() const;

  // 증가, 감소 연산자
  Point &operator++();
  Point operator++(int);
  Point &operator--();
  Point operator--(int);

  // 사칙 연산자
  Point operator+(Point &point);

  // 변환 연산자
  operator int() const;
  operator string() const;

  int getX() { return x; }
  int getY() { return y; }

 private:
  int x, y;
};

Point::operator int() const {
  return x + y;
}

Point::operator string() const {
  return "(" + to_string(x) + ", " + to_string(y) + ")";
}