Код студента: функция карты не работает

Мы сделали этот код в классе:

 int red = 6;
  int green = 7;
  int blue = 8;
  int pot = A0;
  int potVal = 0;
  int chosenColor = 0;


void setup() {
  // put your setup code here, to run once:
  pinMode(red, OUTPUT);
  pinMode(green, OUTPUT);
  pinMode(blue, OUTPUT);
  pinMode(pot, INPUT);
  Serial.begin (9600);
}

void loop() {
  // put your main code here, to run repeatedly:
  potVal = analogRead(pot);
  chosenColor = map(potVal, 0, 1023, 1, 3);
  if(chosenColor = 1) {
    redCycle();
  }

  else {
    analogWrite(red,255);
  }

  if(chosenColor = 2) {
    greenCycle();
  }

  else {
    analogWrite(green,255);
  }


  if(chosenColor = 3) {
    blueCycle();
  }

  else {
    analogWrite(blue,255);
  }
  Serial.println(chosenColor);
  Serial.println(potVal);
  delay(500);
}

void redCycle() { 
    analogWrite(red,0);
  for(int i=0; i < 256; i+=5) {
    analogWrite(red, i);
  }
}

void greenCycle() {
  analogWrite(green,0);
  for(int i=0; i < 256; i+=5) {
    analogWrite(green, i);
  }
}

void blueCycle() {
  analogWrite(blue,0);
  for(int i=0; i < 256; i+=5) {
    analogWrite(blue, i);
  }
}

Когда мы открываем последовательный монитор, мы обнаруживаем, что selectedColor всегда равен 3, независимо от того, что читает potVal. Я уверен, что это что-то простое, но мы не можем найти, где ошибка. Пожалуйста, помогите.

, 👍1

Обсуждение

analogWrite() не работает с выводами 7 и 8, только с выводами, помеченными символом "~"., @Edgar Bonet

Хорошо, это одна проблема, о которой мы не подумали! Спасибо. Все еще не уверен, почему функция карты не работает., @Gabe Ruiz

chosenColor = 3 означает «пусть chosenColor принимает значение 3»., @Edgar Bonet


4 ответа


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

3

Как указал Эдгар Боне, "chosenColor = 3 означает "пусть selectedColor принимает значение 3"". То есть ваш potVal = AnalogRead(pot); selectedColor = map(potVal, 0, 1023, 1, 3); последовательность вполне может работать, но к тому времени, когда вы дойдете до Serial.println(chosenColor);, вы изменили chosenColor на 3.

Во-первых, оператор if(chosenColor = 1) {...} изменяет chosenColor на 1. Затем оператор if(chosenColor = 2) { ...} изменяет chosenColor на 2. Наконец, if(chosenColor = 3) {...} изменяет chosenColor на 3, непосредственно перед выводом текущего значения chosenColor.

Если вы хотите сравнить два числовых значения на равенство, используйте == вместо =.

,

Ага! Я понимаю. Поэтому мне нужно использовать ==. Мы изменим это., @Gabe Ruiz


1

Вы путаете = (назначить) с == (сравнить).

например.

Неправильно! ...

if (chosenColor = 3)  // это присваивает 3 выбранному цвету

Правильно:

if (chosenColor == 3)   // сравнить

Все еще не знаю, почему функция карты не работает.

Вы только что предположили, что это не работает. Прежде чем делать такие предположения, выполните Serial print, чтобы показать, какое значение возвращает функция карты. (Сразу после вызова map, а не далее в коде).

,

Я думал, что <= будет означать меньше или равно чем. Как бы я сделал больше или равно?, @Gabe Ruiz

<= читается как «меньше или равно»; >= означает «больше или равно»., @Mathieu K.


0

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

В таблице ниже я показываю результат карта(potVal, 0, 1023, 1, 3). Столбец с пометкой «не округлено» — это то, что вы бы получили, если бы отображение было выполнено с плавающей запятой. Последний столбец это округленное значение, которое вы фактически получаете из map():

potVal  not rounded  rounded
----------------------------
    0     1.00000       1
            ...
  511     1.99902       1
  512     2.00098       2
            ...
 1022     2.99804       2
 1023     3.00000       3

Как видите, у вас есть сопоставление 512 возможных значений potVal. to 1, 511 значений, сопоставленных с 2, и одно сопоставленное значение до 3.

Я предполагаю, что вы бы предпочли, чтобы одна треть диапазона сопоставлялась с каждым ценить. Этого можно добиться, написав map(potVal, 0, 1024, 1, 4):

potVal  not rounded  rounded
----------------------------
    0     1.00000       1
            ...
  341     1.99902       1
  342     2.00195       2
            ...
  682     2.99805       2
  683     3.00098       3
            ...
 1023     3.99707       3

Это дает 342 значения, сопоставленные с 1, 341 значение сопоставлено to 2 и 341 значения сопоставлены с 3. Теперь проблема в том, что такой способ использования map() сбивает с толку. Вы можете предпочесть написать вместо этого что-то более явное, например:

if (potval < 1023/3) chosenColor = 1;
else if (potval < 1023*2/3) chosenColor = 2;
else chosenColor = 3;
,

0

Не уверен, что это поможет, но я хотел, чтобы ползунок в диапазоне от 0 до 200 давал 3 значения; 0 для первой трети движения, 1 для второй трети и 2 для последней трети

Я использовал карту (значение ползунка, 0, 134, 0, 2)

,