Нужна помощь с программированием ЖК-дисплея для моего проекта

Я пытаюсь сделать цифровые игральные кости для своего школьного проекта. У меня проблемы с программированием, я не очень умею писать код и я не программист.

Я черпал вдохновение из поста на сайте Arduino (https://projecthub.arduino.cc/tylerpeppy/arduino-digital-dice-4d7e2e), где кто-то уже создал проект, который я пытаюсь реализовать.

В коде мне нужно, чтобы он бросал или случайным образом генерировал числа от 1 до 12. Если возможно, я бы хотел сделать так, чтобы у него были разные режимы, например, если я нажму кнопку дважды, он изменит режим на генерацию чисел от 1 до 6.

У МЕНЯ ПРОБЛЕМА:

Когда я загружаю код в Arduino, он говорит «Цифровой», а затем сразу же переключается на «Вращение», и остается на слове «Вращение» и больше ничего не говорит, пока я не нажму кнопку (затем все начинается снова).

ПРИМЕЧАНИЕ: правая половина дисплея пуста из-за аппаратного сбоя

Итак, мой вопрос: как мне это исправить, чтобы оно выдавало мне результаты броска костей?

Вот схемы и несколько изображений;

Это код, который я использовал для программирования;

include <LiquidCrystal.h>
long randNumber;

int Led = 13; //определить порт светодиода
int Shock = 2; //определить порт удара
int val;//определяем цифровую переменную val

// инициализируем библиотеку с номерами интерфейсных контактов
LiquidCrystal lcd(7, 8, 9, 10, 11, 12 );

byte customChar[] = {
  B00000,
  B00000,
  B11111,
  B11001,
  B10101,
  B10011,
  B11111,
  B00000
};

void setup()
{
  lcd.begin(16, 2);
  lcd.createChar(0, customChar);
  lcd.home();

  pinMode(Led, OUTPUT); //определяем светодиод как выходной порт

  randomSeed(analogRead(0));

  pinMode(Shock, INPUT); //определяем датчик удара как выходной порт

  lcd.write(byte( 0));
  lcd.print("Digital dice");
  lcd.write(byte( 0));
  delay(1000);
}

void loop()
{
  val = digitalRead(Shock); //считываем значение цифрового интерфейса 3, назначенного val
  if (val == LOW) //когда датчик удара имеет сигнал, делаем следующее
  {
    lcd.clear();
    lcd.print("Rolling dice...");
    delay(4000);

    lcd.clear();
    lcd.setCursor(0, 0);

    randNumber = random(1,7);

    lcd.print("Dice 1 = ");
    lcd.print(randNumber);
    lcd.setCursor(0, 1);

    randNumber = random(1,7);

    lcd.print("Dice 2 = ");
    lcd.print(randNumber);
  }
  delay(150);
}

Я ценю каждого, кто хочет помочь каким-либо образом!

, 👍1

Обсуждение

вы пытаетесь увидеть что-то, что длится всего несколько миллисекунд... подумайте, почему вы можете видеть Rolling, @jsotola

ага, я понял, так строка delay в коде сообщает вам, как долго что-то отображается?, @Urban

в этой программе, да... инструкция delay фактически останавливает программу... вот почему ее использование нежелательно, когда программа должна реагировать на входные данные, @jsotola

микроконтроллер — очень глупая машина, он может делать только то, что вы ему говорите... поэтому вы всегда должны знать, что вы ему говорите делать., @jsotola

Теперь я это вижу, да. Я немного поигрался с этим и теперь понимаю, как это работает, немного лучше... спасибо @jsotola Я очень благодарен и очень ценю твою помощь и терпение по отношению ко мне, @Urban

Ненавижу, когда люди говорят, что задержка «останавливает программу». Это приводит к типам заблуждений, которые усложняют понимание неблокируемого кода. Функция задержки не «останавливает» программу. Она **ЯВЛЯЕТСЯ** программой. Программа выполняется строка за строкой, как и любая другая программа. И каждая строка выполняет свою задачу по одной за раз. Просто линия задержки занимает очень много времени, чтобы закончить и перейти к следующей строке. Программа выполняется. Она просто выполняет одну строку в течение долгого времени., @Delta_G

Понимание этого помогает, я думаю, понять, что неблокирующий код на самом деле не делает две вещи одновременно. Он просто не останавливается ни на одной строке, чтобы подождать, пока все эти строки не выполнятся хотя бы один раз за какой-то очень короткий период., @Delta_G

@Delta_G, вы правы в своих мыслях... инструкция wait зацикливается внутри себя, подсчитывая прерывания до тех пор, пока не пройдет запрошенный интервал времени... для внешнего наблюдателя программа прекращает работу, @jsotola

Предлагаю вам распечатать номер на последовательном мониторе. Это поможет в процессе отладки., @tepalia


1 ответ


0

Вызов delay() отдает предпочтение одной части скетча или одной его части за раз, не давая другим выполняться. Обычно мы пытаемся поддерживать несколько довольно медленных (обычно внешних) вещей, происходящих одновременно, или, по крайней мере, тестировать их достаточно часто, чтобы обслуживать их так быстро, как это необходимо. Чтобы сделать это, мы должны проверить, нужно ли запускать/останавливать/настраивать каждую из этих вещей, и делать это очень часто и очень быстро, пока/если мы не найдем ту, которая требует некоторого внимания. Даже тогда мы делаем все, что нужно, быстро! и возвращаемся к тестированию остальных наших вещей.
«Вещь» в данном случае означает включение или выключение светодиода, написание сообщения или гашение ЖК-дисплея, запуск или остановку двигателя и т. д.

Написание вашего скетча таким образом называется неблокируемым программированием. Мы не позволяем процессору простаивать, пока происходит что-то внешнее; мы возвращаемся и проверяем его снова позже (может быть, всего через несколько миллисекунд, но позже).

Посмотрите на эту мою более раннюю статью о неблокирующем программировании, затем вернитесь и снова прочитайте этот ответ. Это должно дать вам довольно хорошее представление о том, как должен работать ваш скетч, чтобы он делал то, что вы хотите, и как написать тот, который это делает.

,