Как создать функцию, которая будет вводить определенное значение для подзначения массива в зависимости от положения джойстика?

Мне нужно сделать этот проект для класса, а мой учитель не умеет программировать.

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

Правильно, я пытаюсь создать систему, которая вводит значения для пароля, и я получаю код ошибки.

In function 'void loop()':
    incompatible types in assignment of 'int' to 'int [9]'
           PW = inputValues();

Это мой код:

#define joyX A0
#define joyY A1
#define pB 2

int xValue = analogRead(joyX);
int yValue = analogRead(joyY);
int pButton = digitalRead(pB);

bool Left = false;
bool Right = false;
bool Up = false;
bool Down = false;
bool Press = false;

int PW[9];

void setup() {
  Serial.begin(9600);
  pinMode(pB, INPUT);
  digitalWrite(pB, HIGH);
}

void loop() {

  if (yValue < 506) {
    Down = true;
  }
  if (yValue > 600) {
    Up = true;
  }

  if (xValue < 506) {
    Right = true;
  }
  if (xValue > 600) {
    Left = true;
  }
  if (pButton == 0) {
    Press = true;
  }
  /*Serial.print("Press - ");
  Serial.print(Press);
  Serial.print(" UP - ");
  Serial.print(Up);
  Serial.print(" DOWN - ");
  Serial.print(Down);
  Serial.print(" LEFT - ");
  Serial.print(Left);
  Serial.print(" RIGHT - ");
  Serial.println(Right);
*/
  PW = inputValues();


  Serial.print("A: ");
  Serial.println(PW[0]);
  Serial.print("B: ");
  Serial.println(PW[1]);
  Serial.print("C: ");
  Serial.println(PW[2]);
  Serial.print("D: ");
  Serial.println(PW[3]);
  Serial.print("E: ");
  Serial.println(PW[4]);
  Serial.print("F: ");
  Serial.println(PW[5]);
  Serial.print("G: ");
  Serial.println(PW[6]);
  Serial.print("H: ");
  Serial.println(PW[7]);
  Serial.print("I: ");
  Serial.println(PW[8]);

}

int inputValues() {
  int PassW[9];
  int i = 0;
  for (i = 0; i < 9; i++) {
    if ((Left = true) && (Up = true) && (Right = false) && (Down = false)) {
      PW[i] = 1;
      delay(500);
    } else if ((Left = false) && (Up = true) && (Right = false) && (Down = false)) {
      PW[i] = 2;
      delay(500);
    } else if ((Left = false) && (Up = true) && (Right = true) && (Down = false)) {
      PW[i] = 3;
      delay(500);
    } else if ((Left = true) && (Up = false) && (Right = false) && (Down = false)) {
      PW[i] = 4;
      delay(500);
    } else if ((Left = false) && (Up = false) && (Right = true) && (Down = false)) {
      PW[i] = 5;
      delay(500);
    } else if ((Left = true) && (Up = false) && (Right = false) && (Down = true)) {
      PW[i] = 6;
      delay(500);
    } else if ((Left = false) && (Up = false) && (Right = false) && (Down = true)) {
      PW[i] = 7;
      delay(500);
    } else if ((Left = false) && (Up = false) && (Right = true) && (Down = true)) {
      PW[i] = 8;
      delay(500);
    } else if (Press = true) {
      break;
    }
  }
  return PassW;
}

, 👍-1

Обсуждение

if (Left = false) присваивает значение false переменной Left... она не сравнивает значение Left со значением false.... изучите сравнения в С++, @jsotola

if (yValue < 506) Down = true; не думайте, что Down волшебным образом станет false, когда значение поднимется выше 505, @jsotola

вы можете упростить свой код, назначив значения для каждой из четырех позиций джойстика и добавив значения... затем используйте результат в качестве указателя на таблицу поиска... вверх=1, вниз=2, влево=3, вправо= 6, @jsotola


1 ответ


1

К сожалению, в вашем коде много проблем:

  • Линия

      int xValue = analogRead(joyX);
    

    и два других не работают. Вы можете выполнять код (например, analogRead()) только внутри функции, а не в глобальной области. Здесь вы можете указать только начальное значение. Если вы ничего здесь не укажете (то есть просто int xValue;), глобальная переменная будет неявно инициализирована нулем (это не происходит с локальными переменными).

  • Вышеприведенный пункт подразумевает еще одну проблему. Когда вы выполняете analogRead() только один раз, переменная xValue НЕ волшебным образом подключается к аналоговому выводу. Чтение вывода всегда является активной задачей в вашем коде. В противном случае переменная никогда не изменится. Таким образом, вам нужно спланировать код таким образом, чтобы вы каждый раз читали вывод, чтобы знать текущее значение, выполняя analogRead() и присваивая результат своей переменной. То же самое относится и к digitalRead().

  • В функции inputValues() у вас есть несколько экземпляров Left = false и подобных операторов if. Здесь вы хотите провести сравнение (проверить, равна ли переменная Left false, но единственный = является оператором присваивания. Итак, здесь вы присваиваете false переменной, а не проверяете ее. Вместо этого вам нужно использовать ==, который является оператором сравнения на равенство. В качестве примера для вашего операторы if:

      if ((Left == true) && (Up == true) && (Right == false) && (Down == false))
    

    Но вы можете написать еще короче, так как переменные уже являются логическими (точно так же, как и то, что получается в результате сравнения):

      if(Left && Up && !Right && !Down)
    

    помимо логического оператора И && здесь можно увидеть оператор отрицания !, который инвертирует значение, следующее за ним. Таким образом, если Right равно false, то !Right равно true. Вы можете прочитать эту строку как если влево и вверх, а не вправо и не вниз.

  • В той же функции вы пытаетесь вернуть PassW, который представляет собой массив, который вы создали внутри этой функции как локальную переменную. Во-первых, вам нужно иметь в виду, что локальные переменные помещаются в стек и удаляются, когда программа выходит из их области видимости (в данном случае это функция inputValues()). Таким образом, когда код завершается функция PassW больше не существует, поэтому у вас возникнут проблемы, как только вы попытаетесь получить доступ к возвращаемому значению.

  • В операторах if вы изменяете содержимое глобального массива PW, но также объявляете и возвращаете массив PassW. Вы должны решить, куда вы на самом деле хотите записывать данные.

  • Сообщение об ошибке несовместимые типы при назначении 'int' на 'int [9]' возникает из-за того, что вы объявили функцию как int inputValues(). int в начале указывает, что возвращаемое значение этой функции представляет собой одно целое число, а не массив целых чисел. И вы пытаетесь присвоить это целое число массиву целых чисел PW. Не работает.

  • К сожалению, возвращать массивы в C++ не так просто. В то время как с большинством типов данных фактическое значение переменной копируется, и у вас есть эта независимая копия для работы, это не работает с массивами. Здесь важно понять, как C++ обрабатывает массивы. Давайте посмотрим на ваш массив:

      int PassW[9];
    

    Это массив из 9 целых чисел. Когда вы используете PassW в любом месте своего кода (например, с return PassW), у вас нет полного массива. Вместо этого C++ использует адрес памяти первого элемента массива. Это также называется указателем. Конечно, вы можете вернуть указатель на массив, как вы это делаете, хотя, как описано выше, массив все равно должен существовать, потому что в противном случае этот указатель недействителен. Я понимаю, что это сбивает с толку. Указатели — сложная концепция для понимания.

    Чтобы решить эту проблему, вы должны удалить локальный массив PassW и ничего не возвращать (заменив int inputValues() на void inputValues()). . Вместо этого работайте только с глобально определенными массивами, такими как PW. Тогда вам не нужно беспокоиться об указателях. Вы можете вернуться к этой концепции, когда будете дальше учиться.

  • И последнее, но не менее важное: вам нужно переписать логику программы, так как в настоящее время это беспорядок. Хороший способ сделать это — записывать каждый шаг на обычном языке (не на языке программирования). Это называется псевдокодом. Представьте, что вы будете тем, кто выполняет каждый шаг. Разбейте логику на мельчайшие части. Примером может быть что-то вроде этого:

    Читать ось X джойстика и сохранять ее как xvalue если xvalue ниже 506 исправить если ... повторить все вышесказанное

    Если вы делаете это правильно, то ваш псевдокод можно почти напрямую преобразовать в реальный код C++. Также это поможет вам понять логику, прежде чем погрузиться в проблемы программирования.

Также было бы полезно, если бы вы сделали несколько руководств по C++ из Интернета. Их много.

Надеюсь, ваш проект будет успешным. Дополнительные рекомендации вы можете опубликовать в разделе «Руководство по проекту» на форуме Arduino (поскольку этот сайт представляет собой простой сайт вопросов и ответов, где нет обратной связи)

,