mirror of
https://github.com/m5stack/M5Chain.git
synced 2026-05-20 11:48:41 -07:00
Add Angle、ToF、Encoder
This commit is contained in:
@@ -1,48 +1,29 @@
|
||||
# Product Name
|
||||
# Chain Joystick
|
||||
|
||||
## Overview
|
||||
Chain Joystick is a high‑precision Hall‑effect joystick input node in the M5Stack Chain series.
|
||||
It supports three‑axis control signal input, including analog inputs for the X and Y axes and a digital button input for the Z axis.
|
||||
The device adopts a Hall‑effect joystick, which achieves high‑precision control by detecting changes in the magnetic field.
|
||||
It features a contactless design, high durability, excellent precision, and strong anti‑interference capability, ensuring product stability and long service life.
|
||||
An integrated programmable RGB LED is included for status indication and interactive display.
|
||||
It is suitable for applications such as human‑machine interaction and robot control.
|
||||
|
||||
### SKU:xxx
|
||||
|
||||
Description of the product
|
||||
### SKU: U205
|
||||
|
||||
## Related Link
|
||||
https://docs.m5stack.com/en/products/sku/U205
|
||||
|
||||
- [Document & Datasheet](https://docs.m5stack.com/en/unit/product_Link)
|
||||
|
||||
## Required Libraries:
|
||||
|
||||
- [Adafruit_BMP280_Library](https://github.com/adafruit/Required_Libraries_Link)
|
||||
|
||||
## License
|
||||
|
||||
- [Product Name- MIT](LICENSE)
|
||||
|
||||
## Remaining steps(Editorial Staff Look,After following the steps, remember to delete all the content below)
|
||||
|
||||
1. Change [clang format check path](./.github/workflows/clang-format-check.yml#L42-L47).
|
||||
2. Add License content to [LICENSE](/LICENSE).
|
||||
3. Change link on line 78 of [bug-report.yml](./.github/ISSUE_TEMPLATE/bug-report.yml#L79).
|
||||
|
||||
```cpp
|
||||
Example
|
||||
# M5Unit-ENV
|
||||
# Chain Key
|
||||
|
||||
## Overview
|
||||
Chain Key is a single‑button input node in the M5Stack Chain series.
|
||||
The button adopts a hot‑swappable mechanical keyboard switch design, featuring a tactile Blue switch with a distinct click feel, and also integrates a programmable RGB LED.
|
||||
It is suitable for applications such as human‑machine interaction and smart home control.
|
||||
|
||||
### SKU:U001 & U001-B & U001-C
|
||||
|
||||
Contains M5Stack-**UNIT ENV** series related case programs.ENV is an environmental sensor with integrated SHT30 and QMP6988 internally to detect temperature, humidity, and atmospheric pressure data.
|
||||
### SKU: U206
|
||||
|
||||
## Related Link
|
||||
|
||||
- [Document & Datasheet](https://docs.m5stack.com/en/unit/envIII)
|
||||
|
||||
## Required Libraries:
|
||||
|
||||
- [Adafruit_BMP280_Library](https://github.com/adafruit/Adafruit_BMP280_Library)
|
||||
https://docs.m5stack.com/en/products/sku/U206
|
||||
|
||||
## License
|
||||
|
||||
- [M5Unit-ENV - MIT](LICENSE)
|
||||
```
|
||||
- [MIT](https://github.com/m5stack/M5Chain/blob/main/LICENSE)
|
||||
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
*SPDX-FileCopyrightText: 2025 M5Stack Technology CO LTD
|
||||
*
|
||||
*SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include "M5Chain.h"
|
||||
|
||||
#define TXD_PIN GPIO_NUM_21 // Tx
|
||||
#define RXD_PIN GPIO_NUM_22 // Rx
|
||||
|
||||
Chain M5Chain;
|
||||
|
||||
device_list_t *devices_list = NULL;
|
||||
uint16_t device_nums = 0;
|
||||
uint8_t operation_status = 0;
|
||||
chain_status_t chain_status = CHAIN_OK;
|
||||
|
||||
uint8_t rgb_test[5][3] = {
|
||||
{0xFF, 0x00, 0x00}, {0x00, 0xFF, 0x00}, {0x00, 0x00, 0xFF}, {0xFF, 0xFF, 0xFF}, {0x00, 0x00, 0x00},
|
||||
};
|
||||
|
||||
void printDeviceList(device_list_t *devices)
|
||||
{
|
||||
if (devices == NULL) {
|
||||
Serial.println("devices is NULL");
|
||||
return;
|
||||
}
|
||||
|
||||
Serial.print("devices count: ");
|
||||
Serial.println(devices->count);
|
||||
|
||||
for (uint8_t i = 0; i < devices->count; i++) {
|
||||
Serial.print("devices ID: ");
|
||||
Serial.println(devices->devices[i].id);
|
||||
Serial.print("devices type: ");
|
||||
Serial.println(devices->devices[i].device_type);
|
||||
}
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Serial.println("M5Chain Angle Test");
|
||||
M5Chain.begin(&Serial2, 115200, RXD_PIN, TXD_PIN);
|
||||
|
||||
if (M5Chain.isDeviceConnected()) {
|
||||
Serial.println("devices is connected");
|
||||
chain_status = M5Chain.getDeviceNum(&device_nums);
|
||||
if (chain_status == CHAIN_OK) {
|
||||
devices_list = (device_list_t *)malloc(sizeof(device_list_t));
|
||||
devices_list->count = device_nums;
|
||||
devices_list->devices = (device_info_t *)malloc(sizeof(device_info_t) * device_nums);
|
||||
if (M5Chain.getDeviceList(devices_list)) {
|
||||
Serial.println("get devices list success");
|
||||
printDeviceList(devices_list);
|
||||
} else {
|
||||
Serial.println("get devices list failed");
|
||||
}
|
||||
} else {
|
||||
Serial.printf("error status:%d \r\n", chain_status);
|
||||
Serial.printf("devices num get failed.\r\n");
|
||||
}
|
||||
} else {
|
||||
Serial.println("devices is not connected.");
|
||||
}
|
||||
|
||||
if (devices_list) {
|
||||
for (uint8_t i = 0; i < devices_list->count; i++) {
|
||||
if (devices_list->devices[i].device_type == CHAIN_ANGLE_TYPE_CODE) {
|
||||
chain_status = M5Chain.setRGBLight(devices_list->devices[i].id, 100, &operation_status);
|
||||
if (chain_status == CHAIN_OK && operation_status) {
|
||||
Serial.printf("ID[%d] set rgb light success\r\n", devices_list->devices[i].id);
|
||||
} else {
|
||||
Serial.printf("ID[%d] set rgb light failed, chain_status:%d operation_status:%d \r\n",
|
||||
devices_list->devices[i].id, chain_status, operation_status);
|
||||
}
|
||||
for (uint8_t j = 0; j < 5; j++) {
|
||||
uint8_t rgb[3] = {0};
|
||||
chain_status =
|
||||
M5Chain.setRGBValue(devices_list->devices[i].id, 0, 1, rgb_test[j], 3, &operation_status);
|
||||
if (chain_status == CHAIN_OK && operation_status) {
|
||||
Serial.printf("ID[%d] set rgb %d %d %d success\r\n", devices_list->devices[i].id,
|
||||
rgb_test[j][0], rgb_test[j][1], rgb_test[j][2]);
|
||||
} else {
|
||||
Serial.printf("ID[%d] set rgb %d %d %d failed, chain_status:%d operation_status:%d \r\n",
|
||||
devices_list->devices[i].id, rgb_test[j][0], rgb_test[j][1], rgb_test[j][2],
|
||||
chain_status, operation_status);
|
||||
}
|
||||
chain_status = M5Chain.getRGBValue(devices_list->devices[i].id, 0, 1, rgb, 3, &operation_status);
|
||||
if (chain_status == CHAIN_OK && operation_status) {
|
||||
Serial.printf("ID[%d] get rgb %d %d %d success \r\n", devices_list->devices[i].id, rgb[0],
|
||||
rgb[1], rgb[2]);
|
||||
} else {
|
||||
Serial.printf("ID[%d] get rgb %d %d %d failed, chain_status:%d operation_status:%d \r\n",
|
||||
devices_list->devices[i].id, rgb[0], rgb[1], rgb[2], chain_status,
|
||||
operation_status);
|
||||
}
|
||||
delay(500);
|
||||
}
|
||||
|
||||
// M5Chain.setAngleRotationDirection(devices_list->devices[i].id, ANGLE_ROTATION_DECREASING,
|
||||
// &operation_status,
|
||||
// CHAIN_SAVE_FLASH_ENABLE); // Angle rotation direction decreasing, save to flash
|
||||
// M5Chain.setAngleRotationDirection(devices_list->devices[i].id, ANGLE_ROTATION_INCREASING,
|
||||
// &operation_status,
|
||||
// CHAIN_SAVE_FLASH_ENABLE); // Angle rotation direction increasing, save to flash
|
||||
// chain_status = M5Chain.setAngleRotationDirection(devices_list->devices[i].id,
|
||||
// ANGLE_ROTATION_DECREASING,
|
||||
// &operation_status,
|
||||
// CHAIN_SAVE_FLASH_DISABLE); // Angle rotation direction decreasing, not save to flash
|
||||
M5Chain.setAngleRotationDirection(devices_list->devices[i].id, ANGLE_ROTATION_INCREASING,
|
||||
&operation_status,
|
||||
CHAIN_SAVE_FLASH_DISABLE); // Angle rotation direction increasing, not save to flash
|
||||
|
||||
if (chain_status == CHAIN_OK && operation_status) {
|
||||
Serial.printf("Angle ID[%d] set angle rotation direction success \r\n", devices_list->devices[i].id);
|
||||
} else {
|
||||
Serial.printf(
|
||||
"Angle ID[%d] set angle rotation direction failed, chain_status:%d operation_status:%d \r\n",
|
||||
devices_list->devices[i].id, chain_status, operation_status);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Serial.println("devices list is NULL");
|
||||
}
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
if (devices_list) {
|
||||
for (uint8_t i = 0; i < devices_list->count; i++) {
|
||||
if (devices_list->devices[i].device_type == CHAIN_ANGLE_TYPE_CODE) {
|
||||
uint16_t angle12Bit = 0;
|
||||
uint8_t angle8Bit = 0;
|
||||
angle_rotation_direction_t angle_rotation_direction;
|
||||
chain_status = M5Chain.getAngle12BitAdc(devices_list->devices[i].id, &angle12Bit);
|
||||
if (chain_status == CHAIN_OK) {
|
||||
Serial.printf("Angle ID[%d] angle12Bit:%d \r\n", devices_list->devices[i].id, angle12Bit);
|
||||
} else {
|
||||
Serial.printf("Angle ID[%d] get 12bit adc failed, chain_status:%d \r\n", devices_list->devices[i].id,
|
||||
chain_status);
|
||||
}
|
||||
chain_status = M5Chain.getAngle8BitAdc(devices_list->devices[i].id, &angle8Bit);
|
||||
if (chain_status == CHAIN_OK) {
|
||||
Serial.printf("Angle ID[%d] angle8Bit:%d \r\n", devices_list->devices[i].id, angle8Bit);
|
||||
} else {
|
||||
Serial.printf("Angle ID[%d] get 8bit adc failed, chain_status:%d \r\n", devices_list->devices[i].id,
|
||||
chain_status);
|
||||
}
|
||||
chain_status =
|
||||
M5Chain.getAngleRotationDirection(devices_list->devices[i].id, &angle_rotation_direction);
|
||||
if (chain_status == CHAIN_OK) {
|
||||
Serial.printf("Angle ID[%d] angle_rotation_direction:%d \r\n", devices_list->devices[i].id,
|
||||
angle_rotation_direction);
|
||||
} else {
|
||||
Serial.printf("Angle ID[%d] get rotation direction failed, chain_status:%d \r\n",
|
||||
devices_list->devices[i].id, chain_status);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
delay(100);
|
||||
}
|
||||
@@ -0,0 +1,201 @@
|
||||
/*
|
||||
*SPDX-FileCopyrightText: 2025 M5Stack Technology CO LTD
|
||||
*
|
||||
*SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include "M5Chain.h"
|
||||
|
||||
#define TXD_PIN GPIO_NUM_21 // Tx
|
||||
#define RXD_PIN GPIO_NUM_22 // Rx
|
||||
|
||||
Chain M5Chain;
|
||||
|
||||
device_list_t *devices_list = NULL;
|
||||
uint16_t device_nums = 0;
|
||||
uint8_t operation_status = 0;
|
||||
chain_status_t chain_status = CHAIN_OK;
|
||||
|
||||
uint8_t rgb_test[5][3] = {
|
||||
{0xFF, 0x00, 0x00}, {0x00, 0xFF, 0x00}, {0x00, 0x00, 0xFF}, {0xFF, 0xFF, 0xFF}, {0x00, 0x00, 0x00},
|
||||
};
|
||||
|
||||
void printDeviceList(device_list_t *devices)
|
||||
{
|
||||
if (devices == NULL) {
|
||||
Serial.println("devices is NULL");
|
||||
return;
|
||||
}
|
||||
|
||||
Serial.print("devices count: ");
|
||||
Serial.println(devices->count);
|
||||
|
||||
for (uint8_t i = 0; i < devices->count; i++) {
|
||||
Serial.print("devices ID: ");
|
||||
Serial.println(devices->devices[i].id);
|
||||
Serial.print("devices type: ");
|
||||
Serial.println(devices->devices[i].device_type);
|
||||
}
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Serial.println("M5Chain Encoder Test");
|
||||
M5Chain.begin(&Serial2, 115200, RXD_PIN, TXD_PIN);
|
||||
|
||||
if (M5Chain.isDeviceConnected()) {
|
||||
Serial.println("devices is connected");
|
||||
chain_status = M5Chain.getDeviceNum(&device_nums);
|
||||
if (chain_status == CHAIN_OK) {
|
||||
devices_list = (device_list_t *)malloc(sizeof(device_list_t));
|
||||
devices_list->count = device_nums;
|
||||
devices_list->devices = (device_info_t *)malloc(sizeof(device_info_t) * device_nums);
|
||||
if (M5Chain.getDeviceList(devices_list)) {
|
||||
Serial.println("get devices list success");
|
||||
printDeviceList(devices_list);
|
||||
} else {
|
||||
Serial.println("get devices list failed");
|
||||
}
|
||||
} else {
|
||||
Serial.printf("error status:%d \r\n", chain_status);
|
||||
Serial.printf("devices num get failed.\r\n");
|
||||
}
|
||||
} else {
|
||||
Serial.println("devices is not connected.");
|
||||
}
|
||||
|
||||
if (devices_list) {
|
||||
for (uint8_t i = 0; i < devices_list->count; i++) {
|
||||
if (devices_list->devices[i].device_type == CHAIN_ENCODER_TYPE_CODE) {
|
||||
chain_status = M5Chain.setRGBLight(devices_list->devices[i].id, 100, &operation_status);
|
||||
if (chain_status == CHAIN_OK && operation_status) {
|
||||
Serial.printf("ID[%d] set rgb light success\r\n", devices_list->devices[i].id);
|
||||
} else {
|
||||
Serial.printf("ID[%d] set rgb light failed, chain_status:%d operation_status:%d \r\n",
|
||||
devices_list->devices[i].id, chain_status, operation_status);
|
||||
}
|
||||
for (uint8_t j = 0; j < 5; j++) {
|
||||
uint8_t rgb[3] = {0};
|
||||
chain_status =
|
||||
M5Chain.setRGBValue(devices_list->devices[i].id, 0, 1, rgb_test[j], 3, &operation_status);
|
||||
if (chain_status == CHAIN_OK && operation_status) {
|
||||
Serial.printf("ID[%d] set rgb %d %d %d success\r\n", devices_list->devices[i].id,
|
||||
rgb_test[j][0], rgb_test[j][1], rgb_test[j][2]);
|
||||
} else {
|
||||
Serial.printf("ID[%d] set rgb %d %d %d failed, chain_status:%d operation_status:%d \r\n",
|
||||
devices_list->devices[i].id, rgb_test[j][0], rgb_test[j][1], rgb_test[j][2],
|
||||
chain_status, operation_status);
|
||||
}
|
||||
chain_status = M5Chain.getRGBValue(devices_list->devices[i].id, 0, 1, rgb, 3, &operation_status);
|
||||
if (chain_status == CHAIN_OK && operation_status) {
|
||||
Serial.printf("ID[%d] get rgb %d %d %d success \r\n", devices_list->devices[i].id, rgb[0],
|
||||
rgb[1], rgb[2]);
|
||||
} else {
|
||||
Serial.printf("ID[%d] get rgb %d %d %d failed, chain_status:%d operation_status:%d \r\n",
|
||||
devices_list->devices[i].id, rgb[0], rgb[1], rgb[2], chain_status,
|
||||
operation_status);
|
||||
}
|
||||
delay(500);
|
||||
}
|
||||
chain_status =
|
||||
M5Chain.setKeyButtonTriggerInterval(devices_list->devices[i].id, BUTTON_DOUBLE_CLICK_TIME_200MS,
|
||||
BUTTON_LONG_PRESS_TIME_3S, &operation_status);
|
||||
if (chain_status == CHAIN_OK && operation_status) {
|
||||
Serial.printf("ID[%d] set key button trigger interval success\r\n", devices_list->devices[i].id);
|
||||
} else {
|
||||
Serial.printf(
|
||||
"ID[%d] set key button trigger interval failed, chain_status:%d operation_status:%d \r\n",
|
||||
devices_list->devices[i].id, chain_status, operation_status);
|
||||
}
|
||||
chain_status =
|
||||
M5Chain.setKeyButtonMode(devices_list->devices[i].id, CHAIN_BUTTON_REPORT_MODE, &operation_status);
|
||||
if (chain_status == CHAIN_OK && operation_status) {
|
||||
Serial.printf("ID[%d] set key button mode success\r\n", devices_list->devices[i].id);
|
||||
} else {
|
||||
Serial.printf("ID[%d] set key button mode failed, chain_status:%d operation_status:%d \r\n",
|
||||
devices_list->devices[i].id, chain_status, operation_status);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Serial.println("devices list is NULL");
|
||||
}
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
if (devices_list) {
|
||||
for (uint8_t i = 0; i < devices_list->count; i++) {
|
||||
if (devices_list->devices[i].device_type == CHAIN_ENCODER_TYPE_CODE) {
|
||||
int16_t encoder = 0;
|
||||
int16_t inc_encoder = 0;
|
||||
encoder_ab_t direct;
|
||||
uint8_t button_status = 0;
|
||||
button_double_click_time_t button_double_click_time;
|
||||
button_long_press_time_t button_long_press_time;
|
||||
chain_button_press_type_t button_press_type;
|
||||
chain_button_mode_t button_mode;
|
||||
|
||||
chain_status = M5Chain.getEncoderValue(devices_list->devices[i].id, &encoder);
|
||||
if (chain_status == CHAIN_OK) {
|
||||
Serial.printf("ENCODER ID[%d] encoder:%d \r\n", devices_list->devices[i].id, encoder);
|
||||
} else {
|
||||
Serial.printf("ENCODER ID[%d] get encoder status failed, chain_status:%d \r\n",
|
||||
devices_list->devices[i].id, chain_status);
|
||||
}
|
||||
chain_status = M5Chain.getEncoderIncValue(devices_list->devices[i].id, &inc_encoder);
|
||||
if (chain_status == CHAIN_OK) {
|
||||
Serial.printf("ENCODER ID[%d] inc encoder:%d \r\n", devices_list->devices[i].id, inc_encoder);
|
||||
} else {
|
||||
Serial.printf("ENCODER ID[%d] get inc encoder status failed, chain_status:%d \r\n",
|
||||
devices_list->devices[i].id, chain_status);
|
||||
}
|
||||
chain_status = M5Chain.getEncoderABDirect(devices_list->devices[i].id, &direct);
|
||||
if (chain_status == CHAIN_OK) {
|
||||
Serial.printf("ENCODER ID[%d] ab direct:%d \r\n", devices_list->devices[i].id, direct);
|
||||
} else {
|
||||
Serial.printf("ENCODER ID[%d] get direct status failed, chain_status:%d \r\n",
|
||||
devices_list->devices[i].id, chain_status);
|
||||
}
|
||||
chain_status = M5Chain.getEncoderButtonStatus(devices_list->devices[i].id, &button_status);
|
||||
if (chain_status == CHAIN_OK) {
|
||||
Serial.printf("ENCODER ID[%d] button status:%d \r\n", devices_list->devices[i].id, button_status);
|
||||
} else {
|
||||
Serial.printf("ENCODER ID[%d] get button status failed, chain_status:%d \r\n",
|
||||
devices_list->devices[i].id, chain_status);
|
||||
}
|
||||
chain_status = M5Chain.getEncoderButtonTriggerInterval(
|
||||
devices_list->devices[i].id, &button_double_click_time, &button_long_press_time);
|
||||
if (chain_status == CHAIN_OK) {
|
||||
Serial.printf("ENCODER ID[%d] button double click time:%d, button long press time:%d \r\n",
|
||||
devices_list->devices[i].id, button_double_click_time, button_long_press_time);
|
||||
} else {
|
||||
Serial.printf("ENCODER ID[%d] get button trigger interval failed, chain_status:%d \r\n",
|
||||
devices_list->devices[i].id, chain_status);
|
||||
}
|
||||
chain_status = M5Chain.getEncoderButtonMode(devices_list->devices[i].id, &button_mode);
|
||||
if (chain_status == CHAIN_OK) {
|
||||
Serial.printf("ENCODER ID[%d] button mode:%d \r\n", devices_list->devices[i].id, button_mode);
|
||||
} else {
|
||||
Serial.printf("ENCODER ID[%d] get button mode failed, chain_status:%d \r\n",
|
||||
devices_list->devices[i].id, chain_status);
|
||||
}
|
||||
while (M5Chain.getEncoderButtonPressStatus(devices_list->devices[i].id, &button_press_type)) {
|
||||
switch (button_press_type) {
|
||||
case CHAIN_BUTTON_PRESS_SINGLE:
|
||||
Serial.printf("ENCODER ID[%d] button press type: single \r\n", devices_list->devices[i].id);
|
||||
break;
|
||||
case CHAIN_BUTTON_PRESS_DOUBLE:
|
||||
Serial.printf("ENCODER ID[%d] button press type: double \r\n", devices_list->devices[i].id);
|
||||
break;
|
||||
case CHAIN_BUTTON_PRESS_LONG:
|
||||
Serial.printf("ENCODER ID[%d] button press type: long \r\n", devices_list->devices[i].id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
delay(100);
|
||||
}
|
||||
@@ -0,0 +1,174 @@
|
||||
/*
|
||||
*SPDX-FileCopyrightText: 2025 M5Stack Technology CO LTD
|
||||
*
|
||||
*SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include "M5Chain.h"
|
||||
|
||||
#define TXD_PIN GPIO_NUM_21 // Tx
|
||||
#define RXD_PIN GPIO_NUM_22 // Rx
|
||||
|
||||
Chain M5Chain;
|
||||
|
||||
device_list_t *devices_list;
|
||||
|
||||
uint16_t device_nums = 0;
|
||||
uint8_t operation_status = 0;
|
||||
chain_status_t chain_status = CHAIN_OK;
|
||||
|
||||
uint8_t rgb_test[5][3] = {
|
||||
{0xFF, 0x00, 0x00}, {0x00, 0xFF, 0x00}, {0x00, 0x00, 0xFF}, {0xFF, 0xFF, 0xFF}, {0x00, 0x00, 0x00},
|
||||
};
|
||||
|
||||
void printDeviceList(device_list_t *devices)
|
||||
{
|
||||
if (devices == NULL) {
|
||||
Serial.println("devices is NULL");
|
||||
return;
|
||||
}
|
||||
|
||||
Serial.print("devices count: ");
|
||||
Serial.println(devices->count);
|
||||
|
||||
for (uint8_t i = 0; i < devices->count; i++) {
|
||||
Serial.print("devices ID: ");
|
||||
Serial.println(devices->devices[i].id);
|
||||
Serial.print("devices type: ");
|
||||
Serial.println(devices->devices[i].device_type);
|
||||
}
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Serial.println("M5Chain ToF Test");
|
||||
M5Chain.begin(&Serial2, 115200, RXD_PIN, TXD_PIN);
|
||||
|
||||
if (M5Chain.isDeviceConnected()) {
|
||||
Serial.println("devices is connected");
|
||||
chain_status = M5Chain.getDeviceNum(&device_nums);
|
||||
if (chain_status == CHAIN_OK) {
|
||||
devices_list = (device_list_t *)malloc(sizeof(device_list_t));
|
||||
devices_list->count = device_nums;
|
||||
devices_list->devices = (device_info_t *)malloc(sizeof(device_info_t) * device_nums);
|
||||
if (M5Chain.getDeviceList(devices_list)) {
|
||||
Serial.println("devices list get success");
|
||||
printDeviceList(devices_list);
|
||||
} else {
|
||||
Serial.println("devices list get failed");
|
||||
}
|
||||
} else {
|
||||
Serial.printf("error status:%d \r\n", chain_status);
|
||||
Serial.printf("devices num get failed.\r\n");
|
||||
}
|
||||
} else {
|
||||
Serial.println("devices is not connected.");
|
||||
}
|
||||
|
||||
if (devices_list) {
|
||||
for (uint8_t i = 0; i < devices_list->count; i++) {
|
||||
if (devices_list->devices[i].device_type == CHAIN_TOF_TYPE_CODE) {
|
||||
chain_status = M5Chain.setRGBLight(devices_list->devices[i].id, 100, &operation_status);
|
||||
if (chain_status == CHAIN_OK && operation_status) {
|
||||
Serial.printf("ID[%d] set rgb light success\r\n", devices_list->devices[i].id);
|
||||
} else {
|
||||
Serial.printf("ID[%d] set rgb light failed, chain_status:%d operation_status:%d \r\n",
|
||||
devices_list->devices[i].id, chain_status, operation_status);
|
||||
}
|
||||
for (uint8_t j = 0; j < 5; j++) {
|
||||
uint8_t rgb[3] = {0};
|
||||
chain_status =
|
||||
M5Chain.setRGBValue(devices_list->devices[i].id, 0, 1, rgb_test[j], 3, &operation_status);
|
||||
if (chain_status == CHAIN_OK && operation_status) {
|
||||
Serial.printf("ID[%d] set rgb %d %d %d success\r\n", devices_list->devices[i].id,
|
||||
rgb_test[j][0], rgb_test[j][1], rgb_test[j][2]);
|
||||
} else {
|
||||
Serial.printf("ID[%d] set rgb %d %d %d failed, chain_status:%d operation_status:%d \r\n",
|
||||
devices_list->devices[i].id, rgb_test[j][0], rgb_test[j][1], rgb_test[j][2],
|
||||
chain_status, operation_status);
|
||||
}
|
||||
chain_status = M5Chain.getRGBValue(devices_list->devices[i].id, 0, 1, rgb, 3, &operation_status);
|
||||
if (chain_status == CHAIN_OK && operation_status) {
|
||||
Serial.printf("ID[%d] get rgb %d %d %d success \r\n", devices_list->devices[i].id, rgb[0],
|
||||
rgb[1], rgb[2]);
|
||||
} else {
|
||||
Serial.printf("ID[%d] get rgb %d %d %d failed, chain_status:%d operation_status:%d \r\n",
|
||||
devices_list->devices[i].id, rgb[0], rgb[1], rgb[2], chain_status,
|
||||
operation_status);
|
||||
}
|
||||
delay(500);
|
||||
}
|
||||
|
||||
// 设置测量模式
|
||||
chain_status = M5Chain.setToFMeasureMode(devices_list->devices[i].id, CHAIN_TOF_MODE_CONTINUOUS,
|
||||
&operation_status);
|
||||
if (chain_status == CHAIN_OK && operation_status) {
|
||||
Serial.printf("TOF ID[%d] set measure mode CONTINUOUS success\r\n", devices_list->devices[i].id);
|
||||
} else {
|
||||
Serial.printf(
|
||||
"TOF ID[%d] set measure mode CONTINUOUS failed, chain_status:%d operation_status:%d \r\n",
|
||||
devices_list->devices[i].id, chain_status, operation_status);
|
||||
}
|
||||
|
||||
// 设置测量时间
|
||||
uint8_t measurement_time = 33; // ms
|
||||
chain_status =
|
||||
M5Chain.setToFMeasureTime(devices_list->devices[i].id, measurement_time, &operation_status);
|
||||
if (chain_status == CHAIN_OK && operation_status) {
|
||||
Serial.printf("TOF ID[%d] set measurement_time %d success\r\n", devices_list->devices[i].id,
|
||||
measurement_time);
|
||||
} else {
|
||||
Serial.printf(
|
||||
"TOF ID[%d] set measurement_time %d failed, chain_status:%d operation_status:%d \r\n",
|
||||
devices_list->devices[i].id, measurement_time, chain_status, operation_status);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Serial.println("devices list is NULL");
|
||||
}
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
if (devices_list) {
|
||||
for (uint8_t i = 0; i < devices_list->count; i++) {
|
||||
if (devices_list->devices[i].device_type == CHAIN_TOF_TYPE_CODE) {
|
||||
uint16_t distance = 0;
|
||||
uint8_t measurement_time = 0;
|
||||
chain_tof_mode_t mode;
|
||||
chain_tof_measure_status_t measure_status;
|
||||
chain_status = M5Chain.getToFDistance(devices_list->devices[i].id, &distance);
|
||||
if (chain_status == CHAIN_OK) {
|
||||
Serial.printf("TOF ID[%d] distance:%d \r\n", devices_list->devices[i].id, distance);
|
||||
} else {
|
||||
Serial.printf("TOF ID[%d] get distance failed, chain_status:%d \r\n", devices_list->devices[i].id,
|
||||
chain_status);
|
||||
}
|
||||
chain_status = M5Chain.getToFMeasureTime(devices_list->devices[i].id, &measurement_time);
|
||||
if (chain_status == CHAIN_OK) {
|
||||
Serial.printf("TOF ID[%d] measurement_time:%d \r\n", devices_list->devices[i].id, measurement_time);
|
||||
} else {
|
||||
Serial.printf("TOF ID[%d] get measurement_time failed, chain_status:%d \r\n",
|
||||
devices_list->devices[i].id, chain_status);
|
||||
}
|
||||
chain_status = M5Chain.getToFMeasureMode(devices_list->devices[i].id, &mode);
|
||||
if (chain_status == CHAIN_OK) {
|
||||
Serial.printf("TOF ID[%d] mode:%d \r\n", devices_list->devices[i].id, mode);
|
||||
} else {
|
||||
Serial.printf("TOF ID[%d] get mode failed, chain_status:%d \r\n", devices_list->devices[i].id,
|
||||
chain_status);
|
||||
}
|
||||
chain_status = M5Chain.getToFMeasureStatus(devices_list->devices[i].id, &measure_status);
|
||||
if (chain_status == CHAIN_OK) {
|
||||
Serial.printf("TOF ID[%d] measure_status:%d \r\n", devices_list->devices[i].id, measure_status);
|
||||
} else {
|
||||
Serial.printf("TOF ID[%d] get measure_status failed, chain_status:%d \r\n",
|
||||
devices_list->devices[i].id, chain_status);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
delay(100);
|
||||
}
|
||||
@@ -0,0 +1,215 @@
|
||||
/*
|
||||
*SPDX-FileCopyrightText: 2025 M5Stack Technology CO LTD
|
||||
*
|
||||
*SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include "M5Chain.h"
|
||||
|
||||
#define TXD_PIN GPIO_NUM_21 // Tx
|
||||
#define RXD_PIN GPIO_NUM_22 // Rx
|
||||
|
||||
Chain M5Chain;
|
||||
|
||||
device_list_t *devices_list;
|
||||
|
||||
uint16_t device_nums = 0;
|
||||
uint8_t operation_status = 0;
|
||||
chain_status_t chain_status = CHAIN_OK;
|
||||
|
||||
uint8_t rgb_test[5][3] = {
|
||||
{0xFF, 0x00, 0x00}, {0x00, 0xFF, 0x00}, {0x00, 0x00, 0xFF}, {0xFF, 0xFF, 0xFF}, {0x00, 0x00, 0x00},
|
||||
};
|
||||
|
||||
void printDeviceList(device_list_t *devices)
|
||||
{
|
||||
if (devices == NULL) {
|
||||
Serial.println("devices is NULL");
|
||||
return;
|
||||
}
|
||||
|
||||
Serial.print("devices count: ");
|
||||
Serial.println(devices->count);
|
||||
|
||||
for (uint8_t i = 0; i < devices->count; i++) {
|
||||
Serial.print("devices ID: ");
|
||||
Serial.println(devices->devices[i].id);
|
||||
Serial.print("devices type: ");
|
||||
Serial.println(devices->devices[i].device_type);
|
||||
}
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Serial.println("M5Chain ToF Test");
|
||||
M5Chain.begin(&Serial2, 115200, RXD_PIN, TXD_PIN);
|
||||
|
||||
if (M5Chain.isDeviceConnected()) {
|
||||
Serial.println("devices is connected");
|
||||
chain_status = M5Chain.getDeviceNum(&device_nums);
|
||||
if (chain_status == CHAIN_OK) {
|
||||
devices_list = (device_list_t *)malloc(sizeof(device_list_t));
|
||||
devices_list->count = device_nums;
|
||||
devices_list->devices = (device_info_t *)malloc(sizeof(device_info_t) * device_nums);
|
||||
if (M5Chain.getDeviceList(devices_list)) {
|
||||
Serial.println("devices list get success");
|
||||
printDeviceList(devices_list);
|
||||
} else {
|
||||
Serial.println("devices list get failed");
|
||||
}
|
||||
} else {
|
||||
Serial.printf("error status:%d \r\n", chain_status);
|
||||
Serial.printf("devices num get failed.\r\n");
|
||||
}
|
||||
} else {
|
||||
Serial.println("devices is not connected.");
|
||||
}
|
||||
|
||||
if (devices_list) {
|
||||
for (uint8_t i = 0; i < devices_list->count; i++) {
|
||||
if (devices_list->devices[i].device_type == CHAIN_TOF_TYPE_CODE) {
|
||||
chain_status = M5Chain.setRGBLight(devices_list->devices[i].id, 100, &operation_status);
|
||||
if (chain_status == CHAIN_OK && operation_status) {
|
||||
Serial.printf("ID[%d] set rgb light success\r\n", devices_list->devices[i].id);
|
||||
} else {
|
||||
Serial.printf("ID[%d] set rgb light failed, chain_status:%d operation_status:%d \r\n",
|
||||
devices_list->devices[i].id, chain_status, operation_status);
|
||||
}
|
||||
for (uint8_t j = 0; j < 5; j++) {
|
||||
uint8_t rgb[3] = {0};
|
||||
chain_status =
|
||||
M5Chain.setRGBValue(devices_list->devices[i].id, 0, 1, rgb_test[j], 3, &operation_status);
|
||||
if (chain_status == CHAIN_OK && operation_status) {
|
||||
Serial.printf("ID[%d] set rgb %d %d %d success\r\n", devices_list->devices[i].id,
|
||||
rgb_test[j][0], rgb_test[j][1], rgb_test[j][2]);
|
||||
} else {
|
||||
Serial.printf("ID[%d] set rgb %d %d %d failed, chain_status:%d operation_status:%d \r\n",
|
||||
devices_list->devices[i].id, rgb_test[j][0], rgb_test[j][1], rgb_test[j][2],
|
||||
chain_status, operation_status);
|
||||
}
|
||||
chain_status = M5Chain.getRGBValue(devices_list->devices[i].id, 0, 1, rgb, 3, &operation_status);
|
||||
if (chain_status == CHAIN_OK && operation_status) {
|
||||
Serial.printf("ID[%d] get rgb %d %d %d success \r\n", devices_list->devices[i].id, rgb[0],
|
||||
rgb[1], rgb[2]);
|
||||
} else {
|
||||
Serial.printf("ID[%d] get rgb %d %d %d failed, chain_status:%d operation_status:%d \r\n",
|
||||
devices_list->devices[i].id, rgb[0], rgb[1], rgb[2], chain_status,
|
||||
operation_status);
|
||||
}
|
||||
delay(500);
|
||||
}
|
||||
|
||||
// 设置测量模式
|
||||
chain_status =
|
||||
M5Chain.setToFMeasureMode(devices_list->devices[i].id, CHAIN_TOF_MODE_SINGLE, &operation_status);
|
||||
if (chain_status == CHAIN_OK && operation_status) {
|
||||
Serial.printf("TOF ID[%d] set measure mode SINGLE success\r\n", devices_list->devices[i].id);
|
||||
} else {
|
||||
Serial.printf(
|
||||
"TOF ID[%d] set measure mode SINGLE failed, chain_status:%d operation_status:%d \r\n",
|
||||
devices_list->devices[i].id, chain_status, operation_status);
|
||||
}
|
||||
|
||||
// 设置测量时间
|
||||
uint8_t measurement_time = 33; // ms
|
||||
chain_status =
|
||||
M5Chain.setToFMeasureTime(devices_list->devices[i].id, measurement_time, &operation_status);
|
||||
if (chain_status == CHAIN_OK && operation_status) {
|
||||
Serial.printf("TOF ID[%d] set measurement_time %d success\r\n", devices_list->devices[i].id,
|
||||
measurement_time);
|
||||
} else {
|
||||
Serial.printf(
|
||||
"TOF ID[%d] set measurement_time %d failed, chain_status:%d operation_status:%d \r\n",
|
||||
devices_list->devices[i].id, measurement_time, chain_status, operation_status);
|
||||
}
|
||||
|
||||
// 设置测量状态,单次测量必须手运触发
|
||||
chain_status =
|
||||
M5Chain.setToFMeasureStatus(devices_list->devices[i].id, CHAIN_TOF_STATUS_START, &operation_status);
|
||||
if (chain_status == CHAIN_OK && operation_status) {
|
||||
Serial.printf("TOF ID[%d] set measure status START success\r\n", devices_list->devices[i].id);
|
||||
} else {
|
||||
Serial.printf(
|
||||
"TOF ID[%d] set measure status START failed, chain_status:%d operation_status:%d \r\n",
|
||||
devices_list->devices[i].id, chain_status, operation_status);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Serial.println("devices list is NULL");
|
||||
}
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
if (devices_list) {
|
||||
for (uint8_t i = 0; i < devices_list->count; i++) {
|
||||
if (devices_list->devices[i].device_type == CHAIN_TOF_TYPE_CODE) {
|
||||
uint16_t distance = 0;
|
||||
uint8_t measurement_time = 0;
|
||||
chain_tof_mode_t mode;
|
||||
chain_tof_measure_status_t measure_status;
|
||||
uint8_t complete_flag = 0;
|
||||
|
||||
// 读取测量时间
|
||||
chain_status = M5Chain.getToFMeasureTime(devices_list->devices[i].id, &measurement_time);
|
||||
if (chain_status == CHAIN_OK) {
|
||||
Serial.printf("TOF ID[%d] measurement_time:%d \r\n", devices_list->devices[i].id, measurement_time);
|
||||
} else {
|
||||
Serial.printf("TOF ID[%d] get measurement_time failed, chain_status:%d \r\n",
|
||||
devices_list->devices[i].id, chain_status);
|
||||
}
|
||||
|
||||
// 读取测量模式
|
||||
chain_status = M5Chain.getToFMeasureMode(devices_list->devices[i].id, &mode);
|
||||
if (chain_status == CHAIN_OK) {
|
||||
Serial.printf("TOF ID[%d] mode:%d \r\n", devices_list->devices[i].id, mode);
|
||||
} else {
|
||||
Serial.printf("TOF ID[%d] get mode failed, chain_status:%d \r\n", devices_list->devices[i].id,
|
||||
chain_status);
|
||||
}
|
||||
|
||||
// 读取测量状态
|
||||
chain_status = M5Chain.getToFMeasureStatus(devices_list->devices[i].id, &measure_status);
|
||||
if (chain_status == CHAIN_OK) {
|
||||
Serial.printf("TOF ID[%d] measure_status:%d \r\n", devices_list->devices[i].id, measure_status);
|
||||
} else {
|
||||
Serial.printf("TOF ID[%d] get measure_status failed, chain_status:%d \r\n",
|
||||
devices_list->devices[i].id, chain_status);
|
||||
}
|
||||
|
||||
// 读取测量完成标志
|
||||
chain_status = M5Chain.getToFMeasureCompleteFlag(devices_list->devices[i].id, &complete_flag);
|
||||
if (chain_status == CHAIN_OK) {
|
||||
Serial.printf("TOF ID[%d] complete_flag:%d \r\n", devices_list->devices[i].id, complete_flag);
|
||||
} else {
|
||||
Serial.printf("TOF ID[%d] get complete_flag failed, chain_status:%d \r\n",
|
||||
devices_list->devices[i].id, chain_status);
|
||||
}
|
||||
|
||||
// 如果是单次测量模式,且测量完成,则读取距离值,并重新触发测量
|
||||
if (measure_status == 0 && complete_flag == 1) {
|
||||
chain_status = M5Chain.getToFDistance(devices_list->devices[i].id, &distance);
|
||||
if (chain_status == CHAIN_OK) {
|
||||
Serial.printf("TOF ID[%d] distance:%d \r\n", devices_list->devices[i].id, distance);
|
||||
} else {
|
||||
Serial.printf("TOF ID[%d] get distance failed, chain_status:%d \r\n",
|
||||
devices_list->devices[i].id, chain_status);
|
||||
}
|
||||
// 重新触发单次测量
|
||||
chain_status = M5Chain.setToFMeasureStatus(devices_list->devices[i].id, CHAIN_TOF_STATUS_START,
|
||||
&operation_status);
|
||||
if (chain_status == CHAIN_OK && operation_status) {
|
||||
Serial.printf("TOF ID[%d] set measure status START success\r\n", devices_list->devices[i].id);
|
||||
} else {
|
||||
Serial.printf(
|
||||
"TOF ID[%d] set measure status START failed, chain_status:%d operation_status:%d \r\n",
|
||||
devices_list->devices[i].id, chain_status, operation_status);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
delay(100);
|
||||
}
|
||||
}
|
||||
+4
-1
@@ -26,7 +26,10 @@
|
||||
"-Isrc/Chain",
|
||||
"-Isrc/ChainCommon",
|
||||
"-Isrc/ChainJoystick",
|
||||
"-Isrc/ChainKey"
|
||||
"-Isrc/ChainKey",
|
||||
"-Isrc/ChainEncoder",
|
||||
"-Isrc/ChainAngle",
|
||||
"-Isrc/ChainToF"
|
||||
]
|
||||
},
|
||||
"headers": [
|
||||
|
||||
+5
-4
@@ -1,9 +1,10 @@
|
||||
name=M5Chain
|
||||
version=0.0.1
|
||||
version=1.0.0
|
||||
author=M5Stack
|
||||
maintainer=M5Stack
|
||||
sentence=M5Stack Chain series support library.
|
||||
paragraph=Library for M5Stack Chain series units.
|
||||
category=Uncategorized
|
||||
url=https://github.com/m5stack
|
||||
architectures=*
|
||||
category=Device Control
|
||||
url=https://github.com/m5stack/M5Chain
|
||||
architectures=*
|
||||
includes=M5Chain.hpp
|
||||
+7
-1
@@ -10,10 +10,16 @@
|
||||
#include "ChainCommon/ChainCommon.hpp"
|
||||
#include "ChainJoystick/ChainJoystick.hpp"
|
||||
#include "ChainKey/ChainKey.hpp"
|
||||
#include "ChainAngle/ChainAngle.hpp"
|
||||
#include "ChainEncoder/ChainEncoder.hpp"
|
||||
#include "ChainToF/ChainToF.hpp"
|
||||
|
||||
class Chain : virtual public ChainCommon,
|
||||
virtual public ChainJoystick,
|
||||
virtual public ChainKey {
|
||||
virtual public ChainKey,
|
||||
virtual public ChainAngle,
|
||||
virtual public ChainEncoder,
|
||||
virtual public ChainToF {
|
||||
public:
|
||||
private:
|
||||
};
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
*SPDX-FileCopyrightText: 2025 M5Stack Technology CO LTD
|
||||
*
|
||||
*SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include "ChainAngle/ChainAngle.hpp"
|
||||
|
||||
chain_status_t ChainAngle::getAngle12BitAdc(uint8_t id, uint16_t *adcValue, unsigned long timeout)
|
||||
{
|
||||
chain_status_t status = CHAIN_OK;
|
||||
|
||||
if (acquireMutex()) {
|
||||
cmdBufferSize = 0;
|
||||
sendPacket(id, CHAIN_ANGLE_GET_12ADC, cmdBuffer, cmdBufferSize);
|
||||
if (waitForData(id, CHAIN_ANGLE_GET_12ADC, timeout)) {
|
||||
if (checkPacket(returnPacket, returnPacketSize)) {
|
||||
*adcValue = (returnPacket[7] << 8) | returnPacket[6];
|
||||
} else {
|
||||
status = CHAIN_RETURN_PACKET_ERROR;
|
||||
}
|
||||
} else {
|
||||
status = CHAIN_TIMEOUT;
|
||||
}
|
||||
releaseMutex();
|
||||
} else {
|
||||
status = CHAIN_BUSY;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
chain_status_t ChainAngle::getAngle8BitAdc(uint8_t id, uint8_t *adcValue, unsigned long timeout)
|
||||
{
|
||||
chain_status_t status = CHAIN_OK;
|
||||
|
||||
if (acquireMutex()) {
|
||||
cmdBufferSize = 0;
|
||||
sendPacket(id, CHAIN_ANGLE_GET_8ADC, cmdBuffer, cmdBufferSize);
|
||||
if (waitForData(id, CHAIN_ANGLE_GET_8ADC, timeout)) {
|
||||
if (checkPacket(returnPacket, returnPacketSize)) {
|
||||
*adcValue = returnPacket[6];
|
||||
} else {
|
||||
status = CHAIN_RETURN_PACKET_ERROR;
|
||||
}
|
||||
} else {
|
||||
status = CHAIN_TIMEOUT;
|
||||
}
|
||||
releaseMutex();
|
||||
} else {
|
||||
status = CHAIN_BUSY;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
chain_status_t ChainAngle::setAngleRotationDirection(uint8_t id, angle_rotation_direction_t direction,
|
||||
uint8_t *operationStatus, chain_save_flash_t saveToFlash,
|
||||
unsigned long timeout)
|
||||
{
|
||||
chain_status_t status = CHAIN_OK;
|
||||
|
||||
if (direction > ANGLE_ROTATION_INCREASING) {
|
||||
return CHAIN_PARAMETER_ERROR;
|
||||
}
|
||||
|
||||
if (acquireMutex()) {
|
||||
cmdBufferSize = 0;
|
||||
cmdBuffer[cmdBufferSize++] = direction;
|
||||
cmdBuffer[cmdBufferSize++] = saveToFlash;
|
||||
sendPacket(id, CHAIN_ANGLE_SET_CLOCKWISE_STATUS, cmdBuffer, cmdBufferSize);
|
||||
if (waitForData(id, CHAIN_ANGLE_SET_CLOCKWISE_STATUS, timeout)) {
|
||||
if (checkPacket(returnPacket, returnPacketSize)) {
|
||||
*operationStatus = returnPacket[6];
|
||||
} else {
|
||||
status = CHAIN_RETURN_PACKET_ERROR;
|
||||
}
|
||||
} else {
|
||||
status = CHAIN_TIMEOUT;
|
||||
}
|
||||
releaseMutex();
|
||||
} else {
|
||||
status = CHAIN_BUSY;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
chain_status_t ChainAngle::getAngleRotationDirection(uint8_t id, angle_rotation_direction_t *direction,
|
||||
unsigned long timeout)
|
||||
{
|
||||
chain_status_t status = CHAIN_OK;
|
||||
|
||||
if (acquireMutex()) {
|
||||
cmdBufferSize = 0;
|
||||
sendPacket(id, CHAIN_ANGLE_GET_CLOCKWISE_STATUS, cmdBuffer, cmdBufferSize);
|
||||
if (waitForData(id, CHAIN_ANGLE_GET_CLOCKWISE_STATUS, timeout)) {
|
||||
if (checkPacket(returnPacket, returnPacketSize)) {
|
||||
*direction = (angle_rotation_direction_t)returnPacket[6];
|
||||
} else {
|
||||
status = CHAIN_RETURN_PACKET_ERROR;
|
||||
}
|
||||
} else {
|
||||
status = CHAIN_TIMEOUT;
|
||||
}
|
||||
releaseMutex();
|
||||
} else {
|
||||
status = CHAIN_BUSY;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
*SPDX-FileCopyrightText: 2025 M5Stack Technology CO LTD
|
||||
*
|
||||
*SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#ifndef _CHAIN_ANGLE_HPP_
|
||||
#define _CHAIN_ANGLE_HPP_
|
||||
|
||||
#include "ChainCommon/ChainCommon.hpp"
|
||||
|
||||
/**
|
||||
* @brief RotationDirection status for Angle device.
|
||||
*
|
||||
* This enumeration records whether the Angle device's clockwise direction
|
||||
* is increasing or decreasing.
|
||||
*/
|
||||
typedef enum {
|
||||
ANGLE_ROTATION_DECREASING = 0x00, /**< Rotation direction decreasing angle. */
|
||||
ANGLE_ROTATION_INCREASING = 0x01, /**< Rotation direction increasing angle. */
|
||||
} angle_rotation_direction_t;
|
||||
|
||||
/**
|
||||
* @brief Enumeration for Chain_Angle device commands.
|
||||
*
|
||||
* This enumeration defines command codes for various operations of the Chain_Angle device.
|
||||
*/
|
||||
typedef enum {
|
||||
CHAIN_ANGLE_GET_12ADC = 0x30, /**< Command to get the latest 12-bit ADC value */
|
||||
CHAIN_ANGLE_GET_8ADC = 0x31, /**< Command to get the latest 8-bit mapped ADC value */
|
||||
CHAIN_ANGLE_SET_CLOCKWISE_STATUS = 0x32, /**< Command to set the clockwise direction status */
|
||||
CHAIN_ANGLE_GET_CLOCKWISE_STATUS = 0x33, /**< Command to get the current clockwise direction status */
|
||||
} CHAIN_ANGLE_CMD_T; /**< Command types for Chain_Angle device operations */
|
||||
|
||||
class ChainAngle : virtual public ChainCommon {
|
||||
public:
|
||||
/**
|
||||
* @brief Retrieves the 12-bit ADC value of the Angle device.
|
||||
*
|
||||
* This function fetches the 12-bit ADC value from the specified Angle device.
|
||||
*
|
||||
* @param id The position of the Angle device in the chain (starting from 1).
|
||||
* @param adcValue Pointer to store the retrieved 12-bit ADC value.
|
||||
* @param timeout Timeout duration in milliseconds (default is 100ms).
|
||||
*
|
||||
* @return The operation status (e.g., CHAIN_OK, CHAIN_TIMEOUT, etc.).
|
||||
*/
|
||||
chain_status_t getAngle12BitAdc(uint8_t id, uint16_t *adcValue, unsigned long timeout = 100);
|
||||
|
||||
/**
|
||||
* @brief Retrieves the 8-bit ADC value of the Angle device.
|
||||
*
|
||||
* This function fetches the 8-bit ADC value from the specified Angle device.
|
||||
*
|
||||
* @param id The position of the Angle device in the chain (starting from 1).
|
||||
* @param adcValue Pointer to store the retrieved 8-bit ADC value.
|
||||
* @param timeout Timeout duration in milliseconds (default is 100ms).
|
||||
*
|
||||
* @return The operation status (e.g., CHAIN_OK, CHAIN_TIMEOUT, etc.).
|
||||
*/
|
||||
chain_status_t getAngle8BitAdc(uint8_t id, uint8_t *adcValue, unsigned long timeout = 100);
|
||||
|
||||
/**
|
||||
* @brief Sets the rotation direction change status for the angle device at the specified position in the chain.
|
||||
*
|
||||
* This function sets the rotation direction change status for the angle device. The direction can either be
|
||||
* increasing or decreasing in the clockwise direction. By default, the clockwise direction is set to increasing.
|
||||
*
|
||||
* @param id The position of the angle device in the chain (starting from 1).
|
||||
* @param direction The clockwise direction status. Use `ANGLE_ROTATION_INCREASING` for increasing and
|
||||
* `ANGLE_ROTATION_DECREASING` for decreasing.
|
||||
* @param operationStatus Pointer to store the operation status after execution (1 for success, 0 for failure).
|
||||
* @param saveToFlash Optional parameter to specify whether to save the setting to flash memory (default is 0, no
|
||||
* save).
|
||||
* @param timeout The timeout duration for the operation in milliseconds (default is 100ms).
|
||||
*
|
||||
* @return The operation status (e.g., `CHAIN_OK`, `CHAIN_PARAMETER_ERROR`, etc.).
|
||||
*/
|
||||
chain_status_t setAngleRotationDirection(uint8_t id, angle_rotation_direction_t direction, uint8_t *operationStatus,
|
||||
chain_save_flash_t saveToFlash = CHAIN_SAVE_FLASH_DISABLE,
|
||||
unsigned long timeout = 100);
|
||||
|
||||
/**
|
||||
* @brief Retrieves the current clockwise rotation change status of the angle device at the specified position in
|
||||
* the chain.
|
||||
*
|
||||
* This function gets the current clockwise rotation change status of the angle device. It determines whether the
|
||||
* rotation direction is increasing or decreasing in the clockwise direction.
|
||||
*
|
||||
* @param id The position of the angle device in the chain (starting from 1).
|
||||
* @param direction Pointer to store the current clockwise rotation change status. It will hold
|
||||
* `ANGLE_ROTATION_INCREASING` for increasing and `ANGLE_ROTATION_DECREASING` for decreasing.
|
||||
* @param timeout The timeout duration for the operation in milliseconds (default is 100ms).
|
||||
*
|
||||
* @return The operation status (e.g., `CHAIN_OK`, `CHAIN_TIMEOUT`, etc.).
|
||||
*/
|
||||
chain_status_t getAngleRotationDirection(uint8_t id, angle_rotation_direction_t *direction,
|
||||
unsigned long timeout = 100);
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
#endif // CHAIN_ANGLE_H
|
||||
@@ -182,12 +182,12 @@ typedef enum {
|
||||
CHAIN_KEY_TYPE_CODE = 0x0003, /**< Key device type. */
|
||||
CHAIN_JOYSTICK_TYPE_CODE = 0x0004, /**< Joystick device type. */
|
||||
CHAIN_TOF_TYPE_CODE = 0x0005, /**< TOF device type. */
|
||||
CHAIN_UART_TYPE_CODE = 0x0006, /**< UART device type. */
|
||||
CHAIN_SWITCH_TYPE_CODE = 0x0007, /**< Switch device type. */
|
||||
CHAIN_PEDAL_TYPE_CODE = 0x0008, /**< Pedal device type. */
|
||||
CHAIN_PIR_TYPE_CODE = 0x0009, /**< PIR device type. */
|
||||
CHAIN_MIC_TYPE_CODE = 0x000A, /**< Microphone device type. */
|
||||
CHAIN_BUZZER_TYPE_CODE = 0x000B, /**< Buzzer device type. */
|
||||
// CHAIN_UART_TYPE_CODE = 0x0006, /**< UART device type. */
|
||||
// CHAIN_SWITCH_TYPE_CODE = 0x0007, /**< Switch device type. */
|
||||
// CHAIN_PEDAL_TYPE_CODE = 0x0008, /**< Pedal device type. */
|
||||
// CHAIN_PIR_TYPE_CODE = 0x0009, /**< PIR device type. */
|
||||
// CHAIN_MIC_TYPE_CODE = 0x000A, /**< Microphone device type. */
|
||||
// CHAIN_BUZZER_TYPE_CODE = 0x000B, /**< Buzzer device type. */
|
||||
} chain_device_type_t;
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,295 @@
|
||||
/*
|
||||
*SPDX-FileCopyrightText: 2025 M5Stack Technology CO LTD
|
||||
*
|
||||
*SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include "ChainEncoder/ChainEncoder.hpp"
|
||||
|
||||
chain_status_t ChainEncoder::getEncoderValue(uint8_t id, int16_t *value, unsigned long timeout)
|
||||
{
|
||||
chain_status_t status = CHAIN_OK;
|
||||
|
||||
if (acquireMutex()) {
|
||||
cmdBufferSize = 0;
|
||||
sendPacket(id, CHAIN_ENCODER_GET_VALUE, cmdBuffer, cmdBufferSize);
|
||||
if (waitForData(id, CHAIN_ENCODER_GET_VALUE, timeout)) {
|
||||
if (checkPacket(returnPacket, returnPacketSize)) {
|
||||
*value = (int16_t)((returnPacket[7] << 8) | returnPacket[6]);
|
||||
} else {
|
||||
status = CHAIN_RETURN_PACKET_ERROR;
|
||||
}
|
||||
} else {
|
||||
status = CHAIN_TIMEOUT;
|
||||
}
|
||||
releaseMutex();
|
||||
} else {
|
||||
status = CHAIN_BUSY;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
chain_status_t ChainEncoder::getEncoderIncValue(uint8_t id, int16_t *incValue, unsigned long timeout)
|
||||
{
|
||||
chain_status_t status = CHAIN_OK;
|
||||
|
||||
if (acquireMutex()) {
|
||||
cmdBufferSize = 0;
|
||||
sendPacket(id, CHAIN_ENCODER_GET_INC_VALUE, cmdBuffer, cmdBufferSize);
|
||||
if (waitForData(id, CHAIN_ENCODER_GET_INC_VALUE, timeout)) {
|
||||
if (checkPacket(returnPacket, returnPacketSize)) {
|
||||
*incValue = (int16_t)((returnPacket[7] << 8) | returnPacket[6]);
|
||||
} else {
|
||||
status = CHAIN_RETURN_PACKET_ERROR;
|
||||
}
|
||||
} else {
|
||||
status = CHAIN_TIMEOUT;
|
||||
}
|
||||
releaseMutex();
|
||||
} else {
|
||||
status = CHAIN_BUSY;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
chain_status_t ChainEncoder::resetEncoderValue(uint8_t id, uint8_t *operationStatus, unsigned long timeout)
|
||||
{
|
||||
chain_status_t status = CHAIN_OK;
|
||||
|
||||
if (acquireMutex()) {
|
||||
cmdBufferSize = 0;
|
||||
sendPacket(id, CHAIN_ENCODER_RESET_VALUE, cmdBuffer, cmdBufferSize);
|
||||
if (waitForData(id, CHAIN_ENCODER_RESET_VALUE, timeout)) {
|
||||
if (checkPacket(returnPacket, returnPacketSize)) {
|
||||
*operationStatus = returnPacket[6];
|
||||
} else {
|
||||
status = CHAIN_RETURN_PACKET_ERROR;
|
||||
}
|
||||
} else {
|
||||
status = CHAIN_TIMEOUT;
|
||||
}
|
||||
releaseMutex();
|
||||
} else {
|
||||
status = CHAIN_BUSY;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
chain_status_t ChainEncoder::resetEncoderIncValue(uint8_t id, uint8_t *operationStatus, unsigned long timeout)
|
||||
{
|
||||
chain_status_t status = CHAIN_OK;
|
||||
|
||||
if (acquireMutex()) {
|
||||
cmdBufferSize = 0;
|
||||
sendPacket(id, CHAIN_ENCODER_RESET_INC_VALUE, cmdBuffer, cmdBufferSize);
|
||||
if (waitForData(id, CHAIN_ENCODER_RESET_INC_VALUE, timeout)) {
|
||||
if (checkPacket(returnPacket, returnPacketSize)) {
|
||||
*operationStatus = returnPacket[6];
|
||||
} else {
|
||||
status = CHAIN_RETURN_PACKET_ERROR;
|
||||
}
|
||||
} else {
|
||||
status = CHAIN_TIMEOUT;
|
||||
}
|
||||
releaseMutex();
|
||||
} else {
|
||||
status = CHAIN_BUSY;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
chain_status_t ChainEncoder::setEncoderABDirect(uint8_t id, encoder_ab_t direct, uint8_t *operationStatus,
|
||||
chain_save_flash_t saveToFlash, unsigned long timeout)
|
||||
{
|
||||
chain_status_t status = CHAIN_OK;
|
||||
|
||||
if (acquireMutex()) {
|
||||
cmdBufferSize = 0;
|
||||
cmdBuffer[cmdBufferSize++] = direct;
|
||||
cmdBuffer[cmdBufferSize++] = saveToFlash;
|
||||
sendPacket(id, CHAIN_ENCODER_SET_AB_STATUS, cmdBuffer, cmdBufferSize);
|
||||
if (waitForData(id, CHAIN_ENCODER_SET_AB_STATUS, timeout)) {
|
||||
if (checkPacket(returnPacket, returnPacketSize)) {
|
||||
*operationStatus = returnPacket[6];
|
||||
} else {
|
||||
status = CHAIN_RETURN_PACKET_ERROR;
|
||||
}
|
||||
} else {
|
||||
status = CHAIN_TIMEOUT;
|
||||
}
|
||||
releaseMutex();
|
||||
} else {
|
||||
status = CHAIN_BUSY;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
chain_status_t ChainEncoder::getEncoderABDirect(uint8_t id, encoder_ab_t *direct, unsigned long timeout)
|
||||
{
|
||||
chain_status_t status = CHAIN_OK;
|
||||
|
||||
if (acquireMutex()) {
|
||||
cmdBufferSize = 0;
|
||||
sendPacket(id, CHAIN_ENCODER_GET_AB_STATUS, cmdBuffer, cmdBufferSize);
|
||||
if (waitForData(id, CHAIN_ENCODER_GET_AB_STATUS, timeout)) {
|
||||
if (checkPacket(returnPacket, returnPacketSize)) {
|
||||
*direct = (encoder_ab_t)returnPacket[6];
|
||||
} else {
|
||||
status = CHAIN_RETURN_PACKET_ERROR;
|
||||
}
|
||||
} else {
|
||||
status = CHAIN_TIMEOUT;
|
||||
}
|
||||
releaseMutex();
|
||||
} else {
|
||||
status = CHAIN_BUSY;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
chain_status_t ChainEncoder::getEncoderButtonStatus(uint8_t id, uint8_t *buttonStatus, unsigned long timeout)
|
||||
{
|
||||
chain_status_t status = CHAIN_OK;
|
||||
|
||||
if (acquireMutex()) {
|
||||
cmdBufferSize = 0;
|
||||
sendPacket(id, CHAIN_BUTTON_GET_STATUS, cmdBuffer, cmdBufferSize);
|
||||
if (waitForData(id, CHAIN_BUTTON_GET_STATUS, timeout)) {
|
||||
if (checkPacket(returnPacket, returnPacketSize)) {
|
||||
*buttonStatus = returnPacket[6];
|
||||
} else {
|
||||
status = CHAIN_RETURN_PACKET_ERROR;
|
||||
}
|
||||
} else {
|
||||
status = CHAIN_TIMEOUT;
|
||||
}
|
||||
releaseMutex();
|
||||
} else {
|
||||
status = CHAIN_BUSY;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
chain_status_t ChainEncoder::setEncoderButtonTriggerInterval(uint8_t id, button_double_click_time_t doubleClickTimeout,
|
||||
button_long_press_time_t longPressTimeout,
|
||||
uint8_t *operationStatus, unsigned long timeout)
|
||||
{
|
||||
chain_status_t status = CHAIN_OK;
|
||||
|
||||
if (acquireMutex()) {
|
||||
cmdBufferSize = 0;
|
||||
cmdBuffer[cmdBufferSize++] = doubleClickTimeout;
|
||||
cmdBuffer[cmdBufferSize++] = longPressTimeout;
|
||||
sendPacket(id, CHAIN_BUTTON_SET_TRIGGER_TIMEOUT, cmdBuffer, cmdBufferSize);
|
||||
if (waitForData(id, CHAIN_BUTTON_SET_TRIGGER_TIMEOUT, timeout)) {
|
||||
if (checkPacket(returnPacket, returnPacketSize)) {
|
||||
*operationStatus = returnPacket[6];
|
||||
} else {
|
||||
status = CHAIN_RETURN_PACKET_ERROR;
|
||||
}
|
||||
} else {
|
||||
status = CHAIN_TIMEOUT;
|
||||
}
|
||||
releaseMutex();
|
||||
} else {
|
||||
status = CHAIN_BUSY;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
chain_status_t ChainEncoder::getEncoderButtonTriggerInterval(uint8_t id, button_double_click_time_t *doubleClickTimeout,
|
||||
button_long_press_time_t *longPressTimeout,
|
||||
unsigned long timeout)
|
||||
{
|
||||
chain_status_t status = CHAIN_OK;
|
||||
|
||||
if (acquireMutex()) {
|
||||
cmdBufferSize = 0;
|
||||
sendPacket(id, CHAIN_BUTTON_GET_TRIGGER_TIMEOUT, cmdBuffer, cmdBufferSize);
|
||||
if (waitForData(id, CHAIN_BUTTON_GET_TRIGGER_TIMEOUT, timeout)) {
|
||||
if (checkPacket(returnPacket, returnPacketSize)) {
|
||||
*doubleClickTimeout = (button_double_click_time_t)returnPacket[6];
|
||||
*longPressTimeout = (button_long_press_time_t)returnPacket[7];
|
||||
} else {
|
||||
status = CHAIN_RETURN_PACKET_ERROR;
|
||||
}
|
||||
} else {
|
||||
status = CHAIN_TIMEOUT;
|
||||
}
|
||||
releaseMutex();
|
||||
} else {
|
||||
status = CHAIN_BUSY;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
chain_status_t ChainEncoder::setEncoderButtonMode(uint8_t id, chain_button_mode_t mode, uint8_t *operationStatus,
|
||||
unsigned long timeout)
|
||||
{
|
||||
chain_status_t status = CHAIN_OK;
|
||||
|
||||
if (acquireMutex()) {
|
||||
cmdBufferSize = 0;
|
||||
cmdBuffer[cmdBufferSize++] = mode;
|
||||
sendPacket(id, CHAIN_BUTTON_SET_MODE, cmdBuffer, cmdBufferSize);
|
||||
if (waitForData(id, CHAIN_BUTTON_SET_MODE, timeout)) {
|
||||
if (checkPacket(returnPacket, returnPacketSize)) {
|
||||
*operationStatus = returnPacket[6];
|
||||
} else {
|
||||
status = CHAIN_RETURN_PACKET_ERROR;
|
||||
}
|
||||
} else {
|
||||
status = CHAIN_TIMEOUT;
|
||||
}
|
||||
releaseMutex();
|
||||
} else {
|
||||
status = CHAIN_BUSY;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
chain_status_t ChainEncoder::getEncoderButtonMode(uint8_t id, chain_button_mode_t *mode, unsigned long timeout)
|
||||
{
|
||||
chain_status_t status = CHAIN_OK;
|
||||
|
||||
if (acquireMutex()) {
|
||||
cmdBufferSize = 0;
|
||||
sendPacket(id, CHAIN_BUTTON_GET_MODE, cmdBuffer, cmdBufferSize);
|
||||
if (waitForData(id, CHAIN_BUTTON_GET_MODE, timeout)) {
|
||||
if (checkPacket(returnPacket, returnPacketSize)) {
|
||||
*mode = (chain_button_mode_t)returnPacket[6];
|
||||
} else {
|
||||
status = CHAIN_RETURN_PACKET_ERROR;
|
||||
}
|
||||
} else {
|
||||
status = CHAIN_TIMEOUT;
|
||||
}
|
||||
releaseMutex();
|
||||
} else {
|
||||
status = CHAIN_BUSY;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
bool ChainEncoder::getEncoderButtonPressStatus(uint8_t id, chain_button_press_type_t *buttonStatus)
|
||||
{
|
||||
processIncomingData();
|
||||
bool findStatus = 0;
|
||||
record_info_t result;
|
||||
findStatus = findRecord(&recordList, id, &result);
|
||||
if (findStatus == true) {
|
||||
*buttonStatus = (chain_button_press_type_t)result.type;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -0,0 +1,210 @@
|
||||
/*
|
||||
*SPDX-FileCopyrightText: 2025 M5Stack Technology CO LTD
|
||||
*
|
||||
*SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#ifndef _CHAIN_ENCODER_HPP_
|
||||
#define _CHAIN_ENCODER_HPP_
|
||||
|
||||
#include "ChainCommon/ChainCommon.hpp"
|
||||
|
||||
/**
|
||||
* @brief Enumeration for AB pin status.
|
||||
*/
|
||||
typedef enum {
|
||||
ENCODER_AB = 0x00, /**< AB encoding, clockwise increment. */
|
||||
ENCODER_BA = 0x01, /**< BA encoding, counterclockwise increment. */
|
||||
} encoder_ab_t;
|
||||
|
||||
/**
|
||||
* @brief Command types for the Chain_Encoder.
|
||||
*/
|
||||
typedef enum {
|
||||
CHAIN_ENCODER_GET_VALUE = 0x10, /**< Get encoder value. */
|
||||
CHAIN_ENCODER_GET_INC_VALUE = 0x11, /**< Get encoder increment value. */
|
||||
CHAIN_ENCODER_RESET_VALUE = 0x13, /**< Reset encoder value. */
|
||||
CHAIN_ENCODER_RESET_INC_VALUE = 0x14, /**< Reset encoder increment value. */
|
||||
CHAIN_ENCODER_SET_AB_STATUS = 0x15, /**< Set AB status, 0->AB, 1->BA. */
|
||||
CHAIN_ENCODER_GET_AB_STATUS = 0x16, /**< Get AB status, 0->AB, 1->BA. */
|
||||
} chain_encoder_cmd_t;
|
||||
|
||||
class ChainEncoder : virtual public ChainCommon {
|
||||
public:
|
||||
/**
|
||||
* @brief Retrieves the encoder value.
|
||||
*
|
||||
* This function retrieves the current encoder value for the specified device in the chain.
|
||||
*
|
||||
* @param id The position of the device in the chain (starting from 1).
|
||||
* @param value Pointer to the variable where the encoder value will be stored.
|
||||
* @param timeout The timeout period for the operation (default is 100ms).
|
||||
*
|
||||
* @return Returns the status of the operation (e.g., success or failure).
|
||||
*/
|
||||
chain_status_t getEncoderValue(uint8_t id, int16_t *value, unsigned long timeout = 100);
|
||||
|
||||
/**
|
||||
* @brief Retrieves the encoder increment value.
|
||||
*
|
||||
* This function retrieves the increment value of the encoder for the specified device in the chain.
|
||||
* The increment value represents the change in encoder position since the last read.
|
||||
*
|
||||
* @param id The position of the device in the chain (starting from 1).
|
||||
* @param incValue Pointer to the variable where the increment value will be stored.
|
||||
* @param timeout The timeout period for the operation (default is 100ms).
|
||||
*
|
||||
* @return Returns the status of the operation (e.g., success or failure).
|
||||
*/
|
||||
chain_status_t getEncoderIncValue(uint8_t id, int16_t *incValue, unsigned long timeout = 100);
|
||||
|
||||
/**
|
||||
* @brief Resets the encoder value.
|
||||
*
|
||||
* This function resets the encoder value to its initial state for the specified device in the chain.
|
||||
* It is typically used when the encoder value needs to be cleared or initialized.
|
||||
*
|
||||
* @param id The position of the device in the chain (starting from 1).
|
||||
* @param operationStatus Pointer to the variable where the operation status (1 for success, 0 for failure) will be
|
||||
* stored.
|
||||
* @param timeout The timeout period for the operation (default is 100ms).
|
||||
*
|
||||
* @return Returns the status of the operation (1 for success, 0 for failure).
|
||||
*/
|
||||
chain_status_t resetEncoderValue(uint8_t id, uint8_t *operationStatus, unsigned long timeout = 100);
|
||||
|
||||
/**
|
||||
* @brief Resets the encoder increment value.
|
||||
*
|
||||
* This function resets the encoder increment value to its initial state for the specified device in the chain.
|
||||
* It is typically used when the increment value needs to be cleared or initialized.
|
||||
*
|
||||
* @param id The position of the device in the chain (starting from 1).
|
||||
* @param operationStatus Pointer to the variable where the operation status (1 for success, 0 for failure) will be
|
||||
* stored.
|
||||
* @param timeout The timeout period for the operation (default is 100ms).
|
||||
*
|
||||
* @return Returns the status of the operation (1 for success, 0 for failure).
|
||||
*/
|
||||
chain_status_t resetEncoderIncValue(uint8_t id, uint8_t *operationStatus, unsigned long timeout = 100);
|
||||
|
||||
/**
|
||||
* @brief Sets the encoder AB direction.
|
||||
*
|
||||
* This function sets the AB direction of the encoder for the specified device in the chain.
|
||||
* AB means the direction increases clockwise, and BA means the direction increases counterclockwise.
|
||||
*
|
||||
* @param id The position of the device in the chain (starting from 1).
|
||||
* @param direct The direction to set: 0 for AB (clockwise increase), 1 for BA (counterclockwise increase).
|
||||
* @param operationStatus Pointer to the variable where the operation status (1 for success, 0 for failure) will be
|
||||
* stored.
|
||||
* @param saveToFlash Optional parameter to save the setting to flash memory (default is CHAIN_SAVE_FLASH_DISABLE,
|
||||
* not save).
|
||||
* @param timeout The timeout period for the operation (default is 100ms).
|
||||
*
|
||||
* @return Returns the status of the operation (1 for success, 0 for failure).
|
||||
*/
|
||||
chain_status_t setEncoderABDirect(uint8_t id, encoder_ab_t direct, uint8_t *operationStatus,
|
||||
chain_save_flash_t saveToFlash = CHAIN_SAVE_FLASH_DISABLE,
|
||||
unsigned long timeout = 100);
|
||||
|
||||
/**
|
||||
* @brief Gets the encoder AB direction.
|
||||
*
|
||||
* This function retrieves the current AB direction of the encoder for the specified device in the chain.
|
||||
* AB means the direction increases clockwise, and BA means the direction increases counterclockwise.
|
||||
*
|
||||
* @param id The position of the device in the chain (starting from 1).
|
||||
* @param direct Pointer to the variable where the direction (0 for AB, 1 for BA) will be stored.
|
||||
* @param timeout The timeout period for the operation (default is 100ms).
|
||||
*
|
||||
* @return Returns the status of the operation (1 for success, 0 for failure).
|
||||
*/
|
||||
chain_status_t getEncoderABDirect(uint8_t id, encoder_ab_t *direct, unsigned long timeout = 100);
|
||||
|
||||
/**
|
||||
* @brief Get the status of the encoder button device at a specified chain position.
|
||||
*
|
||||
* Retrieves whether the encoder button is currently pressed.
|
||||
*
|
||||
* @param id The encoder button device position in the chain (starting from 1).
|
||||
* @param buttonStatus Pointer to receive the status (1: pressed, 0: not pressed).
|
||||
* @param timeout Operation timeout in milliseconds (default 100ms).
|
||||
* @return Operation result status code (e.g., CHAIN_OK, CHAIN_PARAMETER_ERROR).
|
||||
*/
|
||||
chain_status_t getEncoderButtonStatus(uint8_t id, uint8_t *buttonStatus, unsigned long timeout = 100);
|
||||
|
||||
/**
|
||||
* @brief Set the double-click and long-press interval times for the encoder button device.
|
||||
*
|
||||
* Configure the required interval durations (in milliseconds) to detect double-click and long-press actions.
|
||||
*
|
||||
* @param id The position of the encoder button device in the chain (starting from 1).
|
||||
* @param doubleClickIntervalMs Pointer to a variable storing the double-click interval time in milliseconds.
|
||||
* @param longPressIntervalMs Pointer to a variable storing the long-press interval time in milliseconds.
|
||||
* @param operationStatus Pointer to store the operation result (1 for success, 0 for failure).
|
||||
* @param timeout Operation timeout in milliseconds (default is 100 ms).
|
||||
*
|
||||
* @return Operation status code, e.g., CHAIN_OK for success, CHAIN_PARAMETER_ERROR for invalid parameters.
|
||||
*/
|
||||
chain_status_t setEncoderButtonTriggerInterval(uint8_t id, button_double_click_time_t doubleClickIntervalMs,
|
||||
button_long_press_time_t longPressIntervalMs,
|
||||
uint8_t *operationStatus, unsigned long timeout = 100);
|
||||
|
||||
/**
|
||||
* @brief Get the double-click and long-press interval times for the encoder button device.
|
||||
*
|
||||
* Retrieve the current interval durations (in milliseconds) used for detecting double-click and long-press actions.
|
||||
*
|
||||
* @param id The position of the encoder button device in the chain (starting from 1).
|
||||
* @param doubleClickIntervalMs Pointer to a variable storing the double-click interval time in milliseconds.
|
||||
* @param longPressIntervalMs Pointer to a variable storing the long-press interval time in milliseconds.
|
||||
* @param timeout Operation timeout in milliseconds (default is 100 ms).
|
||||
*
|
||||
* @return Operation status code, e.g., CHAIN_OK for success, CHAIN_PARAMETER_ERROR for invalid parameters.
|
||||
*/
|
||||
chain_status_t getEncoderButtonTriggerInterval(uint8_t id, button_double_click_time_t *doubleClickIntervalMs,
|
||||
button_long_press_time_t *longPressIntervalMs,
|
||||
unsigned long timeout = 100);
|
||||
|
||||
/**
|
||||
* @brief Set the operating mode of the encoder button device.
|
||||
*
|
||||
* Defines the button behavior mode, such as single-click, double-click, or long-press.
|
||||
*
|
||||
* @param id The encoder device position in the chain (starting from 1).
|
||||
* @param mode Desired encoder button mode.
|
||||
* @param operationStatus Pointer to receive operation result (1: success, 0: failure).
|
||||
* @param timeout Operation timeout in milliseconds (default 100ms).
|
||||
* @return Operation result status code.
|
||||
*/
|
||||
chain_status_t setEncoderButtonMode(uint8_t id, chain_button_mode_t mode, uint8_t *operationStatus,
|
||||
unsigned long timeout = 100);
|
||||
|
||||
/**
|
||||
* @brief Get the current operating mode of the encoder button device.
|
||||
*
|
||||
* Retrieves the current button mode setting.
|
||||
*
|
||||
* @param id The encoder device position in the chain (starting from 1).
|
||||
* @param mode Pointer to receive the current mode.
|
||||
* @param timeout Operation timeout in milliseconds (default 100ms).
|
||||
* @return Operation result status code.
|
||||
*/
|
||||
chain_status_t getEncoderButtonMode(uint8_t id, chain_button_mode_t *mode, unsigned long timeout = 100);
|
||||
|
||||
/**
|
||||
* @brief Get the press type status of the encoder button device.
|
||||
*
|
||||
* Determines the type of press event (single, double, long).
|
||||
*
|
||||
* @param id The encoder device position in the chain (starting from 1).
|
||||
* @param encoderPressType Pointer to receive the press type.
|
||||
* @return true if the encoder button is currently pressed; false otherwise.
|
||||
*/
|
||||
bool getEncoderButtonPressStatus(uint8_t id, chain_button_press_type_t *encoderPressType);
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
#endif // _CHAIN_ENCODER_HPP_
|
||||
@@ -60,8 +60,7 @@ chain_status_t ChainJoystick::getJoystickMappedRange(uint8_t id, uint16_t *mapBu
|
||||
{
|
||||
chain_status_t status = CHAIN_OK;
|
||||
|
||||
if(size != JOYSTICK_MAP_SIZE)
|
||||
{
|
||||
if (size != JOYSTICK_MAP_SIZE) {
|
||||
return CHAIN_PARAMETER_ERROR;
|
||||
}
|
||||
|
||||
@@ -93,8 +92,7 @@ chain_status_t ChainJoystick::setJoystickMappedRange(uint8_t id, uint16_t *mapBu
|
||||
{
|
||||
chain_status_t status = CHAIN_OK;
|
||||
|
||||
if(size != JOYSTICK_MAP_SIZE)
|
||||
{
|
||||
if (size != JOYSTICK_MAP_SIZE) {
|
||||
return CHAIN_PARAMETER_ERROR;
|
||||
}
|
||||
|
||||
@@ -119,7 +117,7 @@ chain_status_t ChainJoystick::setJoystickMappedRange(uint8_t id, uint16_t *mapBu
|
||||
} else {
|
||||
status = CHAIN_BUSY;
|
||||
}
|
||||
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -200,9 +198,10 @@ chain_status_t ChainJoystick::getJoystickButtonStatus(uint8_t id, uint8_t *keySt
|
||||
return status;
|
||||
}
|
||||
|
||||
chain_status_t ChainJoystick::setJoystickButtonTriggerInterval(uint8_t id, button_double_click_time_t doubleClickIntervalMs,
|
||||
button_long_press_time_t longPressIntervalMs, uint8_t *operationStatus,
|
||||
unsigned long timeout)
|
||||
chain_status_t ChainJoystick::setJoystickButtonTriggerInterval(uint8_t id,
|
||||
button_double_click_time_t doubleClickIntervalMs,
|
||||
button_long_press_time_t longPressIntervalMs,
|
||||
uint8_t *operationStatus, unsigned long timeout)
|
||||
{
|
||||
chain_status_t status = CHAIN_OK;
|
||||
|
||||
@@ -228,8 +227,10 @@ chain_status_t ChainJoystick::setJoystickButtonTriggerInterval(uint8_t id, butto
|
||||
return status;
|
||||
}
|
||||
|
||||
chain_status_t ChainJoystick::getJoystickButtonTriggerInterval(uint8_t id, button_double_click_time_t *doubleClickIntervalMs,
|
||||
button_long_press_time_t *longPressIntervalMs, unsigned long timeout)
|
||||
chain_status_t ChainJoystick::getJoystickButtonTriggerInterval(uint8_t id,
|
||||
button_double_click_time_t *doubleClickIntervalMs,
|
||||
button_long_press_time_t *longPressIntervalMs,
|
||||
unsigned long timeout)
|
||||
{
|
||||
chain_status_t status = CHAIN_OK;
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#ifndef _CHAIN_JOYSTICK_HPP_
|
||||
#define _CHAIN_JOYSTICK_HPP_
|
||||
|
||||
#include <ChainCommon/ChainCommon.hpp>
|
||||
#include "ChainCommon/ChainCommon.hpp"
|
||||
|
||||
/**
|
||||
* @brief Size of the joystick map buffer.
|
||||
@@ -155,8 +155,8 @@ public:
|
||||
* @return Operation status code, e.g., CHAIN_OK for success, CHAIN_PARAMETER_ERROR for invalid parameters.
|
||||
*/
|
||||
chain_status_t setJoystickButtonTriggerInterval(uint8_t id, button_double_click_time_t doubleClickIntervalMs,
|
||||
button_long_press_time_t longPressIntervalMs, uint8_t *operationStatus,
|
||||
unsigned long timeout = 100);
|
||||
button_long_press_time_t longPressIntervalMs,
|
||||
uint8_t *operationStatus, unsigned long timeout = 100);
|
||||
|
||||
/**
|
||||
* @brief Get the double-click and long-press interval times for the joystick button device.
|
||||
@@ -171,8 +171,8 @@ public:
|
||||
* @return Operation status code, e.g., CHAIN_OK for success, CHAIN_PARAMETER_ERROR for invalid parameters.
|
||||
*/
|
||||
chain_status_t getJoystickButtonTriggerInterval(uint8_t id, button_double_click_time_t *doubleClickIntervalMs,
|
||||
button_long_press_time_t *longPressIntervalMs,
|
||||
unsigned long timeout = 100);
|
||||
button_long_press_time_t *longPressIntervalMs,
|
||||
unsigned long timeout = 100);
|
||||
|
||||
/**
|
||||
* @brief Set the operating mode of the joystick button device.
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#ifndef _CHAIN_KEY_HPP_
|
||||
#define _CHAIN_KEY_HPP_
|
||||
|
||||
#include <ChainCommon/ChainCommon.hpp>
|
||||
#include "ChainCommon/ChainCommon.hpp"
|
||||
|
||||
class ChainKey : virtual public ChainCommon {
|
||||
public:
|
||||
|
||||
@@ -0,0 +1,218 @@
|
||||
/*
|
||||
*SPDX-FileCopyrightText: 2025 M5Stack Technology CO LTD
|
||||
*
|
||||
*SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include "ChainToF/ChainToF.hpp"
|
||||
|
||||
chain_status_t ChainToF::getToFDistance(uint8_t id, uint16_t *distance, unsigned long timeout)
|
||||
{
|
||||
chain_status_t status = CHAIN_OK;
|
||||
|
||||
if (acquireMutex()) {
|
||||
cmdBufferSize = 0;
|
||||
sendPacket(id, CHAIN_TOF_GET_DISTANCE, cmdBuffer, cmdBufferSize);
|
||||
if (waitForData(id, CHAIN_TOF_GET_DISTANCE, timeout)) {
|
||||
if (checkPacket(returnPacket, returnPacketSize)) {
|
||||
*distance = (returnPacket[7] << 8) | returnPacket[6];
|
||||
} else {
|
||||
status = CHAIN_RETURN_PACKET_ERROR;
|
||||
}
|
||||
} else {
|
||||
status = CHAIN_TIMEOUT;
|
||||
}
|
||||
releaseMutex();
|
||||
} else {
|
||||
status = CHAIN_BUSY;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
chain_status_t ChainToF::setToFMeasureTime(uint8_t id, uint8_t time, uint8_t *operationStatus, unsigned long timeout)
|
||||
{
|
||||
chain_status_t status = CHAIN_OK;
|
||||
|
||||
if (time < TOF_MEASUREMENT_TIME_MIN || time > TOF_MEASUREMENT_TIME_MAX) {
|
||||
return CHAIN_PARAMETER_ERROR;
|
||||
}
|
||||
|
||||
if (acquireMutex()) {
|
||||
cmdBufferSize = 0;
|
||||
cmdBuffer[cmdBufferSize++] = time;
|
||||
sendPacket(id, CHAIN_TOF_SET_MEASURE_TIME, cmdBuffer, cmdBufferSize);
|
||||
if (waitForData(id, CHAIN_TOF_SET_MEASURE_TIME, timeout)) {
|
||||
if (checkPacket(returnPacket, returnPacketSize)) {
|
||||
*operationStatus = returnPacket[6];
|
||||
} else {
|
||||
status = CHAIN_RETURN_PACKET_ERROR;
|
||||
}
|
||||
} else {
|
||||
status = CHAIN_TIMEOUT;
|
||||
}
|
||||
releaseMutex();
|
||||
} else {
|
||||
status = CHAIN_BUSY;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
chain_status_t ChainToF::getToFMeasureTime(uint8_t id, uint8_t *time, unsigned long timeout)
|
||||
{
|
||||
chain_status_t status = CHAIN_OK;
|
||||
|
||||
if (acquireMutex()) {
|
||||
cmdBufferSize = 0;
|
||||
sendPacket(id, CHAIN_TOF_GET_MEASURE_TIME, cmdBuffer, cmdBufferSize);
|
||||
|
||||
if (waitForData(id, CHAIN_TOF_GET_MEASURE_TIME, timeout)) {
|
||||
if (checkPacket(returnPacket, returnPacketSize)) {
|
||||
*time = returnPacket[6];
|
||||
} else {
|
||||
status = CHAIN_RETURN_PACKET_ERROR;
|
||||
}
|
||||
} else {
|
||||
status = CHAIN_TIMEOUT;
|
||||
}
|
||||
releaseMutex();
|
||||
} else {
|
||||
status = CHAIN_BUSY;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
chain_status_t ChainToF::setToFMeasureMode(uint8_t id, chain_tof_mode_t mode, uint8_t *operationStatus,
|
||||
unsigned long timeout)
|
||||
{
|
||||
chain_status_t status = CHAIN_OK;
|
||||
|
||||
if (mode < CHAIN_TOF_MODE_STOP || mode > CHAIN_TOF_MODE_CONTINUOUS) {
|
||||
return CHAIN_PARAMETER_ERROR;
|
||||
}
|
||||
|
||||
if (acquireMutex()) {
|
||||
cmdBufferSize = 0;
|
||||
cmdBuffer[cmdBufferSize++] = mode;
|
||||
sendPacket(id, CHAIN_TOF_SET_MEASURE_MODE, cmdBuffer, cmdBufferSize);
|
||||
if (waitForData(id, CHAIN_TOF_SET_MEASURE_MODE, timeout)) {
|
||||
if (checkPacket(returnPacket, returnPacketSize)) {
|
||||
*operationStatus = returnPacket[6];
|
||||
} else {
|
||||
status = CHAIN_RETURN_PACKET_ERROR;
|
||||
}
|
||||
} else {
|
||||
status = CHAIN_TIMEOUT;
|
||||
}
|
||||
releaseMutex();
|
||||
} else {
|
||||
status = CHAIN_BUSY;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
chain_status_t ChainToF::getToFMeasureMode(uint8_t id, chain_tof_mode_t *mode, unsigned long timeout)
|
||||
{
|
||||
chain_status_t status = CHAIN_OK;
|
||||
|
||||
if (acquireMutex()) {
|
||||
cmdBufferSize = 0;
|
||||
sendPacket(id, CHAIN_TOF_GET_MEASURE_MODE, cmdBuffer, cmdBufferSize);
|
||||
if (waitForData(id, CHAIN_TOF_GET_MEASURE_MODE, timeout)) {
|
||||
if (checkPacket(returnPacket, returnPacketSize)) {
|
||||
*mode = (chain_tof_mode_t)returnPacket[6];
|
||||
} else {
|
||||
status = CHAIN_RETURN_PACKET_ERROR;
|
||||
}
|
||||
} else {
|
||||
status = CHAIN_TIMEOUT;
|
||||
}
|
||||
releaseMutex();
|
||||
} else {
|
||||
status = CHAIN_BUSY;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
chain_status_t ChainToF::setToFMeasureStatus(uint8_t id, chain_tof_measure_status_t measureStatus,
|
||||
uint8_t *operationStatus, unsigned long timeout)
|
||||
{
|
||||
chain_status_t status = CHAIN_OK;
|
||||
|
||||
if (measureStatus < CHAIN_TOF_STATUS_STOP || measureStatus > CHAIN_TOF_STATUS_START) {
|
||||
return CHAIN_PARAMETER_ERROR;
|
||||
}
|
||||
|
||||
if (acquireMutex()) {
|
||||
cmdBufferSize = 0;
|
||||
cmdBuffer[cmdBufferSize++] = measureStatus;
|
||||
sendPacket(id, CHAIN_TOF_SET_MEASURE_STATUS, cmdBuffer, cmdBufferSize);
|
||||
if (waitForData(id, CHAIN_TOF_SET_MEASURE_STATUS, timeout)) {
|
||||
if (checkPacket(returnPacket, returnPacketSize)) {
|
||||
*operationStatus = returnPacket[6];
|
||||
} else {
|
||||
status = CHAIN_RETURN_PACKET_ERROR;
|
||||
}
|
||||
} else {
|
||||
status = CHAIN_TIMEOUT;
|
||||
}
|
||||
releaseMutex();
|
||||
} else {
|
||||
status = CHAIN_BUSY;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
chain_status_t ChainToF::getToFMeasureStatus(uint8_t id, chain_tof_measure_status_t *measureStatus,
|
||||
unsigned long timeout)
|
||||
{
|
||||
chain_status_t status = CHAIN_OK;
|
||||
|
||||
if (acquireMutex()) {
|
||||
cmdBufferSize = 0;
|
||||
sendPacket(id, CHAIN_TOF_GET_MEASURE_STATUS, cmdBuffer, cmdBufferSize);
|
||||
if (waitForData(id, CHAIN_TOF_GET_MEASURE_STATUS, timeout)) {
|
||||
if (checkPacket(returnPacket, returnPacketSize)) {
|
||||
*measureStatus = (chain_tof_measure_status_t)returnPacket[6];
|
||||
} else {
|
||||
status = CHAIN_RETURN_PACKET_ERROR;
|
||||
}
|
||||
} else {
|
||||
status = CHAIN_TIMEOUT;
|
||||
}
|
||||
releaseMutex();
|
||||
} else {
|
||||
status = CHAIN_BUSY;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
chain_status_t ChainToF::getToFMeasureCompleteFlag(uint8_t id, uint8_t *completeFlag, unsigned long timeout)
|
||||
{
|
||||
chain_status_t status = CHAIN_OK;
|
||||
|
||||
if (acquireMutex()) {
|
||||
cmdBufferSize = 0;
|
||||
sendPacket(id, CHAIN_TOF_GET_MEASURE_COMPLETE_FLAG, cmdBuffer, cmdBufferSize);
|
||||
if (waitForData(id, CHAIN_TOF_GET_MEASURE_COMPLETE_FLAG, timeout)) {
|
||||
if (checkPacket(returnPacket, returnPacketSize)) {
|
||||
*completeFlag = returnPacket[6];
|
||||
} else {
|
||||
status = CHAIN_RETURN_PACKET_ERROR;
|
||||
}
|
||||
} else {
|
||||
status = CHAIN_TIMEOUT;
|
||||
}
|
||||
releaseMutex();
|
||||
} else {
|
||||
status = CHAIN_BUSY;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 M5Stack Technology CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#ifndef _CHAIN_TOF_HPP_
|
||||
#define _CHAIN_TOF_HPP_
|
||||
|
||||
#include "ChainCommon/ChainCommon.hpp"
|
||||
|
||||
/**
|
||||
* @brief Minimum allowable measurement time for the Chain_ToF sensor (in milliseconds).
|
||||
*
|
||||
* Shorter integration time results in faster updates but lower accuracy.
|
||||
*/
|
||||
#define TOF_MEASUREMENT_TIME_MIN (20)
|
||||
|
||||
/**
|
||||
* @brief Maximum allowable measurement time for the Chain_ToF sensor (in milliseconds).
|
||||
*
|
||||
* Longer integration time generally increases accuracy but reduces the update rate.
|
||||
*/
|
||||
#define TOF_MEASUREMENT_TIME_MAX (200)
|
||||
|
||||
/**
|
||||
* @brief Command codes for Chain_ToF sensor operations.
|
||||
*
|
||||
* These codes are used when communicating with the device over the chain protocol.
|
||||
*/
|
||||
typedef enum {
|
||||
CHAIN_TOF_GET_DISTANCE = 0x50, /**< Retrieve distance measurement from the sensor */
|
||||
CHAIN_TOF_SET_MEASURE_TIME = 0x51, /**< Set the measurement (integration) time */
|
||||
CHAIN_TOF_GET_MEASURE_TIME = 0x52, /**< Get the current measurement time */
|
||||
CHAIN_TOF_SET_MEASURE_MODE = 0x53, /**< Set the measurement mode (STOP / SINGLE / CONTINUOUS) */
|
||||
CHAIN_TOF_GET_MEASURE_MODE = 0x54, /**< Get the current measurement mode */
|
||||
CHAIN_TOF_SET_MEASURE_STATUS = 0x55, /**< Start or stop measurement explicitly */
|
||||
CHAIN_TOF_GET_MEASURE_STATUS = 0x56, /**< Get the current measurement status */
|
||||
CHAIN_TOF_GET_MEASURE_COMPLETE_FLAG = 0x57 /**< Check if the latest measurement is complete */
|
||||
} chain_tof_cmd_t;
|
||||
|
||||
/**
|
||||
* @brief Measure modes for Chain_ToF sensor.
|
||||
*/
|
||||
typedef enum {
|
||||
CHAIN_TOF_MODE_STOP = 0, /**< Stop measurements; sensor idle */
|
||||
CHAIN_TOF_MODE_SINGLE = 1, /**< Take a single measurement then stop */
|
||||
CHAIN_TOF_MODE_CONTINUOUS = 2 /**< Continue measuring until stopped */
|
||||
} chain_tof_mode_t;
|
||||
|
||||
/**
|
||||
* @brief Measure status values for Chain_ToF sensor.
|
||||
*
|
||||
* Used to explicitly start or stop measurements.
|
||||
*/
|
||||
typedef enum {
|
||||
CHAIN_TOF_STATUS_STOP = 0, /**< Stop the measurement process */
|
||||
CHAIN_TOF_STATUS_START = 1 /**< Start the measurement process */
|
||||
} chain_tof_measure_status_t;
|
||||
|
||||
/**
|
||||
* @class ChainToF
|
||||
* @brief Interface for controlling chained Time-of-Flight (ToF) distance sensors.
|
||||
*
|
||||
* The ChainToF class inherits from ChainCommon and provides high-level methods
|
||||
* for querying measurements, setting timing and modes, and controlling the measurement lifecycle.
|
||||
* Sensors are addressed by their position in the chain starting from index 1.
|
||||
*/
|
||||
class ChainToF : virtual public ChainCommon {
|
||||
public:
|
||||
/**
|
||||
* @brief Get the measured distance from the ToF device.
|
||||
*
|
||||
* @param id Position of the ToF device in the chain (starting from 1).
|
||||
* @param distance Pointer to store the measured distance (in mm).
|
||||
* @param timeout Timeout duration in milliseconds (default: 100 ms).
|
||||
* @return Operation status (e.g., CHAIN_OK, CHAIN_TIMEOUT).
|
||||
*/
|
||||
chain_status_t getToFDistance(uint8_t id, uint16_t *distance, unsigned long timeout = 100);
|
||||
|
||||
/**
|
||||
* @brief Set the measurement timing (integration time) for the ToF device.
|
||||
*
|
||||
* @param id Position of the ToF device in the chain (starting from 1).
|
||||
* @param time Measure time in milliseconds.
|
||||
* Must be between TOF_MEASUREMENT_TIME_MIN and TOF_MEASUREMENT_TIME_MAX.
|
||||
* @param operationStatus Pointer to store the device's execution result (1 = accepted, 0 = rejected).
|
||||
* @param timeout Timeout duration in milliseconds (default: 100 ms).
|
||||
* @return Operation status.
|
||||
*/
|
||||
chain_status_t setToFMeasureTime(uint8_t id, uint8_t time, uint8_t *operationStatus, unsigned long timeout = 100);
|
||||
|
||||
/**
|
||||
* @brief Get the current measurement timing from the ToF device.
|
||||
*
|
||||
* @param id Position of the ToF device in the chain (starting from 1).
|
||||
* @param time Pointer to store the measurement time in milliseconds.
|
||||
* @param timeout Timeout duration in milliseconds (default: 100 ms).
|
||||
* @return Operation status.
|
||||
*/
|
||||
chain_status_t getToFMeasureTime(uint8_t id, uint8_t *time, unsigned long timeout = 100);
|
||||
|
||||
/**
|
||||
* @brief Set the measurement mode.
|
||||
*
|
||||
* @param id Position of the ToF device in the chain (starting from 1).
|
||||
* @param mode Desired measurement mode (`chain_tof_mode_t`).
|
||||
* @param operationStatus Pointer to store the device's execution result (1 = accepted, 0 = rejected).
|
||||
* @param timeout Timeout duration in milliseconds (default: 100 ms).
|
||||
* @return Operation status.
|
||||
*/
|
||||
chain_status_t setToFMeasureMode(uint8_t id, chain_tof_mode_t mode, uint8_t *operationStatus,
|
||||
unsigned long timeout = 100);
|
||||
|
||||
/**
|
||||
* @brief Get the current measurement mode from the ToF device.
|
||||
*
|
||||
* @param id Position of the ToF device in the chain (starting from 1).
|
||||
* @param mode Pointer to store the retrieved mode (`chain_tof_mode_t`).
|
||||
* @param timeout Timeout duration in milliseconds (default: 100 ms).
|
||||
* @return Operation status.
|
||||
*/
|
||||
chain_status_t getToFMeasureMode(uint8_t id, chain_tof_mode_t *mode, unsigned long timeout = 100);
|
||||
|
||||
/**
|
||||
* @brief Set the measurement status (START / STOP) for the ToF device.
|
||||
*
|
||||
* Explicitly starts or stops the measurement process, regardless of the current mode.
|
||||
*
|
||||
* @param id Position of the ToF device in the chain (starting from 1).
|
||||
* @param measureStatus Desired status (`chain_tof_measure_status_t`).
|
||||
* @param operationStatus Pointer to store the device's execution result (1 = accepted, 0 = rejected).
|
||||
* @param timeout Timeout duration in milliseconds (default: 100 ms).
|
||||
* @return Operation status.
|
||||
*/
|
||||
chain_status_t setToFMeasureStatus(uint8_t id, chain_tof_measure_status_t measureStatus, uint8_t *operationStatus,
|
||||
unsigned long timeout = 100);
|
||||
|
||||
/**
|
||||
* @brief Get the current measurement status (START / STOP) from the ToF device.
|
||||
*
|
||||
* @param id Position of the ToF device in the chain (starting from 1).
|
||||
* @param measureStatus Pointer to store the retrieved status (`chain_tof_measure_status_t`).
|
||||
* @param timeout Timeout duration in milliseconds (default: 100 ms).
|
||||
* @return Operation status.
|
||||
*/
|
||||
chain_status_t getToFMeasureStatus(uint8_t id, chain_tof_measure_status_t *measureStatus,
|
||||
unsigned long timeout = 100);
|
||||
|
||||
/**
|
||||
* @brief Check whether the current measurement cycle is complete.
|
||||
*
|
||||
* This flag can be used to determine if the latest measurement data is ready for retrieval.
|
||||
*
|
||||
* @param id Position of the ToF device in the chain (starting from 1).
|
||||
* @param completeFlag Pointer to store the completion flag (1 = complete, 0 = not ready).
|
||||
* @param timeout Timeout duration in milliseconds (default: 100 ms).
|
||||
* @return Operation status.
|
||||
*/
|
||||
chain_status_t getToFMeasureCompleteFlag(uint8_t id, uint8_t *completeFlag, unsigned long timeout = 100);
|
||||
|
||||
private:
|
||||
// No private members declared, potentially reserved for internal buffer or state tracking.
|
||||
};
|
||||
|
||||
#endif // _CHAIN_TOF_HPP_
|
||||
Reference in New Issue
Block a user