Отображение двоичных данных на светодиодах

Я написал программу для Arduino UNO и 3 светодиодных лампочек. Программа должна преобразовывать введенное число в двоичное, а затем отображать его на светодиодах, вкл. - 1, выкл. - 0. Я просматривал ее довольно много раз и не понимаю, почему она не работает так, как должна. Я новичок в работе с Arduino, поэтому мне, вероятно, просто нужен более опытный взгляд, чтобы показать мне, где я накосячил. Ниже у меня есть ссылка на изображение настройки Arduino. Спасибо! https://drive.google.com/file/d/0B8k_WNZ3eFOkZHkwNUllTEp4WGM/view?usp=sharing

//настройка освещения
const int lightOne = 13;
const int lightTwo = 12;
const int lightThree = 11;

//массив огней для печати двоичного кода
int lights[] = {lightOne, lightTwo, lightThree};


void setup() {
  //установка режимов выводов и запуск последовательного монитора
  pinMode(lightOne, OUTPUT);
  pinMode(lightTwo, OUTPUT);
  pinMode(lightThree, OUTPUT);
  Serial.begin(9600);
}


//преобразует заданное число в двоичное
String binary(int number) {
  String r;
  while(number!=0) {
    r = (number % 2 == 0 ? "0" : "1")+r; 
    number /= 2;
  }
  return r;
}

//выводит двоичную строку на индикаторы (не ожидая чисел больше 9)
void printBinary(String binaryNumber) {
  for (int i = 0; i < sizeof(binaryNumber); i++) {
    digitalWrite(lights[i+11], (binaryNumber[i] == '0' ? LOW : HIGH));
    delay(2000);
  }
}


void loop() {
  int input = Serial.read();                //получить число
  String binaryNumber = binary(input);      //преобразовать число в двоичное
  Serial.println(binaryNumber);             //вывести двоичный код на последовательный монитор
  printBinary(binaryNumber);                //отображение числа в двоичном виде на светодиодах

}

, 👍2


3 ответа


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

2

Добро пожаловать в SE Arduino!

Длинная версия

Вам нужно обратить внимание на несколько вещей:

  1. Не используйте класс String, он слишком нагружает Arduino.
  2. Ваша функция преобразования на самом деле не нужна, поскольку вы можете преобразовать ее в Serial.println(), указав binary в качестве выходных данных. Например: <code>Serial.println(number, BIN)</code>;
  3. Serial.read возвращает целое число, но этот int в любом случае содержит только <code>byte</code> (беззнаковое) значение (если только нечего читать, в таком случае он возвращает -1). Поскольку вы принимаете число (на самом деле не имеет значения) и хотите, чтобы оно было числом при возврате, просто используйте int или byte (беззнаковое: 0 <-> 255) или <code>char</code> (со знаком: -127 <-> +128).
  4. Вы можете/должны/не имеет значения, используете ли вы Serial.available() или нет, это ваше дело, я обычно так делаю, но это в любом случае неблокируемо, и если там нечего читать, то он просто продолжит работу. Хотя, если вы не собираетесь его использовать, вам следует проверить на -1, поскольку то, что вы делаете в данный момент, это берете это и преобразуете в двоичный код (который равен 0xFF, что означает все включено). Это одна из ваших основных проблем в коде (другая находится в разделе Короткая версия.
  5. Вы используете "0" и "1", которые являются значениями ASCII, и вы не указали, как вы получаете число. Так что это может быть ASCII (byte) или на самом деле значение byte. т. е. "0" это 48 (dec) или 30 (hex). Тогда как 0 это просто ноль. Достаточно забавно, что поскольку вы используете остаток от деления (%), это на самом деле не имеет значения, потому что вас интересует только младший полубайт, который для вашего кода не имеет значения, что закодировано в старшем конце. например: 1 (0b00000001) то же самое, что "1" = 49 (dec) = 0x31 = 0b00110001 при использовании с %2.
  6. Избавьтесь от delay(2000). Задержки — зло* :) Вы можете записывать значения на контакты целый день, и это не вызовет никаких проблем. Если вы хотите выводить меньше данных на последовательный порт (что вам и следует делать), вы можете сделать синхронизированный вывод обратно на последовательный порт. Например, выполняйте Serial.println() раз в секунду или записывайте значения в резервные/старые переменные и сравнивайте их, а вывод выводите только в случае изменения значения.
  7. Самое важное — в следующем разделе

Короткая версия

Вот ваша главная проблема, в этой строке:

digitalWrite(lights[i+11], (binaryNumber[i] == '0' ? LOW : HIGH));

Я думаю, вам нужно:

digitalWrite(lights[i], (binaryNumber[i] == '0' ? LOW : HIGH));

У вас уже есть значение PIN-кода, закодированное в массиве, вам не нужно добавлять 11 к индексу, это поднимет вас выше трех значений света :)

* Задержки — зло: Это вопрос мнения, и это просто то, что я чувствую, я на самом деле погуглил, и это просто случайный ответ. Но он содержит суть того, что я бы сказал в любом случае: http://www.makeuseof.com/tag/arduino-delay-function-shouldnt-use/

,

Я собирался переписать ваш код, но вы в любом случае дали ему довольно хороший удар, так что возьмите мою информацию выше на вооружение и попробуйте еще раз. Если у вас возникнут какие-либо проблемы, опубликуйте свой новый код в обновлении вопроса, и мы поможем вам поработать над ним дальше. Если вы под кайфом и просто хотите получить ответ, дайте нам знать, и я или кто-то другой сможет подсказать вам, как мы это сделаем, но нет ничего лучше, чем учиться, чем делать это самостоятельно. Это засядет у вас в голове гораздо лучше, когда вы попробуете еще раз самостоятельно. Вы больше не будете делать ошибок, подобных этому index (или, во всяком случае, не таким образом), @Madivad

Спасибо! На самом деле изначально у меня не было ошибки в индексе, но когда я вчера вечером просматривал ее, мой уставший разум подумал, что я допустил ошибку там, где ее не было, и исправил ее., @Jamerack

Удивительно, что иногда делает уставший разум. Я часто обнаруживаю, что пытаюсь закончить «одно дело» перед тем, как лечь спать, и это может поставить меня в тупик на несколько часов! В какой-то момент я сдаюсь и прекращаю работу. На следующее утро, отдохнувший, вы бросаете взгляд на него и видите то, что вы просто не можете поверить, что пропустили прошлой ночью, и за 30 секунд вы исправили предыдущие 4+ часа беспокойства. Вы думаете про себя, в следующий раз, когда это произойдет, я просто пойду спать. Но в следующий раз, когда это происходит, вы проводите еще одну ночь над одной проблемой, на решение которой уходит еще 30 секунд на следующий день, снова! lol, @Madivad

Я обязательно так и сделаю в следующий раз и избавлю себя от лишних хлопот, лол., @Jamerack


1

Перед чтением необходимо проверить наличие доступных символов. См. документацию по Serial.read() (и Serial.available()).

Ура!

,

0

Глядя на вашу фотографию, кажется, что есть только одно соединение с каждым светодиодом. Вам также нужно заземление. У вас есть провод, который идет к шине заземления на плате прототипа, но не оттуда к самим светодиодам.

,

Я подключил резисторы между светодиодами и шиной заземления., @Jamerack