Hi @youngil_sohn
I have used Wio terminal to make a little gyro ball demo before. You can read this for some reference.
#include <TFT_eSPI.h> // Include the graphics library (this includes the sprite functions)
TFT_eSPI tft = TFT_eSPI(); // Create object "tft"
TFT_eSprite img = TFT_eSprite(&tft); // Create Sprite object "img" with pointer to "tft" object
// the pointer is used by pushSprite() to push it onto the TFT
#include"LIS3DHTR.h"
LIS3DHTR<TwoWire> lis;
#define SPEED 5 //Higher the quicker
#define COLOR TFT_RED //Color of circle
#define SIZE 18 //Size of Circle
float x_raw, y_raw, z_raw;
float roll, pitch, rollF, pitchF=0;
void setup(void) {
tft.init();
tft.setRotation(0);
Serial.begin(115200);
lis.begin(Wire1);
if (!lis) {
Serial.println("ERROR");
while(1);
}
lis.setOutputDataRate(LIS3DHTR_DATARATE_25HZ); //Data output rate
lis.setFullScaleRange(LIS3DHTR_RANGE_2G); //Scale range set to 2g
}
void loop() {
img.createSprite(TFT_WIDTH, TFT_HEIGHT);
img.fillSprite(TFT_BLACK);
x_raw = lis.getAccelerationX();
y_raw = lis.getAccelerationY();
z_raw = lis.getAccelerationZ();
// Serial.print(x_raw);
// Serial.print(" ");
// Serial.print(x_raw);
// Serial.print(" ");
// Serial.println(z_raw);
roll = atan(y_raw / sqrt(pow(x_raw, 2) + pow(z_raw, 2))) * 180 / PI;
pitch = atan(-1 * x_raw / sqrt(pow(y_raw, 2) + pow(z_raw, 2))) * 180 / PI;
// Low-pass filter
rollF = 0.90 * rollF + 0.10 * roll;
pitchF = 0.90 * pitchF + 0.10 * pitch;
Serial.print(rollF);
Serial.print("/");
Serial.println(pitchF);
// BOTTTOM BOUNDARY
if (TFT_WIDTH/2+(-pitchF)*SPEED >= TFT_WIDTH-SIZE) {
if (TFT_HEIGHT/2+(rollF)*SPEED >= TFT_HEIGHT-SIZE) { // LEFT CORNER
img.fillCircle(TFT_WIDTH-SIZE, TFT_HEIGHT-SIZE, SIZE, COLOR);
img.drawCircle(TFT_WIDTH-SIZE, TFT_HEIGHT-SIZE, SIZE+0.5, TFT_WHITE);
}
else if (TFT_HEIGHT/2+(rollF)*SPEED <= SIZE) { // RIGHT CORNER
img.fillCircle(TFT_WIDTH-SIZE, SIZE, SIZE, COLOR);
img.drawCircle(TFT_WIDTH-SIZE, SIZE, SIZE+0.5, TFT_WHITE);
}
else {
img.fillCircle(TFT_WIDTH-SIZE, TFT_HEIGHT/2+(rollF)*SPEED, SIZE, COLOR);
img.drawCircle(TFT_WIDTH-SIZE, TFT_HEIGHT/2+(rollF)*SPEED, SIZE+0.5, TFT_WHITE);
}
}
// TOP BOUNDARY
else if (TFT_WIDTH/2+(-pitchF)*SPEED <= SIZE) {
if (TFT_HEIGHT/2+(rollF)*SPEED >= TFT_HEIGHT-SIZE) { // LEFT CORNER
img.fillCircle(SIZE, TFT_HEIGHT-SIZE, SIZE, COLOR);
img.drawCircle(SIZE, TFT_HEIGHT-SIZE, SIZE+0.5, TFT_WHITE);
}
else if (TFT_HEIGHT/2+(rollF)*SPEED <= SIZE){ // RIGHT CORNER
img.fillCircle(SIZE, SIZE, SIZE, COLOR);
img.drawCircle(SIZE, SIZE, SIZE+0.5, TFT_WHITE);
}
else {
img.fillCircle(SIZE, TFT_HEIGHT/2+(rollF)*SPEED, SIZE, COLOR);
img.drawCircle(SIZE, TFT_HEIGHT/2+(rollF)*SPEED, SIZE+0.5, TFT_WHITE);
}
}
// LEFT BOUNDARY
else if (TFT_HEIGHT/2+(rollF)*SPEED >= TFT_HEIGHT-SIZE) {
img.fillCircle(TFT_WIDTH/2+(-pitchF)*SPEED, TFT_HEIGHT-SIZE, SIZE, COLOR);
img.drawCircle(TFT_WIDTH/2+(-pitchF)*SPEED, TFT_HEIGHT-SIZE, SIZE+0.5, TFT_WHITE);
}
// RIGHT BOUNDARY
else if (TFT_HEIGHT/2+(rollF)*SPEED <= SIZE) {
img.fillCircle(TFT_WIDTH/2+(-pitchF)*SPEED, SIZE, SIZE, COLOR);
img.drawCircle(TFT_WIDTH/2+(-pitchF)*SPEED, SIZE, SIZE+0.5, TFT_WHITE);
}
//DEFAULT
else {
img.fillCircle(TFT_WIDTH/2+(-pitchF)*SPEED, TFT_HEIGHT/2+(rollF)*SPEED, SIZE, COLOR);
img.drawCircle(TFT_WIDTH/2+(-pitchF)*SPEED, TFT_HEIGHT/2+(rollF)*SPEED, SIZE+0.5, TFT_WHITE);
}
img.pushSprite(0, 0);
img.deleteSprite();
}
You can work out roll and pitch using accelerator readings.