Управление трёхцветным светодиодом по USB

0razzu
Offline
Зарегистрирован: 02.06.2016

Задумка такая: с клавиатуры вводится 16-ричный код цвета, трёхцветный светодиод отображает этот цвет, но на деле как-то криво всё работает. Например, при вводе "000000" светодиод горит. ЧЯДНТ?

#define R 9
#define G 10
#define B 11
#include <math.h>

String c;
byte r = 0, g = 0, b = 0, i = 0;

void setup() {
  pinMode(R, OUTPUT);
  pinMode(G, OUTPUT);
  pinMode(B, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  while (Serial.available())
  {
    char inChar = Serial.read();
    if (inChar == '\n')
    {
      for (i = 0; i <= 1; i++)
      {
        if (c[i] == 'A')
          r += (10 * pow(16, 1 - i));
        else if (c[i] == 'B')
          r += (11 * pow(16, 1 - i));
        else if (c[i] == 'C')
          r += (12 * pow(16, 1 - i));
        else if (c[i] == 'D')
          r += (13 * pow(16, 1 - i));
        else if (c[i] == 'E')
          r += (14 * pow(16, 1 - i));
        else if (c[i] == 'F')
          r += (15 * pow(16, 1 - i));
        else
          r += (c[i] * pow(16, 1 - i));
      }
      analogWrite(R, r);
      for (i = 2; i <= 3; i++)
      {
        if (c[i] == 'A')
          g += (10 * pow(16, 3 - i));
        else if (c[i] == 'B')
          g += (11 * pow(16, 3 - i));
        else if (c[i] == 'C')
          g += (12 * pow(16, 3 - i));
        else if (c[i] == 'D')
          g += (13 * pow(16, 3 - i));
        else if (c[i] == 'E')
          g += (14 * pow(16, 3 - i));
        else if (c[i] == 'F')
          g += (15 * pow(16, 3 - i));
        else
          g += (c[i] * pow(16, 3 - i));
      }
      analogWrite(G, g);
      for (i = 4; i <= 5; i++)
      {
        if (c[i] == 'A')
          b += (10 * pow(16, 5 - i));
        else if (c[i] == 'B')
          b += (11 * pow(16, 5 - i));
        else if (c[i] == 'C')
          b += (12 * pow(16, 5 - i));
        else if (c[i] == 'D')
          b += (13 * pow(16, 5 - i));
        else if (c[i] == 'E')
          b += (14 * pow(16, 5 - i));
        else if (c[i] == 'F')
          b += (15 * pow(16, 5 - i));
        else
          b += (c[i] * pow(16, 5 - i));
      }
      analogWrite(B, b);
      c = "";
    }
    else
      c += inChar;
  }
}

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Вы как-то слишком уж мудрёно переводите числа. Ещё мудренее не пробовали?

Ошибки очевидны, но Вам лучше найти их самому. 

Для этого поставьте перед строками 39, 57 и 75 вывод в сериал соответсвенно r, g и b. Хоть посмотрите что у Вас там получается. Когда посмотрите, думайте, как исправить.

А вообще, это надо делать раз в 20 короче и проще. Вот, смотрите. Все чудеса происхлдят в строках 15-17. Всё остальное - оформительство.

template <typename T> inline Print & operator << (Print &s, T n) { s.print(n); return s; }

inline void prompt(void) {
	Serial << "Enter three bytes hexadecimal number (six characters 0-F with no spaces):\n";
}

void setup() {
	Serial.begin(115200);
	Serial.setTimeout(0xFFFFFFFF);
	prompt();
}

void loop() {
	if (! Serial.available()) return;
	String s = Serial.readStringUntil('\n');
	unsigned r, g, b;
	sscanf(s.c_str(), "%2x%2x%2x", &r, &g, &b);
	Serial << "s=" << s << "=  r=" << r << "  g=" << g << "  b=" << b << "\n\n";
	prompt();
}

Здесь нет никакой проверки на правильность введённой информации, а также никакого "паренья" об эффективности. Если уж Вы используете String, то эффективность Вас не волнует, как я понимаю. Если нужна эффективность, то это пшется чуть длинее, но без String и без sscanf.

0razzu
Offline
Зарегистрирован: 02.06.2016

Спасибо огромное! Как всё оказалось просто)