Проведение линии под заданным углом
Я пытаюсь использовать устройство, которое измеряет угол наклона. У меня есть настройка 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, и становится хуже, чем больше значение угла.
Мой код:
#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 для каждого значения угла и рисования линии с фиксированными координатами на основе каждого значения угла. Но это кажется слишком трудоемким и может занять слишком много памяти. Кто-нибудь знает простую формулу, которую я мог бы использовать? Спасибо, что прочитали.
@ar6rider, 👍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);
Возможно, вам придется поэкспериментировать со смещением и радиусом, но я верю, что это приблизит вас к тому, что вы хотите.
- mcufriend 2.4 TFT с ESP8266
- Прокрутите одну строку текста, пока другая строка остается статической на OLED-дисплее SSD1306.
- ILI9341 подсветка мерцает при использовании питания USB от ноутбука
- ESP8266 не работает с MPU 6050 по проводной библиотеке и I2C
- Как читать и записывать EEPROM в ESP8266
- Как сделать выводы Tx и Rx на ESP-8266-01 в выводах GPIO?
- Как навсегда изменить скорость передачи данных ESP8266 (12e)?
- Как заставить 5-вольтовое реле работать с NodeMCU
Привет, спасибо за это, мне придется больше заниматься тригонометрией, но еще раз спасибо, кажется, это работает!, @ar6rider