문서의 이전 판입니다!


```

전자기식 부저 제어

모든 ComfilePi 패널 PC에는 전자기식 부저가 내장되어 있습니다. 기본 설정에서는 화면을 터치할 때 부저음이 울립니다.

터치 부저음 활성화/비활성화

터치 부저음을 비활성화하려면 다음 명령을 실행하십시오.

sudo systemctl stop touch-beep.service
sudo systemctl disable touch-beep.service

터치 부저음을 활성화하려면 다음 명령을 실행하십시오.

sudo systemctl enable touch-beep.service
sudo systemctl start touch-beep.service

터미널에서 부저음 출력

CPi-G/J

CPi-G/J 패널 PC에는 SoC의 PWM 중 하나에 연결된 전기기계식 부저가 장착되어 있습니다.

특정 주파수와 재생 시간으로 부저음을 출력하려면 beep 프로그램을 사용하십시오. 예: beep -f 2000 -l 100

CPi-A/B/C/S

전자기식 부저는 CPi-A/B/S 패널 PC에서는 GPIO 핀 30에 연결되어 있으며, CPi-C 패널 PC에서는 GPIO 핀 27에 연결되어 있습니다. pigpio 라이브러리를 사용하여 제어할 수 있습니다.

# 의존성 패키지 설치
# sudo apt install pigpio-tools
 
pigs pfs 30 2700 pwm 30 128 mils 100 pwm 30 0

전자기식 부저 프로그래밍

CPi-G/J

CPi-G/J 패널 PC에는 SoC의 PWM 중 하나에 연결된 전기기계식 부저가 장착되어 있습니다.

프로그램에서 부저음을 출력하려면 EV_SND 이벤트를 /dev/input/by-path/platform-buzzer-event 장치에 기록하십시오. 다음 예제는 부저를 사용하여 사이렌 소리를 출력합니다. 자세한 내용은 Linux 입력 서브시스템 문서를 참고하십시오.

C# 예제

using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading;
 
class Siren
{
    static void Main(string[] args)
    {
        Console.CancelKeyPress += (sender, e) =>
        {
            e.Cancel = true;
            exiting = true;
            Console.WriteLine("\nCtrl+C가 입력되었습니다. 사이렌을 중지합니다...");
        };
 
        const string eventPath = "/dev/input/by-path/platform-buzzer-event";
 
        Console.WriteLine("사이렌 발생기가 실행 중입니다. 중지하려면 Ctrl+C를 누르십시오.");
 
        double time = 0;
        double step = 0.02; // 50Hz 갱신 주기(20ms)
 
        FileStream? fs = null;
 
        try
        {
            fs = new FileStream(eventPath, FileMode.Open, FileAccess.Write, FileShare.ReadWrite);
 
            while (!exiting)
            {
                // 사이렌: 2초 동안 500Hz에서 1500Hz까지 상승한 후 다시 하강
                double cycleTime = time % 2.0;
                double frequency;
 
                if (cycleTime < 1.0)
                    frequency = 500 + (cycleTime * 1000);          // 상승
                else
                    frequency = 1500 - ((cycleTime - 1.0) * 1000); // 하강
 
                int hz = (int)Math.Round(frequency);
 
                SendTone(fs, hz);
 
                Thread.Sleep((int)(step * 1000));
                time += step;
            }
        }
        catch (Exception ex)
        {
            Console.Error.WriteLine(ex.Message);
        }
        finally
        {
            // 부저음이 반드시 중지되도록 처리
            try
            {
                if (fs != null)
                {
                    SendTone(fs, 0);
                    fs.Dispose();
                }
            }
            catch (Exception ex)
            {
                Console.Error.WriteLine(ex.Message);
            }
 
            Console.WriteLine("사이렌이 중지되었습니다.");
        }
    }
 
    // Linux 입력 이벤트 상수
    const ushort EV_SYN = 0x00;
    const ushort EV_SND = 0x12;
    const ushort SYN_REPORT = 0x00;
    const ushort SND_BELL = 0x01;
    const ushort SND_TONE = 0x02;
 
    static bool exiting = false;
 
    // <linux/input.h>에 정의된 input_event 구조체
    // struct timeval { long tv_sec; long tv_usec; };
    // struct input_event { struct timeval time; __u16 type; __u16 code; __s32 value; };
    [StructLayout(LayoutKind.Sequential)]
    struct TimeVal
    {
        public long tv_sec;
        public long tv_usec;
    }
 
    [StructLayout(LayoutKind.Sequential)]
    struct InputEvent
    {
        public TimeVal time;
        public ushort type;
        public ushort code;
        public int value;
    }
 
    // 반복적인 리플렉션성 비용을 방지하기 위해 한 번만 계산
    static readonly int InputEventSize = Marshal.SizeOf<InputEvent>();
 
    static void SendTone(FileStream fs, int hz)
    {
        // hz > 0: 지정된 주파수의 소리 출력
        // hz == 0: 소리 출력 중지
        WriteEvent(fs, EV_SND, SND_TONE, hz);
        WriteEvent(fs, EV_SYN, SYN_REPORT, 0);
        fs.Flush();
    }
 
    static void WriteEvent(FileStream fs, ushort type, ushort code, int value)
    {
        // 로컬 구조체는 스택에 저장됨(힙 할당 없음)
        InputEvent ev = new InputEvent
        {
            time = default, // 커널이 타임스탬프를 설정하므로 0으로 초기화해도 무방함
            type = type,
            code = code,
            value = value
        };
 
        // 스택에 바이트 버퍼 할당
        Span<byte> buffer = stackalloc byte[InputEventSize];
 
        // 구조체 데이터를 스택 버퍼로 복사
        MemoryMarshal.Write(buffer, in ev);
 
        // 추가 할당 없이 기록
        fs.Write(buffer);
    }
}

CPi-A/B/C/S

전자기식 부저는 CPi-A/B/S 패널 PC에서는 GPIO 핀 30에 연결되어 있으며, CPi-C 패널 PC에서는 GPIO 핀 27에 연결되어 있습니다. pigpio 라이브러리를 사용하여 제어할 수 있습니다.

다음 예제는 프로그래밍 언어를 사용하여 부저음을 출력하는 방법을 보여줍니다.

Python 예제

먼저 sudo apt install python3-pigpio를 실행하여 의존성 패키지를 설치하십시오.

import time
import pigpio
 
PIN = 30  # CPi-A/B/S
# PIN = 27  # CPi-C
 
pi = pigpio.pi()
 
# 샘플링 속도의 제한으로 인해 실제로는 2700Hz를
# 정확히 출력할 수 없지만, 가능한 가장 가까운 주파수로 설정됩니다.
pi.set_PWM_frequency(PIN, 2700)
 
# 128/255 = 50% 듀티비
pi.set_PWM_dutycycle(PIN, 128)
 
# 100밀리초 동안 부저음 출력
time.sleep(0.100)
 
# 부저음 중지
pi.set_PWM_dutycycle(PIN, 0)
 
pi.stop()

ComfilePi - 산업용 Raspberry Pi 패널 PC ```