Yocto 프로젝트에서 센서 데이터를 처리하는 과정은 시스템 설계, 데이터 수집, 데이터 처리 및 데이터 전송의 총 4단계로 구분할 수 있다. 이 장에서는 이러한 각 단계를 심도 있게 다룰 것이다.

시스템 설계

센서 데이터를 처리하기 위한 Yocto 프로젝트의 시스템 설계는 다음과 같은 단계로 이루어진다.

센서 드라이버 설치 및 설정

센서 드라이버는 센서와 상호작용하는 소프트웨어 모듈이다. Yocto 프로젝트의 레시피 파일을 수정하여 센서 드라이버를 포함시킬 수 있다.

레시피 파일

Yocto에서 레시피 파일은 *.bb 확장자를 가지며, 특정 패키지를 빌드하기 위한 지침을 담고 있다.

DESCRIPTION = "Example recipe for sensor driver"
LICENSE = "GPLv2"
SRC_URI = "file://sensor_driver.c"

do_compile() {
    oe_runmake
}

do_install() {
    install -d ${D}
    install -m 0755 ${WORKDIR}/sensor_driver${D}/usr/bin/
}

데이터 수집

센서 데이터 수집은 크게 로우 레벨 데이터 접근과 고레벨 데이터 접근으로 나눌 수 있다. 로우 레벨 접근 방식에서는 센서가 제공하는 원시 데이터를 그대로 읽어 오며, 고레벨 접근 방식에서는 데이터를 해석하여 의미 있는 정보를 추출한다.

로우 레벨 데이터 접근

로우레벨 데이터 접근은 센서의 하드웨어 레지스터를 직접 읽고 쓰는 과정이다.

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>

#define SENSOR_IOCTL_MAGIC 's'
#define SENSOR_IOCTL_READ _IOR(SENSOR_IOCTL_MAGIC, 1, int)

int main() {
    int fd = open("/dev/sensor0", O_RDONLY);
    if (fd < 0) {
        perror("Failed to open device");
        return -1;
    }

    int data;
    if (ioctl(fd, SENSOR_IOCTL_READ, &data) < 0) {
        perror("Failed to read data");
        close(fd);
        return -1;
    }

    printf("Sensor data: %d\n", data);
    close(fd);
    return 0;
}

데이터 처리

수집한 데이터를 처리하는 단계에서는 필터링, 변환, 분석 등의 작업을 수행한다.

데이터 필터링

필터링은 잡음을 제거하고 원하는 신호만을 추출하는 과정이다. 예를 들어, 저역 필터를 사용하여 고주파 잡음을 제거할 수 있다.

import numpy as np

def low_pass_filter(data, cutoff_frequency, sampling_rate):
    nyquist_rate = sampling_rate / 2.0
    normal_cutoff = cutoff_frequency / nyquist_rate
    b, a = butter(1, normal_cutoff, btype='low', analog=False)
    return lfilter(b, a, data)

데이터 변환

변환 단계는 수집된 센서 데이터를 다른 형태로 변경하는 과정이다. 예를 들어, 아날로그 신호를 디지털 신호로 변환하거나, 원시 데이터를 물리적 단위로 변환한다.

def raw_to_temperature(raw_value):
    # Assuming 10mV per degree Celsius and 500mV offset
    return (raw_value - 500) / 10.0

데이터 전송

처리된 데이터를 저장하거나, 다른 시스템으로 전송할 수 있다. 데이터 전송 방법에는 로컬 저장소에 저장, 클라우드로 전송, 혹은 다른 디바이스로 실시간 스트리밍하는 방식 등이 있다.

로컬 저장소에 저장

데이터를 파일 시스템이나 데이터베이스에 저장할 수 있다. 간단한 예로, 텍스트 파일에 데이터를 저장할 수 있다.

data = {
    "timestamp": "2023-10-01T10:00:00Z",
    "temperature": 23.5,
    "humidity": 55.0
}

with open("/path/to/data.txt", "a") as file:
    file.write(f"{data['timestamp']},{data['temperature']},{data['humidity']}\n")

클라우드 전송

처리된 데이터를 클라우드 서버로 전송하여 중앙에서 관리할 수 있다. 이를 위해 HTTP 요청을 사용한 예를 들 수 있다.

import requests

data = {
    "timestamp": "2023-10-01T10:00:00Z",
    "temperature": 23.5,
    "humidity": 55.0
}

response = requests.post("http://example.com/api/sensor_data", json=data)
if response.status_code == 200:
    print("Data sent successfully")
else:
    print(f"Failed to send data: {response.status_code}")

실시간 스트리밍

실시간 데이터를 다른 장치로 스트리밍하는 방법으로는 MQTT 프로토콜이 자주 사용된다.

import paho.mqtt.client as mqtt

client = mqtt.Client()
client.connect("mqtt.example.com", 1883, 60)

data = {
    "timestamp": "2023-10-01T10:00:00Z",
    "temperature": 23.5,
    "humidity": 55.0
}

client.publish("sensor/data", str(data))
client.disconnect()

예제 프로젝트

여기서는 예제 프로젝트를 통해 위의 과정을 종합한 실습을 진행해보겠다. 우리의 목표는 간단한 온도 센서를 통해 수집한 데이터를 처리하고 클라우드 서버로 전송하는 것이다.

1단계: 하드웨어 및 드라이버 설정

레시피 파일을 사용하여 드라이버를 설치한다.

DESCRIPTION = "DS18B20 temperature sensor driver"
LICENSE = "GPLv2"
SRC_URI = "file://ds18b20.c"

do_compile() {
    oe_runmake
}

do_install() {
    install -d ${D}
    install -m 0755 ${WORKDIR}/ds18b20${D}/usr/bin/
}

2단계: 데이터 수집

보드에서 DS18B20 센서의 데이터를 읽어온다.

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>

#define SENSOR_IOCTL_MAGIC 's'
#define SENSOR_IOCTL_READ _IOR(SENSOR_IOCTL_MAGIC, 1, int)

int main() {
    int fd = open("/dev/ds18b20", O_RDONLY);
    if (fd < 0) {
        perror("Failed to open device");
        return -1;
    }

    int data;
    if (ioctl(fd, SENSOR_IOCTL_READ, &data) < 0) {
        perror("Failed to read data");
        close(fd);
        return -1;
    }

    printf("Temperature data: %d\n", data);
    close(fd);
    return 0;
}

3단계: 데이터 처리

온도 데이터를 필터링하고 변환한다.

import numpy as np

def raw_to_temperature(raw_value):
    return (raw_value / 16.0) * 0.0625

raw_value = 300
temperature = raw_to_temperature(raw_value)
print(f"Temperature: {temperature}°C")

4단계: 데이터 전송

온도 데이터를 클라우드 서버로 전송한다.

import requests

data = {
    "timestamp": "2023-10-01T10:00:00Z",
    "temperature": 23.5
}

response = requests.post("http://example.com/api/sensor_data", json=data)
if response.status_code == 200:
    print("Data sent successfully")
else:
    print(f"Failed to send data: {response.status_code}")

이 예제를 통해 Yocto 프로젝트를 활용하여 센서 데이터를 처리하고 전송하는 과정을 이해할 수 있다. 이러한 과정은 IoT 시스템 설계의 기초가 되며, 다양한 응용 분야에 활용될 수 있다.