mirror of
https://github.com/m5stack/StackChan-BSP.git
synced 2026-05-20 11:51:35 -07:00
init
This commit is contained in:
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
Reference in New Issue
Block a user