반응형

CFMEGA2는 노이즈 보호를 위해 8개(5, 6, 7, 8, 9, 11, 12, 42)의 지정된 GPIO 단자만 나와 있다.

 

 

하드웨어 SPI 핀이 필요하다면 CF-SHIELD를 연결해야 한다. 소프트웨어 SPI 통신을 한다면 아무 GPIO 핀을 이용해도 된다.

 

 

CF-SHIELD는 CFMEGA2에 나와 있지 않은 4번, 10번 GPIO 및 하드웨어 SPI 통신 핀, 그리고 몇 개의 전원선을 가져온다. 그 외의 다른 핀들은 연결되지 않는다.

 

반응형
Posted by J-sean
:
반응형

CFMEGA2에서 OMRON E8Y 압력 센서를 사용해 보자.

 

정확히 이 모델을 사용한 건 아니다.

 

// CFMEGA2에서 A0~A3은 0~20mA 전류값을 0~1023의 디지털 값으로 변환한다. (Analog to Digital Converter)
// OMRON E8Y 압력 센서는 압력에 따라 4~20mA의 아날로그 전류를 출력한다.
//
// 4mA의 ADC 값: 약 204 (1023의 20%)
// 20mA의 ADC 값: 1023
//
// 그럼 이론적으로는 CFMEGA2에서 204~1023의 값을 감지할 것이다. (범위: 819)
// 하지만 압력 센서를 연결하고 압력을 가하지 않은 상태의 값을 확인해 보면 195,
// 센서가 감지할 수 있는 최대 압력을 가한 상태의 값을 확인해 보면 985가 나온다. (범위: 790)
//
// 실제 값에 맞게 보정해 주어야 한다.

const int sensorPin = A0;  // 0~20mA 전용 입력 핀에 연결 (회색 선).
const float maxPressure = 1000.0f; // 압력 센서 데이터시트에 기재된 최대 측정 압력값. (1,000Pa)
const float maxCurrent = 20.0f; // 압력 센서 데이터시트에 기재된 최대 측정 전류값.
const int initialADCValue = 195; // 압력이 없을때 ADC 값으로 195가 들어온다.
const int maxADCValue = 985; // 최대 압력일때 ADC 값으로 985가 들어온다.

void setup() {
  Serial.begin(9600);
  Serial.println("----------- CFMEGA2 Pressure Measure Start -----------");
}

void loop() {
  int adcValue = analogRead(sensorPin);
  
  // 센서 단선 또는 전원 오류 확인 (4mA 미만 확인)
  // 오차를 감안해 ADC 값이 190(약 3.7mA) 미만으로 떨어지면 오류로 간주
  if (adcValue < 190) {
    Serial.println("Error: Weak Sensor Signal. Check the sensor or the cable.");
  } else {
    // ADC 값(204~1023)을 압력(0~maxPressure)으로 비례 변환
    float pressure = (adcValue - initialADCValue) * (maxPressure / (maxADCValue - initialADCValue));
    // 값 보정: 실제 센서에 압력이 전혀 안 걸려 있을 때 출력되는 전류가 정확히
    // 4mA(ADC 204)가 아닐 수 있다. 초기값이 미세하게 맞지 않는다면 initialADCValue 값을
    // 실제 측정된 초기 ADC 값으로 조금씩 수정하여 보정한다.
    // 내 경우엔 195다. 최대 압력이 걸렸을때는 1023이 아니라 985다.

    // 센서에서 현재 출력되는 전류(mA) 역산
    float current_mA = adcValue * (maxCurrent / maxADCValue);
    
    Serial.print("adc: ");
    Serial.print(adcValue);
    Serial.print("  |  Current: ");
    Serial.print(current_mA, 2); // 소수점 둘째 자리까지 출력
    Serial.print(" mA  |  Pressure: ");
    Serial.print(pressure, 2);
    Serial.println(" Pa");
  }
  
  delay(1000); // 1초 대기
}

 

센서 데이터가 표시된다.

 

 

이번엔 아스키 문자가 아닌 바이너리 데이터를 전달해 보자.

const int sensorPin = A0;  // 0~20mA 전용 입력 핀에 연결 (회색 선)
const float maxPressure = 1000.0f; // 압력 센서 데이터시트에 기재된 최대 측정 압력값
const float maxCurrent = 20.0f; // 압력 센서 데이터시트에 기재된 최대 측정 전류값
const int initialADCValue = 195; // 압력이 없을때 ADC 값으로 195가 들어온다.
const int maxADCValue = 985; // 최대 압력일때 ADC 값으로 985가 들어온다.

void setup() {
  Serial.begin(9600);
  //Serial.println("----------- CFMEGA2 Pressure Measure Start -----------");
}

void loop() {
  int adcValue = analogRead(sensorPin);
  
  // 센서 단선 또는 전원 오류 확인 (4mA 미만 확인)
  // 오차를 감안해 ADC 값이 190(약 3.7mA) 미만으로 떨어지면 오류로 간주
  if (adcValue < 190) {
    Serial.println("Error: Weak Sensor Signal. Check the sensor or the cable.");
  } else {
    // ADC 값(204~1023)을 압력(0~maxPressure)으로 비례 변환
    float pressure = (adcValue - initialADCValue) * (maxPressure / (maxADCValue - initialADCValue));
    // 값 보정: 실제 센서에 압력이 전혀 안 걸려 있을 때 출력되는 전류가 정확히
    // 4mA(ADC 204)가 아닐 수 있다. 초기값이 미세하게 맞지 않는다면 initialADCValue 값을
    // 실제 측정된 초기 ADC 값으로 조금씩 수정하여 보정한다.
    // 내 경우엔 195다. 최대 압력이 걸렸을때는 1023이 아니라 985다.

    // 센서에서 현재 출력되는 전류(mA) 역산
    float current_mA = adcValue * (maxCurrent / maxADCValue);
    
    //Serial.print("adc: ");
    //Serial.print(adcValue);
    //Serial.print("  |  Current: ");
    //Serial.print(current_mA, 2); // 소수점 둘째 자리까지 출력
    //Serial.print(" mA  |  Pressure: ");
    //Serial.print(pressure, 2);
    //Serial.println(" Pa");
    
    // CFMEGA2(Arduino)의 int는 2바이트(16비트) 크기를 가진다.
    Serial.write(highByte((int)pressure)); // 상위 1바이트(8비트) 먼저 전송
    Serial.write(lowByte((int)pressure)); // 하위 1바이트(8비트) 이어서 전송
  }
  
  delay(1000); // 1초 대기
}

 

아스키 문자가 아닌 바이너리 데이터이기 때문에 Arduino IDE의 Serial Monitor를 통해 확인하면 알 수 없는 문자가 표시된다.

 

시리얼 통신용 프로그램을 사용하면 바이너리 데이터를 직접 확인할 수 있다.

1초당 2바이트씩 데이터를 읽는다. 처음 4초간은 압력이 없기 때문에 00 01이 4번 입력되고 5초에 177 Pa의 압력이 가해져 00 B1이 입력되었다.

 

센서가 출력하는 전류값이나 CFMEGA2가 읽는 전류값은 높은 정밀도를 가질 수 없을 것이다.

압력이 없을 때 센서를 통해 CFMEGA2에 들어온 ADC값이 처음엔 195였는데 몇 번 테스트하는 과정에서 196으로 바뀌었고 변환 과정을 거쳐 압력은 1로 표시되었다.  최대 압력일 때 ADC값도 최초 985에서 986으로 바뀌었다. 986은 변환식을 통해 1001이 된다.

 

예) (h): HEX, (d): DEC

■ 00 01(h): 1(d)

■ 00 B1(h): 177(d)

■ 01 20(h): 288(d)

...

■ 03 E9(h): 1001(d)

 

반응형
Posted by J-sean
:
반응형

시리얼 릴레이 사용법을 알아보자.

 

 

A frame instruction is generally composed of device address, function code, register address, register data, check code, and frame length is related to the function code.
Generally, the first byte of each frame data is the device address, which can be set to 1~255. The default is 255(0xFF), and the last two bytes are the CRC check code.

- Turn on relay_1
FF 05 00 00 FF 00 99 E4
3~4 바이트: 릴레이 번호
5~6 바이트: FF00 = 릴레이 켜기, 0000 = 릴레이 끄기
마지막 두 바이트: CRC16 (명령어가 바뀔때마다 다시 계산해야 한다)

- Turn on relay_2
FF 05 00 01 FF 00 C8 24

- Turn off relay_1
FF 05 00 00 00 00 D8 14

 

- Turn off relay_2
FF 05 00 01 00 00 89 D4

- Turn on all relays
FF 0F 00 00 00 08 01 FF 30 1D

- Turn off all relays
FF 0F 00 00 00 08 01 00 70 5D

- 1번 릴레이 2초 켰다 끄기
FF 10 00 03 00 02 04 00 04 00 14 C5 9F
3~4 바이트: 릴레이 번호, 0003=1번, 0008=2번, 000D=3번, 0012=4번, 0017=5번, 001C=6번
10~11 바이트: 딜레이 시간, 10~11바이트 값에 0.1초를 곱하는 숫자가 딜레이 시간, 0014*0.1 = 20*0.1 = 2초

- 3번 릴레이 5초 켰다 끄기
FF 10 00 0D 00 02 04 00 04 00 32 C5 C9

- 3초 후 릴레이 1번 켜기 (켜져 있는 상태에서 하면 꺼졌다가 3초 후 다시 켜진다)
FF 10 00 03 00 02 04 00 02 00 1E A5 99
3~4 바이트: 릴레이 번호, 0003=1번, 0008=2번, 000D=3번, 0012=4번, 0017=5번, 001C=6번
10~11 바이트: 딜레이 시간, 10~11바이트 값에 0.1초를 곱하는 숫자가 딜레이 시간, 001E*0.1 = 30*0.1 = 3초

- 5초 후 릴레이 4번 켜기 (켜져 있는 상태에서 하면 꺼졌다가 5초 후 다시 켜진다)
FF 10 00 12 00 02 04 00 02 00 32 64 84

- Read device address
00 03 00 00 00 01 85 DB
결과로 돌아오는 값에서 5번째 바이트가 주소 (ex: FF)

- Read baud rate
FF 03 03 E8 00 01 11 A4
결과로 돌아오는 값에서 5번째 바이트가 baud rate
0x02=4,800 0x03=9,600 0x04=19,200

 

아래는 JK-SR-2 시리얼 릴레이 사용법이다.

컴퓨터에 연결할 때 JK-SR-2의 시리얼 포트(RS-232) 9핀을 분리해서 USB to UART 컨버터에 연결해 사용하지 말고 USB to RS-232/DB-9 케이블(컨버터)을 사용하자. RS-232와 UART(TTL)는 신호 레벨이 다르고(12V, 5V) 논리도(정논리, 부논리) 다르기 때문에 UART의 RX, TX, GND 핀을 연결해도 이상하게 작동한다.

실제 연결해서 확인해 보면 논리가 다르기 때문인지, 연결하자마자 아무 메세지를 보내지 않아도 끊임없이 FF값이 수신된다.(위 파란색 제품도 마찬가지일 듯..)

 

 

 

아래는 Ethernet (Wi‑Fi) Relay 설명이다.

 

I1~I8과 GND를 단락시켜서 릴레이 조작이 가능하다. (스위치를 만들 수 있을것이다)

 

relay_sdk.z01
19.53MB
relay_sdk.z02
19.53MB
relay_sdk.z03
19.53MB
relay_sdk.zip
11.20MB

 

Ethernet은 컴퓨터와 랜케이블로 연결하고 192.168.1.100에 접속하면 간단히 되는데 Wi-Fi는 어떻게 해야 할지 모르겠다. 잘 안 된다.

 

반응형
Posted by J-sean
:
반응형

컴퓨터와 다른 기기 사이에 시리얼 통신을 해 보자.

 

hterm-windows.zip
2.14MB

 

 

실행화면

 

Port, Baud를 맞추고 Connect 버튼을 누르면 연결된다. Input control의 Type을 HEX로 바꾸고 메세지를 보낸다.

 

※ 참고

HTerm

Arduino Hex 명령

CRC16 계산기

CRC 계산기 (시리얼 통신용 CRC는 'CRC-16/MODBUS'를 확인하면 된다)

 

반응형
Posted by J-sean
:
반응형

USB Serial Port를 사용해 보자.

 

 

AX781x0_MCS78x0_Win11_64bit_Driver_v3.22.2.0.zip
1.08MB

Windows 11(x64)

 

포트에 아무것도 연결하지 않은 상태에서 간단히 테스트할 수 있는 코드를 작성해 보자.

import serial
import time
import sys

serials = []
ports = ['COM2', 'COM7', 'COM8', 'COM9', 'COM10', 'COM11', 'COM12', 'COM13']
baudrate = 9600
databit = serial.EIGHTBITS
stopbit = serial.STOPBITS_ONE
parity = serial.PARITY_NONE

try:
    ser1 = serial.Serial(ports[0], baudrate, databit, parity, stopbit, timeout=1)
    ser2 = serial.Serial(ports[1], baudrate, databit, parity, stopbit, timeout=1)
    ser3 = serial.Serial(ports[2], baudrate, databit, parity, stopbit, timeout=1)
    ser4 = serial.Serial(ports[3], baudrate, databit, parity, stopbit, timeout=1)
    ser5 = serial.Serial(ports[4], baudrate, databit, parity, stopbit, timeout=1)
    ser6 = serial.Serial(ports[5], baudrate, databit, parity, stopbit, timeout=1)
    ser7 = serial.Serial(ports[6], baudrate, databit, parity, stopbit, timeout=1)
    ser8 = serial.Serial(ports[7], baudrate, databit, parity, stopbit, timeout=1)

    time.sleep(2)  # 장치 초기화 대기

    # 각 포트 연결 상태 확인
    for ser in [ser1, ser2, ser3, ser4, ser5, ser6, ser7, ser8]:
        if ser.is_open:
            print(f"{ser.port} 포트에 성공적으로 연결되었습니다.")
        else:
            print(f"{ser.port} 포트에 연결할 수 없습니다.")
            sys.exit(1)

    # 테스트 신호 5회 반복 전송
    for _ in range(5):
        for ser in [ser1, ser2, ser3, ser4, ser5, ser6, ser7, ser8]:
            test_signal = b"Test Signal\r\n"
            ser.write(test_signal)
            #print(f"{ser.port} 포트에 데이터 전송 완료: {test_signal}")
            time.sleep(0.2)

    """
    # 수신 데이터 확인 (응답이 있을 경우 출력)
    time.sleep(0.5)
    for ser in [ser1, ser2, ser3, ser4, ser5, ser6, ser7, ser8]:
        if ser.in_waiting > 0:
            response = ser.readline()
            print(f"{ser.port} 포트에서 수신된 데이터: {response}")
    """

    # 연결 종료
    for ser in [ser1, ser2, ser3, ser4, ser5, ser6, ser7, ser8]:
        ser.close()
        print(f"{ser.port} 포트를 안전하게 닫았습니다.")

except serial.SerialException as e:
    print(f"시리얼 포트 오류: {e}")
    
except Exception as e:
    print(f"오류 발생: {e}")

 

Tx LED가 순서대로 깜빡거린다.

 

 

이번엔 FIS 센서를 연결하고 데이터를 수신해 보자.

 

2026.05.15 - [Raspberry Pi & Arduino] - [Arduino] FIS Low concentration solvent gas sensor module

 

FIS 센서는 TTL 시그널을 사용하므로 RS232 - TTL 컨버터가 필요하다.

 

RS232 - TTL Converter

 

FIS Sensor RS232 - TTL Converter Power
1 VDD VCC VCC(5V)
2 VSS(GND) GND GND
6 SERIAL TXD  
7 RST   VCC(5V)

 

※ 주의

FIS Sensor의 6번(SERIAL) 핀은 Converter의 TXD에 연결해야 한다. RXD에 연결하면 안 된다.

센서에서 데이터가 계속 생성되도록 7번(RST) 핀은 VCC에 연결한다.

 

import serial
import time
import sys

try:
    serialPort = serial.Serial('COM2', 9600, 8, 'N', 1, timeout=1)
    # 시리얼 통신 설정. COM3 포트, 9600 보드레이트, 8 데이터 비트, 패리티 없음, 1 스톱 비트, 타임아웃 1초.
    time.sleep(1)  # 시리얼 연결이 초기화될 때까지 대기

except Exception as e:
    print("Serial error: ", e)
    sys.exit(0)

try:
    while (serialPort.readable()): # 시리얼 포트가 읽을 수 있는 상태인지 확인.
        if (serialPort.in_waiting > 0): # 시리얼 버퍼에 대기 중인 데이터가 있는지 확인.
            print(serialPort.readline().decode("utf-8", errors="ignore"), end="")
            # readline() 메서드를 사용하여 시리얼 포트에서 한 줄씩 데이터를 읽고 UTF-8로 디코딩하여 출력.
            # 오류가 발생할 경우 무시하도록 설정.
        else:
            print("No data waiting in the serial buffer.")

        time.sleep(0.2)

except KeyboardInterrupt:
    print("\n[알림] Ctrl+C 입력 감지. 프로그램을 종료합니다.")

finally:
    if 'serialPort' in locals() and serialPort.is_open:
        # locals() 함수를 사용하여 serialPort 변수가 정의되어 있는지 확인하고, 시리얼 포트가 열려 있는지 확인.
        serialPort.close()
        print("시리얼 포트가 안전하게 닫혔습니다.")

 

H0196에 알코올을 감지했다.

 

 

※ 참고

드라이버 다운로드 및 설치방법

 

반응형
Posted by J-sean
:
반응형

사용 중인 시리얼 포트를 확인해 보자.

 

장치관리자에서 확인해 보면 3개의 포트가 사용 중이다.

 

콘솔창에서 mode 명령어로 간단히 확인할 수 있다.

 

 

C++, CreateFile 예제

#include <windows.h>
#include <iostream>
#include <string>

int main() {
	std::cout << "Available COM Ports: \n";

	for (int i = 1; i < 256; ++i) {
		std::string portName = "\\\\.\\COM" + std::to_string(i);
		// \\.\com (코드 작성 시 이스케이프 문자를 적용한 \\\\.\\com)는 Windows 운영체제에서 직렬 포트(Serial Port)나 병렬 포트(LPT) 같은 하드웨어 장치에 직접 접근하기 위한 경로 형식이다.
		// 이 경로는 일반적으로 COM 포트에 접근할 때 사용된다. 예를 들어, COM1 포트에 접근하려면 "\\\\.\\COM1"과 같은 형식으로 경로를 지정한다.
		// 이 방식은 Windows에서 하드웨어 장치와 통신하기 위해 사용되는 표준적인 방법 중 하나이다.
		// 포트 번호가 10 이하인 경우에는 "COM1", "COM2"와 같이 간단히 사용할 수 있지만, 포트 번호가 10 이상인 경우에는 "\\\\.\\COM10"과 같이 전체 경로를 사용해야 한다.

		HANDLE hComm = CreateFileA(
			portName.c_str(), // 만들거나 열 파일 또는 디바이스의 이름.
			GENERIC_READ | GENERIC_WRITE, //파일 또는 디바이스에 대한 요청된 액세스이며 읽기, 쓰기, 둘 다 또는 0으로 요약할 수 있다.
			NULL, // 파일 또는 디바이스의 요청된 공유 모드.
			NULL, // 보안 속성에 대한 포인터.
			OPEN_EXISTING, // 파일이 존재하는 경우에만 열고, 그렇지 않으면 실패.
			NULL, // 파일 또는 디바이스에 대한 플래그 및 속성.
			NULL); // 템플릿 파일 핸들 또는 디바이스 핸들로 사용할 수 있는 유효한 핸들. 이 매개변수는 CreateFile이 새 파일을 만들 때만 사용. 이 매개변수는 일반적으로 NULL로 설정.

		if (hComm != INVALID_HANDLE_VALUE) {
			std::cout << "-> COM" << i << " is available.\n";
			CloseHandle(hComm);
		}
	}

	return 0;
}

 

 

C, QueryDosDevice 예제

#include <windows.h>
#include <stdio.h>

int main() {
	char deviceName[256];
	char comPort[16];
	char openPortName[32];

	printf("--- 사용 가능한 COM 포트 목록 ---\n");

	// COM1부터 COM256까지 가능한 포트 번호를 순회하며 확인
	for (int i = 1; i < 256; i++) {
		sprintf_s(comPort, sizeof(comPort), "COM%d", i);

		// QueryDosDevice를 이용해 해당 포트가 존재하는지 확인
		DWORD result = QueryDosDeviceA(comPort, deviceName, sizeof(deviceName));
		// CreateFile 함수로 포트를 열 때는 \\\\.\\COM10 형식을 써야 하지만, QueryDosDevice로
		// 시스템에 등록된 장치 이름을 조회할 때는 접두사(\\.\)를 붙이면 안된다.
		// 이 함수는 순수한 커널 장치 이름(예: COM1, COM10)만 인자로 받도록 설계되어 있다.

		if (result != 0) { // result는 deviceName에 복사된 문자열의 길이.
			// 실제 포트를 열거나 사용할 때는 "\\\\.\\" 접두사를 붙여서 출력 및 활용한다.
			sprintf_s(openPortName, sizeof(openPortName), "\\\\.\\%s", comPort);
			printf("%s 연결됨 (장치명: %s)\n", openPortName, deviceName);
		}
	}

	return 0;
}

 

 

어떤 프로그램이 시리얼 포트를 사용 중인지 조사할 때 File Handle의 이름으로 위 그림의 해당 장치명을 지정해야 찾을 수 있다.

Process Explorer - Find - Find Handle or DLL... 클릭 - Handle or DLL substring에 장치명을 입력하고 Search 클릭

시리얼 포트가 사용중이라면 사용하고 있는 프로세스가 표시된다. python.exe가 사용 중이다.

 

장치관리자에서는 포트 - 속성 - 자세히 - 서비스 - 값에 표시된 이름을 이용하자.

 

 

C# 예제

using System;
using System.IO.Ports;

namespace ConsoleApp1
{
    internal class Program
    {
        static void Main(string[] args)
        {
            // PC에서 사용 가능한 모든 시리얼 포트 배열 가져오기
            string[] ports = SerialPort.GetPortNames();

            Console.WriteLine("사용 가능한 시리얼 포트:");
            foreach (string port in ports)
            {
                Console.WriteLine(port);
            }

            // GetPortNames()는 PC에 잡혀있는 모든 포트를 반환하므로, 특정 포트가 현재 다른 프로그램에서
            // 사용 중이거나 연결 가능한 상태인지 확인하려면 직접 Open()을 시도해 봐야 한다.
            Console.WriteLine(Environment.NewLine + "연결 가능한 시리얼 포트:");
            foreach (string port in ports)
            {
                using (SerialPort serialPort = new SerialPort(port))
                {
                    try
                    {
                        serialPort.Open();
                        Console.WriteLine($"{port} : 연결 가능 (사용 가능)");
                        serialPort.Close();
                    }
                    catch (UnauthorizedAccessException)
                    {
                        Console.WriteLine($"{port} : 접근 거부 (다른 프로그램에서 사용 중)");
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"{port} : 오류 발생 - {ex.Message}");
                    }
                }
            }
        }
    }
}

 

 

다른 프로그램에서 사용중인 경우

 

Python, pyserial 예제

import serial.tools.list_ports

# 사용 가능한 포트 리스트 가져오기
ports = serial.tools.list_ports.comports()

print("연결된 시리얼 포트 목록:")
print("-" * 30)
if ports:
    for port in ports:
        print(f"포트 이름: {port.device}")
        print(f"설명: {port.description}")
        print(f"하드웨어 ID: {port.hwid}")
        print("-" * 30)
else:
    print("사용 가능한 시리얼 포트가 없습니다.")

"""
# 각 포트에 대해 연결 가능 여부 확인
import serial

try:
    for port in ports:
        ser = serial.Serial(port.device)
        if ser.is_open:
            print(f"{port.device} : 연결 가능 (사용 가능)")
            ser.close()
        else:
            print(f"{port.device} : 연결 불가능 (사용 중)")

except serial.SerialException as e:
    print(f"시리얼 포트 확인 중 오류 발생: {e}")
"""

 

 

반응형
Posted by J-sean
:
반응형

USB to UART Converter를 사용해 시리얼 통신을 해 보자.

 

 

링크에서 드라이버를 다운로드받거나 아래 파일을 다운로드받고 설치한다.

CP210x_Windows_Drivers.zip
6.84MB

 

 

드라이버 설치 후 USB to UART Converter를 컴퓨터에 연결하면 정상적으로 포트에 잡힌다.

 

FIS Sensor를 연결하고 테스트해 보자.

FIS Sensor USB to UART Converter
1 VDD 5V
2 VSS(GND) GND
6 SERIAL RXD
7 RST 5V

 

센서 자체에서 시리얼 통신으로 데이터를 보내오기 때문에 아두이노 같은 컨트롤러가 필요 없다.

아래 파이썬 코드를 입력하고 실행한다.

import serial
import time
import sys

try:
    serialPort = serial.Serial('COM4', 9600, 8, 'N', 1, timeout=1)
    # 시리얼 통신 설정. COM4 포트, 9600 보드레이트, 8 데이터 비트, 패리티 없음, 1 스톱 비트, 타임아웃 1초.
    time.sleep(2)  # 시리얼 연결이 초기화될 때까지 대기

except Exception as e:
    print("Serial error: ", e)
    sys.exit(0)

while (serialPort.readable()): # 시리얼 포트가 읽을 수 있는 상태인지 확인.
    if (serialPort.in_waiting > 0): # 시리얼 버퍼에 대기 중인 데이터가 있는지 확인.
        print(serialPort.readline().decode("utf-8", errors="ignore"), end="")
        # readline() 메서드를 사용하여 시리얼 포트에서 한 줄씩 데이터를 읽고 UTF-8로 디코딩하여 출력.
        # 오류가 발생할 경우 무시하도록 설정.
    
    time.sleep(0.1)

serialPort.close()

 

 

반응형
Posted by J-sean
:

[RetroPie] Runcommand Script

Embedded 2026. 5. 20. 23:21 |
반응형

Runcommand Script는 게임이 실행되기 전과 후에 사용자 스크립트를 실행할 수 있다. 스크립트는 반드시 /opt/retropie/configs/all/에 존재해야 한다.

 

https://retropie.org.uk/docs/Runcommand/

 

Runcommand - RetroPie Docs

runcommand The runcommand is the script responsible to launch your emulators/games. This page shows the runcommand's configurations and features. Runcommand Launch Menu Each time you load a ROM there is an option to open what is called the Runcommand Launc

retropie.org.uk

 

runcommand-onstart.zip
0.00MB

 

 

※ 참고

Runcommand

모니터 회전&수평센서

 

반응형
Posted by J-sean
: