Булева логика с символами для выбора входа двигателя

Контекст кода:

Я пытаюсь управлять двумя двигателями постоянного тока через H-затвор, это означает, что всего имеется 4 входа: Для двигателя постоянного тока 1: Вход 1 (VCC) и Вход 2 (GND). Для двигателя постоянного тока 2: вход 3 (VCC) и вход 2 (земля).

Сводка кода:

Глобальные переменные — это motinpN, которые представляют собой контакты, подключенные к различным входам.

Массив, в котором хранятся разные ШИМ для скорости двигателя.

Char x — переменная, используемая для логической логики.

Затем следует собственно цикл, состоящий из 4 похожих функций, функции "селектор входа" и операторов, которые превращают целые числа, хранящиеся в массивах inpSpeedS[], в скорости двигателя.

Проблема:

Код не войдет в первый цикл, т. е. не продвинется дальше

Serial.println("X равно:"); Серийный.print(x);"

Я хотел бы тогда знать, что я делаю неправильно, чтобы это не сработало?

   int Speed = 0;
const int motinp1 = 2;
const int motinp2 = 3;
const int motinp3 = 4;
const int motinp4 = 5;

char  x = '0';

int inpSpeedS[4]; // Массив для определения скорости каждого отдельного ввода

void setup()
{
  Serial.begin(9600);
  pinMode(motinp1, OUTPUT);
}

void loop() {
  Serial.println("X equals:");
  Serial.print(x);

  if (Serial.available () && (x == '0')) {
    Serial.print("Which input?");
    x = Serial.read();
    Serial.println(x);
  }
  if (Serial.available () && (x == 'a'))
  {
    Serial.println("Input 1 selected");
    inpSpeedS[0] = Serial.parseInt();
    Serial.print("Input 1: ");
    Serial.println(inpSpeedS[0]);
   x = '0'; //сбрасываем x, возвращаемся к выбору ввода
  } if (Serial.available () && (x == 'b'))
  {
    Serial.println("Input 2 selected");
    inpSpeedS[1] = Serial.parseInt();
    Serial.print("Input 2: ");
    Serial.println(inpSpeedS[1]);
   x = '0';
  }
  if (Serial.available () && (x == 'c'))
  {
    Serial.println("Input 3 selected");
    inpSpeedS[2] = Serial.parseInt();
    Serial.println("Input 3: ");
    Serial.print(inpSpeedS[2]);
   x = '0';
  }
  if (Serial.available () && (x == 'd'))
  {
    Serial.println("Input 4 selected");
    inpSpeedS[3] = Serial.parseInt();
    Serial.print("Input 4: ");
    Serial.println(inpSpeedS[3]);
   x = '0';
  }
  analogWrite(motinp1, inpSpeedS[0]);
  analogWrite(motinp2, inpSpeedS[1]);
  analogWrite(motinp3, inpSpeedS[2]);
  analogWrite(motinp4, inpSpeedS[3]);
} 

РЕДАКТИРОВАТЬ. Я превратил символ 0 из строкового литерала null в код ASCII для 0, и то же самое для других символов. Он по-прежнему застрял вне функциональных циклов.

, 👍1

Обсуждение

Как это возможно, что char x = "0"; не говорит вам, что вы назначаете указатель на строку C в переменную char?, @KIIV

@KIIV Я еще не читал книг по C, только прошел курсы Udemy, поэтому, к сожалению, я не знаю, о чем вы говорите, кроме самых поверхностных, которые я могу найти в Google за 10 минут. Не могли бы вы уточнить?, @GeorgeWTrump

Между «0» и «0» существует огромная разница. Первый - это ASCII-значение нулевого символа, второй - указатель на память, где хранится строка, содержащая {'0', '\0'}, @KIIV

Также обратите внимание, что у вас есть переменная тени x в цикле. Вероятно, это не очень хорошая идея., @Delta_G

@Delta_G Может быть, это редактирование все равно следует удалить, @KIIV

Или просто уберите "int" перед x='0';, @Delta_G


1 ответ


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

1

Он кричит на тебя:

sketch_jun13a.ino:7:11: warning: invalid conversion from 'const char*' to 'char' [-fpermissive]

 char  x = "0";

           ^~~

sketch_jun13a.ino: In function 'void loop()':

sketch_jun13a.ino:21:36: warning: comparison with string literal results in unspecified behavior [-Waddress]

   if (Serial.available () && (x == "0")) {

                                    ^~~

sketch_jun13a.ino:21:36: warning: ISO C++ forbids comparison between pointer and integer [-fpermissive]

sketch_jun13a.ino:26:36: warning: comparison with string literal results in unspecified behavior [-Waddress]

   if (Serial.available () && (x == "a"))

                                    ^~~

sketch_jun13a.ino:33:9: warning: invalid conversion from 'const char*' to 'char' [-fpermissive]

     x = "0"; //сбрасываем x, возвращаемся к выбору ввода

         ^~~

sketch_jun13a.ino:34:38: warning: comparison with string literal results in unspecified behavior [-Waddress]

   } if (Serial.available () && (x == "b"))

                                      ^~~


sketch_jun13a.ino:41:9: warning: invalid conversion from 'const char*' to 'char' [-fpermissive]

     x = "0";

         ^~~

sketch_jun13a.ino:43:36: warning: comparison with string literal results in unspecified behavior [-Waddress]

   if (Serial.available () && (x == "c"))

                                    ^~~

sketch_jun13a.ino:50:9: warning: invalid conversion from 'const char*' to 'char' [-fpermissive]

     x = "0";

         ^~~

sketch_jun13a.ino:52:36: warning: comparison with string literal results in unspecified behavior [-Waddress]

   if (Serial.available () && (x == "d"))

                                    ^~~

sketch_jun13a.ino:52:36: warning: ISO C++ forbids comparison between pointer and integer [-fpermissive]

sketch_jun13a.ino:58:9: warning: invalid conversion from 'const char*' to 'char' [-fpermissive]

     x = "0";

         ^~~

По сути, это переменная char с назначенным символьным литералом: char x = '0';

А это строка C: char str[] = "0"; или ее эквивалент: char str[] = {'0', '\0'};. Где '\0' — это так называемый NUL терминальный символ.

Все, что вам нужно знать о строках C

ИЗМЕНИТЬ:

Простая демонстрация "парсера" - она не идеальна, но этого должно хватить:

char  x = '0';

int inpSpeedS[4]; // Массив для определения скорости каждого отдельного ввода

void setup() {
  Serial.begin(9600);
  Serial.println("Select channel [a..d] and speed [0..255]: ");
}

void loop() {

  if (Serial.available() > 1) { // ждем дополнительных символов в буфере
    switch (Serial.read()) {
      case 'a': inpSpeedS[0] = Serial.parseInt(); break;
      case 'b': inpSpeedS[1] = Serial.parseInt(); break;
      case 'c': inpSpeedS[2] = Serial.parseInt(); break;
      case 'd': inpSpeedS[3] = Serial.parseInt(); break;
      default : return; // пропускать недопустимые символы, такие как окончания строк
    }

    Serial.print("Speeds: ");
    for (auto spd : inpSpeedS) {
      Serial.print(' ');
      Serial.print(spd);
    }
    Serial.println();
    Serial.println("Select channel [a..d] and speed [0..255]: ");

    /*
      analogWrite(motinp1, inpSpeedS[0]);
      analogWrite(motinp2, inpSpeedS[1]);
      analogWrite(motinp3, inpSpeedS[2]);
      analogWrite(motinp4, inpSpeedS[3]);
    */

  }
}

И результат:

-> Select channel [a..d] and speed [0..255]:
<- a547
-> Speeds:  547 0 0 0
-> Select channel [a..d] and speed [0..255]:
,

Ах, спасибо, Но по этой логике не следует превращать [code]char x = "0"[/code] в [code]char x = '0'[/code], а затем исправлять цикл? Если да, то что-то еще было не так с циклом, так как он все еще застрял на [code] Serial.println("X Equals:"); Serial.print(x);[/code], @GeorgeWTrump

Вы должны исправить все это, включая «а», «б», «в», «г». Но может быть и другая ошибка, так как код не компилируется из-за пропущенных переменных, которые я поленился дописать, @KIIV

Что ж, если вы хотите помочь дальше, я отредактировал код, чтобы он соответствовал рекомендациям, которые вы дали., @GeorgeWTrump

Кстати, это не зависание, если вы отправите, например, a154, он установит первый канал на 154, но это должно быть установлено один раз, вы не хотите отправлять его каждый цикл. Так же, как вы не хотите отправлять вывод при каждом цикле, @KIIV

@GeorgeWTrump Я добавил немного упрощенный пример, но почему-то работает, @KIIV

Это странно, я не получаю таких же результатов, как вы, используя ваш код? Вы используете Arduino IDE? Кроме того, если подумать, разве Arduino IDE не использует С++?, @GeorgeWTrump

Давайте [продолжим обсуждение в чате](https://chat.stackexchange.com/rooms/109300/discussion-between-kiiv-and-georgewtrump)., @KIIV