아두이노 우노 Q Linux와 MCU 간의 통신

Arduino UNO Q에는 두 개의 프로세서가 있습니다: Arduino 스케치를 실행하는 STM32 MCU와 Python을 실행하는 Qualcomm Linux MPU. 이 튜토리얼에서는 Arduino UNO Q를 고유하게 만드는 핵심 메커니즘인 Bridge를 사용하여 이 두 프로세서가 서로 통신하는 방법을 배웁니다.

이 튜토리얼에서는 다음을 배웁니다:

Arduino UNO Q linux mcu communication

필요한 하드웨어

1×Arduino UNO Q 아마존
1×USB Cable for Arduino Uno Q 아마존
1×(추천) 아두이노 우노용 스크루 터미널 블록 쉴드 쿠팡 | 아마존
1×(추천) Sensors/Servo Expansion Shield for Arduino Uno 쿠팡 | 아마존
1×(추천) 아두이노 우노용 브레드보드 쉴드 쿠팡 | 아마존
1×(추천) 아두이노 우노용 케이스 쿠팡 | 아마존
1×(추천) 아두이노 우노용 프로토타이핑 베이스 플레이트 & 브레드보드 키트 아마존
공개: 이 포스팅 에 제공된 일부 링크는 아마존 제휴 링크입니다. 이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.

Bridge가 어떻게 작동하는지

Arduino UNO Q는 두 프로세서 간의 내부 직렬 링크를 사용합니다. 이는 Arduino_RouterBridge 라이브러리에 의해 자동으로 관리됩니다. 코드에서 이 링크를 직접 열지 않습니다.

※ 주의:

/dev/ttyHS1(Linux 측) 및 Serial1(MCU 측)은 라우터 브릿지에 의해 예약되어 있습니다. 코드에서 열지 마세요. 열 경우 Bridge 통신이 중단됩니다.

통신은 요청 → 응답 모델을 따릅니다. 전화 통화와 같이 생각하면 됩니다:

  • Linux(Python)가 항상 통화를 시작합니다 — MCU에 무언가를 하도록 요청하거나 값을 요청합니다.
  • MCU는 항상 응답합니다 — 요청된 함수를 실행하고 응답으로 값을 반환할 수 있습니다.
  • MCU는 자체적으로 Linux를 호출할 수 없습니다 — Linux가 요청할 때만 응답합니다.
주체 수행하는 작업 API
Linux (Python) MCU에 요청을 전송합니다 Bridge.call("fn")
MCU (C/C++) 요청을 수신하고 함수를 실행하고 응답합니다 Bridge.provide_safe("fn", fn)

이는 데이터가 양방향으로 흐를 수 있음을 의미합니다. 다만 Linux가 항상 대화를 시작합니다:

  • Linux → MCU: Linux가 명령을 전송합니다(예: "LED 켜기") MCU가 실행합니다.
  • MCU → Linux: Linux가 "센서 값은 무엇인가?"를 요청하고 MCU가 데이터로 응답합니다.

MCU는 자체적으로 대화를 시작할 수 없습니다. MCU가 무언가를 보고해야 하는 경우(예: 버튼이 눌려진 경우) 해결책은 폴링입니다: MCU가 이벤트를 변수에 저장하고 Python은 정기적으로 Bridge.call("get_event") 함수를 호출하여 그 변수를 확인합니다.

Monitor와 Serial 정보

Arduino UNO Q에서 MCU에서 출력을 인쇄하는 두 가지 방법이 있습니다:

메서드 App Lab 콘솔에 표시 필요한 라이브러리
Monitor.println() ✅ 예 Arduino_RouterBridge
Serial.println() ❌ 아니오 없음 (내장)

App Lab에서 MCU 출력을 보고 싶을 때는 Monitor.println()을 사용합니다. Serial 출력은 UART 핀으로만 이동하며 App Lab에서는 보이지 않습니다.

예제 1: Linux가 MCU를 호출 (Linux → MCU)

이것은 가장 일반적인 패턴입니다. Python 스크립트는 MCU의 함수를 호출합니다(예: LED를 켜거나 끕니다).

MCU 코드

/* * 이 Arduino UNO Q 코드는 newbiely.kr 에서 개발되었습니다 * 이 Arduino UNO Q 코드는 어떠한 제한 없이 공개 사용을 위해 제공됩니다. * 상세한 지침 및 연결도에 대해서는 다음을 방문하세요: * https://newbiely.kr/tutorials/arduino-uno-q/arduino-uno-q-communication-between-linux-and-mcu */ #include "Arduino_RouterBridge.h" #define LED_PIN LED_BUILTIN // Built-in RGB LED on Arduino UNO Q (LED3 on the board, lights up RED, active LOW) void set_led(int state) { // Active LOW: state 1 = on (LOW), state 0 = off (HIGH) digitalWrite(LED_PIN, state ? LOW : HIGH); Monitor.print("set_led called: state="); Monitor.println(state); } void setup() { Bridge.begin(); Monitor.begin(); pinMode(LED_PIN, OUTPUT); digitalWrite(LED_PIN, HIGH); // start with LED off Bridge.provide_safe("set_led", set_led); Monitor.println("Bridge ready"); } void loop() {}

Python 코드

/* * 이 Arduino UNO Q 코드는 newbiely.kr 에서 개발되었습니다 * 이 Arduino UNO Q 코드는 어떠한 제한 없이 공개 사용을 위해 제공됩니다. * 상세한 지침 및 연결도에 대해서는 다음을 방문하세요: * https://newbiely.kr/tutorials/arduino-uno-q/arduino-uno-q-communication-between-linux-and-mcu */ from arduino.app_utils import * import time def loop(): print("Turning LED ON...") result = Bridge.call("set_led", 1) print(result) time.sleep(1) print("Turning LED OFF...") result = Bridge.call("set_led", 0) print(result) time.sleep(1) App.run(user_loop=loop)

빠른 단계

Arduino UNO Q를 처음 사용하시나요? 진행하기 전에 아두이노 우노 Q 시작하기 튜토리얼을 따릅니다.

  • 연결: USB-C 케이블을 Arduino UNO Q에 연결합니다.
  • Arduino App Lab 열기: Arduino App Lab을 시작하고 보드를 감지할 때까지 기다립니다.
  • 새 앱 만들기: Create New App 버튼을 클릭합니다.
create new app in 아두이노 app lab on Arduino UNO Q
  • 앱에 이름을 지정합니다. 예: LinuxMcuComm1
  • Create를 클릭하여 확인합니다.
아두이노 app lab app folders and files on Arduino UNO Q
  • MCU 스케치 붙여넣기: 위의 MCU 코드를 복사하여 sketch/sketch.ino에 붙여넣습니다.
  • Python 코드 붙여넣기: 위의 Python 코드를 복사하여 앱의 Python 파일에 붙여넣습니다.
  • Install the library: Click the Add sketch library button (the open book icon with a + sign) in the left sidebar.
add sketch 라이브러리 in 아두이노 app lab on Arduino UNO Q
  • Search for Arduino_RouterBridge created by Arduino and click the Install button.
My Apps / DIYables Apps
Run
Bricks
No bricks added...
Sketch Libraries
No sketch libra...
Files
python
sketch
.gitignore
README.md
app.yaml
sketch.ino
Add sketch library
Arduino_RouterBridge Arduino

This library provides a simple RPC bridge for Arduino UNO Q boards, allowing communication between the board and other devices using MsgPack serialization.

0.4.1
Install
More Info
  • 업로드: Arduino App Lab에서 Run 버튼을 클릭합니다.
click run 버튼 in 아두이노 app lab on Arduino UNO Q

App Lab 콘솔 출력

DIYables_Apps
Stop
sketch.ino
1#include "Arduino_RouterBridge.h"
Serial Monitor
Python
Message (Enter to send a message to "Newbiely" on usb(2820070321))
New Line
9600 baud
[2026-05-07 09:00:01] Bridge ready [2026-05-07 09:00:02] set_led called: state=1 [2026-05-07 09:00:03] set_led called: state=0 [2026-05-07 09:00:04] set_led called: state=1 [2026-05-07 09:00:05] set_led called: state=0
DIYables_Apps
Stop
sketch.ino
1#include "Arduino_RouterBridge.h"
Serial Monitor
Python
[2026-05-07 09:00:01] Turning LED ON... [2026-05-07 09:00:02] OK [2026-05-07 09:00:03] Turning LED OFF... [2026-05-07 09:00:04] OK

작동 방식

  • MCU는 Bridge.provide_safe()를 통해 set_led 함수를 등록합니다.
  • Python 스크립트는 Bridge.call("set_led", 1)을 호출합니다. 이는 RPC 요청을 MCU에 전송합니다.
  • MCU는 set_led(1)을 실행하고 Monitor.println()을 통해 확인 메시지를 인쇄합니다.
  • Bridge.call()은 함수가 완료되면 "OK"를 반환합니다.

예제 2: MCU가 Linux로 데이터 전송 (MCU → Linux 반환 값 사용)

이 패턴에서 Python 측은 MCU에서 센서 판독값을 요청합니다. MCU는 센서를 읽고 Bridge를 통해 값을 Python으로 반환합니다.

MCU 코드

/* * 이 Arduino UNO Q 코드는 newbiely.kr 에서 개발되었습니다 * 이 Arduino UNO Q 코드는 어떠한 제한 없이 공개 사용을 위해 제공됩니다. * 상세한 지침 및 연결도에 대해서는 다음을 방문하세요: * https://newbiely.kr/tutorials/arduino-uno-q/arduino-uno-q-communication-between-linux-and-mcu */ #include "Arduino_RouterBridge.h" const char* get_value() { int raw = analogRead(A0); // read analog sensor on A0 static char buf[8]; itoa(raw, buf, 10); Monitor.print("get_value called — returning "); Monitor.println(buf); return buf; } void setup() { Bridge.begin(); Monitor.begin(); Bridge.provide_safe("get_value", get_value); Monitor.println("Bridge ready"); } void loop() {}

Python 코드

/* * 이 Arduino UNO Q 코드는 newbiely.kr 에서 개발되었습니다 * 이 Arduino UNO Q 코드는 어떠한 제한 없이 공개 사용을 위해 제공됩니다. * 상세한 지침 및 연결도에 대해서는 다음을 방문하세요: * https://newbiely.kr/tutorials/arduino-uno-q/arduino-uno-q-communication-between-linux-and-mcu */ from arduino.app_utils import * import time def loop(): result = Bridge.call("get_value") print("MCU returned:", result) time.sleep(2) App.run(user_loop=loop)

App Lab 콘솔 출력

DIYables_Apps
Stop
sketch.ino
1#include "Arduino_RouterBridge.h"
Serial Monitor
Python
Message (Enter to send a message to "Newbiely" on usb(2820070321))
New Line
9600 baud
[2026-05-07 09:00:01] Bridge ready [2026-05-07 09:00:02] get_value called — returning 42 [2026-05-07 09:00:04] get_value called — returning 43 [2026-05-07 09:00:06] get_value called — returning 41
DIYables_Apps
Stop
sketch.ino
1#include "Arduino_RouterBridge.h"
Serial Monitor
Python
[2026-05-07 09:00:02] MCU returned: 42 [2026-05-07 09:00:04] MCU returned: 43 [2026-05-07 09:00:06] MCU returned: 41

작동 방식

  • MCU 함수는 센서를 읽습니다(여기서는 analogRead(A0)로 시뮬레이션) 그리고 값을 문자열로 반환합니다.
  • Python 측에서 Bridge.call("get_value")는 그 문자열을 반환합니다. Python은 이를 파싱하고 사용할 수 있습니다.
  • 이것은 Linux 측에서 MCU 센서를 읽기 위한 표준 패턴입니다.

예제 3: Linux에서 MCU로 인수 전달

Python 측은 MCU 함수에 인수를 전달할 수 있습니다. 이는 매개변수를 포함하는 명령에 유용합니다(예: 대상 각도, 임계값 또는 속도 값 설정).

MCU 코드

/* * 이 Arduino UNO Q 코드는 newbiely.kr 에서 개발되었습니다 * 이 Arduino UNO Q 코드는 어떠한 제한 없이 공개 사용을 위해 제공됩니다. * 상세한 지침 및 연결도에 대해서는 다음을 방문하세요: * https://newbiely.kr/tutorials/arduino-uno-q/arduino-uno-q-communication-between-linux-and-mcu */ #include "Arduino_RouterBridge.h" #define LED_PIN LED_BUILTIN // Built-in RGB LED on Arduino UNO Q (LED3 on the board, lights up RED, active LOW) void set_brightness(int value) { // analogWrite simulates brightness (0 = off, 255 = full on) // Note: active LOW — invert for LED_BUILTIN analogWrite(LED_PIN, 255 - value); Monitor.print("set_brightness called: value="); Monitor.println(value); } void setup() { Bridge.begin(); Monitor.begin(); pinMode(LED_PIN, OUTPUT); Bridge.provide_safe("set_brightness", set_brightness); Monitor.println("Bridge ready"); } void loop() {}

Python 코드

/* * 이 Arduino UNO Q 코드는 newbiely.kr 에서 개발되었습니다 * 이 Arduino UNO Q 코드는 어떠한 제한 없이 공개 사용을 위해 제공됩니다. * 상세한 지침 및 연결도에 대해서는 다음을 방문하세요: * https://newbiely.kr/tutorials/arduino-uno-q/arduino-uno-q-communication-between-linux-and-mcu */ from arduino.app_utils import * import time def loop(): for brightness in [0, 64, 128, 192, 255]: print(f"Setting brightness to {brightness}...") result = Bridge.call("set_brightness", brightness) print(result) time.sleep(1) App.run(user_loop=loop)

App Lab 콘솔 출력

DIYables_Apps
Stop
sketch.ino
1#include "Arduino_RouterBridge.h"
Serial Monitor
Python
Message (Enter to send a message to "Newbiely" on usb(2820070321))
New Line
9600 baud
[2026-05-07 09:00:01] Bridge ready [2026-05-07 09:00:02] set_brightness called: value=0 [2026-05-07 09:00:03] set_brightness called: value=64 [2026-05-07 09:00:04] set_brightness called: value=128 [2026-05-07 09:00:05] set_brightness called: value=192 [2026-05-07 09:00:06] set_brightness called: value=255
DIYables_Apps
Stop
sketch.ino
1#include "Arduino_RouterBridge.h"
Serial Monitor
Python
[2026-05-07 09:00:01] Setting brightness to 0... [2026-05-07 09:00:02] Done [2026-05-07 09:00:03] Setting brightness to 64... [2026-05-07 09:00:04] Done [2026-05-07 09:00:05] Setting brightness to 128... [2026-05-07 09:00:06] Done

작동 방식

  • 인수는 Bridge.call("function_name", arg1, arg2, ...)에 추가 매개변수로 전달됩니다.
  • MCU 측에서 등록된 함수는 int(또는 문자열의 경우 const char *) 매개변수로 인수를 수신합니다.
  • MCU는 함수 반환 값으로 Python에 결과 문자열을 반환할 수 있습니다.

요약

패턴 MCU 측 Python 측
Linux가 MCU를 호출 Bridge.provide_safe("fn", fn) Bridge.call("fn")
MCU가 값을 반환 return "value" result = Bridge.call("fn")
Linux가 인수를 전달 void fn(int a, int b) Bridge.call("fn", a, b)
MCU 콘솔 출력 Monitor.println("...") *(App Lab 콘솔에 표시)*

※ 주의:

모든 Bridge 함수는 논블로킹이어야 합니다. Bridge 등록 함수 내에서 delay()를 사용하지 마세요. MCU 함수가 너무 오래 걸리면 Bridge가 시간 초과됩니다.

문제 해결

Bridge.call()이 오류 또는 빈 문자열을 반환합니다:

  • Bridge.call("name")의 함수 이름이 MCU 측의 Bridge.provide_safe("name", fn)에서 사용한 이름과 정확히 일치하는지 확인하세요. 대소문자를 구분합니다.
  • Bridge.provide_safe() 전에 setup()에서 Bridge.begin()이 호출되었는지 확인합니다.

MCU 출력이 App Lab에 표시되지 않습니다:

  • Serial.println() 대신 Monitor.println()을 사용합니다. App Lab 콘솔에는 Monitor 출력만 표시됩니다.
  • setup()에서 Monitor.begin()이 호출되었는지 확인합니다.

보드가 한동안 응답하지 않습니다:

  • 코드에서 /dev/ttyHS1(Linux) 또는 Serial1(MCU)을 열지 마세요. 이들은 Bridge 라우터용으로 예약되어 있습니다.
  • Bridge 등록 함수 내에서 delay()를 사용하지 마세요.