This commit is contained in:
Forairaaaaa
2026-04-15 10:08:15 +08:00
parent 57bbda98bd
commit cd12f67cd6
59 changed files with 6241 additions and 10 deletions
@@ -0,0 +1,138 @@
/*
* SPDX-FileCopyrightText: 2026 M5Stack Technology CO LTD
*
* SPDX-License-Identifier: MIT
*/
#include <Arduino.h>
#include <M5StackChan.h>
void setup()
{
/* Init StackChan */
M5StackChan.begin();
/* Setup display */
M5StackChan.Display().setTextSize(2);
M5StackChan.Display().setTextScroll(true);
M5StackChan.Display().setTextColor(TFT_YELLOW);
M5StackChan.Display().printf("> Touch the top to start\n");
M5StackChan.Display().setTextColor(TFT_GREENYELLOW);
// Set to false if high-frequency updates are needed
// M5StackChan.Motion.setAutoAngleSyncEnabled(false);
}
void loop()
{
M5StackChan.update();
if (M5StackChan.TouchSensor.wasPressed()) {
delay(200);
/* Angle unit: 10 = 1 degrees, Speed range: 0~1000 */
/* Range X: -1280 ~ 1280 (-128° ~ 128°), Range Y: 0 ~ 900 (0° ~ 90°) */
/* Move to home position (0, 0) */
M5StackChan.Motion.goHome();
M5StackChan.Display().printf("> Go home\n");
delay(2000);
/* Move X servo to 100° */
M5StackChan.Motion.moveX(1000, 200);
M5StackChan.Display().printf("> Turn Left (Slow: 200)\n");
delay(2000);
/* Move X servo to -100° */
M5StackChan.Motion.moveX(-1000, 200);
M5StackChan.Display().printf("> Turn Right (Slow: 200)\n");
delay(2000);
/* Move X servo to 100° */
M5StackChan.Motion.moveX(1000, 800);
M5StackChan.Display().printf("> Turn Left (Fast: 800)\n");
delay(2000);
/* Move X servo to -100° */
M5StackChan.Motion.moveX(-1000, 800);
M5StackChan.Display().printf("> Turn Right (Fast: 800)\n");
delay(2000);
M5StackChan.Motion.goHome();
M5StackChan.Display().printf("> Go home\n");
delay(2000);
/* Move Y servo to 90° */
M5StackChan.Motion.moveY(900, 200);
M5StackChan.Display().printf("> Look Up (Slow: 200)\n");
delay(2000);
/* Move Y servo to 0° */
M5StackChan.Motion.moveY(0, 200);
M5StackChan.Display().printf("> Look Down (Slow: 200)\n");
delay(2000);
/* Move Y servo to 90° */
M5StackChan.Motion.moveY(900, 800);
M5StackChan.Display().printf("> Look Up (Fast: 800)\n");
delay(2000);
/* Move Y servo to 0° */
M5StackChan.Motion.moveY(0, 800);
M5StackChan.Display().printf("> Look Down (Fast: 800)\n");
delay(2000);
/* Move X servo to 60°, Y servo to 70° */
M5StackChan.Motion.move(600, 700);
M5StackChan.Display().printf("> Top Left\n");
delay(2000);
M5StackChan.Motion.goHome();
M5StackChan.Display().printf("> Go home\n");
delay(2000);
/* Move X servo to -60°, Y servo to 70° */
M5StackChan.Motion.move(-600, 700);
M5StackChan.Display().printf("> Top Right\n");
delay(2000);
M5StackChan.Motion.goHome();
M5StackChan.Display().printf("> Go home\n");
delay(2000);
/* Only X axis supports continuous 360° rotation. Y axis does not. */
/* Velocity range: -1000 ~ 1000 (Negative: CW, Positive: CCW) */
/* Rotate clockwise */
M5StackChan.Motion.rotateX(-300);
M5StackChan.Display().printf("> Rotate clockwise (Slow: 300)\n");
delay(3000);
/* Rotate clockwise */
M5StackChan.Motion.rotateX(-800);
M5StackChan.Display().printf("> Rotate clockwise (Fast: 800)\n");
delay(3000);
M5StackChan.Motion.goHome();
M5StackChan.Display().printf("> Go home\n");
delay(2000);
/* Rotate counter-clockwise */
M5StackChan.Motion.rotateX(300);
M5StackChan.Display().printf("> Rotate counter-clockwise (Slow: 300)\n");
delay(3000);
/* Rotate counter-clockwise */
M5StackChan.Motion.rotateX(800);
M5StackChan.Display().printf("> Rotate counter-clockwise (Fast: 800)\n");
delay(3000);
M5StackChan.Motion.goHome();
M5StackChan.Display().printf("> Go home\n");
delay(2000);
M5StackChan.Display().setTextColor(TFT_YELLOW);
M5StackChan.Display().printf("> Touch the top to start\n");
M5StackChan.Display().setTextColor(TFT_GREENYELLOW);
}
delay(100);
}
+111
View File
@@ -0,0 +1,111 @@
/*
* SPDX-FileCopyrightText: 2026 M5Stack Technology CO LTD
*
* SPDX-License-Identifier: MIT
*/
#include <Arduino.h>
#include <M5StackChan.h>
/**
* @brief
* Angle unit: 10 = 1 degrees, Speed range: 0~1000
* Range X: -1280 ~ 1280 (-128° ~ 128°), Range Y: 0 ~ 900 (0° ~ 90°)
*
*/
struct Keyframe_t {
int x = 0;
int y = 0;
int speed = 500;
uint32_t interval = 0;
};
/* Move around */
std::vector<Keyframe_t> dance_1 = {
{0, 0, 500, 1000}, // Home, 1s
{600, 200, 800, 500}, // Left, fast
{-600, 200, 800, 500}, // Right, fast
{600, 200, 800, 500}, // Left, fast
{-600, 200, 800, 500}, // Right, fast
{0, 800, 900, 400}, // Look Up
{0, 0, 900, 400}, // Look Down
{0, 800, 900, 400}, // Look Up
{0, 0, 900, 400}, // Look Down
{800, 700, 700, 500}, // Top Left
{-800, 700, 700, 500}, // Top Right
{800, 700, 700, 500}, // Top Left
{-800, 700, 700, 500}, // Top Right
{0, 0, 500, 1000} // Back Home
};
/* Shake */
std::vector<Keyframe_t> dance_2 = {
{0, 0, 500, 1000}, // Home
{300, 0, 750, 250}, // Shake Left
{-300, 0, 750, 250}, // Shake Right
{300, 0, 750, 250}, // Shake Left
{-300, 0, 750, 250}, // Shake Right
{300, 0, 750, 250}, // Shake Left
{-300, 0, 750, 250}, // Shake Right
{0, 0, 500, 1000} // Back Home
};
/* Nod */
std::vector<Keyframe_t> dance_3 = {
{0, 0, 500, 1000}, // Home
{0, 350, 900, 250}, // Nod Up
{0, 0, 900, 250}, // Nod Down
{0, 350, 900, 250}, // Nod Up
{0, 0, 900, 250}, // Nod Down
{0, 350, 900, 250}, // Nod Up
{0, 0, 900, 250}, // Nod Down
{0, 0, 500, 500} // Back Home
};
std::vector<std::vector<Keyframe_t>*> dances = {
&dance_1,
&dance_2,
&dance_3,
};
static int dance_index = 0;
void setup()
{
/* Init StackChan */
M5StackChan.begin();
/* Setup display */
M5StackChan.Display().setTextSize(2);
M5StackChan.Display().setTextScroll(true);
M5StackChan.Display().setTextColor(TFT_YELLOW);
M5StackChan.Display().printf("> Touch the top to start\n");
M5StackChan.Display().setTextColor(TFT_GREENYELLOW);
// Disable auto angle sync for smooth and continuous movement
M5StackChan.Motion.setAutoAngleSyncEnabled(false);
}
void loop()
{
M5StackChan.update();
if (M5StackChan.TouchSensor.wasPressed()) {
delay(200);
/* Perform dance */
M5StackChan.Display().printf("> Dance #%d!\n", dance_index + 1);
for (const auto& frame : *dances[dance_index]) {
M5StackChan.Motion.move(frame.x, frame.y, frame.speed);
delay(frame.interval);
}
M5StackChan.Display().printf("> Finished!\n");
/* Next dance */
dance_index = (dance_index + 1) % dances.size();
M5StackChan.Display().setTextColor(TFT_YELLOW);
M5StackChan.Display().printf("> Touch the top to start\n");
M5StackChan.Display().setTextColor(TFT_GREENYELLOW);
}
delay(100);
}
@@ -0,0 +1,111 @@
/*
* SPDX-FileCopyrightText: 2026 M5Stack Technology CO LTD
*
* SPDX-License-Identifier: MIT
*/
#include <Arduino.h>
#include <M5StackChan.h>
namespace {
constexpr uint16_t kBackgroundColor = TFT_BLACK;
constexpr uint16_t kBorderColor = TFT_WHITE;
constexpr uint16_t kTopButtonColor = 0x39C7;
constexpr uint16_t kTopButtonPressedColor = 0x2204;
constexpr uint16_t kBottomButtonColor = 0x03EF;
constexpr uint16_t kBottomButtonPressedColor = 0x01E8;
constexpr uint16_t kTextColor = TFT_WHITE;
enum class ButtonZone {
None,
SetHome,
GoHome,
};
ButtonZone pressed_zone = ButtonZone::None;
ButtonZone getButtonZone(const int16_t y, const int16_t height)
{
return y < (height / 2) ? ButtonZone::SetHome : ButtonZone::GoHome;
}
void drawButton(const int16_t x, const int16_t y, const int16_t w, const int16_t h, const uint16_t color,
const char* line_1, const char* line_2)
{
auto& display = M5StackChan.Display();
display.fillRect(x, y, w, h, color);
display.drawRect(x, y, w, h, kBorderColor);
display.setTextDatum(middle_center);
display.setTextColor(kTextColor, color);
display.setTextSize(2);
display.drawString(line_1, x + w / 2, y + h / 2 - 12);
display.drawString(line_2, x + w / 2, y + h / 2 + 12);
}
void drawUi(ButtonZone active_zone)
{
auto& display = M5StackChan.Display();
const int16_t width = display.width();
const int16_t height = display.height();
const int16_t gap = 8;
const int16_t button_x = 8;
const int16_t button_w = width - button_x * 2;
const int16_t half_h = (height - gap) / 2;
display.startWrite();
display.fillScreen(kBackgroundColor);
display.fillRect(0, half_h, width, gap, kBackgroundColor);
drawButton(button_x, 8, button_w, half_h - 12,
active_zone == ButtonZone::SetHome ? kTopButtonPressedColor : kTopButtonColor, "set current postion",
"as home");
drawButton(button_x, half_h + gap + 4, button_w, height - (half_h + gap + 12),
active_zone == ButtonZone::GoHome ? kBottomButtonPressedColor : kBottomButtonColor, "move to", "home");
display.endWrite();
}
} // namespace
void setup()
{
/* Init StackChan */
M5StackChan.begin();
/* Setup display */
M5StackChan.Display().setTextScroll(false);
drawUi(ButtonZone::None);
}
void loop()
{
M5StackChan.update();
auto& display = M5StackChan.Display();
const int16_t screen_height = display.height();
int16_t touch_x = 0;
int16_t touch_y = 0;
const bool touching = display.getTouch(&touch_x, &touch_y);
if (touching) {
const ButtonZone current_zone = getButtonZone(touch_y, screen_height);
if (current_zone != pressed_zone) {
pressed_zone = current_zone;
drawUi(pressed_zone);
}
} else if (pressed_zone != ButtonZone::None) {
const ButtonZone released_zone = pressed_zone;
pressed_zone = ButtonZone::None;
drawUi(ButtonZone::None);
if (released_zone == ButtonZone::SetHome) {
M5StackChan.Motion.setCurrentPostionAsHome();
} else if (released_zone == ButtonZone::GoHome) {
M5StackChan.Motion.goHome();
}
}
delay(16);
}