CodexPad Arduino 库 3.0.0
载入中...
搜索中...
未找到
basic_polling.ino
浏览该文件的文档.
1/**
2 * @~English
3 * @file basic_polling.ino
4 * @example basic_polling.ino
5 * @brief Demonstrates the basic polling method to periodically query and print all CodexPad button states and joystick values.
6 * @details This example establishes a connection to a specific CodexPad device (by Bluetooth Device Address) and implements a
7 * simple polling loop. Every 30 milliseconds, it queries and prints the current state (pressed/released) of all
8 * buttons and the raw analog values (0-255) of both joysticks. It showcases the fundamental usage of
9 * `gamepad::input::Tracker[Button]` for discrete button queries and `gamepad::input::Tracker[Axis]` for continuous
10 * joystick readings.
11 * @note This example uses a simple timing mechanism (`millis()`) to print at a fixed interval, which is suitable for
12 * monitoring or logging. For real-time control, ensure `Update()` is called as frequently as possible without blocking
13 * delays.
14 * @see CodexPad::Update
15 */
16/**
17 * @~Chinese
18 * @file basic_polling.ino
19 * @example basic_polling.ino
20 * @brief 演示通过基本轮询方式定期查询并打印 CodexPad 所有按钮状态与摇杆值。
21 * @details 本示例通过Bluetooth Device Address连接到指定的 CodexPad 设备,并实现了一个简单的轮询循环。
22 * 每隔 30 毫秒,它会查询并打印所有按钮的当前状态(按下/弹起)以及两个摇杆的原始模拟值(0-255)。
23 * 它展示了 `gamepad::input::Tracker[Button]` 用于离散按钮查询和 `gamepad::input::Tracker[Axis]`
24 * 用于连续摇杆读取的基本用法。
25 * @note 本示例使用简单的定时机制(`millis()`)以固定间隔打印,适用于状态监控或日志记录。
26 * 对于实时控制应用,请确保尽可能频繁地调用 `Update()` 且无阻塞延时。
27 * @see CodexPad::Update
28 */
29
30#include "codex_pad.h"
31
32/**
33 * IMPORTANT:
34 * This using directive is REQUIRED to directly access `Button` and `Axis`.
35 * Without it, you must write the fully qualified names:
36 * gamepad::input::Button::kUp
37 * gamepad::input::Axis::kLeftStickX
38 * Forgetting this line will cause compile errors when using Button or Axis.
39 */
40/**
41 * 重要:
42 * 必须使用该命名空间,否则无法直接访问 `Button` 和 `Axis`。
43 * 如果没有这一行,就必须写成完整限定名:
44 * gamepad::input::Button::kUp
45 * gamepad::input::Axis::kLeftStickX
46 * 忘记引入命名空间会导致编译失败。
47 */
48using namespace gamepad::input; // ⚠️ DO NOT REMOVE THIS LINE ⚠️
49
50namespace {
51// Replace with your CodexPad device's Bluetooth device address
52// 替换为你的 CodexPad 的 Bluetooth device address
53const std::string kBluetoothDeviceAddress = "16:00:00:00:03:27";
54
55CodexPad g_codex_pad;
56
57void Connect() {
58 printf("Start to connect %s\n", kBluetoothDeviceAddress.c_str());
59 // Connect to the CodexPad with specified Bluetooth device address
60 // 连接到指定蓝牙设备地址的手柄
61 while (!g_codex_pad.Connect(kBluetoothDeviceAddress, 5000)) {
62 printf("Retry to connect %s\n", kBluetoothDeviceAddress.c_str());
63 }
64
65 printf("Remote device name: %s\n", g_codex_pad.remote_device_name().c_str());
66 printf("Remote model number: %s\n", g_codex_pad.remote_model_number().c_str());
67 printf("Remote firmware revision: %u.%u.%u\n", g_codex_pad.remote_firmware_version()[0],
68 g_codex_pad.remote_firmware_version()[1], g_codex_pad.remote_firmware_version()[2]);
69
70 if (const auto ble_client = g_codex_pad.ble_client(); ble_client != nullptr) {
71 printf("Remote Bluetooth Device Address: %s\n", ble_client->getPeerAddress().toString().c_str());
72 } else {
73 printf("Remote Bluetooth Device Address: unknown\n");
74 }
75
76 // Set transmission power to 0 dBm
77 // Transmission power affects communication range and power consumption:
78 // Higher power provides longer range but consumes more battery
79 // Choose appropriate power level based on your application to balance range and battery life
80 // 设置发射功率为 0 dBm
81 // 发射功率影响通信距离和功耗:功率越高,通信距离越远,但功耗也越大
82 // 建议根据实际应用场景选择合适的功率等级以平衡距离和电池寿命
84 printf("Set remote tx power to 0 dBm successfully\n");
85 }
86
87 printf("Connected\n");
88}
89} // namespace
90
91void setup() {
92 Serial.begin(115200);
93
94 printf("Init\n");
95 g_codex_pad.Init();
96
97 Connect();
98}
99
100void loop() {
101 // ==========================================================================
102 // 🔴 CRITICAL: Call Update() as frequently as possible in loop()
103 // ==========================================================================
104 // • Update() processes incoming Bluetooth packets from the CodexPad
105 // • Any delay(...) or long blocking code WILL cause:
106 // - Packet loss
107 // - Input lag
108 // - Unstable connection
109 //
110 // • For real-time control, call Update() every loop iteration
111 // without any blocking operations
112 //
113 // 🔴【重要】Update() 必须在 loop() 中尽可能高频调用
114 // • Update() 负责处理来自 CodexPad 的蓝牙数据包
115 // • 任何形式的 delay 或阻塞代码都会导致:
116 // - 数据丢失
117 // - 响应延迟
118 // - 连接不稳定
119 //
120 // • 实时控制应用中,必须每轮循环都调用 Update(),不可阻塞
121 // ==========================================================================
122 const gamepad::input::Tracker& it = g_codex_pad.Update();
123 // ==========================================================================
124 // Tracker: Access button and joystick states
125 // ==========================================================================
126 // • Returned Tracker provides access to ALL gamepad inputs
127 // • Buttons → it[Button::kXXX] (bool, true = pressed)
128 // • Axes → it[Axis::kXXX] (uint8_t, 0–255)
129 //
130 // 📚 GamepadInput Library Documentation:
131 // https://codexpad.github.io/gamepad_input_arduino_lib/
132 //
133 // • Tracker 可用于访问所有按钮和摇杆状态
134 // • 按钮 → it[Button::kXXX](bool,true 表示按下)
135 // • 摇杆轴 → it[Axis::kXXX](0~255)
136 //
137 // 📘 库文档:
138 // https://codexpad.github.io/gamepad_input_arduino_lib/
139 // ==========================================================================
140
141 if (!g_codex_pad.is_connected()) {
142 printf("Disconnected, start to reconnect\n");
143 Connect();
144 return;
145 }
146
147 static uint32_t s_print_time = 0;
148 if (s_print_time != 0 && s_print_time + 30 > millis()) {
149 return;
150 }
151
152 s_print_time = millis();
153
154 printf(
155 "Up:%u, Down:%u, Left:%u, Right:%u, Square(X):%u, Triangle(Y):%u, Cross(A):%u, Circle(B):%u, L1:%u, L2:%u, L3:%u, R1:%u, "
156 "R2:%u, R3:%u, Select:%u, Start:%u, Home:%u, L(X:%3u, Y:%3u), R(X:%3u, Y:%3u)\n",
157
158 // ------------------------------------------------------------------
159 // Button states (boolean -> uint)
160 // operator[] returns bool:
161 // true = pressed
162 // false = released
163 //
164 // 按钮状态(bool 类型,打印时被隐式转换为 1 / 0)
165 // true : 按下
166 // false : 弹起
167 // ------------------------------------------------------------------
168 it[Button::kUp], it[Button::kDown], it[Button::kLeft], it[Button::kRight], it[Button::kSquareX], it[Button::kTriangleY],
169 it[Button::kCrossA], it[Button::kCircleB], it[Button::kL1], it[Button::kL2], it[Button::kL3], it[Button::kR1],
170 it[Button::kR2], it[Button::kR3], it[Button::kSelect], it[Button::kStart], it[Button::kHome],
171
172 // ------------------------------------------------------------------
173 // Joystick axis values (0–255)
174 // Center position ≈ 128
175 // Smaller → left / down
176 // Larger → right / up
177 //
178 // 摇杆轴数据(0~255)
179 // 中间值约 128
180 // 越小越左 / 下,越大越右 / 上
181 // ------------------------------------------------------------------
182 it[Axis::kLeftStickX], it[Axis::kLeftStickY], it[Axis::kRightStickX], it[Axis::kRightStickY]);
183}
CodexPad主类
bool Connect(const std::string &bluetooth_device_address, uint32_t timeout_ms=5000) noexcept
连接
bool is_connected() const noexcept
是否连接
const std::array< uint8_t, 3 > & remote_firmware_version() const noexcept
获取CodexPad的固件版本
const gamepad::input::Tracker & Update() noexcept
更新,需要在Loop中不断调用
const std::string & remote_model_number() const noexcept
获取CodexPad的型号
void Init() noexcept
初始化
NimBLEClient * ble_client() const noexcept
获取 BLE 客户端对象
const std::string & remote_device_name() const noexcept
获取CodexPad的型号
bool set_remote_tx_power(TxPower power) noexcept
设置发射功率,连接状态下调用,立即生效于当前连接,下次连接生效