Невозможно заставить ЖК-дисплей и гироскоп работать вместе.

Я новичок в этом, поэтому в моем коде есть несколько плохих методов, когда я пытаюсь ввести ЖК-дисплей в цикл. Моя проблема в том, что задержка ЖК-дисплея и задержка сервопривода мешают друг другу. Как я могу их изолировать? Мне нравится отклик сервопривода в 50 мс. Но мне бы хотелось обновить ЖК-дисплей за 200 мс. Но в их текущем состоянии они дают очень странный ответ, если я держу их обоих в курсе. Сервопривод вращается медленнее, как будто добавляет обе задержки. Если я отключу ЖК-дисплей, все вернется в норму. Есть идеи? Может ли кто-нибудь показать мне правильный метод, чтобы я мог расширяться в будущем? Спасибо!!!!

У меня пока это получилось:

#include<Wire.h>
const int MPU_addr=0x68;  // I2C-адрес MPU-6050
int16_t AcX,AcY,AcZ,Tmp,GyX,GyY,GyZ;

//СЕРВО
#include <Servo.h>
Servo microservo1;
int servo_pin = 8;

//СООБРАЖЕННЫЕ ЗНАЧЕНИЯ
int16_t AcXmapped, AcYmapped, AcZmapped;

//ЖК-дисплей
#include <LiquidCrystal.h>
const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
//инициализирует библиотеку

void setup(){

  //НАСТРОЙКА СЕРВО
  microservo1.attach ( servo_pin );

  //НАСТРОЙКА ПРОВОДА
  Wire.begin();
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x6B);  // регистр PWR_MGMT_1
  Wire.write(0);     // устанавливаем на ноль (пробуждает MPU-6050)
  Wire.endTransmission(true);
  Serial.begin(9600);
  Serial.println("Transmission Line Initializing"); 
  delay(350);
  //печать("3"); печать("2"); печать("1");
  Serial.println("3");
  delay(1000);
  Serial.println("2");
  delay(1000);
  Serial.println("1");
  delay(1000);

  //НАСТРОЙКА ЖК-дисплея
  lcd.begin(16,2); //настраиваем количество столбцов и строк на ЖК-дисплее
  digitalWrite(9,1); //может пойти либо 0 --> 1 или НИЗКИЙ --> ВЫСОКИЙ || включает или выключает ЖК-дисплей ||
  analogWrite(6,70); //настройка контрастности текста на ЖК-дисплее
}

void loop(){

  //ПЕТЛЯ
  Wire.beginTransmission(MPU_addr); 
  Wire.write(0x3B);  // начиная с регистра 0x3B (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(MPU_addr,14,true);  // запрашиваем всего 14 регистров
  AcX=Wire.read()<<8|Wire.read();  // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
  AcY=Wire.read()<<8|Wire.read();  // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
  AcZ=Wire.read()<<8|Wire.read();  // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
  Tmp=Wire.read()<<8|Wire.read();  // 0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L)
  GyX=Wire.read()<<8|Wire.read();  // 0x43 (GYRO_XOUT_H) & 0x44 (ГИРО_XOUT_L)
  GyY=Wire.read()<<8|Wire.read();  // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
  GyZ=Wire.read()<<8|Wire.read();  // 0x47 (GYRO_ZOUT_H) & 0x48 (ГИРО_ZOUT_L)
  Serial.print(" | AcX = "); Serial.print(AcX);
  Serial.print(" | AcY = "); Serial.print(AcY);
  Serial.print(" | AcZ = "); Serial.print(AcZ);
  //Serial.print(" | Tmp = "); Serial.print(Tmp/340.00+36.53); //уравнение температуры в градусах Цельсия из таблицы данных
  Serial.print(" | GyX = "); Serial.print(GyX);
  Serial.print(" | GyY = "); Serial.print(GyY);
  Serial.print(" | GyZ = "); Serial.println(GyZ);

  // СООБЩЕНИЕ значений, например, из AcX в AcX, отображается так, чтобы они были лучшими значениями для сервоуправления.
  //установите AcX внутри карты в отрицательное значение, если вы хотите инвертировать вращение сервопривода.
  AcXmapped = map (AcX, -17000, 17000, 0, 180); //РУЛОН
  AcYmapped = map (AcY, -17000, 17000, 0, 180); //ПОДАЧА
  AcZmapped = map (AcZ, -17000, 17000, 0, 180); //рыскание

  //СЕРВОПЕТКА
  microservo1.write(AcYmapped);
  //50 мс отклик между движениями
  delay(50); 

  //ЖК-ЦИКЛ
  lcd.setCursor(0,0); //устанавливаем курсор на (0,0)
  lcd.print(AcYmapped);
  delay(50);

  //ЭКСТРА ЖК-дисплей
  lcd.noAutoscroll(); //отключаем автопрокрутку
  lcd.clear(); //очищаем экран для следующего цикла


}

, 👍0


2 ответа


1

Сначала загрузите полученные сообщения об ошибках . Во-вторых, ЖК-дисплей не может отображать значения в реальном времени, потому что, когда гироскоп перемещается, Arduino блокирует ЖК-дисплей и считывает данные с гироскопа, потому что вы не используете кодирование планирования. Я рекомендую вам использовать миллис вместо задержек и использовать многозадачный код, например freertos.

,

Я исправил сообщение об ошибке, НО (проблема с скобками) мой код все еще доставляет мне проблемы. Мои задержки объединяются между сервоприводом и ЖК-дисплеем. Знаете ли вы, как я могу изолировать их, чтобы дать им обоим возможность отсрочки?, @ardoknow

Используйте millis(), если вы считаете, что необходимы данные в реальном времени. Я заметил, что вы используете функцию lcd.noautoscroll() под дополнительным комментарием к ЖК-дисплею, в котором нет необходимости, поскольку ЖК-дисплей по умолчанию не прокручивает символы. Поэтому попробуйте удалить эту функцию. Теперь сначала попробуйте удалить все задержки и запустите свой код, а затем посмотрите, как ведет себя система. На самом деле сервоприводу требуется определенное время при движении. Во время движения сервопривода Arduino блокирует все действия до тех пор, пока сервопривод не достигнет желаемого угла, а затем выполняет остальное в цикле., @user11249082

сервопривод в этом вопросе является сервоприводом для хобби.... он неблокируется, потому что нет обратной связи по положению..... код просто изменяет сигнал ШИМ, который отправляется на сервопривод... сервопривод выполняет автоматически перемещается на нужный угол, @jsotola


0

Вообще не используйте delay(). Вам необходимо провести рефакторинг кода, чтобы записать значение millis() в начале интервала времени, а затем подождать, пока новое значение millis() не станет больше на желаемый интервал. Выполните поиск в Google по запросу «Arduino моргает без задержки» и найдите статьи, в которых обсуждается эта техника кодирования. Это основа программирования для однопоточного микроконтроллера, такого как Arduino, и вам необходимо научиться этому, если вы собираетесь писать для платформы что-либо любой сложности.

,