Проведение линии под заданным углом

esp8266 mpu6050 tft ssd1306

Я пытаюсь использовать устройство, которое измеряет угол наклона. У меня есть настройка ESP8266 + MPU6050 + SSD1306, и мне удалось создать шаткое, но в некоторой степени функционирующее устройство.

Что я хотел бы сделать, так это использовать библиотеку Adafruit_SSD1306 для вызова функции display.DrawLine(x, y, x1, y1, цвет) и вывести линию на измеренный угол на выходе MPU6050.

Экран, который я использую, имеет размер 128 X 64

MPU6050 изначально лежит ровно под углом 180 градусов, но установлен и отображается как 0 градусов наклона. Линия рисуется на экране вертикально и поворачивается вокруг x1 и y1 на 64, 64 соответственно в середине в нижней части экрана.

Если MPU6050 поворачивается влево, как на рисунке, само измерение угла примерно правильное, но индикатор линии показывает больше 30 градусов, чем 45, и становится хуже, чем больше значение угла. line indicator

Мой код:

#include <Adafruit_MPU6050.h>
#include <Wire.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_Sensor.h>

const int MPU_addr=0x68;
int16_t axis_X,axis_Y,axis_Z;

Adafruit_MPU6050 mpu;
Adafruit_SSD1306 display = Adafruit_SSD1306(128, 64, &Wire);

int minVal=265;
int maxVal=402;

double x;
double y;
double z;
int tiltAngle;
double y2;
 
void setup(){
  Serial.begin(9600);
  Serial.println("MPU6050 OLED demo");

  if (!mpu.begin()) {
    Serial.println("Sensor init failed");
    while (1)
      yield();
  }
  Serial.println("Found a MPU-6050 sensor");
  
    // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128x64
    Serial.println(F("SSD1306 allocation failed"));
    for (;;)
      ; // Don't proceed, loop forever
  }
  
  display.display();
  delay(500); // Pause for 2 seconds
  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.setRotation(0);
}
void loop(){
  display.clearDisplay();
  display.setCursor(0, 0);
  
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x3B);
  Wire.endTransmission(false);
  Wire.requestFrom(MPU_addr,14,true);
  axis_X=Wire.read()<<8|Wire.read();
  axis_Y=Wire.read()<<8|Wire.read();
  axis_Z=Wire.read()<<8|Wire.read();
    int xAng = map(axis_X,minVal,maxVal,-90,90);
    int yAng = map(axis_Y,minVal,maxVal,-90,90);
    int zAng = map(axis_Z,minVal,maxVal,-90,90);

     x= RAD_TO_DEG * (atan2(-yAng, -zAng)+PI);
     y= RAD_TO_DEG * (atan2(-xAng, -zAng)+PI);
     z= RAD_TO_DEG * (atan2(-yAng, -xAng)+PI);

     tiltAngle = (int) x - 180; // мы хотим, чтобы угол наклона был равен 0 градусам
     display.println(" ");
     display.println(" ");
     display.println(" ");

     // display only positive angle values for either direction of tilt
     if(tiltAngle > 0){ display.print(tiltAngle);}
     else if (tiltAngle < 0) { display.print(tiltAngle * -1);}
     else {display.print(tiltAngle);}

     
     display.drawLine(-tiltAngle + 64, 0,64,64,WHITE);
     display.display();
     delay(100);  
}

Я знаю, что для моей первой координаты y мне нужно будет использовать какую-то формулу, чтобы линия двигалась вниз от 0 (в верхней части экрана) по мере увеличения угла наклона. Я надеюсь, что кто-нибудь сможет указать мне правильное направление для рисования линии под углом, заданным MPU6050.

Я действительно рассматривал возможность использования операторов case для каждого значения угла и рисования линии с фиксированными координатами на основе каждого значения угла. Но это кажется слишком трудоемким и может занять слишком много памяти. Кто-нибудь знает простую формулу, которую я мог бы использовать? Спасибо, что прочитали.

, 👍1


1 ответ


Лучший ответ:

1

Используйте функции тригонометрии (sin() и cos ()), чтобы получить правильные координаты x и y.

Я бы подумал о замене вашей команды DrawLine() чем-то подобным (непроверенным), если предположить, что угол наклона составляет от -90 до +90 градусов (при 0 градусах прямо вверх), и вы хотите нарисовать линию под этим углом от начала координат (63, 63) с радиусом 64.

float tiltAngleRad = tiltAngle * DEG_TO_RAD; // преобразовать угол в радианах
int xEnd = 63 + 64 * sin (tiltAngleRad); // конец X-координата смещения и радиус
int yEnd = 63 - 64 * cos (tiltAngleRad); // конец y-координата смещения и радиус
display.drawLine (63, 63, xEnd, yEnd);

Возможно, вам придется поэкспериментировать со смещением и радиусом, но я верю, что это приблизит вас к тому, что вы хотите.

,

Привет, спасибо за это, мне придется больше заниматься тригонометрией, но еще раз спасибо, кажется, это работает!, @ar6rider