Помогите с очисткой памяти.

Я получил следующий код с Github и экспериментировал с ним последние пару месяцев. Цикл ВСЕГДА начинается с одного и того же светодиода, пока вы выполняете полный сброс платы или включаете ее. Если я нажму кнопку запуска (я добавил) после предыдущего запуска цикла, обычно загорится другой светодиод. Я хочу, чтобы один и тот же светодиод запускал каждый цикл ВСЕ время (сброс, включение питания И кнопка запуска).

Моя текущая макетная плата — это Arduino Mega, в которой используется матрица 4x4 для кнопок и светодиодов для некоторых цифровых выходов. В настоящее время я использую 6 светодиодов, но планирую добавить еще несколько, когда все будет работать так, как я хочу.

Краткое описание того, как это работает... При включении питания на ЖК-дисплее отображается надпись «Таймер реакции Киндры». При нажатии кнопки старт начинается обратный отсчет и загорается первый светодиод (светодиод 2), при нажатии соответствующей кнопки загорается другой светодиод до тех пор, пока не будет нажата соответствующая кнопка и т. д. Игра длится 30 секунд, по окончании В игре отображается ваш счет. В этот момент вы можете просто нажать «Старт», чтобы сделать это снова. Моя текущая проблема: я хочу, чтобы светодиод «2» загорался первым при запуске следующей игры. Я знаю, что есть что-то, сохраняющее память, потому что, когда вы наблюдаете, как последний свет включается за секунду до окончания таймера, он зажигает тот же свет на долю секунды в следующей игре.

Я подозреваю, что (old_butn = 0;) моя проблема. Я пробовал перемещать его по всему эскизу и менять цифры после него, но безуспешно .

Я надеюсь, что кто-нибудь укажет мне правильное направление.

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
#include <Utility.h>
#include "tones.h" //файл музыки, лежит в папке прошивки

#define GAMETIME 30000
#define LAMP 6
#define RES_KEY 15
#define BUZZER_PIN 19
#define BLINK 40

LiquidCrystal_I2C lcd(0x3F, 20, 4);

const byte ROWS = 4;
const byte COLS = 4;
char hexaKeys[ROWS][COLS] = {
  {'<', '8', '4', '0'},
  {'=', '9', '5', '1'},
  {'>', ':', '6', '2'},
  {'?', ';', '7', '3'}
};

byte colPins[ROWS] = {39, 37, 35, 33};
byte rowPins[COLS] = {41, 43, 45, 47};
boolean lamp_on[6];
boolean steps = true, go_game = true;
int lamp_pin[15] = {2, 3, 4, 5, 6, 7};
unsigned long startTime [12] = { 0, 0, 0, 0 };
unsigned long duration [12] ;
const int buttonPin = 14;
const int startPin = 8;
long last_pressed = 0;
long nowMillis = 0;
long toSec = 0;
long gameStart = 0;
long toBlink = 0;
int score = 0;
int dlay = 1000;
int butn = 0;
int old_butn = 100;
char customKey;

int melody[] = { NOTE_C4, NOTE_G3, NOTE_G3, NOTE_A3, NOTE_G3, 0, NOTE_B3, NOTE_C4 };
int noteDurations[] = { 4, 8, 8, 4, 4, 4, 4, 4 };

Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);
//====================================
void(* resetFunc) (void) = 0;
//====================================
void setup()
{
  randomSeed(analogRead(0));
  pinMode(BUZZER_PIN, OUTPUT);
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(startPin, OUTPUT);
  tone(BUZZER_PIN, 5000, 500);
  foreach (lamp_pin, LAMP, pinMode, OUTPUT);
  foreach (lamp_pin, LAMP, digitalWrite, HIGH);
  foreach (lamp_pin, LAMP, digitalWrite, LOW);
  delay(500);
  lcd.init();
  lcd.backlight();
  lcd.setCursor(4, 0);
  lcd.print("ver 3.5");
  lcd.setCursor(0, 2);
  lcd.print("KYNDRAS REACTION");
  lcd.setCursor(6, 3);
  lcd.print("GAME");
}
//====================================
void loop()
{
  //******* позволяет выполнить сброс в любой момент внутри цикла
  customKey = customKeypad.getKey();
  if (customKey - 48 == RES_KEY) {
    go_game = true;
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("RESTART!");
    delay(500);
    resetFunc();
  }
  //******* дерьмо становится реальностью
  if (digitalRead(startPin) == HIGH)
  {
    foreach (lamp_pin, LAMP, digitalWrite, LOW);//заставляет все светодиоды гаснуть после случайного мигания

    countDown();
    //-------
    gameStart = millis();
    nowMillis = gameStart;
    score = 0;
    steps = true;
    go_game = true; //эта строка позволяет начать без сброса
    while ((nowMillis - gameStart < GAMETIME) and (go_game)) {
      nowMillis = millis();
      //**********
      if (nowMillis - toSec > 1000) {
        lcd_print();
        toSec = nowMillis;
      }
      //**********
      if (nowMillis - toBlink > BLINK) {
        if (lamp_on[old_butn]) {
          sw_led_off(old_butn);
        }
        else {
          sw_led_on(old_butn);
        }
        toBlink = nowMillis;
      }
      //**********
      if (steps) {
        while (old_butn == butn) {
          butn = random(LAMP);
        }
        sw_led_off(old_butn);
        old_butn = butn;
        sw_led_on(butn);
        steps = false;
      }
      //**********
      customKey = customKeypad.getKey();
      if (customKey) Serial.println((int)customKey);
      if (customKey - 48 == butn) {
        sw_led_off(customKey - 48);
        score++;
        steps = true;
        lcd_print();
      } else if (customKey - 48 == RES_KEY) {
        gameStart = millis();
        foreach (lamp_pin, LAMP, digitalWrite, LOW);
        score = 0;
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("RESTART!");
        delay(500);
        resetFunc();
      }
    }
    if (go_game) game_over(); // игра окончена
    go_game = false;
      }
  //******** случайное моргание

  for (int i = 0; i < 6; i++)
  {
    randomBlink(i);
  }
}

//====================================
void lcd_print() {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("TIME:");
  int time = GAMETIME / 1000 - (nowMillis - gameStart) / 1000;
  lcd.print(time);
  if (time < 11) {
    tone(BUZZER_PIN, 3500 + time * 300, 150);
  }
  lcd.setCursor(11, 0);
  lcd.print("BTN:");
  lcd.print(customKey);
  lcd.setCursor(0, 2);
  lcd.print("SCORE:");
  lcd.print(score);
}
//====================================
void game_over() {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("   END");
  lcd.setCursor(0, 2);
  lcd.print("     SCORE: ");
  lcd.print(score);
  foreach (lamp_pin, LAMP, digitalWrite, HIGH);//все лампы загораются на 2 секунды в конце игры
  delay (2000);
  for (int thisNote = 0; thisNote < 8; thisNote++) {
    int noteDuration = 1000 / noteDurations[thisNote];
    tone(BUZZER_PIN, melody[thisNote], noteDuration);
    int pauseBetweenNotes = noteDuration * 1.30;
    delay(pauseBetweenNotes);
    noTone(BUZZER_PIN);
  }
}
//====================================
void sw_led_on(int num) {
  digitalWrite(lamp_pin[num], 1);
  lamp_on[num] = 1;
}
//====================================
void sw_led_off(int num) {
  digitalWrite(lamp_pin[num], 0);
  lamp_on[num] = 0;
}
//====================================
void randomBlink(int pin)
{
  if (millis() - startTime[pin] >= duration[pin])
  {
    digitalWrite(lamp_pin[pin], !digitalRead(lamp_pin[pin]));
    duration[pin] = random(150, 1500);  //наименьшее и самое продолжительное время включения/выключения.
    startTime[pin] = millis();
  }
}
//=====================================
void countDown() {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("   GET READY");
  delay(500);
  lcd.setCursor(0, 2);
  lcd.print("   START IN 3...");
  tone(BUZZER_PIN, 4000, 200);
  delay(500);
  lcd.setCursor(0, 2);
  lcd.print("   START IN 2...");
  tone(BUZZER_PIN, 4500, 200);
  delay(500);
  lcd.setCursor(0, 2);
  lcd.print("   START IN 1...");
  tone(BUZZER_PIN, 5000, 200);
  delay(500);
  lcd.clear();
  lcd.setCursor(0, 1);
  lcd.print("  GO!");
  delay(250);
  for (int i = 0; i < 5; i++) {
    int frequency = 4000 + i * 300;
    tone(BUZZER_PIN, frequency, 150);
    delay(130);
  }
}

, 👍0

Обсуждение

Можете дать ссылку на Github, где вы это нашли? Что такое <Utility.h>? Это игровая библиотека? Функция foreach есть в этой библиотеке? Я не уверен, что вы хотите, и не знаю, возможно ли это., @Jot

посмотрите на все команды, которые имеют отношение к случайным числам... одна из них может быть причиной, @jsotola


1 ответ


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

0

Переменные butn и old_butn устанавливаются в значения 0 и 100 перед запуском игры. Мне не ясно, что представляют собой эти значения. Но переназначение переменных обратно на 0 и 100 при каждом перезапуске или перезагрузке игры должно исправить это.

Возможно, в конце функции game_over(). Однако, вероятно, это также следует сделать перед вызовом resetFunc() — что бы это ни делало, его определение не включается.

,

Спасибо. Я попробовал это с каждым. Вы были правы, нужно было сделать и то, и другое., @Bender